diff --git a/Cargo.lock b/Cargo.lock index e1225f2cc..408849d69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -441,7 +441,7 @@ dependencies = [ "sha1", "sync_wrapper 1.0.1", "tokio", - "tokio-tungstenite 0.21.0", + "tokio-tungstenite", "tower", "tower-layer", "tower-service", @@ -1593,7 +1593,7 @@ dependencies = [ "tar", "thiserror", "tokio", - "tokio-tungstenite 0.21.0", + "tokio-tungstenite", "toml", "tracing", "tracing-subscriber", @@ -1624,16 +1624,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" -[[package]] -name = "flatbuffers" -version = "23.5.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dac53e22462d78c16d64a1cd22371b54cc3fe94aa15e7886a2fa6e5d1ab8640" -dependencies = [ - "bitflags 1.3.2", - "rustc_version", -] - [[package]] name = "flatbuffers" version = "24.3.25" @@ -1712,7 +1702,7 @@ dependencies = [ "delegate", "directories", "either", - "flatbuffers 24.3.25", + "flatbuffers", "freenet-stdlib", "futures", "headers", @@ -1743,7 +1733,7 @@ dependencies = [ "thiserror", "time", "tokio", - "tokio-tungstenite 0.21.0", + "tokio-tungstenite", "tower-http", "tracing", "tracing-opentelemetry", @@ -1773,7 +1763,7 @@ dependencies = [ "bs58", "byteorder", "chrono", - "flatbuffers 23.5.26", + "flatbuffers", "freenet-macros", "futures", "js-sys", @@ -1787,7 +1777,7 @@ dependencies = [ "serde_with", "thiserror", "tokio", - "tokio-tungstenite 0.20.1", + "tokio-tungstenite", "tracing", "tracing-subscriber", "wasm-bindgen", @@ -5694,18 +5684,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-tungstenite" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" -dependencies = [ - "futures-util", - "log", - "tokio", - "tungstenite 0.20.1", -] - [[package]] name = "tokio-tungstenite" version = "0.21.0" @@ -5715,7 +5693,7 @@ dependencies = [ "futures-util", "log", "tokio", - "tungstenite 0.21.0", + "tungstenite", ] [[package]] @@ -6019,25 +5997,6 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" -[[package]] -name = "tungstenite" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" -dependencies = [ - "byteorder", - "bytes", - "data-encoding", - "http 0.2.12", - "httparse", - "log", - "rand", - "sha1", - "thiserror", - "url", - "utf-8", -] - [[package]] name = "tungstenite" version = "0.21.0" diff --git a/contract-detail.tsx b/contract-detail.tsx new file mode 100644 index 000000000..aa9701ea2 --- /dev/null +++ b/contract-detail.tsx @@ -0,0 +1,399 @@ +import { useEffect, useState } from "react"; +import { createRoot } from "react-dom/client"; +import { + TransactionDetailInterface, + TransactionPeerInterface, + TransactionData +} from "./type_definitions"; +import { PeerId } from "./topology"; + +interface TransactionDetailPeersHistoryInterface { + tx_peer_list: Array; +} + +interface FilterInterface { + filter_type: string; + filter_value: string; +} + +interface FilterDictionaryInterface { + [key: string]: FilterInterface; +} + +let ring_mock_data = []; +const TransactionPeersHistory = ({ + tx_peer_list, +}: TransactionDetailPeersHistoryInterface) => { + const [filter, set_filter] = useState({}); + const [filtered_list, set_filtered_list] = useState(tx_peer_list); + + const add_filter = (filter_type: string, filter_value: string) => { + if (check_if_contains_filter(filter_type)) { + return; + } + + filter[filter_type] = { + filter_type, + filter_value, + }; + + set_filter(filter); + + update_filtered_list(); + }; + + const update_filtered_list = () => { + let filtered_list = tx_peer_list; + + Object.keys(filter).forEach((filter_type) => { + const filter_value = filter[filter_type].filter_value; + filtered_list = filtered_list.filter((tx) => { + for (const [key, value] of Object.entries(tx)) { + if (key === filter_type) { + return value === filter_value; + } + } + }); + }); + + set_filtered_list(filtered_list); + }; + + const clear_one_filter = (filter_type: string) => { + delete filter[filter_type]; + update_filtered_list(); + }; + + const clear_all_filters = () => { + set_filter({}); + }; + + useEffect(() => { + update_filtered_list(); + + let ring_mock_data = [ + { + id: new PeerId("1"), + currentLocation: 0.123485, + connectionTimestamp: 1234567890, + connections: [], + history: [], + locationHistory: [], + }, + { + id: new PeerId("2"), + currentLocation: 0.183485, + connectionTimestamp: 1234567890, + connections: [], + history: [], + locationHistory: [], + }, + { + id: new PeerId("3"), + currentLocation: 0.323485, + connectionTimestamp: 1234567890, + connections: [], + history: [], + locationHistory: [], + }, + { + id: new PeerId("4"), + currentLocation: 0.423485, + connectionTimestamp: 1234567890, + connections: [], + history: [], + locationHistory: [], + }, + { + id: new PeerId("5"), + currentLocation: 0.783285, + connectionTimestamp: 1234567890, + connections: [], + history: [], + locationHistory: [], + }, + ]; + + // ringHistogram(ring_mock_data); + + // const graphContainer = d3.select( + // document.getElementById("other-peer-conns-graph") + // ); + + // ringVisualization(ring_mock_data[0], graphContainer, 1.25); + }, [filter]); + + const check_if_contains_filter = (filter_type: string) => { + return filter[filter_type] !== undefined; + }; + + return ( +
+

Transaction Peers History

+ {Object.keys(filter).length > 0 && ( +
+ +
+ )} + + + + + + + + + + + + + {filtered_list.map((tx) => ( + + + + + + + + + ))} + +
+ Peer Id + {check_if_contains_filter("peer_id") && ( + + )} + Localization + State + {check_if_contains_filter("last_state") && ( + + )} + + Message + {check_if_contains_filter("last_message") && ( + + )} + StartedFinalized
+ add_filter("peer_id", tx.peer_id) + } + style={{ + cursor: "pointer", + }} + > + {tx.peer_id} + {tx.location} + add_filter("last_state", tx.last_state) + } + style={{ + cursor: "pointer", + }} + > + {tx.last_state} + + add_filter("last_message", tx.last_message) + } + style={{ + cursor: "pointer", + }} + > + {tx.last_message} + {tx.started}{tx.finalized}
+
+ ); +}; + +// TODO: use real types +const TransactionHistory = ({ tx_history }: any) => ( +
+

Transaction History

+ + + + + + + + + {/* + + */} + + + + {tx_history && + tx_history.map((change: TransactionData) => ( + + + + + + + + ))} + +
Transaction IdRequester Peer IdTarget Peer IdTypeContract KeyStatusStartedFinalized
{change.transaction_id}{change.requester}{change.target}{change.change_type}{change.contract_id}
+
+); + +const TransactionDetail = ({ + transaction, + is_displayed, + close_detail, + peers_history, + tx_history, +}: TransactionDetailInterface) => ( +
+
+ +

Transaction Detail

+
+

ID {transaction.transaction_id}

+

Type {transaction.change_type}

+ {/*

Status {transaction.status}

+

Started {transaction.started}

+

Finalized {transaction.finalized}

*/} +

Requester {transaction.requester}

+

Target {transaction.target}

+

Contract Key {transaction.contract_id}

+
+ +
+

Location Peers

+
+
+ +
+ {another_ring_visualization()} +
+ + {peers_history && ( + + )} + + +
+
+); + +const another_ring_visualization = () => { + // Declare the chart dimensions and margins. + const width = 640; + const height = 400; + const marginTop = 20; + const marginRight = 20; + const marginBottom = 30; + const marginLeft = 40; + + // // Declare the x (horizontal position) scale. + // const x = d3 + // .scaleUtc() + // .domain([new Date("2023-01-01"), new Date("2024-01-01")]) + // .range([marginLeft, width - marginRight]); + + // // Declare the y (vertical position) scale. + // const y = d3 + // .scaleLinear() + // .domain([0, 100]) + // .range([height - marginBottom, marginTop]); + + // // Create the SVG container. + // const svg = d3.create("svg").attr("width", width).attr("height", height); + + // // Add the x-axis. + // svg.append("g") + // .attr("transform", `translate(0,${height - marginBottom})`) + // .call(d3.axisBottom(x)); + + // // Add the y-axis. + // svg.append("g") + // .attr("transform", `translate(${marginLeft},0)`) + // .call(d3.axisLeft(y)); + + let a = ( + + + + + + + + + + + ); + + // Append the SVG element. + return a; +}; + +export default TransactionDetail; diff --git a/crates/core/src/client_events.rs b/crates/core/src/client_events.rs index 02fea0a2b..6489eb87a 100644 --- a/crates/core/src/client_events.rs +++ b/crates/core/src/client_events.rs @@ -471,7 +471,22 @@ pub(crate) mod test { } return Some(request.into()); } - val if (5..35).contains(&val) => { + val if (5..20).contains(&val) => { + if let Some(contract) = self.choose(&state.existing_contracts) { + if !for_this_peer { + continue; + } + + let request = ContractRequest::Put { + contract: contract.clone(), + state: WrappedState::new(self.random_byte_vec()), + related_contracts: RelatedContracts::new(), + }; + + return Some(request.into()); + } + } + val if (20..35).contains(&val) => { if let Some(contract) = self.choose(&state.existing_contracts) { if !for_this_peer { continue; diff --git a/crates/core/src/generated/mod.rs b/crates/core/src/generated/mod.rs index dd5c0a55d..52efedad5 100644 --- a/crates/core/src/generated/mod.rs +++ b/crates/core/src/generated/mod.rs @@ -2,6 +2,7 @@ #[cfg(feature = "trace")] pub(crate) mod topology_generated; +use freenet_stdlib::prelude::ContractKey; pub use topology_generated::*; use crate::{message::Transaction, node::PeerId}; @@ -16,6 +17,116 @@ pub enum PeerChange<'a> { Error(topology::Error<'a>), } +pub enum ContractChange<'a> { + PutRequest(topology::PutRequest<'a>), + PutSuccess(topology::PutSuccess<'a>), + PutFailure(topology::PutFailure<'a>), +} + +// TODO: Change this to EventWrapper +pub enum ChangesWrapper<'a> { + ContractChange(ContractChange<'a>), + PeerChange(PeerChange<'a>), +} + +impl ContractChange<'_> { + pub fn put_request_msg( + transaction: String, + contract: String, + requester: String, + target: String, + ) -> Vec { + let mut buf = flatbuffers::FlatBufferBuilder::new(); + let transaction = buf.create_string(transaction.as_str()); + let contract = buf.create_string(contract.as_str()); + let requester = buf.create_string(requester.as_str()); + let target = buf.create_string(target.as_str()); + let put_req = topology::PutRequest::create( + &mut buf, + &topology::PutRequestArgs { + transaction: Some(transaction), + key: Some(contract), + requester: Some(requester), + target: Some(target), + }, + ); + let msg = topology::ContractChange::create( + &mut buf, + &topology::ContractChangeArgs { + contract_id: Some(contract), + change_type: topology::ContractChangeType::PutRequest, + change: Some(put_req.as_union_value()), + }, + ); + buf.finish_minimal(msg); + buf.finished_data().to_vec() + } + + pub fn put_success_msg( + transaction: String, + contract: String, + requester: String, + target: String, + ) -> Vec { + let mut buf = flatbuffers::FlatBufferBuilder::new(); + let transaction = buf.create_string(transaction.as_str()); + let contract = buf.create_string(contract.as_str()); + let requester = buf.create_string(requester.as_str()); + let target = buf.create_string(target.to_string().as_str()); + let put_success = topology::PutSuccess::create( + &mut buf, + &topology::PutSuccessArgs { + transaction: Some(transaction), + key: Some(contract), + requester: Some(requester), + target: Some(target), + }, + ); + let msg = topology::ContractChange::create( + &mut buf, + &topology::ContractChangeArgs { + contract_id: Some(contract), + change_type: topology::ContractChangeType::PutSuccess, + change: Some(put_success.as_union_value()), + }, + ); + buf.finish_minimal(msg); + buf.finished_data().to_vec() + } + + pub fn put_failure_msg( + transaction: impl AsRef, + contract: impl AsRef, + requester: impl AsRef, + target: impl AsRef, + ) -> Vec { + let mut buf = flatbuffers::FlatBufferBuilder::new(); + let transaction = buf.create_string(transaction.as_ref()); + let contract = buf.create_string(contract.as_ref()); + let requester = buf.create_string(requester.as_ref()); + let target = buf.create_string(target.as_ref()); + let put_failure = topology::PutFailure::create( + &mut buf, + &topology::PutFailureArgs { + transaction: Some(transaction), + key: Some(contract), + requester: Some(requester), + target: Some(target), + }, + ); + let msg = topology::ContractChange::create( + &mut buf, + &topology::ContractChangeArgs { + contract_id: Some(contract), + change_type: topology::ContractChangeType::PutFailure, + change: Some(put_failure.as_union_value()), + }, + ); + buf.finish_minimal(msg); + buf.finished_data().to_vec() + } +} + impl PeerChange<'_> { pub fn current_state_msg<'a>( to: PeerId, @@ -170,3 +281,42 @@ impl<'a> topology::ControllerResponse<'a> { builder.finished_data().to_vec() } } + +impl<'a> TryFromFbs<'a> for ContractChange<'a> { + fn try_decode_fbs(buf: &'a [u8]) -> Result { + let req = flatbuffers::root::(&buf)?; + match req.change_type() { + topology::ContractChangeType::PutRequest => { + let req = req.change_as_put_request().ok_or_else(|| { + flatbuffers::InvalidFlatbuffer::InconsistentUnion { + field: "change_type", + field_type: "ContractChangeType", + error_trace: Default::default(), + } + })?; + Ok(Self::PutRequest(req)) + } + topology::ContractChangeType::PutSuccess => { + let req = req.change_as_put_success().ok_or_else(|| { + flatbuffers::InvalidFlatbuffer::InconsistentUnion { + field: "change_type", + field_type: "ContractChangeType", + error_trace: Default::default(), + } + })?; + Ok(Self::PutSuccess(req)) + } + topology::ContractChangeType::PutFailure => { + let req = req.change_as_put_failure().ok_or_else(|| { + flatbuffers::InvalidFlatbuffer::InconsistentUnion { + field: "change_type", + field_type: "ContractChangeType", + error_trace: Default::default(), + } + })?; + Ok(Self::PutFailure(req)) + } + _ => unreachable!(), + } + } +} diff --git a/crates/core/src/generated/topology_generated.rs b/crates/core/src/generated/topology_generated.rs index b9b9e08fb..ecea1b1c7 100644 --- a/crates/core/src/generated/topology_generated.rs +++ b/crates/core/src/generated/topology_generated.rs @@ -215,6 +215,123 @@ pub mod topology { impl flatbuffers::SimpleToVerifyInSlice for Response {} pub struct ResponseUnionTableOffset {} + #[deprecated( + since = "2.0.0", + note = "Use associated constants instead. This will no longer be generated in 2021." + )] + pub const ENUM_MIN_CONTRACT_CHANGE_TYPE: u8 = 0; + #[deprecated( + since = "2.0.0", + note = "Use associated constants instead. This will no longer be generated in 2021." + )] + pub const ENUM_MAX_CONTRACT_CHANGE_TYPE: u8 = 6; + #[deprecated( + since = "2.0.0", + note = "Use associated constants instead. This will no longer be generated in 2021." + )] + #[allow(non_camel_case_types)] + pub const ENUM_VALUES_CONTRACT_CHANGE_TYPE: [ContractChangeType; 7] = [ + ContractChangeType::NONE, + ContractChangeType::PutRequest, + ContractChangeType::PutSuccess, + ContractChangeType::PutFailure, + ContractChangeType::UpdateRequest, + ContractChangeType::UpdateSuccess, + ContractChangeType::UpdateFailure, + ]; + + #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] + #[repr(transparent)] + pub struct ContractChangeType(pub u8); + #[allow(non_upper_case_globals)] + impl ContractChangeType { + pub const NONE: Self = Self(0); + pub const PutRequest: Self = Self(1); + pub const PutSuccess: Self = Self(2); + pub const PutFailure: Self = Self(3); + pub const UpdateRequest: Self = Self(4); + pub const UpdateSuccess: Self = Self(5); + pub const UpdateFailure: Self = Self(6); + + pub const ENUM_MIN: u8 = 0; + pub const ENUM_MAX: u8 = 6; + pub const ENUM_VALUES: &'static [Self] = &[ + Self::NONE, + Self::PutRequest, + Self::PutSuccess, + Self::PutFailure, + Self::UpdateRequest, + Self::UpdateSuccess, + Self::UpdateFailure, + ]; + /// Returns the variant's name or "" if unknown. + pub fn variant_name(self) -> Option<&'static str> { + match self { + Self::NONE => Some("NONE"), + Self::PutRequest => Some("PutRequest"), + Self::PutSuccess => Some("PutSuccess"), + Self::PutFailure => Some("PutFailure"), + Self::UpdateRequest => Some("UpdateRequest"), + Self::UpdateSuccess => Some("UpdateSuccess"), + Self::UpdateFailure => Some("UpdateFailure"), + _ => None, + } + } + } + impl core::fmt::Debug for ContractChangeType { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + if let Some(name) = self.variant_name() { + f.write_str(name) + } else { + f.write_fmt(format_args!("", self.0)) + } + } + } + impl<'a> flatbuffers::Follow<'a> for ContractChangeType { + type Inner = Self; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + let b = flatbuffers::read_scalar_at::(buf, loc); + Self(b) + } + } + + impl flatbuffers::Push for ContractChangeType { + type Output = ContractChangeType; + #[inline] + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + flatbuffers::emplace_scalar::(dst, self.0); + } + } + + impl flatbuffers::EndianScalar for ContractChangeType { + type Scalar = u8; + #[inline] + fn to_little_endian(self) -> u8 { + self.0.to_le() + } + #[inline] + #[allow(clippy::wrong_self_convention)] + fn from_little_endian(v: u8) -> Self { + let b = u8::from_le(v); + Self(b) + } + } + + impl<'a> flatbuffers::Verifiable for ContractChangeType { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, + pos: usize, + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + u8::run_verifier(v, pos) + } + } + + impl flatbuffers::SimpleToVerifyInSlice for ContractChangeType {} + pub struct ContractChangeTypeUnionTableOffset {} + pub enum AddedConnectionOffset {} #[derive(Copy, Clone, PartialEq)] @@ -1244,4 +1361,1539 @@ pub mod topology { ds.finish() } } + pub enum PutRequestOffset {} + #[derive(Copy, Clone, PartialEq)] + + pub struct PutRequest<'a> { + pub _tab: flatbuffers::Table<'a>, + } + + impl<'a> flatbuffers::Follow<'a> for PutRequest<'a> { + type Inner = PutRequest<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { + _tab: flatbuffers::Table::new(buf, loc), + } + } + } + + impl<'a> PutRequest<'a> { + pub const VT_TRANSACTION: flatbuffers::VOffsetT = 4; + pub const VT_KEY: flatbuffers::VOffsetT = 6; + pub const VT_REQUESTER: flatbuffers::VOffsetT = 8; + pub const VT_TARGET: flatbuffers::VOffsetT = 10; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + PutRequest { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + args: &'args PutRequestArgs<'args>, + ) -> flatbuffers::WIPOffset> { + let mut builder = PutRequestBuilder::new(_fbb); + if let Some(x) = args.target { + builder.add_target(x); + } + if let Some(x) = args.requester { + builder.add_requester(x); + } + if let Some(x) = args.key { + builder.add_key(x); + } + if let Some(x) = args.transaction { + builder.add_transaction(x); + } + builder.finish() + } + + #[inline] + pub fn transaction(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(PutRequest::VT_TRANSACTION, None) + .unwrap() + } + } + #[inline] + pub fn key(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(PutRequest::VT_KEY, None) + .unwrap() + } + } + #[inline] + pub fn requester(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(PutRequest::VT_REQUESTER, None) + .unwrap() + } + } + #[inline] + pub fn target(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(PutRequest::VT_TARGET, None) + .unwrap() + } + } + } + + impl flatbuffers::Verifiable for PutRequest<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, + pos: usize, + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::>( + "transaction", + Self::VT_TRANSACTION, + true, + )? + .visit_field::>("key", Self::VT_KEY, true)? + .visit_field::>( + "requester", + Self::VT_REQUESTER, + true, + )? + .visit_field::>("target", Self::VT_TARGET, true)? + .finish(); + Ok(()) + } + } + pub struct PutRequestArgs<'a> { + pub transaction: Option>, + pub key: Option>, + pub requester: Option>, + pub target: Option>, + } + impl<'a> Default for PutRequestArgs<'a> { + #[inline] + fn default() -> Self { + PutRequestArgs { + transaction: None, // required field + key: None, // required field + requester: None, // required field + target: None, // required field + } + } + } + + pub struct PutRequestBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + start_: flatbuffers::WIPOffset, + } + impl<'a: 'b, 'b> PutRequestBuilder<'a, 'b> { + #[inline] + pub fn add_transaction(&mut self, transaction: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>( + PutRequest::VT_TRANSACTION, + transaction, + ); + } + #[inline] + pub fn add_key(&mut self, key: flatbuffers::WIPOffset<&'b str>) { + self.fbb_ + .push_slot_always::>(PutRequest::VT_KEY, key); + } + #[inline] + pub fn add_requester(&mut self, requester: flatbuffers::WIPOffset<&'b str>) { + self.fbb_ + .push_slot_always::>(PutRequest::VT_REQUESTER, requester); + } + #[inline] + pub fn add_target(&mut self, target: flatbuffers::WIPOffset<&'b str>) { + self.fbb_ + .push_slot_always::>(PutRequest::VT_TARGET, target); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> PutRequestBuilder<'a, 'b> { + let start = _fbb.start_table(); + PutRequestBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + self.fbb_ + .required(o, PutRequest::VT_TRANSACTION, "transaction"); + self.fbb_.required(o, PutRequest::VT_KEY, "key"); + self.fbb_.required(o, PutRequest::VT_REQUESTER, "requester"); + self.fbb_.required(o, PutRequest::VT_TARGET, "target"); + flatbuffers::WIPOffset::new(o.value()) + } + } + + impl core::fmt::Debug for PutRequest<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("PutRequest"); + ds.field("transaction", &self.transaction()); + ds.field("key", &self.key()); + ds.field("requester", &self.requester()); + ds.field("target", &self.target()); + ds.finish() + } + } + pub enum UpdateRequestOffset {} + #[derive(Copy, Clone, PartialEq)] + + pub struct UpdateRequest<'a> { + pub _tab: flatbuffers::Table<'a>, + } + + impl<'a> flatbuffers::Follow<'a> for UpdateRequest<'a> { + type Inner = UpdateRequest<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { + _tab: flatbuffers::Table::new(buf, loc), + } + } + } + + impl<'a> UpdateRequest<'a> { + pub const VT_TRANSACTION: flatbuffers::VOffsetT = 4; + pub const VT_KEY: flatbuffers::VOffsetT = 6; + pub const VT_REQUESTER: flatbuffers::VOffsetT = 8; + pub const VT_TARGET: flatbuffers::VOffsetT = 10; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + UpdateRequest { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + args: &'args UpdateRequestArgs<'args>, + ) -> flatbuffers::WIPOffset> { + let mut builder = UpdateRequestBuilder::new(_fbb); + if let Some(x) = args.target { + builder.add_target(x); + } + if let Some(x) = args.requester { + builder.add_requester(x); + } + if let Some(x) = args.key { + builder.add_key(x); + } + if let Some(x) = args.transaction { + builder.add_transaction(x); + } + builder.finish() + } + + #[inline] + pub fn transaction(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(UpdateRequest::VT_TRANSACTION, None) + .unwrap() + } + } + #[inline] + pub fn key(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(UpdateRequest::VT_KEY, None) + .unwrap() + } + } + #[inline] + pub fn requester(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(UpdateRequest::VT_REQUESTER, None) + .unwrap() + } + } + #[inline] + pub fn target(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(UpdateRequest::VT_TARGET, None) + .unwrap() + } + } + } + + impl flatbuffers::Verifiable for UpdateRequest<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, + pos: usize, + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::>( + "transaction", + Self::VT_TRANSACTION, + true, + )? + .visit_field::>("key", Self::VT_KEY, true)? + .visit_field::>( + "requester", + Self::VT_REQUESTER, + true, + )? + .visit_field::>("target", Self::VT_TARGET, true)? + .finish(); + Ok(()) + } + } + pub struct UpdateRequestArgs<'a> { + pub transaction: Option>, + pub key: Option>, + pub requester: Option>, + pub target: Option>, + } + impl<'a> Default for UpdateRequestArgs<'a> { + #[inline] + fn default() -> Self { + UpdateRequestArgs { + transaction: None, // required field + key: None, // required field + requester: None, // required field + target: None, // required field + } + } + } + + pub struct UpdateRequestBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + start_: flatbuffers::WIPOffset, + } + impl<'a: 'b, 'b> UpdateRequestBuilder<'a, 'b> { + #[inline] + pub fn add_transaction(&mut self, transaction: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>( + UpdateRequest::VT_TRANSACTION, + transaction, + ); + } + #[inline] + pub fn add_key(&mut self, key: flatbuffers::WIPOffset<&'b str>) { + self.fbb_ + .push_slot_always::>(UpdateRequest::VT_KEY, key); + } + #[inline] + pub fn add_requester(&mut self, requester: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>( + UpdateRequest::VT_REQUESTER, + requester, + ); + } + #[inline] + pub fn add_target(&mut self, target: flatbuffers::WIPOffset<&'b str>) { + self.fbb_ + .push_slot_always::>(UpdateRequest::VT_TARGET, target); + } + #[inline] + pub fn new( + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, + ) -> UpdateRequestBuilder<'a, 'b> { + let start = _fbb.start_table(); + UpdateRequestBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + self.fbb_ + .required(o, UpdateRequest::VT_TRANSACTION, "transaction"); + self.fbb_.required(o, UpdateRequest::VT_KEY, "key"); + self.fbb_ + .required(o, UpdateRequest::VT_REQUESTER, "requester"); + self.fbb_.required(o, UpdateRequest::VT_TARGET, "target"); + flatbuffers::WIPOffset::new(o.value()) + } + } + + impl core::fmt::Debug for UpdateRequest<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("UpdateRequest"); + ds.field("transaction", &self.transaction()); + ds.field("key", &self.key()); + ds.field("requester", &self.requester()); + ds.field("target", &self.target()); + ds.finish() + } + } + pub enum PutSuccessOffset {} + #[derive(Copy, Clone, PartialEq)] + + pub struct PutSuccess<'a> { + pub _tab: flatbuffers::Table<'a>, + } + + impl<'a> flatbuffers::Follow<'a> for PutSuccess<'a> { + type Inner = PutSuccess<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { + _tab: flatbuffers::Table::new(buf, loc), + } + } + } + + impl<'a> PutSuccess<'a> { + pub const VT_TRANSACTION: flatbuffers::VOffsetT = 4; + pub const VT_REQUESTER: flatbuffers::VOffsetT = 6; + pub const VT_TARGET: flatbuffers::VOffsetT = 8; + pub const VT_KEY: flatbuffers::VOffsetT = 10; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + PutSuccess { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + args: &'args PutSuccessArgs<'args>, + ) -> flatbuffers::WIPOffset> { + let mut builder = PutSuccessBuilder::new(_fbb); + if let Some(x) = args.key { + builder.add_key(x); + } + if let Some(x) = args.target { + builder.add_target(x); + } + if let Some(x) = args.requester { + builder.add_requester(x); + } + if let Some(x) = args.transaction { + builder.add_transaction(x); + } + builder.finish() + } + + #[inline] + pub fn transaction(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(PutSuccess::VT_TRANSACTION, None) + .unwrap() + } + } + #[inline] + pub fn requester(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(PutSuccess::VT_REQUESTER, None) + .unwrap() + } + } + #[inline] + pub fn target(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(PutSuccess::VT_TARGET, None) + .unwrap() + } + } + #[inline] + pub fn key(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(PutSuccess::VT_KEY, None) + .unwrap() + } + } + } + + impl flatbuffers::Verifiable for PutSuccess<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, + pos: usize, + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::>( + "transaction", + Self::VT_TRANSACTION, + true, + )? + .visit_field::>( + "requester", + Self::VT_REQUESTER, + true, + )? + .visit_field::>("target", Self::VT_TARGET, true)? + .visit_field::>("key", Self::VT_KEY, true)? + .finish(); + Ok(()) + } + } + pub struct PutSuccessArgs<'a> { + pub transaction: Option>, + pub requester: Option>, + pub target: Option>, + pub key: Option>, + } + impl<'a> Default for PutSuccessArgs<'a> { + #[inline] + fn default() -> Self { + PutSuccessArgs { + transaction: None, // required field + requester: None, // required field + target: None, // required field + key: None, // required field + } + } + } + + pub struct PutSuccessBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + start_: flatbuffers::WIPOffset, + } + impl<'a: 'b, 'b> PutSuccessBuilder<'a, 'b> { + #[inline] + pub fn add_transaction(&mut self, transaction: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>( + PutSuccess::VT_TRANSACTION, + transaction, + ); + } + #[inline] + pub fn add_requester(&mut self, requester: flatbuffers::WIPOffset<&'b str>) { + self.fbb_ + .push_slot_always::>(PutSuccess::VT_REQUESTER, requester); + } + #[inline] + pub fn add_target(&mut self, target: flatbuffers::WIPOffset<&'b str>) { + self.fbb_ + .push_slot_always::>(PutSuccess::VT_TARGET, target); + } + #[inline] + pub fn add_key(&mut self, key: flatbuffers::WIPOffset<&'b str>) { + self.fbb_ + .push_slot_always::>(PutSuccess::VT_KEY, key); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> PutSuccessBuilder<'a, 'b> { + let start = _fbb.start_table(); + PutSuccessBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + self.fbb_ + .required(o, PutSuccess::VT_TRANSACTION, "transaction"); + self.fbb_.required(o, PutSuccess::VT_REQUESTER, "requester"); + self.fbb_.required(o, PutSuccess::VT_TARGET, "target"); + self.fbb_.required(o, PutSuccess::VT_KEY, "key"); + flatbuffers::WIPOffset::new(o.value()) + } + } + + impl core::fmt::Debug for PutSuccess<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("PutSuccess"); + ds.field("transaction", &self.transaction()); + ds.field("requester", &self.requester()); + ds.field("target", &self.target()); + ds.field("key", &self.key()); + ds.finish() + } + } + pub enum PutFailureOffset {} + #[derive(Copy, Clone, PartialEq)] + + pub struct PutFailure<'a> { + pub _tab: flatbuffers::Table<'a>, + } + + impl<'a> flatbuffers::Follow<'a> for PutFailure<'a> { + type Inner = PutFailure<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { + _tab: flatbuffers::Table::new(buf, loc), + } + } + } + + impl<'a> PutFailure<'a> { + pub const VT_TRANSACTION: flatbuffers::VOffsetT = 4; + pub const VT_REQUESTER: flatbuffers::VOffsetT = 6; + pub const VT_TARGET: flatbuffers::VOffsetT = 8; + pub const VT_KEY: flatbuffers::VOffsetT = 10; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + PutFailure { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + args: &'args PutFailureArgs<'args>, + ) -> flatbuffers::WIPOffset> { + let mut builder = PutFailureBuilder::new(_fbb); + if let Some(x) = args.key { + builder.add_key(x); + } + if let Some(x) = args.target { + builder.add_target(x); + } + if let Some(x) = args.requester { + builder.add_requester(x); + } + if let Some(x) = args.transaction { + builder.add_transaction(x); + } + builder.finish() + } + + #[inline] + pub fn transaction(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(PutFailure::VT_TRANSACTION, None) + .unwrap() + } + } + #[inline] + pub fn requester(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(PutFailure::VT_REQUESTER, None) + .unwrap() + } + } + #[inline] + pub fn target(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(PutFailure::VT_TARGET, None) + .unwrap() + } + } + #[inline] + pub fn key(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(PutFailure::VT_KEY, None) + .unwrap() + } + } + } + + impl flatbuffers::Verifiable for PutFailure<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, + pos: usize, + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::>( + "transaction", + Self::VT_TRANSACTION, + true, + )? + .visit_field::>( + "requester", + Self::VT_REQUESTER, + true, + )? + .visit_field::>("target", Self::VT_TARGET, true)? + .visit_field::>("key", Self::VT_KEY, true)? + .finish(); + Ok(()) + } + } + pub struct PutFailureArgs<'a> { + pub transaction: Option>, + pub requester: Option>, + pub target: Option>, + pub key: Option>, + } + impl<'a> Default for PutFailureArgs<'a> { + #[inline] + fn default() -> Self { + PutFailureArgs { + transaction: None, // required field + requester: None, // required field + target: None, // required field + key: None, // required field + } + } + } + + pub struct PutFailureBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + start_: flatbuffers::WIPOffset, + } + impl<'a: 'b, 'b> PutFailureBuilder<'a, 'b> { + #[inline] + pub fn add_transaction(&mut self, transaction: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>( + PutFailure::VT_TRANSACTION, + transaction, + ); + } + #[inline] + pub fn add_requester(&mut self, requester: flatbuffers::WIPOffset<&'b str>) { + self.fbb_ + .push_slot_always::>(PutFailure::VT_REQUESTER, requester); + } + #[inline] + pub fn add_target(&mut self, target: flatbuffers::WIPOffset<&'b str>) { + self.fbb_ + .push_slot_always::>(PutFailure::VT_TARGET, target); + } + #[inline] + pub fn add_key(&mut self, key: flatbuffers::WIPOffset<&'b str>) { + self.fbb_ + .push_slot_always::>(PutFailure::VT_KEY, key); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> PutFailureBuilder<'a, 'b> { + let start = _fbb.start_table(); + PutFailureBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + self.fbb_ + .required(o, PutFailure::VT_TRANSACTION, "transaction"); + self.fbb_.required(o, PutFailure::VT_REQUESTER, "requester"); + self.fbb_.required(o, PutFailure::VT_TARGET, "target"); + self.fbb_.required(o, PutFailure::VT_KEY, "key"); + flatbuffers::WIPOffset::new(o.value()) + } + } + + impl core::fmt::Debug for PutFailure<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("PutFailure"); + ds.field("transaction", &self.transaction()); + ds.field("requester", &self.requester()); + ds.field("target", &self.target()); + ds.field("key", &self.key()); + ds.finish() + } + } + pub enum UpdateSuccessOffset {} + #[derive(Copy, Clone, PartialEq)] + + pub struct UpdateSuccess<'a> { + pub _tab: flatbuffers::Table<'a>, + } + + impl<'a> flatbuffers::Follow<'a> for UpdateSuccess<'a> { + type Inner = UpdateSuccess<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { + _tab: flatbuffers::Table::new(buf, loc), + } + } + } + + impl<'a> UpdateSuccess<'a> { + pub const VT_TRANSACTION: flatbuffers::VOffsetT = 4; + pub const VT_REQUESTER: flatbuffers::VOffsetT = 6; + pub const VT_TARGET: flatbuffers::VOffsetT = 8; + pub const VT_KEY: flatbuffers::VOffsetT = 10; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + UpdateSuccess { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + args: &'args UpdateSuccessArgs<'args>, + ) -> flatbuffers::WIPOffset> { + let mut builder = UpdateSuccessBuilder::new(_fbb); + if let Some(x) = args.key { + builder.add_key(x); + } + if let Some(x) = args.target { + builder.add_target(x); + } + if let Some(x) = args.requester { + builder.add_requester(x); + } + if let Some(x) = args.transaction { + builder.add_transaction(x); + } + builder.finish() + } + + #[inline] + pub fn transaction(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(UpdateSuccess::VT_TRANSACTION, None) + .unwrap() + } + } + #[inline] + pub fn requester(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(UpdateSuccess::VT_REQUESTER, None) + .unwrap() + } + } + #[inline] + pub fn target(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(UpdateSuccess::VT_TARGET, None) + .unwrap() + } + } + #[inline] + pub fn key(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(UpdateSuccess::VT_KEY, None) + .unwrap() + } + } + } + + impl flatbuffers::Verifiable for UpdateSuccess<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, + pos: usize, + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::>( + "transaction", + Self::VT_TRANSACTION, + true, + )? + .visit_field::>( + "requester", + Self::VT_REQUESTER, + true, + )? + .visit_field::>("target", Self::VT_TARGET, true)? + .visit_field::>("key", Self::VT_KEY, true)? + .finish(); + Ok(()) + } + } + pub struct UpdateSuccessArgs<'a> { + pub transaction: Option>, + pub requester: Option>, + pub target: Option>, + pub key: Option>, + } + impl<'a> Default for UpdateSuccessArgs<'a> { + #[inline] + fn default() -> Self { + UpdateSuccessArgs { + transaction: None, // required field + requester: None, // required field + target: None, // required field + key: None, // required field + } + } + } + + pub struct UpdateSuccessBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + start_: flatbuffers::WIPOffset, + } + impl<'a: 'b, 'b> UpdateSuccessBuilder<'a, 'b> { + #[inline] + pub fn add_transaction(&mut self, transaction: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>( + UpdateSuccess::VT_TRANSACTION, + transaction, + ); + } + #[inline] + pub fn add_requester(&mut self, requester: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>( + UpdateSuccess::VT_REQUESTER, + requester, + ); + } + #[inline] + pub fn add_target(&mut self, target: flatbuffers::WIPOffset<&'b str>) { + self.fbb_ + .push_slot_always::>(UpdateSuccess::VT_TARGET, target); + } + #[inline] + pub fn add_key(&mut self, key: flatbuffers::WIPOffset<&'b str>) { + self.fbb_ + .push_slot_always::>(UpdateSuccess::VT_KEY, key); + } + #[inline] + pub fn new( + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, + ) -> UpdateSuccessBuilder<'a, 'b> { + let start = _fbb.start_table(); + UpdateSuccessBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + self.fbb_ + .required(o, UpdateSuccess::VT_TRANSACTION, "transaction"); + self.fbb_ + .required(o, UpdateSuccess::VT_REQUESTER, "requester"); + self.fbb_.required(o, UpdateSuccess::VT_TARGET, "target"); + self.fbb_.required(o, UpdateSuccess::VT_KEY, "key"); + flatbuffers::WIPOffset::new(o.value()) + } + } + + impl core::fmt::Debug for UpdateSuccess<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("UpdateSuccess"); + ds.field("transaction", &self.transaction()); + ds.field("requester", &self.requester()); + ds.field("target", &self.target()); + ds.field("key", &self.key()); + ds.finish() + } + } + pub enum UpdateFailureOffset {} + #[derive(Copy, Clone, PartialEq)] + + pub struct UpdateFailure<'a> { + pub _tab: flatbuffers::Table<'a>, + } + + impl<'a> flatbuffers::Follow<'a> for UpdateFailure<'a> { + type Inner = UpdateFailure<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { + _tab: flatbuffers::Table::new(buf, loc), + } + } + } + + impl<'a> UpdateFailure<'a> { + pub const VT_TRANSACTION: flatbuffers::VOffsetT = 4; + pub const VT_REQUESTER: flatbuffers::VOffsetT = 6; + pub const VT_TARGET: flatbuffers::VOffsetT = 8; + pub const VT_KEY: flatbuffers::VOffsetT = 10; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + UpdateFailure { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + args: &'args UpdateFailureArgs<'args>, + ) -> flatbuffers::WIPOffset> { + let mut builder = UpdateFailureBuilder::new(_fbb); + if let Some(x) = args.key { + builder.add_key(x); + } + if let Some(x) = args.target { + builder.add_target(x); + } + if let Some(x) = args.requester { + builder.add_requester(x); + } + if let Some(x) = args.transaction { + builder.add_transaction(x); + } + builder.finish() + } + + #[inline] + pub fn transaction(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(UpdateFailure::VT_TRANSACTION, None) + .unwrap() + } + } + #[inline] + pub fn requester(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(UpdateFailure::VT_REQUESTER, None) + .unwrap() + } + } + #[inline] + pub fn target(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(UpdateFailure::VT_TARGET, None) + .unwrap() + } + } + #[inline] + pub fn key(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(UpdateFailure::VT_KEY, None) + .unwrap() + } + } + } + + impl flatbuffers::Verifiable for UpdateFailure<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, + pos: usize, + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::>( + "transaction", + Self::VT_TRANSACTION, + true, + )? + .visit_field::>( + "requester", + Self::VT_REQUESTER, + true, + )? + .visit_field::>("target", Self::VT_TARGET, true)? + .visit_field::>("key", Self::VT_KEY, true)? + .finish(); + Ok(()) + } + } + pub struct UpdateFailureArgs<'a> { + pub transaction: Option>, + pub requester: Option>, + pub target: Option>, + pub key: Option>, + } + impl<'a> Default for UpdateFailureArgs<'a> { + #[inline] + fn default() -> Self { + UpdateFailureArgs { + transaction: None, // required field + requester: None, // required field + target: None, // required field + key: None, // required field + } + } + } + + pub struct UpdateFailureBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + start_: flatbuffers::WIPOffset, + } + impl<'a: 'b, 'b> UpdateFailureBuilder<'a, 'b> { + #[inline] + pub fn add_transaction(&mut self, transaction: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>( + UpdateFailure::VT_TRANSACTION, + transaction, + ); + } + #[inline] + pub fn add_requester(&mut self, requester: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>( + UpdateFailure::VT_REQUESTER, + requester, + ); + } + #[inline] + pub fn add_target(&mut self, target: flatbuffers::WIPOffset<&'b str>) { + self.fbb_ + .push_slot_always::>(UpdateFailure::VT_TARGET, target); + } + #[inline] + pub fn add_key(&mut self, key: flatbuffers::WIPOffset<&'b str>) { + self.fbb_ + .push_slot_always::>(UpdateFailure::VT_KEY, key); + } + #[inline] + pub fn new( + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, + ) -> UpdateFailureBuilder<'a, 'b> { + let start = _fbb.start_table(); + UpdateFailureBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + self.fbb_ + .required(o, UpdateFailure::VT_TRANSACTION, "transaction"); + self.fbb_ + .required(o, UpdateFailure::VT_REQUESTER, "requester"); + self.fbb_.required(o, UpdateFailure::VT_TARGET, "target"); + self.fbb_.required(o, UpdateFailure::VT_KEY, "key"); + flatbuffers::WIPOffset::new(o.value()) + } + } + + impl core::fmt::Debug for UpdateFailure<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("UpdateFailure"); + ds.field("transaction", &self.transaction()); + ds.field("requester", &self.requester()); + ds.field("target", &self.target()); + ds.field("key", &self.key()); + ds.finish() + } + } + pub enum ContractChangeOffset {} + #[derive(Copy, Clone, PartialEq)] + + pub struct ContractChange<'a> { + pub _tab: flatbuffers::Table<'a>, + } + + impl<'a> flatbuffers::Follow<'a> for ContractChange<'a> { + type Inner = ContractChange<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { + _tab: flatbuffers::Table::new(buf, loc), + } + } + } + + impl<'a> ContractChange<'a> { + pub const VT_CONTRACT_ID: flatbuffers::VOffsetT = 4; + pub const VT_CHANGE_TYPE: flatbuffers::VOffsetT = 6; + pub const VT_CHANGE: flatbuffers::VOffsetT = 8; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + ContractChange { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + args: &'args ContractChangeArgs<'args>, + ) -> flatbuffers::WIPOffset> { + let mut builder = ContractChangeBuilder::new(_fbb); + if let Some(x) = args.change { + builder.add_change(x); + } + if let Some(x) = args.contract_id { + builder.add_contract_id(x); + } + builder.add_change_type(args.change_type); + builder.finish() + } + + #[inline] + pub fn contract_id(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>(ContractChange::VT_CONTRACT_ID, None) + .unwrap() + } + } + #[inline] + pub fn change_type(&self) -> ContractChangeType { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::( + ContractChange::VT_CHANGE_TYPE, + Some(ContractChangeType::NONE), + ) + .unwrap() + } + } + #[inline] + pub fn change(&self) -> Option> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { + self._tab + .get::>>( + ContractChange::VT_CHANGE, + None, + ) + } + } + #[inline] + #[allow(non_snake_case)] + pub fn change_as_put_request(&self) -> Option> { + if self.change_type() == ContractChangeType::PutRequest { + self.change().map(|t| { + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + unsafe { PutRequest::init_from_table(t) } + }) + } else { + None + } + } + + #[inline] + #[allow(non_snake_case)] + pub fn change_as_put_success(&self) -> Option> { + if self.change_type() == ContractChangeType::PutSuccess { + self.change().map(|t| { + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + unsafe { PutSuccess::init_from_table(t) } + }) + } else { + None + } + } + + #[inline] + #[allow(non_snake_case)] + pub fn change_as_put_failure(&self) -> Option> { + if self.change_type() == ContractChangeType::PutFailure { + self.change().map(|t| { + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + unsafe { PutFailure::init_from_table(t) } + }) + } else { + None + } + } + + #[inline] + #[allow(non_snake_case)] + pub fn change_as_update_request(&self) -> Option> { + if self.change_type() == ContractChangeType::UpdateRequest { + self.change().map(|t| { + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + unsafe { UpdateRequest::init_from_table(t) } + }) + } else { + None + } + } + + #[inline] + #[allow(non_snake_case)] + pub fn change_as_update_success(&self) -> Option> { + if self.change_type() == ContractChangeType::UpdateSuccess { + self.change().map(|t| { + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + unsafe { UpdateSuccess::init_from_table(t) } + }) + } else { + None + } + } + + #[inline] + #[allow(non_snake_case)] + pub fn change_as_update_failure(&self) -> Option> { + if self.change_type() == ContractChangeType::UpdateFailure { + self.change().map(|t| { + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + unsafe { UpdateFailure::init_from_table(t) } + }) + } else { + None + } + } + } + + impl flatbuffers::Verifiable for ContractChange<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, + pos: usize, + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::>( + "contract_id", + Self::VT_CONTRACT_ID, + true, + )? + .visit_union::( + "change_type", + Self::VT_CHANGE_TYPE, + "change", + Self::VT_CHANGE, + false, + |key, v, pos| match key { + ContractChangeType::PutRequest => v + .verify_union_variant::>( + "ContractChangeType::PutRequest", + pos, + ), + ContractChangeType::PutSuccess => v + .verify_union_variant::>( + "ContractChangeType::PutSuccess", + pos, + ), + ContractChangeType::PutFailure => v + .verify_union_variant::>( + "ContractChangeType::PutFailure", + pos, + ), + ContractChangeType::UpdateRequest => v + .verify_union_variant::>( + "ContractChangeType::UpdateRequest", + pos, + ), + ContractChangeType::UpdateSuccess => v + .verify_union_variant::>( + "ContractChangeType::UpdateSuccess", + pos, + ), + ContractChangeType::UpdateFailure => v + .verify_union_variant::>( + "ContractChangeType::UpdateFailure", + pos, + ), + _ => Ok(()), + }, + )? + .finish(); + Ok(()) + } + } + pub struct ContractChangeArgs<'a> { + pub contract_id: Option>, + pub change_type: ContractChangeType, + pub change: Option>, + } + impl<'a> Default for ContractChangeArgs<'a> { + #[inline] + fn default() -> Self { + ContractChangeArgs { + contract_id: None, // required field + change_type: ContractChangeType::NONE, + change: None, + } + } + } + + pub struct ContractChangeBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + start_: flatbuffers::WIPOffset, + } + impl<'a: 'b, 'b> ContractChangeBuilder<'a, 'b> { + #[inline] + pub fn add_contract_id(&mut self, contract_id: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>( + ContractChange::VT_CONTRACT_ID, + contract_id, + ); + } + #[inline] + pub fn add_change_type(&mut self, change_type: ContractChangeType) { + self.fbb_.push_slot::( + ContractChange::VT_CHANGE_TYPE, + change_type, + ContractChangeType::NONE, + ); + } + #[inline] + pub fn add_change(&mut self, change: flatbuffers::WIPOffset) { + self.fbb_ + .push_slot_always::>(ContractChange::VT_CHANGE, change); + } + #[inline] + pub fn new( + _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, + ) -> ContractChangeBuilder<'a, 'b> { + let start = _fbb.start_table(); + ContractChangeBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + self.fbb_ + .required(o, ContractChange::VT_CONTRACT_ID, "contract_id"); + flatbuffers::WIPOffset::new(o.value()) + } + } + + impl core::fmt::Debug for ContractChange<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("ContractChange"); + ds.field("contract_id", &self.contract_id()); + ds.field("change_type", &self.change_type()); + match self.change_type() { + ContractChangeType::PutRequest => { + if let Some(x) = self.change_as_put_request() { + ds.field("change", &x) + } else { + ds.field( + "change", + &"InvalidFlatbuffer: Union discriminant does not match value.", + ) + } + } + ContractChangeType::PutSuccess => { + if let Some(x) = self.change_as_put_success() { + ds.field("change", &x) + } else { + ds.field( + "change", + &"InvalidFlatbuffer: Union discriminant does not match value.", + ) + } + } + ContractChangeType::PutFailure => { + if let Some(x) = self.change_as_put_failure() { + ds.field("change", &x) + } else { + ds.field( + "change", + &"InvalidFlatbuffer: Union discriminant does not match value.", + ) + } + } + ContractChangeType::UpdateRequest => { + if let Some(x) = self.change_as_update_request() { + ds.field("change", &x) + } else { + ds.field( + "change", + &"InvalidFlatbuffer: Union discriminant does not match value.", + ) + } + } + ContractChangeType::UpdateSuccess => { + if let Some(x) = self.change_as_update_success() { + ds.field("change", &x) + } else { + ds.field( + "change", + &"InvalidFlatbuffer: Union discriminant does not match value.", + ) + } + } + ContractChangeType::UpdateFailure => { + if let Some(x) = self.change_as_update_failure() { + ds.field("change", &x) + } else { + ds.field( + "change", + &"InvalidFlatbuffer: Union discriminant does not match value.", + ) + } + } + _ => { + let x: Option<()> = None; + ds.field("change", &x) + } + }; + ds.finish() + } + } } // pub mod topology diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index 6a38a4acb..a59e10165 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -49,6 +49,7 @@ pub mod dev_tool { }; pub use contract::{storages::Storage, Executor, OperationMode}; pub use flatbuffers; + pub use message::Transaction; pub use node::{ testing_impl::{ EventChain, NetworkPeer, NodeLabel, PeerMessage, PeerStatus, SimNetwork, SimPeer, diff --git a/crates/core/src/message.rs b/crates/core/src/message.rs index 46434200a..ed7a293ba 100644 --- a/crates/core/src/message.rs +++ b/crates/core/src/message.rs @@ -31,7 +31,7 @@ pub(crate) use sealed_msg_type::{TransactionType, TransactionTypeId}; /// /// A transaction may span different messages sent across the network. #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Hash, Clone, Copy)] -pub(crate) struct Transaction { +pub struct Transaction { id: Ulid, } @@ -141,7 +141,7 @@ impl Ord for Transaction { } /// Get the transaction type associated to a given message type. -pub(crate) trait TxType: sealed_msg_type::SealedTxType { +pub trait TxType: sealed_msg_type::SealedTxType { fn tx_type_id() -> TransactionTypeId; } @@ -157,18 +157,18 @@ where mod sealed_msg_type { use super::*; - pub(crate) trait SealedTxType { + pub trait SealedTxType { fn tx_type_id() -> TransactionTypeId; } #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Serialize, Deserialize)] #[cfg_attr(test, derive(arbitrary::Arbitrary))] - pub(crate) struct TransactionTypeId(pub(super) TransactionType); + pub struct TransactionTypeId(pub(super) TransactionType); #[repr(u8)] #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Serialize, Deserialize)] #[cfg_attr(test, derive(arbitrary::Arbitrary))] - pub(crate) enum TransactionType { + pub enum TransactionType { Connect = 0, Put = 1, Get = 2, diff --git a/crates/core/src/operations/put.rs b/crates/core/src/operations/put.rs index bbb2fb2ba..520a1fa96 100644 --- a/crates/core/src/operations/put.rs +++ b/crates/core/src/operations/put.rs @@ -418,6 +418,7 @@ impl Operation for PutOp { return_msg = Some(PutMsg::SuccessfulPut { id: *id, target: *upstream, + key: key.clone(), }); new_state = None; } @@ -436,11 +437,12 @@ impl Operation for PutOp { this_peer = %op_manager.ring.peer_key, "Peer completed contract value put", ); - new_state = Some(PutState::Finished { key }); + new_state = Some(PutState::Finished { key: key.clone() }); if let Some(upstream) = upstream { return_msg = Some(PutMsg::SuccessfulPut { id: *id, target: upstream, + key, }); } else { return_msg = None; @@ -646,6 +648,7 @@ async fn try_to_broadcast( return_msg = Some(PutMsg::SuccessfulPut { id, target: upstream, + key: key.clone(), }); } } @@ -886,6 +889,7 @@ mod messages { SuccessfulPut { id: Transaction, target: PeerKeyLocation, + key: ContractKey, }, /// Target the node which is closest to the key SeekNode { diff --git a/crates/core/src/tracing.rs b/crates/core/src/tracing.rs index aa14c121b..902703f6a 100644 --- a/crates/core/src/tracing.rs +++ b/crates/core/src/tracing.rs @@ -23,6 +23,7 @@ use tokio_tungstenite::{MaybeTlsStream, WebSocketStream}; use crate::{ config::GlobalExecutor, contract::StoreResponse, + generated::ContractChange, message::{NetMessage, Transaction}, node::PeerId, operations::{connect, get::GetMsg, put::PutMsg, subscribe::SubscribeMsg}, @@ -253,17 +254,28 @@ impl<'a> NetEventLog<'a> { return Either::Right(events); } NetMessage::Put(PutMsg::RequestPut { - contract, target, .. + contract, + target, + id, + .. }) => { + let this_peer = &op_manager.ring.peer_key; let key = contract.key(); EventKind::Put(PutEvent::Request { - requester: target.peer, + requester: *this_peer, + target: *target, key, + id: *id, + }) + } + NetMessage::Put(PutMsg::SuccessfulPut { id, target, key }) => { + EventKind::Put(PutEvent::PutSuccess { + id: *id, + requester: op_manager.ring.peer_key, + target: *target, + key: key.clone(), }) } - NetMessage::Put(PutMsg::SuccessfulPut { .. }) => EventKind::Put(PutEvent::PutSuccess { - requester: op_manager.ring.peer_key, - }), NetMessage::Put(PutMsg::Broadcasting { new_value, broadcast_to, @@ -785,7 +797,34 @@ async fn send_to_metrics_server( let msg = PeerChange::removed_connection_msg(*from, send_msg.peer_id); ws_stream.send(Message::Binary(msg)).await } - // todo: send op events too (put, get, update, etc) so we can keep track of transactions + EventKind::Put(PutEvent::Request { + requester, + key, + target, + .. + }) => { + let msg = ContractChange::put_request_msg( + send_msg.tx.to_string(), + key.to_string(), + requester.to_string(), + target.peer.to_string(), + ); + ws_stream.send(Message::Binary(msg)).await + } + EventKind::Put(PutEvent::PutSuccess { + requester, + target, + key, + .. + }) => { + let msg = ContractChange::put_success_msg( + send_msg.tx.to_string(), + key.to_string(), + requester.to_string(), + target.peer.to_string(), + ); + ws_stream.send(Message::Binary(msg)).await + } _ => Ok(()), }; if let Err(error) = res { @@ -1123,11 +1162,16 @@ enum ConnectEvent { #[cfg_attr(test, derive(arbitrary::Arbitrary))] enum PutEvent { Request { + id: Transaction, requester: PeerId, key: ContractKey, + target: PeerKeyLocation, }, PutSuccess { + id: Transaction, requester: PeerId, + target: PeerKeyLocation, + key: ContractKey, }, BroadcastEmitted { /// subscribed peers @@ -1341,7 +1385,7 @@ pub(super) mod test { PutEvent::Request { key, .. } if key == for_key => { is_expected_key = true; } - PutEvent::PutSuccess { requester } if requester == peer => { + PutEvent::PutSuccess { requester, .. } if requester == peer => { is_expected_peer = true; } _ => {} diff --git a/crates/fdev/src/network_metrics_server.rs b/crates/fdev/src/network_metrics_server.rs index 480bbd3b4..fc5d580f1 100644 --- a/crates/fdev/src/network_metrics_server.rs +++ b/crates/fdev/src/network_metrics_server.rs @@ -14,7 +14,9 @@ use axum::{ use dashmap::DashMap; use freenet::{ dev_tool::PeerId, - generated::{topology::ControllerResponse, PeerChange, TryFromFbs}, + generated::{ + topology::ControllerResponse, ChangesWrapper, ContractChange, PeerChange, TryFromFbs, + }, }; use futures::{SinkExt, StreamExt}; use serde::{Deserialize, Serialize}; @@ -76,6 +78,7 @@ async fn run_server( .with_state(Arc::new(ServerState { changes, peer_data: DashMap::new(), + transactions_data: DashMap::new(), })); tracing::info!("Starting metrics server on port {port}"); @@ -127,7 +130,30 @@ async fn push_interface(ws: WebSocket, state: Arc) -> anyhow::Resul break; } Ok(change) => { - if let Err(err) = state.save_record(change) { + if let Err(err) = state.save_record(ChangesWrapper::PeerChange(change)) { + tracing::error!(error = %err, "Failed saving report"); + tx.send(Message::Binary(ControllerResponse::into_fbs_bytes(Err( + format!("{err}"), + )))) + .await?; + } + } + Err(decoding_error) => { + tracing::error!(error = %decoding_error, "Failed to decode message"); + tx.send(Message::Binary(ControllerResponse::into_fbs_bytes(Err( + format!("{decoding_error}"), + )))) + .await?; + } + } + match ContractChange::try_decode_fbs(&msg) { + Ok(ContractChange::PutFailure(_err)) => { + // FIXME: handle put failure + tracing::error!(error = "Failed to put contract"); + } + Ok(change) => { + if let Err(err) = state.save_record(ChangesWrapper::ContractChange(change)) + { tracing::error!(error = %err, "Failed saving report"); tx.send(Message::Binary(ControllerResponse::into_fbs_bytes(Err( format!("{err}"), @@ -194,6 +220,20 @@ async fn pull_interface(ws: WebSocket, state: Arc) -> anyhow::Resul let msg = PeerChange::removed_connection_msg(at.0, from.0); tx.send(Message::Binary(msg)).await?; } + Change::PutRequest { + tx_id, + key, + requester, + target, + } => { + tracing::debug!(%tx_id, %key, %requester, %target, "sending put request"); + let msg = ContractChange::put_request_msg(tx_id, key, requester, target); + tx.send(Message::Binary(msg)).await?; + } + Change::PutSuccess { tx_id, key, target } => { + let msg = ContractChange::put_success_msg(tx_id, key, target.clone(), target); + tx.send(Message::Binary(msg)).await?; + } } } Ok(()) @@ -202,6 +242,7 @@ async fn pull_interface(ws: WebSocket, state: Arc) -> anyhow::Resul struct ServerState { changes: tokio::sync::broadcast::Sender, peer_data: DashMap, + transactions_data: DashMap>, } struct PeerData { @@ -222,6 +263,17 @@ pub(crate) enum Change { from: PeerIdHumanReadable, at: PeerIdHumanReadable, }, + PutRequest { + tx_id: String, + key: String, + requester: String, + target: String, + }, + PutSuccess { + tx_id: String, + key: String, + target: String, + }, } #[derive(Debug, Clone)] @@ -249,9 +301,9 @@ impl From for PeerIdHumanReadable { } impl ServerState { - fn save_record(&self, change: PeerChange<'_>) -> Result<(), anyhow::Error> { + fn save_record(&self, change: ChangesWrapper) -> Result<(), anyhow::Error> { match change { - PeerChange::AddedConnection(added) => { + ChangesWrapper::PeerChange(PeerChange::AddedConnection(added)) => { let from_peer_id = PeerId::from_str(added.from())?; let from_loc = added.from_location(); @@ -294,7 +346,7 @@ impl ServerState { to: (to_peer_id.into(), to_loc), }); } - PeerChange::RemovedConnection(removed) => { + ChangesWrapper::PeerChange(PeerChange::RemovedConnection(removed)) => { let from_peer_id = PeerId::from_str(removed.from())?; let at_peer_id = PeerId::from_str(removed.at())?; @@ -315,6 +367,56 @@ impl ServerState { at: at_peer_id.into(), }); } + ChangesWrapper::ContractChange(ContractChange::PutRequest(change)) => { + let tx_id = change.transaction().to_string(); + let key = change.key().to_string(); + let requester = change.requester().to_string(); + let target = change.target().to_string(); + + if self.transactions_data.get_mut(&tx_id).is_some() { + unreachable!( + "found an already included in logs transaction when it should create it." + ); + } else { + self.transactions_data.insert( + tx_id.clone(), + vec![format!( + "tx_id {} key {} req {} target {} state PutRequest", + tx_id, key, requester, target + )], + ); + } + + tracing::debug!(%tx_id, %key, %requester, %target, "checking values from save_record -- putrequest"); + + let _ = self.changes.send(Change::PutRequest { + tx_id, + key, + requester, + target, + }); + } + ChangesWrapper::ContractChange(ContractChange::PutSuccess(change)) => { + let tx_id = change.transaction().to_string(); + let key = change.key().to_string(); + let requester = change.requester().to_string(); + let target = change.target().to_string(); + + if let Some(mut entry) = self.transactions_data.get_mut(&tx_id) { + entry.push(format!( + "tx_id {} key {} req {} target {} state PutSuccess", + tx_id, key, requester, target + )); + } else { + tracing::error!("transaction data not found for this tx when it should."); + unreachable!() + } + + tracing::debug!(%tx_id, %key, %requester, %target, "checking values from save_record -- putsuccess"); + + let _ = self.changes.send(Change::PutSuccess { tx_id, key, target }); + } + _ => unreachable!(), } Ok(()) diff --git a/network-monitor/.prettierrc b/network-monitor/.prettierrc new file mode 100644 index 000000000..330f17ff1 --- /dev/null +++ b/network-monitor/.prettierrc @@ -0,0 +1,5 @@ +{ + "tabWidth": 4, + "bracketSpacing": true, + "useTabs": false +} diff --git a/network-monitor/dist/index.html b/network-monitor/dist/index.html index fa02b2fdb..337113199 100644 --- a/network-monitor/dist/index.html +++ b/network-monitor/dist/index.html @@ -11,6 +11,13 @@ rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" /> +
@@ -64,6 +71,8 @@

Connections history

+
+
diff --git a/network-monitor/package.json b/network-monitor/package.json index 359f02944..997a8339b 100644 --- a/network-monitor/package.json +++ b/network-monitor/package.json @@ -15,6 +15,7 @@ "devDependencies": { "@types/d3": "^7.4.3", "@types/jest": "^29.5.10", + "@types/react-dom": "^18.2.18", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "ts-jest": "^29.1.1", @@ -26,7 +27,11 @@ "webpack-dev-server": "^4.15.1" }, "dependencies": { + "@types/react": "^18.2.53", "d3": "^7.8.5", - "flatbuffers": "^23.5.26" + "flatbuffers": "^23.5.26", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.22.0" } } diff --git a/network-monitor/src/app.ts b/network-monitor/src/app.ts index cdd7ee309..766f7aa37 100644 --- a/network-monitor/src/app.ts +++ b/network-monitor/src/app.ts @@ -1,40 +1,154 @@ import * as flatbuffers from "flatbuffers"; import * as fbTopology from "./generated/topology"; import { handleChange } from "./topology"; +import { handlePutRequest, handlePutSuccess } from "./transactions-data"; +import { parse_put_msg_data } from "./utils"; -const PEER_CHANGES = new WebSocket( - "ws://127.0.0.1:55010/pull-stats/peer-changes/" -); -PEER_CHANGES.onmessage = handlePeerChanges; +let connection_established = false; + +const ws_connection_interval = setInterval(() => { + if (!connection_established) { + try { + const socket = new WebSocket( + "ws://127.0.0.1:55010/pull-stats/peer-changes/" + ); + + socket.addEventListener("open", () => { + connection_established = true; + console.log("WS Connection established"); + }); + + socket.addEventListener("message", handleChanges); + } catch (e) { + console.error(e); + } + } else { + console.log("WS Connection established"); + clearInterval(ws_connection_interval); + } +}, 3000); // const DELIVER_MESSAGE = new WebSocket("ws://127.0.0.1:55010/pull-stats/network-events/"); -function handlePeerChanges(event: MessageEvent) { - const data = event.data as Blob; - convertBlobToUint8Array(data) - .then((uint8Array) => { - const buf = new flatbuffers.ByteBuffer(uint8Array); - const peerChange = fbTopology.PeerChange.getRootAsPeerChange(buf); - handleChange(peerChange); - }) - .catch((error) => { - console.error("Failed to handle message:", error); - }); +function handleChanges(event: MessageEvent) { + const data = event.data as Blob; + convertBlobToUint8Array(data) + .then((uint8Array) => { + const buf = new flatbuffers.ByteBuffer(uint8Array); + + try { + const contractChange = + fbTopology.ContractChange.getRootAsContractChange(buf); + + console.log(contractChange.changeType()); + + if ( + contractChange.changeType() === + fbTopology.ContractChangeType.PutRequest + ) { + let { + transaction, + contract_id, + target, + requester, + change_type, + } = parse_put_msg_data( + contractChange, + fbTopology.ContractChangeType.PutRequest + ); + + handlePutRequest( + transaction, + contract_id, + target, + requester, + change_type + ); + + return; + } + + if ( + contractChange.changeType() === + fbTopology.ContractChangeType.PutSuccess + ) { + let { + transaction, + contract_id, + target, + requester, + change_type, + } = parse_put_msg_data( + contractChange, + fbTopology.ContractChangeType.PutSuccess + ); + + handlePutSuccess( + transaction, + contract_id, + target, + requester, + change_type + ); + + return; + } + + if ( + contractChange.changeType() === + fbTopology.ContractChangeType.PutFailure + ) { + let { + transaction, + contract_id, + target, + requester, + change_type, + } = parse_put_msg_data( + contractChange, + fbTopology.ContractChangeType.PutFailure + ); + + handlePutSuccess( + transaction, + contract_id, + target, + requester, + change_type + ); + + return; + } + } catch (e) { + console.error(e); + } + + try { + const peerChange = + fbTopology.PeerChange.getRootAsPeerChange(buf); + handleChange(peerChange); + + return; + } catch (e) {} + }) + .catch((error) => { + console.error("Failed to handle message:", error); + }); } function convertBlobToUint8Array(blob: Blob): Promise { - return new Promise((resolve, reject) => { - const reader = new FileReader(); - reader.onloadend = () => { - if (reader.result instanceof ArrayBuffer) { - const arrayBuffer = reader.result; - const uint8Array = new Uint8Array(arrayBuffer); - resolve(uint8Array); - } else { - reject(new Error("Failed to convert Blob to Uint8Array.")); - } - }; - reader.onerror = reject; - reader.readAsArrayBuffer(blob); - }); + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onloadend = () => { + if (reader.result instanceof ArrayBuffer) { + const arrayBuffer = reader.result; + const uint8Array = new Uint8Array(arrayBuffer); + resolve(uint8Array); + } else { + reject(new Error("Failed to convert Blob to Uint8Array.")); + } + }; + reader.onerror = reject; + reader.readAsArrayBuffer(blob); + }); } diff --git a/network-monitor/src/contract-detail.tsx b/network-monitor/src/contract-detail.tsx new file mode 100644 index 000000000..1548b3c7b --- /dev/null +++ b/network-monitor/src/contract-detail.tsx @@ -0,0 +1,376 @@ +import { useEffect, useState } from "react"; +import { createRoot } from "react-dom/client"; +import { + TransactionDetailInterface, + TransactionPeerInterface, + TransactionData +} from "./type_definitions"; +import { PeerId } from "./topology"; +import { another_ring_visualization } from "./ring-visualization"; + +interface TransactionDetailPeersHistoryInterface { + tx_peer_list: Array; +} + +interface FilterInterface { + filter_type: string; + filter_value: string; +} + +interface FilterDictionaryInterface { + [key: string]: FilterInterface; +} + +let ring_mock_data = []; +const ContractPeersHistory = ({ + tx_peer_list, +}: TransactionDetailPeersHistoryInterface) => { + const [filter, set_filter] = useState({}); + const [filtered_list, set_filtered_list] = useState(tx_peer_list); + + const add_filter = (filter_type: string, filter_value: string) => { + if (check_if_contains_filter(filter_type)) { + return; + } + + filter[filter_type] = { + filter_type, + filter_value, + }; + + set_filter(filter); + + update_filtered_list(); + }; + + const update_filtered_list = () => { + let filtered_list = tx_peer_list; + + Object.keys(filter).forEach((filter_type) => { + const filter_value = filter[filter_type].filter_value; + filtered_list = filtered_list.filter((tx) => { + for (const [key, value] of Object.entries(tx)) { + if (key === filter_type) { + return value === filter_value; + } + } + }); + }); + + set_filtered_list(filtered_list); + }; + + const clear_one_filter = (filter_type: string) => { + delete filter[filter_type]; + update_filtered_list(); + }; + + const clear_all_filters = () => { + set_filter({}); + }; + + useEffect(() => { + update_filtered_list(); + + let ring_mock_data = [ + { + id: new PeerId("1"), + currentLocation: 0.123485, + connectionTimestamp: 1234567890, + connections: [], + history: [], + locationHistory: [], + }, + { + id: new PeerId("2"), + currentLocation: 0.183485, + connectionTimestamp: 1234567890, + connections: [], + history: [], + locationHistory: [], + }, + { + id: new PeerId("3"), + currentLocation: 0.323485, + connectionTimestamp: 1234567890, + connections: [], + history: [], + locationHistory: [], + }, + { + id: new PeerId("4"), + currentLocation: 0.423485, + connectionTimestamp: 1234567890, + connections: [], + history: [], + locationHistory: [], + }, + { + id: new PeerId("5"), + currentLocation: 0.783285, + connectionTimestamp: 1234567890, + connections: [], + history: [], + locationHistory: [], + }, + ]; + + // ringHistogram(ring_mock_data); + + // const graphContainer = d3.select( + // document.getElementById("other-peer-conns-graph") + // ); + + // ringVisualization(ring_mock_data[0], graphContainer, 1.25); + }, [filter]); + + const check_if_contains_filter = (filter_type: string) => { + return filter[filter_type] !== undefined; + }; + + return ( +
+

Contract Transactions History

+ {Object.keys(filter).length > 0 && ( +
+ +
+ )} + + + + + + + + + + + + {filtered_list.map((tx) => ( + + + + + + + + ))} + +
+ Contract Id + {check_if_contains_filter("contract_id") && ( + + )} + + Transaction Id + {check_if_contains_filter("transaction_id") && ( + + )} + + Requester + {check_if_contains_filter("requester") && ( + + )} + + Target + {check_if_contains_filter("target") && ( + + )} + + Change Type + {check_if_contains_filter("change_type") && ( + + )} +
+ add_filter("contract_id", tx.contract_id) + } + style={{ + cursor: "pointer", + }} + > + {tx.contract_id.slice(-8)} + + add_filter("transaction_id", tx.transaction_id) + } + style={{ + cursor: "pointer", + }} + > + {tx.transaction_id} + + add_filter("requester", tx.requester) + } + style={{ + cursor: "pointer", + }} + > + {tx.requester.slice(-8)} + + add_filter("target", tx.target) + } + style={{ + cursor: "pointer", + }} + > + {tx.target.slice(-8)} + + add_filter("change_type", tx.change_type) + } + style={{ + cursor: "pointer", + }} + > + {tx.change_type} +
+
+ ); +}; + +// TODO: use real types +const ContractHistory = ({ contract_history }: any) => ( +
+

Contract History

+ + + + + + + + + {/* + + */} + + + + {contract_history && + contract_history.map((change: TransactionData, index: number) => ( + + + + + + + + ))} + +
Contract KeyTransaction IdRequester Peer IdTarget Peer IdTypeStatusStartedFinalized
{change.contract_id.slice(-8)}{change.transaction_id.slice(-8)}{change.requester.slice(-8)}{change.target.slice(-8)}{change.change_type}
+
+); + +export const ContractDetail = ({ + transaction, + is_displayed, + close_detail, + peers_history, + tx_history, +}: TransactionDetailInterface) => ( +
+
+ +

Contract Details

+
+

Contract Key {transaction.contract_id}

+

Requester {transaction.requester}

+

Target {transaction.target}

+ {/*

Status {transaction.status}

+

Started {transaction.started}

+

Finalized {transaction.finalized}

*/} +
+ +
+

Location Peers

+
+
+ +
+ {/*another_ring_visualization()*/} +
+ + {tx_history && ( + + )} + + {/**/} +
+
+); + + diff --git a/network-monitor/src/contracts.tsx b/network-monitor/src/contracts.tsx new file mode 100644 index 000000000..70f89b595 --- /dev/null +++ b/network-monitor/src/contracts.tsx @@ -0,0 +1,105 @@ +import { useEffect, useState } from "react"; +import { TransactionData, TransactionPeerInterface, TxTableInterface } from "./type_definitions"; +import {all_contracts} from "./transactions-data"; +import {ContractDetail} from "./contract-detail"; + +export const ContractsTable = ({ open_tx_detail, tx_list }: TxTableInterface) => ( + + + + + + + + + {/* + + */} + + + + { + tx_list?.map((tx, index) => ( + + + + + + + {/* + + */} + + )) + } + +
Contract KeyLast Requester Peer IdLast Target Peer IdLast Transaction IdLast TypeStatusStartedFinalized
open_tx_detail(tx.contract_id)} style={{cursor: "pointer"}}>{tx.contract_id.slice(-8)}{tx.requester.slice(-8)}{tx.target.slice(-8)}{tx.transaction_id.slice(-8)}{tx.change_type}{tx.status}{tx.started}{tx.finalized}
+); + + + +export function ContractsContainer() { + const [is_detail_open, set_is_detail_open] = useState(false); + const [transaction, set_transaction] = useState(null); + const [transaction_history, set_transaction_history] = useState>([]); + const [peers_history, set_peers_history] = useState>([]); + const [tx_list, set_tx_list] = useState>([]); + + const open_tx_detail = (contract_id: string) => { + let contract_history = all_contracts.get(contract_id); + if (!contract_history) { + console.error("Transaction not found"); + return; + } + + set_transaction(contract_history[0]); + set_transaction_history(contract_history); + // set_peers_history(mock_peers_in_tx[tx.id]); + set_is_detail_open(true); + window.scrollTo(0, 0); + }; + + const close_detail = () => { + set_is_detail_open(false); + }; + + const load_contracts_list = () => { + let updated_tx_list = []; + + updated_tx_list = Array.from(all_contracts.values()); + + updated_tx_list = updated_tx_list.map((tx) => tx[tx.length - 1]); + + console.log(updated_tx_list); + set_tx_list(updated_tx_list); + } + + document.addEventListener("keydown", (e: any) => { + if (e.key === "Escape") { + close_detail(); + } + }); + + useEffect(() => { + setInterval(() => { + load_contracts_list(); + }, 3000); + }, []); + + return ( +
+ + + {transaction && transaction_history && ( + + )} +
+ ); +} + diff --git a/network-monitor/src/generated/topology.ts b/network-monitor/src/generated/topology.ts index d3e400b84..296d86e1c 100644 --- a/network-monitor/src/generated/topology.ts +++ b/network-monitor/src/generated/topology.ts @@ -1,16 +1,21 @@ // automatically generated by the FlatBuffers compiler, do not modify export { AddedConnection, AddedConnectionT } from "./topology/added-connection"; -export { - ControllerResponse, - ControllerResponseT, -} from "./topology/controller-response"; +export { ContractChange } from "./topology/contract-change"; +export { ContractChangeType } from "./topology/contract-change-type"; +export { ControllerResponse } from "./topology/controller-response"; export { Error, ErrorT } from "./topology/error"; export { Ok, OkT } from "./topology/ok"; export { PeerChange, PeerChangeT } from "./topology/peer-change"; export { PeerChangeType } from "./topology/peer-change-type"; +export { PutFailure } from "./topology/put-failure"; +export { PutRequest } from "./topology/put-request"; +export { PutSuccess } from "./topology/put-success"; export { - RemovedConnection, - RemovedConnectionT, + RemovedConnection, + RemovedConnectionT, } from "./topology/removed-connection"; export { Response } from "./topology/response"; +export { UpdateFailure } from "./topology/update-failure"; +export { UpdateRequest } from "./topology/update-request"; +export { UpdateSuccess } from "./topology/update-success"; diff --git a/network-monitor/src/generated/topology/contract-change-type.ts b/network-monitor/src/generated/topology/contract-change-type.ts new file mode 100644 index 000000000..56824cf87 --- /dev/null +++ b/network-monitor/src/generated/topology/contract-change-type.ts @@ -0,0 +1,112 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import { PutFailure } from "../topology/put-failure"; +import { PutRequest } from "../topology/put-request"; +import { PutSuccess } from "../topology/put-success"; +import { UpdateFailure } from "../topology/update-failure"; +import { UpdateRequest } from "../topology/update-request"; +import { UpdateSuccess } from "../topology/update-success"; + +export enum ContractChangeType { + NONE = 0, + PutRequest = 1, + PutSuccess = 2, + PutFailure = 3, + UpdateRequest = 4, + UpdateSuccess = 5, + UpdateFailure = 6, +} + +export function unionToContractChangeType( + type: ContractChangeType, + accessor: ( + obj: + | PutFailure + | PutRequest + | PutSuccess + | UpdateFailure + | UpdateRequest + | UpdateSuccess + ) => + | PutFailure + | PutRequest + | PutSuccess + | UpdateFailure + | UpdateRequest + | UpdateSuccess + | null +): + | PutFailure + | PutRequest + | PutSuccess + | UpdateFailure + | UpdateRequest + | UpdateSuccess + | null { + switch (ContractChangeType[type]) { + case "NONE": + return null; + case "PutRequest": + return accessor(new PutRequest())! as PutRequest; + case "PutSuccess": + return accessor(new PutSuccess())! as PutSuccess; + case "PutFailure": + return accessor(new PutFailure())! as PutFailure; + case "UpdateRequest": + return accessor(new UpdateRequest())! as UpdateRequest; + case "UpdateSuccess": + return accessor(new UpdateSuccess())! as UpdateSuccess; + case "UpdateFailure": + return accessor(new UpdateFailure())! as UpdateFailure; + default: + return null; + } +} + +export function unionListToContractChangeType( + type: ContractChangeType, + accessor: ( + index: number, + obj: + | PutFailure + | PutRequest + | PutSuccess + | UpdateFailure + | UpdateRequest + | UpdateSuccess + ) => + | PutFailure + | PutRequest + | PutSuccess + | UpdateFailure + | UpdateRequest + | UpdateSuccess + | null, + index: number +): + | PutFailure + | PutRequest + | PutSuccess + | UpdateFailure + | UpdateRequest + | UpdateSuccess + | null { + switch (ContractChangeType[type]) { + case "NONE": + return null; + case "PutRequest": + return accessor(index, new PutRequest())! as PutRequest; + case "PutSuccess": + return accessor(index, new PutSuccess())! as PutSuccess; + case "PutFailure": + return accessor(index, new PutFailure())! as PutFailure; + case "UpdateRequest": + return accessor(index, new UpdateRequest())! as UpdateRequest; + case "UpdateSuccess": + return accessor(index, new UpdateSuccess())! as UpdateSuccess; + case "UpdateFailure": + return accessor(index, new UpdateFailure())! as UpdateFailure; + default: + return null; + } +} diff --git a/network-monitor/src/generated/topology/contract-change.ts b/network-monitor/src/generated/topology/contract-change.ts new file mode 100644 index 000000000..1b6fe0de8 --- /dev/null +++ b/network-monitor/src/generated/topology/contract-change.ts @@ -0,0 +1,107 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from "flatbuffers"; + +import { + ContractChangeType, + unionToContractChangeType, + unionListToContractChangeType, +} from "../topology/contract-change-type"; + +export class ContractChange { + bb: flatbuffers.ByteBuffer | null = null; + bb_pos = 0; + __init(i: number, bb: flatbuffers.ByteBuffer): ContractChange { + this.bb_pos = i; + this.bb = bb; + return this; + } + + static getRootAsContractChange( + bb: flatbuffers.ByteBuffer, + obj?: ContractChange + ): ContractChange { + return (obj || new ContractChange()).__init( + bb.readInt32(bb.position()) + bb.position(), + bb + ); + } + + static getSizePrefixedRootAsContractChange( + bb: flatbuffers.ByteBuffer, + obj?: ContractChange + ): ContractChange { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new ContractChange()).__init( + bb.readInt32(bb.position()) + bb.position(), + bb + ); + } + + contractId(): string | null; + contractId( + optionalEncoding: flatbuffers.Encoding + ): string | Uint8Array | null; + contractId(optionalEncoding?: any): string | Uint8Array | null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset + ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) + : null; + } + + changeType(): ContractChangeType { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset + ? this.bb!.readUint8(this.bb_pos + offset) + : ContractChangeType.NONE; + } + + change(obj: any): any | null { + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.__union(obj, this.bb_pos + offset) : null; + } + + static startContractChange(builder: flatbuffers.Builder) { + builder.startObject(3); + } + + static addContractId( + builder: flatbuffers.Builder, + contractIdOffset: flatbuffers.Offset + ) { + builder.addFieldOffset(0, contractIdOffset, 0); + } + + static addChangeType( + builder: flatbuffers.Builder, + changeType: ContractChangeType + ) { + builder.addFieldInt8(1, changeType, ContractChangeType.NONE); + } + + static addChange( + builder: flatbuffers.Builder, + changeOffset: flatbuffers.Offset + ) { + builder.addFieldOffset(2, changeOffset, 0); + } + + static endContractChange(builder: flatbuffers.Builder): flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 4); // contract_id + return offset; + } + + static createContractChange( + builder: flatbuffers.Builder, + contractIdOffset: flatbuffers.Offset, + changeType: ContractChangeType, + changeOffset: flatbuffers.Offset + ): flatbuffers.Offset { + ContractChange.startContractChange(builder); + ContractChange.addContractId(builder, contractIdOffset); + ContractChange.addChangeType(builder, changeType); + ContractChange.addChange(builder, changeOffset); + return ContractChange.endContractChange(builder); + } +} diff --git a/network-monitor/src/generated/topology/put-failure.ts b/network-monitor/src/generated/topology/put-failure.ts new file mode 100644 index 000000000..dfacd429c --- /dev/null +++ b/network-monitor/src/generated/topology/put-failure.ts @@ -0,0 +1,88 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +export class PutFailure { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):PutFailure { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsPutFailure(bb:flatbuffers.ByteBuffer, obj?:PutFailure):PutFailure { + return (obj || new PutFailure()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsPutFailure(bb:flatbuffers.ByteBuffer, obj?:PutFailure):PutFailure { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new PutFailure()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +transaction():string|null +transaction(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +transaction(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +requester():string|null +requester(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +requester(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +target():string|null +target(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +target(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +key():string|null +key(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +key(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 10); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +static startPutFailure(builder:flatbuffers.Builder) { + builder.startObject(4); +} + +static addTransaction(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, transactionOffset, 0); +} + +static addRequester(builder:flatbuffers.Builder, requesterOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, requesterOffset, 0); +} + +static addTarget(builder:flatbuffers.Builder, targetOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, targetOffset, 0); +} + +static addKey(builder:flatbuffers.Builder, keyOffset:flatbuffers.Offset) { + builder.addFieldOffset(3, keyOffset, 0); +} + +static endPutFailure(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 4) // transaction + builder.requiredField(offset, 6) // requester + builder.requiredField(offset, 8) // target + builder.requiredField(offset, 10) // key + return offset; +} + +static createPutFailure(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset, requesterOffset:flatbuffers.Offset, targetOffset:flatbuffers.Offset, keyOffset:flatbuffers.Offset):flatbuffers.Offset { + PutFailure.startPutFailure(builder); + PutFailure.addTransaction(builder, transactionOffset); + PutFailure.addRequester(builder, requesterOffset); + PutFailure.addTarget(builder, targetOffset); + PutFailure.addKey(builder, keyOffset); + return PutFailure.endPutFailure(builder); +} +} diff --git a/network-monitor/src/generated/topology/put-request.ts b/network-monitor/src/generated/topology/put-request.ts new file mode 100644 index 000000000..ce2a1ae0b --- /dev/null +++ b/network-monitor/src/generated/topology/put-request.ts @@ -0,0 +1,88 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +export class PutRequest { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):PutRequest { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsPutRequest(bb:flatbuffers.ByteBuffer, obj?:PutRequest):PutRequest { + return (obj || new PutRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsPutRequest(bb:flatbuffers.ByteBuffer, obj?:PutRequest):PutRequest { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new PutRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +transaction():string|null +transaction(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +transaction(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +key():string|null +key(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +key(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +requester():string|null +requester(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +requester(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +target():string|null +target(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +target(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 10); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +static startPutRequest(builder:flatbuffers.Builder) { + builder.startObject(4); +} + +static addTransaction(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, transactionOffset, 0); +} + +static addKey(builder:flatbuffers.Builder, keyOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, keyOffset, 0); +} + +static addRequester(builder:flatbuffers.Builder, requesterOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, requesterOffset, 0); +} + +static addTarget(builder:flatbuffers.Builder, targetOffset:flatbuffers.Offset) { + builder.addFieldOffset(3, targetOffset, 0); +} + +static endPutRequest(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 4) // transaction + builder.requiredField(offset, 6) // key + builder.requiredField(offset, 8) // requester + builder.requiredField(offset, 10) // target + return offset; +} + +static createPutRequest(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset, keyOffset:flatbuffers.Offset, requesterOffset:flatbuffers.Offset, targetOffset:flatbuffers.Offset):flatbuffers.Offset { + PutRequest.startPutRequest(builder); + PutRequest.addTransaction(builder, transactionOffset); + PutRequest.addKey(builder, keyOffset); + PutRequest.addRequester(builder, requesterOffset); + PutRequest.addTarget(builder, targetOffset); + return PutRequest.endPutRequest(builder); +} +} diff --git a/network-monitor/src/generated/topology/put-success.ts b/network-monitor/src/generated/topology/put-success.ts new file mode 100644 index 000000000..ca1e950e2 --- /dev/null +++ b/network-monitor/src/generated/topology/put-success.ts @@ -0,0 +1,88 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +export class PutSuccess { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):PutSuccess { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsPutSuccess(bb:flatbuffers.ByteBuffer, obj?:PutSuccess):PutSuccess { + return (obj || new PutSuccess()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsPutSuccess(bb:flatbuffers.ByteBuffer, obj?:PutSuccess):PutSuccess { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new PutSuccess()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +transaction():string|null +transaction(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +transaction(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +requester():string|null +requester(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +requester(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +target():string|null +target(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +target(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +key():string|null +key(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +key(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 10); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +static startPutSuccess(builder:flatbuffers.Builder) { + builder.startObject(4); +} + +static addTransaction(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, transactionOffset, 0); +} + +static addRequester(builder:flatbuffers.Builder, requesterOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, requesterOffset, 0); +} + +static addTarget(builder:flatbuffers.Builder, targetOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, targetOffset, 0); +} + +static addKey(builder:flatbuffers.Builder, keyOffset:flatbuffers.Offset) { + builder.addFieldOffset(3, keyOffset, 0); +} + +static endPutSuccess(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 4) // transaction + builder.requiredField(offset, 6) // requester + builder.requiredField(offset, 8) // target + builder.requiredField(offset, 10) // key + return offset; +} + +static createPutSuccess(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset, requesterOffset:flatbuffers.Offset, targetOffset:flatbuffers.Offset, keyOffset:flatbuffers.Offset):flatbuffers.Offset { + PutSuccess.startPutSuccess(builder); + PutSuccess.addTransaction(builder, transactionOffset); + PutSuccess.addRequester(builder, requesterOffset); + PutSuccess.addTarget(builder, targetOffset); + PutSuccess.addKey(builder, keyOffset); + return PutSuccess.endPutSuccess(builder); +} +} diff --git a/network-monitor/src/generated/topology/update-failure.ts b/network-monitor/src/generated/topology/update-failure.ts new file mode 100644 index 000000000..f25f2ff89 --- /dev/null +++ b/network-monitor/src/generated/topology/update-failure.ts @@ -0,0 +1,88 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +export class UpdateFailure { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):UpdateFailure { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsUpdateFailure(bb:flatbuffers.ByteBuffer, obj?:UpdateFailure):UpdateFailure { + return (obj || new UpdateFailure()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsUpdateFailure(bb:flatbuffers.ByteBuffer, obj?:UpdateFailure):UpdateFailure { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new UpdateFailure()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +transaction():string|null +transaction(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +transaction(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +requester():string|null +requester(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +requester(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +target():string|null +target(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +target(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +key():string|null +key(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +key(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 10); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +static startUpdateFailure(builder:flatbuffers.Builder) { + builder.startObject(4); +} + +static addTransaction(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, transactionOffset, 0); +} + +static addRequester(builder:flatbuffers.Builder, requesterOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, requesterOffset, 0); +} + +static addTarget(builder:flatbuffers.Builder, targetOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, targetOffset, 0); +} + +static addKey(builder:flatbuffers.Builder, keyOffset:flatbuffers.Offset) { + builder.addFieldOffset(3, keyOffset, 0); +} + +static endUpdateFailure(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 4) // transaction + builder.requiredField(offset, 6) // requester + builder.requiredField(offset, 8) // target + builder.requiredField(offset, 10) // key + return offset; +} + +static createUpdateFailure(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset, requesterOffset:flatbuffers.Offset, targetOffset:flatbuffers.Offset, keyOffset:flatbuffers.Offset):flatbuffers.Offset { + UpdateFailure.startUpdateFailure(builder); + UpdateFailure.addTransaction(builder, transactionOffset); + UpdateFailure.addRequester(builder, requesterOffset); + UpdateFailure.addTarget(builder, targetOffset); + UpdateFailure.addKey(builder, keyOffset); + return UpdateFailure.endUpdateFailure(builder); +} +} diff --git a/network-monitor/src/generated/topology/update-request.ts b/network-monitor/src/generated/topology/update-request.ts new file mode 100644 index 000000000..b634c452d --- /dev/null +++ b/network-monitor/src/generated/topology/update-request.ts @@ -0,0 +1,88 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +export class UpdateRequest { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):UpdateRequest { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsUpdateRequest(bb:flatbuffers.ByteBuffer, obj?:UpdateRequest):UpdateRequest { + return (obj || new UpdateRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsUpdateRequest(bb:flatbuffers.ByteBuffer, obj?:UpdateRequest):UpdateRequest { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new UpdateRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +transaction():string|null +transaction(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +transaction(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +key():string|null +key(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +key(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +requester():string|null +requester(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +requester(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +target():string|null +target(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +target(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 10); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +static startUpdateRequest(builder:flatbuffers.Builder) { + builder.startObject(4); +} + +static addTransaction(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, transactionOffset, 0); +} + +static addKey(builder:flatbuffers.Builder, keyOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, keyOffset, 0); +} + +static addRequester(builder:flatbuffers.Builder, requesterOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, requesterOffset, 0); +} + +static addTarget(builder:flatbuffers.Builder, targetOffset:flatbuffers.Offset) { + builder.addFieldOffset(3, targetOffset, 0); +} + +static endUpdateRequest(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 4) // transaction + builder.requiredField(offset, 6) // key + builder.requiredField(offset, 8) // requester + builder.requiredField(offset, 10) // target + return offset; +} + +static createUpdateRequest(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset, keyOffset:flatbuffers.Offset, requesterOffset:flatbuffers.Offset, targetOffset:flatbuffers.Offset):flatbuffers.Offset { + UpdateRequest.startUpdateRequest(builder); + UpdateRequest.addTransaction(builder, transactionOffset); + UpdateRequest.addKey(builder, keyOffset); + UpdateRequest.addRequester(builder, requesterOffset); + UpdateRequest.addTarget(builder, targetOffset); + return UpdateRequest.endUpdateRequest(builder); +} +} diff --git a/network-monitor/src/generated/topology/update-success.ts b/network-monitor/src/generated/topology/update-success.ts new file mode 100644 index 000000000..535fdff86 --- /dev/null +++ b/network-monitor/src/generated/topology/update-success.ts @@ -0,0 +1,88 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +export class UpdateSuccess { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):UpdateSuccess { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsUpdateSuccess(bb:flatbuffers.ByteBuffer, obj?:UpdateSuccess):UpdateSuccess { + return (obj || new UpdateSuccess()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsUpdateSuccess(bb:flatbuffers.ByteBuffer, obj?:UpdateSuccess):UpdateSuccess { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new UpdateSuccess()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +transaction():string|null +transaction(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +transaction(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +requester():string|null +requester(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +requester(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +target():string|null +target(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +target(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +key():string|null +key(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +key(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 10); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +static startUpdateSuccess(builder:flatbuffers.Builder) { + builder.startObject(4); +} + +static addTransaction(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, transactionOffset, 0); +} + +static addRequester(builder:flatbuffers.Builder, requesterOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, requesterOffset, 0); +} + +static addTarget(builder:flatbuffers.Builder, targetOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, targetOffset, 0); +} + +static addKey(builder:flatbuffers.Builder, keyOffset:flatbuffers.Offset) { + builder.addFieldOffset(3, keyOffset, 0); +} + +static endUpdateSuccess(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 4) // transaction + builder.requiredField(offset, 6) // requester + builder.requiredField(offset, 8) // target + builder.requiredField(offset, 10) // key + return offset; +} + +static createUpdateSuccess(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset, requesterOffset:flatbuffers.Offset, targetOffset:flatbuffers.Offset, keyOffset:flatbuffers.Offset):flatbuffers.Offset { + UpdateSuccess.startUpdateSuccess(builder); + UpdateSuccess.addTransaction(builder, transactionOffset); + UpdateSuccess.addRequester(builder, requesterOffset); + UpdateSuccess.addTarget(builder, targetOffset); + UpdateSuccess.addKey(builder, keyOffset); + return UpdateSuccess.endUpdateSuccess(builder); +} +} diff --git a/network-monitor/src/react-init.tsx b/network-monitor/src/react-init.tsx new file mode 100644 index 000000000..0b7299aec --- /dev/null +++ b/network-monitor/src/react-init.tsx @@ -0,0 +1,35 @@ +import { ContractsTable } from "./contracts"; +import { TransactionContainer } from "./transactions"; +import { ContractsContainer } from "./contracts"; +import {another_ring_visualization} from "./ring-visualization"; + +function ReactContainer() { + return ( +
+ + {another_ring_visualization({peerId: "abc", localization: 0.1}, [{peerId: "0x593b", localization: 0.3}, {peerId: "0x593b", localization: 0.5}, {peerId: "0x593b", localization: 0.7}, {peerId: "0x593b", localization: 0.9}])} + + + +
+ + ) +} + +export const component = ; + + + // const localizations = [0.0001, 0.5498, 0.865, 0.988]; + + // const points = localizations.map((x) => { + // return { + // x: Math.cos(2 * Math.PI * x), + // y: Math.sin(2 * Math.PI * x), + // }; + // } +// +// +// + // + // + // diff --git a/network-monitor/src/ring-visualization.tsx b/network-monitor/src/ring-visualization.tsx new file mode 100644 index 000000000..bcccec040 --- /dev/null +++ b/network-monitor/src/ring-visualization.tsx @@ -0,0 +1,209 @@ +import { local } from "d3"; + +interface RingVisualizationPoint { + peerId: string; + localization: number; +} + +export const another_ring_visualization = ( + main_peer: RingVisualizationPoint, + other_peers: RingVisualizationPoint[] +) => { + // Declare the chart dimensions and margins. + const width = 640; + const height = 400; + const marginTop = 20; + const marginRight = 20; + const marginBottom = 30; + const marginLeft = 40; + + // // Declare the x (horizontal position) scale. + // const x = d3 + // .scaleUtc() + // .domain([new Date("2023-01-01"), new Date("2024-01-01")]) + // .range([marginLeft, width - marginRight]); + + // // Declare the y (vertical position) scale. + // const y = d3 + // .scaleLinear() + // .domain([0, 100]) + // .range([height - marginBottom, marginTop]); + + // // Create the SVG container. + // const svg = d3.create("svg").attr("width", width).attr("height", height); + + // // Add the x-axis. + // svg.append("g") + // .attr("transform", `translate(0,${height - marginBottom})`) + // .call(d3.axisBottom(x)); + + // // Add the y-axis. + // svg.append("g") + // .attr("transform", `translate(${marginLeft},0)`) + // .call(d3.axisLeft(y)); + // + let scale = 3; + + console.log(calculate_point(other_peers[0].localization, scale)); + console.log(calculate_point(other_peers[1].localization, scale)); + + let tooltip_x = 100; + let tooltip_y = 100; + + let tooltips_visibility = {}; + + let a = ( + + + + + + + + {other_peers.map((peer, index) => { + let return_values = ( + <> + { + document.styleSheets[2].addRule( + `.svg-tooltip-${peer.localization + .toString() + .replace(".", "")}`, + "display: block" + ); + }} + onMouseLeave={() => { + document.styleSheets[2].addRule( + `.svg-tooltip-${peer.localization + .toString() + .replace(".", "")}`, + "display: none" + ); + }} + /> + + + {peer.peerId}: {peer.localization} + + + ); + + document.styleSheets[2].addRule( + `.svg-tooltip-${peer.localization + .toString() + .replace(".", "")}`, + "display: none" + ); + return return_values; + })} + + {other_peers.map((peer, index) => { + let return_values = ( + <> + { + document.styleSheets[2].addRule( + `.svg-tooltip-distance-${peer.localization + .toString() + .replace(".", "")}`, + "display: block" + ); + }} + onMouseLeave={() => { + document.styleSheets[2].addRule( + `.svg-tooltip-distance-${peer.localization + .toString() + .replace(".", "")}`, + "display: none" + ); + }} + /> + + + distance: {Math.abs(peer.localization - main_peer.localization)} + + + + ); + + + document.styleSheets[2].addRule( + `.svg-tooltip-distance-${peer.localization + .toString() + .replace(".", "")}`, + "display: none" + ); + + return return_values; + })} + + + ); + + // Append the SVG element. + return a; +}; + +const calculate_point = (localization: number, scale: number) => { + return { + x: + Math.cos(2 * Math.PI * localization) * 40 * scale + + 40 * scale + + 20 * scale, + y: + Math.sin(2 * Math.PI * localization) * 40 * scale + + 40 * scale + + 10 * scale, + }; +}; diff --git a/network-monitor/src/topology.ts b/network-monitor/src/topology.ts index 42ff098f5..806d03448 100644 --- a/network-monitor/src/topology.ts +++ b/network-monitor/src/topology.ts @@ -1,829 +1,851 @@ import * as fbTopology from "./generated/topology"; import * as d3 from "d3"; import { BaseType } from "d3-selection"; +import { createRoot } from "react-dom/client"; +import { component } from "./react-init"; export let peers: PeerList = {}; interface PeerList { - [id: string]: Peer; + [id: string]: Peer; } interface Peer { - id: PeerId; - currentLocation: number; - connectionTimestamp: number; - connections: Connection[]; - history: ChangeInfo[]; - locationHistory: { location: number; timestamp: number }[]; + id: PeerId; + currentLocation: number; + connectionTimestamp: number; + connections: Connection[]; + history: ChangeInfo[]; + locationHistory: { location: number; timestamp: number }[]; } interface Connection { - transaction: string | null; - id: PeerId; - location: number; + transaction: string | null; + id: PeerId; + location: number; } interface ChangeInfo { - type: "Added" | "Removed"; - from: Connection; - to: Connection; - timestamp: number; + type: "Added" | "Removed"; + from: Connection; + to: Connection; + timestamp: number; } export class PeerId { - private id: string; + private id: string; - constructor(id: string | Uint8Array) { - if (id instanceof Uint8Array) { - this.id = new TextDecoder().decode(id); - } else { - this.id = id; + constructor(id: string | Uint8Array) { + if (id instanceof Uint8Array) { + this.id = new TextDecoder().decode(id); + } else { + this.id = id; + } } - } - get short() { - return this.id.slice(-8); - } + get short() { + return this.id.slice(-8); + } - get full() { - return this.id; - } + get full() { + return this.id; + } } export function handleChange(peerChange: fbTopology.PeerChange) { - const previousPeers = Object.keys(peers).length; - try { - const unpacked = peerChange.unpack(); - switch (unpacked.changeType) { - case fbTopology.PeerChangeType.AddedConnection: - handleAddedConnection(unpacked.change as fbTopology.AddedConnectionT); - break; - case fbTopology.PeerChangeType.RemovedConnection: - handleRemovedConnection( - unpacked.change as fbTopology.RemovedConnectionT - ); - break; - case fbTopology.PeerChangeType.NONE: - break; - case fbTopology.PeerChangeType.Error: - const error = unpacked.change as fbTopology.ErrorT; - if (error.message) { - console.error(error.message); + const previousPeers = Object.keys(peers).length; + try { + const unpacked = peerChange.unpack(); + switch (unpacked.changeType) { + case fbTopology.PeerChangeType.AddedConnection: + handleAddedConnection( + unpacked.change as fbTopology.AddedConnectionT + ); + break; + case fbTopology.PeerChangeType.RemovedConnection: + handleRemovedConnection( + unpacked.change as fbTopology.RemovedConnectionT + ); + break; + case fbTopology.PeerChangeType.NONE: + break; + case fbTopology.PeerChangeType.Error: + const error = unpacked.change as fbTopology.ErrorT; + if (error.message) { + console.error(error.message); + } + break; } - break; - } - unpacked.currentState.forEach((connection) => { - handleAddedConnection(connection, false); - }); - } catch (e) { - console.error(e); - } finally { - if (previousPeers !== Object.keys(peers).length) { - ringHistogram(Object.values(peers)); - updateTable(); + unpacked.currentState.forEach((connection) => { + handleAddedConnection(connection, false); + }); + } catch (e) { + console.error(e); + } finally { + if (previousPeers !== Object.keys(peers).length) { + ringHistogram(Object.values(peers)); + updateTable(); + } + return true; } - } } export function handleAddedConnection( - peerChange: fbTopology.AddedConnectionT, - skipNonTransaction = true + peerChange: fbTopology.AddedConnectionT, + skipNonTransaction = true ) { - if (!peerChange.transaction && skipNonTransaction) { - // only add connections if they have been reported as part of a transaction - // otherwise we end up with duplicates here - return; - } - const added = peerChange; - const from = new PeerId(added.from!); - const to = new PeerId(added.to!); - - let transaction: string | null; - if (typeof added.transaction === "string") { - transaction = added.transaction; - } else if (added.transaction instanceof Uint8Array) { - transaction = new TextDecoder().decode(added.transaction); - } else { - transaction = null; - } - const fromConnection: Connection = { - transaction: transaction, - id: from, - location: added.fromLocation, - }; - - const toConnection: Connection = { - transaction: transaction, - id: to, - location: added.toLocation, - }; - - const fromFullId = from.full; - if (peers[fromFullId]) { - if (peers[fromFullId].currentLocation !== added.fromLocation) { - peers[fromFullId].locationHistory.push({ - location: peers[fromFullId].currentLocation, - timestamp: Date.now(), - }); - peers[fromFullId].currentLocation = added.fromLocation; + if (!peerChange.transaction && skipNonTransaction) { + // only add connections if they have been reported as part of a transaction + // otherwise we end up with duplicates here + return; } - - if ( - !peers[fromFullId].connections.some((conn) => conn.id.full === to.full) - ) { - peers[fromFullId].connections.push(toConnection); + const added = peerChange; + const from = new PeerId(added.from!); + const to = new PeerId(added.to!); + + let transaction: string | null; + if (typeof added.transaction === "string") { + transaction = added.transaction; + } else if (added.transaction instanceof Uint8Array) { + transaction = new TextDecoder().decode(added.transaction); + } else { + transaction = null; } - } else { - peers[fromFullId] = { - id: from, - currentLocation: added.fromLocation, - connectionTimestamp: Date.now(), - connections: [toConnection], - history: [], - locationHistory: [], + const fromConnection: Connection = { + transaction: transaction, + id: from, + location: added.fromLocation, }; - } - const toFullId = to.full; - if (peers[toFullId]) { - if (peers[toFullId].currentLocation !== added.toLocation) { - peers[toFullId].locationHistory.push({ - location: peers[toFullId].currentLocation, - timestamp: Date.now(), - }); - peers[toFullId].currentLocation = added.toLocation; + const toConnection: Connection = { + transaction: transaction, + id: to, + location: added.toLocation, + }; + + const fromFullId = from.full; + if (peers[fromFullId]) { + if (peers[fromFullId].currentLocation !== added.fromLocation) { + peers[fromFullId].locationHistory.push({ + location: peers[fromFullId].currentLocation, + timestamp: Date.now(), + }); + peers[fromFullId].currentLocation = added.fromLocation; + } + + if ( + !peers[fromFullId].connections.some( + (conn) => conn.id.full === to.full + ) + ) { + peers[fromFullId].connections.push(toConnection); + } + } else { + peers[fromFullId] = { + id: from, + currentLocation: added.fromLocation, + connectionTimestamp: Date.now(), + connections: [toConnection], + history: [], + locationHistory: [], + }; } - if ( - !peers[toFullId].connections.some((conn) => conn.id.full === from.full) - ) { - peers[toFullId].connections.push(fromConnection); + const toFullId = to.full; + if (peers[toFullId]) { + if (peers[toFullId].currentLocation !== added.toLocation) { + peers[toFullId].locationHistory.push({ + location: peers[toFullId].currentLocation, + timestamp: Date.now(), + }); + peers[toFullId].currentLocation = added.toLocation; + } + + if ( + !peers[toFullId].connections.some( + (conn) => conn.id.full === from.full + ) + ) { + peers[toFullId].connections.push(fromConnection); + } + } else { + peers[toFullId] = { + id: to, + currentLocation: added.toLocation, + connectionTimestamp: Date.now(), + connections: [fromConnection], + history: [], + locationHistory: [], + }; } - } else { - peers[toFullId] = { - id: to, - currentLocation: added.toLocation, - connectionTimestamp: Date.now(), - connections: [fromConnection], - history: [], - locationHistory: [], + + const changeInfo: ChangeInfo = { + type: "Added", + from: fromConnection, + to: toConnection, + timestamp: Date.now(), }; - } - - const changeInfo: ChangeInfo = { - type: "Added", - from: fromConnection, - to: toConnection, - timestamp: Date.now(), - }; - - // Check if the (to, from) pair or its reverse is already present in the history - const isPresent = peers[fromFullId].history.some( - (item) => - (item.from.id.full === changeInfo.from.id.full && - item.to.id.full === changeInfo.to.id.full && - item.from.transaction === changeInfo.from.transaction) || - (item.from.id.full === changeInfo.to.id.full && - item.to.id.full === changeInfo.from.id.full && - item.from.transaction === changeInfo.from.transaction) - ); - - // Only push changeInfo if the pair is not already present - if (!isPresent) { - peers[fromFullId].history.push(changeInfo); - peers[toFullId].history.push(changeInfo); - } + + // Check if the (to, from) pair or its reverse is already present in the history + const isPresent = peers[fromFullId].history.some( + (item) => + (item.from.id.full === changeInfo.from.id.full && + item.to.id.full === changeInfo.to.id.full && + item.from.transaction === changeInfo.from.transaction) || + (item.from.id.full === changeInfo.to.id.full && + item.to.id.full === changeInfo.from.id.full && + item.from.transaction === changeInfo.from.transaction) + ); + + // Only push changeInfo if the pair is not already present + if (!isPresent) { + peers[fromFullId].history.push(changeInfo); + peers[toFullId].history.push(changeInfo); + } } export function handleRemovedConnection( - peerChange: fbTopology.RemovedConnectionT + peerChange: fbTopology.RemovedConnectionT ) { - const from = new PeerId(peerChange.from!); - const at = new PeerId(peerChange.at!); - - const index = peers[from.full].connections.findIndex( - (connection) => connection.id.full === at.full - ); - - if (index > -1) { - peers[from.full].connections.splice(index, 1); - } - - const reverseIndex = peers[at.full].connections.findIndex( - (connection: Connection) => connection.id.full === from.full - ); - - if (reverseIndex > -1) { - peers[at.full].connections.splice(reverseIndex, 1); - } - - const changeInfo: ChangeInfo = { - type: "Removed", - from: { - transaction: null, - id: from, - location: peers[from.full].currentLocation, - }, - to: { - transaction: null, - id: at, - location: peers[at.full].currentLocation, - }, - timestamp: Date.now(), - }; - - peers[from.full].history.push(changeInfo); - peers[at.full].history.push(changeInfo); -} + const from = new PeerId(peerChange.from!); + const at = new PeerId(peerChange.at!); -function updateTable() { - const peerConnectionsDiv = document.getElementById("peer-details")!; - - const table = document.getElementById("peers-table")!; + const index = peers[from.full].connections.findIndex( + (connection) => connection.id.full === at.full + ); - const tbody = table.querySelector("tbody")!; - tbody.innerHTML = ""; + if (index > -1) { + peers[from.full].connections.splice(index, 1); + } - const setDivPosition = (event: MouseEvent) => { - peerConnectionsDiv.style.display = "block"; - const rect = peerConnectionsDiv.offsetParent!.getBoundingClientRect(); - const divHeight = peerConnectionsDiv.offsetHeight; + const reverseIndex = peers[at.full].connections.findIndex( + (connection: Connection) => connection.id.full === from.full + ); - // Check if the div would render off the bottom of the screen - if (event.clientY + divHeight > window.innerHeight) { - // If so, position it above the mouse cursor instead - peerConnectionsDiv.style.top = `${ - event.clientY - rect.top - divHeight - }px`; - } else { - // Otherwise, position it below the mouse cursor as usual - peerConnectionsDiv.style.top = `${event.clientY - rect.top}px`; + if (reverseIndex > -1) { + peers[at.full].connections.splice(reverseIndex, 1); } - peerConnectionsDiv.style.left = `${event.clientX - rect.left + 15}px`; - }; + const changeInfo: ChangeInfo = { + type: "Removed", + from: { + transaction: null, + id: from, + location: peers[from.full].currentLocation, + }, + to: { + transaction: null, + id: at, + location: peers[at.full].currentLocation, + }, + timestamp: Date.now(), + }; - for (const peer in peers) { - const peerData = peers[peer]; - const row = document.createElement("tr"); - row.addEventListener("mouseover", (event) => { - setDivPosition(event); - showPeerData(peers[peer]); - }); - row.addEventListener("mousemove", (event) => { - setDivPosition(event); - }); - row.addEventListener( - "mouseout", - () => (peerConnectionsDiv.style.display = "none") - ); - row.addEventListener("click", () => { - const modal = document.createElement("div"); - modal.classList.add("modal", "is-active"); - const modalBackground = document.createElement("div"); - modalBackground.classList.add("modal-background"); - modal.appendChild(modalBackground); - - const modalContent = document.createElement("div"); - modalContent.classList.add("modal-content"); - // Set the width of the modal content based on the viewport width - if (window.innerWidth >= 1200) { - modalContent.style.width = "80%"; - } else if (window.innerWidth >= 769) { - modalContent.style.width = "640px"; - } else { - modalContent.style.width = "100%"; - } - - const modalBox = document.createElement("div"); - modalBox.classList.add("box", "column"); - modalBox.style.overflowWrap = "break-word"; - modalBox.style.whiteSpace = "normal"; - - const currentDetails = document.getElementById("peer-details")!.innerHTML; - modalBox.innerHTML = currentDetails; - // Make the table width 100% to ensure it fits within the modal box - modalBox.querySelectorAll("table").forEach((table) => { - if (table) { - table.style.width = "100%"; - table.style.tableLayout = "fixed"; + peers[from.full].history.push(changeInfo); + peers[at.full].history.push(changeInfo); +} + +function updateTable() { + const peerConnectionsDiv = document.getElementById("peer-details")!; + + const table = document.getElementById("peers-table")!; + + const tbody = table.querySelector("tbody")!; + tbody.innerHTML = ""; + + const setDivPosition = (event: MouseEvent) => { + peerConnectionsDiv.style.display = "block"; + const rect = peerConnectionsDiv.offsetParent!.getBoundingClientRect(); + const divHeight = peerConnectionsDiv.offsetHeight; + + // Check if the div would render off the bottom of the screen + if (event.clientY + divHeight > window.innerHeight) { + // If so, position it above the mouse cursor instead + peerConnectionsDiv.style.top = `${ + event.clientY - rect.top - divHeight + }px`; + } else { + // Otherwise, position it below the mouse cursor as usual + peerConnectionsDiv.style.top = `${event.clientY - rect.top}px`; } - }); - - modalContent.appendChild(modalBox); - modal.appendChild(modalContent); - - const closeModal = document.createElement("button"); - closeModal.classList.add("modal-close", "is-large"); - modal.appendChild(closeModal); - - const mainDiv = document.querySelector(".main")!; - mainDiv.appendChild(modal); - modal.addEventListener("click", () => { - modal.style.display = "none"; - const graphContainer = d3.select("#peer-conns-graph"); - graphContainer.selectAll("*").remove(); - modal.remove(); - }); - - // Build the neightbours information section - const neightboursDiv = document.createElement("div"); - neightboursDiv.classList.add("columns"); - - const graphDiv = document.createElement("div"); - graphDiv.id = "peer-conns-graph"; - graphDiv.classList.add("column"); - graphDiv.style.display = "flex"; - graphDiv.style.justifyContent = "center"; - graphDiv.style.alignItems = "center"; - const scaleFactor = 1.25; // Replace this with your actual scale factor - graphDiv.style.padding = `${10 * scaleFactor}px`; // Replace 10 with your actual padding - neightboursDiv.appendChild(graphDiv); - - const peerConnectionsT = modalBox.querySelector("#peer-connections-t")!; - peerConnectionsT.classList.add("column"); - neightboursDiv.appendChild(peerConnectionsT); - - const graphContainer = d3.select(graphDiv); - ringVisualization(peerData, graphContainer, scaleFactor); - - // Insert the new div before peer-connections-t in modalBox - modalBox - .querySelector("#neighbours-t")! - .insertAdjacentElement("afterend", neightboursDiv); - }); - const id = document.createElement("td"); - id.textContent = "..." + peerData.id.short; - const location = document.createElement("td"); - location.textContent = peerData.currentLocation.toString(); - const connectionTimestamp = document.createElement("td"); - const timestamp = new Date(peerData.connectionTimestamp); - connectionTimestamp.textContent = `${timestamp.toUTCString()} (${timestamp.getMilliseconds()}ms)`; - row.appendChild(id); - row.appendChild(location); - row.appendChild(connectionTimestamp); - - // Add event listeners to each td element - const tds = row.getElementsByTagName("td"); - for (let i = 0; i < tds.length; i++) { - tds[i].addEventListener("mouseover", (event) => { - setDivPosition(event); - showPeerData(peers[peer]); - }); - row.addEventListener("mousemove", (event) => { - setDivPosition(event); - }); - tds[i].addEventListener( - "mouseout", - () => (peerConnectionsDiv.style.display = "none") - ); - } + peerConnectionsDiv.style.left = `${event.clientX - rect.left + 15}px`; + }; - tbody.appendChild(row); - } + for (const peer in peers) { + const peerData = peers[peer]; + const row = document.createElement("tr"); + row.addEventListener("mouseover", (event) => { + setDivPosition(event); + showPeerData(peers[peer]); + }); + row.addEventListener("mousemove", (event) => { + setDivPosition(event); + }); + row.addEventListener( + "mouseout", + () => (peerConnectionsDiv.style.display = "none") + ); + row.addEventListener("click", () => { + const modal = document.createElement("div"); + modal.classList.add("modal", "is-active"); + const modalBackground = document.createElement("div"); + modalBackground.classList.add("modal-background"); + modal.appendChild(modalBackground); + + const modalContent = document.createElement("div"); + modalContent.classList.add("modal-content"); + // Set the width of the modal content based on the viewport width + if (window.innerWidth >= 1200) { + modalContent.style.width = "80%"; + } else if (window.innerWidth >= 769) { + modalContent.style.width = "640px"; + } else { + modalContent.style.width = "100%"; + } + + const modalBox = document.createElement("div"); + modalBox.classList.add("box", "column"); + modalBox.style.overflowWrap = "break-word"; + modalBox.style.whiteSpace = "normal"; + + const currentDetails = + document.getElementById("peer-details")!.innerHTML; + modalBox.innerHTML = currentDetails; + // Make the table width 100% to ensure it fits within the modal box + modalBox.querySelectorAll("table").forEach((table) => { + if (table) { + table.style.width = "100%"; + table.style.tableLayout = "fixed"; + } + }); + + modalContent.appendChild(modalBox); + modal.appendChild(modalContent); + + const closeModal = document.createElement("button"); + closeModal.classList.add("modal-close", "is-large"); + modal.appendChild(closeModal); + + const mainDiv = document.querySelector(".main")!; + mainDiv.appendChild(modal); + modal.addEventListener("click", () => { + modal.style.display = "none"; + const graphContainer = d3.select("#peer-conns-graph"); + graphContainer.selectAll("*").remove(); + modal.remove(); + }); + + // Build the neightbours information section + const neightboursDiv = document.createElement("div"); + neightboursDiv.classList.add("columns"); + + const graphDiv = document.createElement("div"); + graphDiv.id = "peer-conns-graph"; + graphDiv.classList.add("column"); + graphDiv.style.display = "flex"; + graphDiv.style.justifyContent = "center"; + graphDiv.style.alignItems = "center"; + const scaleFactor = 1.25; // Replace this with your actual scale factor + graphDiv.style.padding = `${10 * scaleFactor}px`; // Replace 10 with your actual padding + neightboursDiv.appendChild(graphDiv); + + const peerConnectionsT = modalBox.querySelector( + "#peer-connections-t" + )!; + peerConnectionsT.classList.add("column"); + neightboursDiv.appendChild(peerConnectionsT); + + const graphContainer = d3.select(graphDiv); + ringVisualization(peerData, graphContainer, scaleFactor); + + // Insert the new div before peer-connections-t in modalBox + modalBox + .querySelector("#neighbours-t")! + .insertAdjacentElement("afterend", neightboursDiv); + }); + + const id = document.createElement("td"); + id.textContent = "..." + peerData.id.short; + const location = document.createElement("td"); + location.textContent = peerData.currentLocation.toString(); + const connectionTimestamp = document.createElement("td"); + const timestamp = new Date(peerData.connectionTimestamp); + connectionTimestamp.textContent = `${timestamp.toUTCString()} (${timestamp.getMilliseconds()}ms)`; + row.appendChild(id); + row.appendChild(location); + row.appendChild(connectionTimestamp); + + // Add event listeners to each td element + const tds = row.getElementsByTagName("td"); + for (let i = 0; i < tds.length; i++) { + tds[i].addEventListener("mouseover", (event) => { + setDivPosition(event); + showPeerData(peers[peer]); + }); + row.addEventListener("mousemove", (event) => { + setDivPosition(event); + }); + tds[i].addEventListener( + "mouseout", + () => (peerConnectionsDiv.style.display = "none") + ); + } - const rows = Array.from(tbody.querySelectorAll("tr")); - const sortedRows = rows.sort((a, b) => { - const cellA = a.cells[2].textContent!; - const cellB = b.cells[2].textContent!; - return cellA.localeCompare(cellB); - }); + tbody.appendChild(row); + } - rows.forEach((row) => tbody.removeChild(row)); - sortedRows.forEach((row) => tbody.appendChild(row)); + const rows = Array.from(tbody.querySelectorAll("tr")); + const sortedRows = rows.sort((a, b) => { + const cellA = a.cells[2].textContent!; + const cellB = b.cells[2].textContent!; + return cellA.localeCompare(cellB); + }); + + rows.forEach((row) => tbody.removeChild(row)); + sortedRows.forEach((row) => tbody.appendChild(row)); } const sortDirections: number[] = []; document.addEventListener("DOMContentLoaded", () => { - ringHistogram(Object.values(peers)); - - document - .querySelector("#peers-table-h")! - .querySelectorAll("th")! - .forEach((header, index) => { - sortDirections.push(1); - tableSorting(header, index); - }); - - (window as any).resetPeersTable = function () { - peers = {}; - updateTable(); ringHistogram(Object.values(peers)); - }; + + document + .querySelector("#peers-table-h")! + .querySelectorAll("th")! + .forEach((header, index) => { + sortDirections.push(1); + tableSorting(header, index); + }); + + const root = createRoot(document.getElementById("react-init-point")!); + root.render(component); + + (window as any).resetPeersTable = function () { + peers = {}; + updateTable(); + ringHistogram(Object.values(peers)); + }; }); function tableSorting(header: HTMLTableCellElement, index: number) { - header.addEventListener("click", () => { - const tbody = - header.parentElement!.parentElement!.parentElement!.querySelector( - "tbody" - )!; - const rows = Array.from(tbody.querySelectorAll("tr")); - - const sortedRows = rows.sort((a, b) => { - const cellA = a.cells[index].textContent!; - const cellB = b.cells[index].textContent!; + header.addEventListener("click", () => { + const tbody = + header.parentElement!.parentElement!.parentElement!.querySelector( + "tbody" + )!; + const rows = Array.from(tbody.querySelectorAll("tr")); + + const sortedRows = rows.sort((a, b) => { + const cellA = a.cells[index].textContent!; + const cellB = b.cells[index].textContent!; + + // Use a locale-sensitive string comparison for proper sorting + // Multiply by the sort direction to toggle between ascending and descending order + return cellA.localeCompare(cellB) * sortDirections[index]; + }); + + // Toggle the sort direction for the next click + sortDirections[index] = -sortDirections[index]; + const icon = header.querySelector("i")!; + if (icon.classList.contains("fa-sort-amount-down")) { + icon.classList.remove("fa-sort-amount-down"); + icon.classList.add("fa-sort-amount-up"); + } else { + icon.classList.remove("fa-sort-amount-up"); + icon.classList.add("fa-sort-amount-down"); + } - // Use a locale-sensitive string comparison for proper sorting - // Multiply by the sort direction to toggle between ascending and descending order - return cellA.localeCompare(cellB) * sortDirections[index]; + rows.forEach((row) => tbody.removeChild(row)); + sortedRows.forEach((row) => tbody.appendChild(row)); }); - - // Toggle the sort direction for the next click - sortDirections[index] = -sortDirections[index]; - const icon = header.querySelector("i")!; - if (icon.classList.contains("fa-sort-amount-down")) { - icon.classList.remove("fa-sort-amount-down"); - icon.classList.add("fa-sort-amount-up"); - } else { - icon.classList.remove("fa-sort-amount-up"); - icon.classList.add("fa-sort-amount-down"); - } - - rows.forEach((row) => tbody.removeChild(row)); - sortedRows.forEach((row) => tbody.appendChild(row)); - }); } export function showPeerData(peer: Peer) { - const id = peer.id; - peer.connections.sort((a, b) => a.location - b.location); + const id = peer.id; + peer.connections.sort((a, b) => a.location - b.location); - // Set title - const peerDataHeader = document.getElementById("peer-details-h")!; - peerDataHeader.innerHTML = ` + // Set title + const peerDataHeader = document.getElementById("peer-details-h")!; + peerDataHeader.innerHTML = `
Peer Id: ${id.full}
Location: ${peer.currentLocation ?? ""}
`; - listPeerConnections(peer.connections); - displayHistory(peer); + listPeerConnections(peer.connections); + displayHistory(peer); } function ringVisualization( - peer: Peer, - graphContainer: d3.Selection, - scaleFactor: number + peer: Peer, + graphContainer: d3.Selection, + scaleFactor: number ) { - const width = 200; - const height = 200; - - const svg = graphContainer - .append("svg") - .attr("width", width) - .attr("height", height) - .attr("style", "max-width: 100%") - .attr("transform", `scale(${scaleFactor})`); - - // Set up the ring - const radius = 75; - const centerX = width / 2; - const centerY = height / 2; - - const referencePoint = { value: peer.currentLocation, legend: peer.id.short }; - const dataPoints = peer.connections.map((conn) => { - return { value: conn.location, legend: conn.id.short }; - }); - - svg - .append("circle") - .attr("cx", centerX) - .attr("cy", centerY) - .attr("r", radius) - .attr("stroke", "black") - .attr("stroke-width", 2) - .attr("fill", "none"); - - const tooltip = graphContainer - .append("div") - .attr("class", "tooltip") - .style("position", "absolute") - .style("visibility", "hidden") - .style("background-color", "white") - .style("border", "solid") - .style("border-width", "2px") - .style("border-radius", "5px") - .style("padding", "5px"); - - // Create points along the ring with legends - svg - .append("circle") - .attr("class", "fixed-point") - .attr("cx", centerX + radius * Math.cos(referencePoint.value * 2 * Math.PI)) - .attr("cy", centerY + radius * Math.sin(referencePoint.value * 2 * Math.PI)) - .attr("r", 5) - .attr("fill", "red"); - - function showLegend( - this: SVGCircleElement, - e: MouseEvent, - d: { value: number; legend: string } - ) { - tooltip - .style("visibility", "visible") - .style("position", "absolute") - .style("stroke", "black") - .html(`${d.legend}: ${d.value}`); - const tooltipRect = tooltip.node()!.getBoundingClientRect(); - tooltip - .style("left", e.clientX - tooltipRect.width / 2 + "px") - .style("top", e.clientY - tooltipRect.height / 2 + "px"); - d3.select(this).style("stroke", "black"); - } - - function hideLegend(this: SVGCircleElement) { - tooltip.style("visibility", "hidden"); - d3.select(this).style("stroke", "none"); - } - - function circleId(d: { value: number; legend: string }, i: number) { - return `circle-${i}-${d.legend}`; - } - - svg - .selectAll(".point") - .data(dataPoints) - .enter() - .append("circle") - .attr("class", "point") - .attr("id", (d, i) => circleId(d, i)) - .attr("cx", (d) => centerX + radius * Math.cos(d.value * 2 * Math.PI)) - .attr("cy", (d) => centerY + radius * Math.sin(d.value * 2 * Math.PI)) - .attr("r", 5) - .attr("fill", "steelblue") - .on("mouseover", showLegend) - .on("mousemove", showLegend) - .on("mouseout", hideLegend); - - // Connect all points to the fixed point (0.3) with distances as tooltips - - function showDistance( - this: SVGLineElement, - e: MouseEvent, - d: { value: number; legend: string } - ) { - const distance = getDistance(referencePoint.value, d.value).toFixed(5); - tooltip - .style("visibility", "visible") - .style("position", "absolute") - .style("z-index", "2") - .html(`Distance: ${distance}`); - const tooltipRect = tooltip.node()!.getBoundingClientRect(); - tooltip - .style("left", e.clientX - tooltipRect.width / 2 + "px") - .style("top", e.clientY - tooltipRect.height / 2 + "px"); - d3.select(this).style("stroke", "black"); - } - - function hideDistance(this: SVGLineElement) { - tooltip.style("visibility", "hidden"); - d3.select(this).style("stroke", "gray"); - } - - function getDistance(point1: number, point2: number) { - const diff = Math.abs(point1 - point2); - return Math.min(diff, 1 - diff); - } - - svg - .selectAll(".edge") - .data(dataPoints) - .enter() - .append("line") - .attr("class", "edge") - .attr("x1", centerX + radius * Math.cos(referencePoint.value * 2 * Math.PI)) - .attr("y1", centerY + radius * Math.sin(referencePoint.value * 2 * Math.PI)) - .attr("x2", (d) => centerX + radius * Math.cos(d.value * 2 * Math.PI)) - .attr("y2", (d) => centerY + radius * Math.sin(d.value * 2 * Math.PI)) - .attr("stroke", "gray") - .attr("stroke-width", 1.5) - .on("mouseover", showDistance) - .on("mousemove", showDistance) - .on("mouseout", hideDistance); + const width = 200; + const height = 200; + + const svg = graphContainer + .append("svg") + .attr("width", width) + .attr("height", height) + .attr("style", "max-width: 100%") + .attr("transform", `scale(${scaleFactor})`); + + // Set up the ring + const radius = 75; + const centerX = width / 2; + const centerY = height / 2; + + const referencePoint = { + value: peer.currentLocation, + legend: peer.id.short, + }; + const dataPoints = peer.connections.map((conn) => { + return { value: conn.location, legend: conn.id.short }; + }); + + svg.append("circle") + .attr("cx", centerX) + .attr("cy", centerY) + .attr("r", radius) + .attr("stroke", "black") + .attr("stroke-width", 2) + .attr("fill", "none"); + + const tooltip = graphContainer + .append("div") + .attr("class", "tooltip") + .style("position", "absolute") + .style("visibility", "hidden") + .style("background-color", "white") + .style("border", "solid") + .style("border-width", "2px") + .style("border-radius", "5px") + .style("padding", "5px"); + + // Create points along the ring with legends + svg.append("circle") + .attr("class", "fixed-point") + .attr( + "cx", + centerX + radius * Math.cos(referencePoint.value * 2 * Math.PI) + ) + .attr( + "cy", + centerY + radius * Math.sin(referencePoint.value * 2 * Math.PI) + ) + .attr("r", 5) + .attr("fill", "red"); + + function showLegend( + this: SVGCircleElement, + e: MouseEvent, + d: { value: number; legend: string } + ) { + tooltip + .style("visibility", "visible") + .style("position", "absolute") + .style("stroke", "black") + .html(`${d.legend}: ${d.value}`); + const tooltipRect = tooltip.node()!.getBoundingClientRect(); + tooltip + .style("left", e.clientX - tooltipRect.width / 2 + "px") + .style("top", e.clientY - tooltipRect.height / 2 + "px"); + d3.select(this).style("stroke", "black"); + } + + function hideLegend(this: SVGCircleElement) { + tooltip.style("visibility", "hidden"); + d3.select(this).style("stroke", "none"); + } + + function circleId(d: { value: number; legend: string }, i: number) { + return `circle-${i}-${d.legend}`; + } + + svg.selectAll(".point") + .data(dataPoints) + .enter() + .append("circle") + .attr("class", "point") + .attr("id", (d, i) => circleId(d, i)) + .attr("cx", (d) => centerX + radius * Math.cos(d.value * 2 * Math.PI)) + .attr("cy", (d) => centerY + radius * Math.sin(d.value * 2 * Math.PI)) + .attr("r", 5) + .attr("fill", "steelblue") + .on("mouseover", showLegend) + .on("mousemove", showLegend) + .on("mouseout", hideLegend); + + // Connect all points to the fixed point (0.3) with distances as tooltips + + function showDistance( + this: SVGLineElement, + e: MouseEvent, + d: { value: number; legend: string } + ) { + const distance = getDistance(referencePoint.value, d.value).toFixed(5); + tooltip + .style("visibility", "visible") + .style("position", "absolute") + .style("z-index", "2") + .html(`Distance: ${distance}`); + const tooltipRect = tooltip.node()!.getBoundingClientRect(); + tooltip + .style("left", e.clientX - tooltipRect.width / 2 + "px") + .style("top", e.clientY - tooltipRect.height / 2 + "px"); + d3.select(this).style("stroke", "black"); + } + + function hideDistance(this: SVGLineElement) { + tooltip.style("visibility", "hidden"); + d3.select(this).style("stroke", "gray"); + } + + function getDistance(point1: number, point2: number) { + const diff = Math.abs(point1 - point2); + return Math.min(diff, 1 - diff); + } + + svg.selectAll(".edge") + .data(dataPoints) + .enter() + .append("line") + .attr("class", "edge") + .attr( + "x1", + centerX + radius * Math.cos(referencePoint.value * 2 * Math.PI) + ) + .attr( + "y1", + centerY + radius * Math.sin(referencePoint.value * 2 * Math.PI) + ) + .attr("x2", (d) => centerX + radius * Math.cos(d.value * 2 * Math.PI)) + .attr("y2", (d) => centerY + radius * Math.sin(d.value * 2 * Math.PI)) + .attr("stroke", "gray") + .attr("stroke-width", 1.5) + .on("mouseover", showDistance) + .on("mousemove", showDistance) + .on("mouseout", hideDistance); } function listPeerConnections(connections: Connection[]) { - // Find the existing peer connections table - const tableBody = document.getElementById("peer-connections-b")!; - - // Clear the existing table rows - while (tableBody.firstChild) { - tableBody.removeChild(tableBody.firstChild); - } - - // Create the table header row - const headerRow = document.createElement("tr"); - const idHeader = document.createElement("th"); - idHeader.textContent = "Neighbour Id"; - const locationHeader = document.createElement("th"); - locationHeader.textContent = "Location"; - headerRow.appendChild(idHeader); - headerRow.appendChild(locationHeader); - tableBody.appendChild(headerRow); - - // Create and append the table rows for all peers - connections.forEach((connection) => { - const row = document.createElement("tr"); - const idCell = document.createElement("td"); - idCell.textContent = "..." + connection.id.short; - const locationCell = document.createElement("td"); - locationCell.textContent = connection.location.toString() ?? ""; - row.appendChild(idCell); - row.appendChild(locationCell); - tableBody.appendChild(row); - }); + // Find the existing peer connections table + const tableBody = document.getElementById("peer-connections-b")!; + + // Clear the existing table rows + while (tableBody.firstChild) { + tableBody.removeChild(tableBody.firstChild); + } + + // Create the table header row + const headerRow = document.createElement("tr"); + const idHeader = document.createElement("th"); + idHeader.textContent = "Neighbour Id"; + const locationHeader = document.createElement("th"); + locationHeader.textContent = "Location"; + headerRow.appendChild(idHeader); + headerRow.appendChild(locationHeader); + tableBody.appendChild(headerRow); + + // Create and append the table rows for all peers + connections.forEach((connection) => { + const row = document.createElement("tr"); + const idCell = document.createElement("td"); + idCell.textContent = "..." + connection.id.short; + const locationCell = document.createElement("td"); + locationCell.textContent = connection.location.toString() ?? ""; + row.appendChild(idCell); + row.appendChild(locationCell); + tableBody.appendChild(row); + }); } function displayHistory(peer: Peer) { - const peerDetails = document.getElementById("peer-details")!; - - // Remove the existing table if it exists - const existingTable = peerDetails.querySelector("#connection-history"); - if (existingTable) { - existingTable.remove(); - } - - // Create a new table - const table = document.createElement("table"); - table.id = "connection-history"; - table.classList.add("table", "is-striped", "block", "is-bordered"); - table.style.overflowWrap = "break-word"; - - // Create the table header row - const thead = document.createElement("thead"); - const headerRow = document.createElement("tr"); - const typeHeader = document.createElement("th"); - typeHeader.textContent = "Type"; - const fromHeader = document.createElement("th"); - fromHeader.textContent = "From"; - const toHeader = document.createElement("th"); - toHeader.textContent = "To"; - const dateHeader = document.createElement("th"); - dateHeader.textContent = "Date"; - const transaction = document.createElement("th"); - transaction.textContent = "Transaction"; - headerRow.appendChild(typeHeader); - headerRow.appendChild(fromHeader); - headerRow.appendChild(toHeader); - headerRow.appendChild(dateHeader); - headerRow.appendChild(transaction); - thead.appendChild(headerRow); - table.appendChild(thead); - - // Create the table body - const tbody = document.createElement("tbody"); - const historyRows = peer.history.map((change) => { - const row = document.createElement("tr"); - const typeCell = document.createElement("td"); - typeCell.textContent = change.type; - const fromCell = document.createElement("td"); - fromCell.textContent = "..." + change.from.id.short; // Show last 8 characters - const toCell = document.createElement("td"); - toCell.textContent = "..." + change.to.id.short; // Show last 8 characters - const dateColumn = document.createElement("td"); - const date = new Date(change.timestamp); - dateColumn.textContent = `${date.toUTCString()} (${date.getMilliseconds()}ms)`; - const transactionCell = document.createElement("td"); - transactionCell.textContent = change.from.transaction - ? change.from.transaction - : ""; - row.appendChild(typeCell); - row.appendChild(fromCell); - row.appendChild(toCell); - row.appendChild(dateColumn); - row.appendChild(transactionCell); - return row; - }); - historyRows.forEach((row) => { - tbody.appendChild(row); - }); - table.appendChild(tbody); - - // Append the new table to the peerConnections element - peerDetails.appendChild(table); + const peerDetails = document.getElementById("peer-details")!; + + // Remove the existing table if it exists + const existingTable = peerDetails.querySelector("#connection-history"); + if (existingTable) { + existingTable.remove(); + } + + // Create a new table + const table = document.createElement("table"); + table.id = "connection-history"; + table.classList.add("table", "is-striped", "block", "is-bordered"); + table.style.overflowWrap = "break-word"; + + // Create the table header row + const thead = document.createElement("thead"); + const headerRow = document.createElement("tr"); + const typeHeader = document.createElement("th"); + typeHeader.textContent = "Type"; + const fromHeader = document.createElement("th"); + fromHeader.textContent = "From"; + const toHeader = document.createElement("th"); + toHeader.textContent = "To"; + const dateHeader = document.createElement("th"); + dateHeader.textContent = "Date"; + const transaction = document.createElement("th"); + transaction.textContent = "Transaction"; + headerRow.appendChild(typeHeader); + headerRow.appendChild(fromHeader); + headerRow.appendChild(toHeader); + headerRow.appendChild(dateHeader); + headerRow.appendChild(transaction); + thead.appendChild(headerRow); + table.appendChild(thead); + + // Create the table body + const tbody = document.createElement("tbody"); + const historyRows = peer.history.map((change) => { + const row = document.createElement("tr"); + const typeCell = document.createElement("td"); + typeCell.textContent = change.type; + const fromCell = document.createElement("td"); + fromCell.textContent = "..." + change.from.id.short; // Show last 8 characters + const toCell = document.createElement("td"); + toCell.textContent = "..." + change.to.id.short; // Show last 8 characters + const dateColumn = document.createElement("td"); + const date = new Date(change.timestamp); + dateColumn.textContent = `${date.toUTCString()} (${date.getMilliseconds()}ms)`; + const transactionCell = document.createElement("td"); + transactionCell.textContent = change.from.transaction + ? change.from.transaction + : ""; + row.appendChild(typeCell); + row.appendChild(fromCell); + row.appendChild(toCell); + row.appendChild(dateColumn); + row.appendChild(transactionCell); + return row; + }); + historyRows.forEach((row) => { + tbody.appendChild(row); + }); + table.appendChild(tbody); + + // Append the new table to the peerConnections element + peerDetails.appendChild(table); } function ringHistogram(peerLocations: Peer[]) { - const width = 500; - const height = 300; - const margin = { top: 10, right: 30, bottom: 50, left: 60 }; - const innerWidth = width - margin.left - margin.right; - - const container = d3.select("#peers-histogram"); - container.selectAll("*").remove(); - - const svg = container - .append("svg") - .attr("width", width) - .attr("height", height) - .append("g") - .attr("transform", `translate(${margin.left}, ${margin.top})`); - - const bucketSize = 0.05; - - const binsData: number[] = Array(Math.ceil(1 / bucketSize)).fill(0); - peerLocations.forEach((peer) => { - const binIndex = Math.floor(peer.currentLocation / bucketSize); - binsData[binIndex]++; - }); - - const histogram = binsData.map((count, i) => ({ - x0: i * bucketSize, - x1: (i + 1) * bucketSize, - count, - })); - - const xScale = d3.scaleLinear().domain([0, 1]).range([0, innerWidth]); - const legendSpace = 50; - const adjustedHeight = height - legendSpace; - const padding = 10; - const yScale = d3 - .scaleLinear() - .domain([0, d3.max(histogram, (d) => d.count)! + padding]) - .range([adjustedHeight, 0]); - - const colorScale = d3 - .scaleQuantile() - .domain(binsData) - .range(d3.schemeYlGn[9]); - - const bins = svg - .selectAll("rect") - .data(histogram) - .enter() - .append("rect") - .attr("x", (d) => xScale(d.x0!)) - .attr("y", (d) => yScale(d.count)) - .attr("width", innerWidth / histogram.length) - .attr("height", (d) => adjustedHeight - yScale(d.count)) - .attr("fill", (d) => colorScale(d.count)) - .attr("stroke", "black") - .attr("stroke-width", 1); - - const tooltip = container - .append("div") - .attr("class", "bin-tooltip") - .style("background-color", "white") - .style("border", "solid") - .style("border-width", "2px") - .style("border-radius", "5px") - .style("padding", "5px") - .style("opacity", 0) - .style("position", "absolute"); - - bins - .on("mouseover", (event: MouseEvent, d) => { - tooltip.transition().duration(200).style("opacity", 0.9); - tooltip - .html( - `Number of peers: ${d.count}, Subrange: [${d.x0.toFixed( - 2 - )}, ${d.x1.toFixed(2)})` - ) - .style("left", event.clientX + window.scrollX + "px") - .style("top", event.clientY + window.scrollY - 150 + "px"); - }) - .on("mousemove", (event, _) => { - tooltip - .style("left", event.clientX + window.scrollX + "px") - .style("top", event.clientY + window.scrollY - 150 + "px"); - }) - .on("mouseout", (_) => { - tooltip.transition().duration(500).style("opacity", 0); + const width = 500; + const height = 300; + const margin = { top: 10, right: 30, bottom: 50, left: 60 }; + const innerWidth = width - margin.left - margin.right; + + const container = d3.select("#peers-histogram"); + container.selectAll("*").remove(); + + const svg = container + .append("svg") + .attr("width", width) + .attr("height", height) + .append("g") + .attr("transform", `translate(${margin.left}, ${margin.top})`); + + const bucketSize = 0.05; + + const binsData: number[] = Array(Math.ceil(1 / bucketSize)).fill(0); + peerLocations.forEach((peer) => { + const binIndex = Math.floor(peer.currentLocation / bucketSize); + binsData[binIndex]++; }); - const xAxisTicks = Math.floor(innerWidth / 50); // 50 is the desired space between ticks - const xAxis = d3.axisBottom(xScale).ticks(xAxisTicks); - svg - .append("g") - .attr("transform", `translate(0, ${adjustedHeight})`) - .call(xAxis); - - const yAxisTicks = Math.floor(adjustedHeight / 50); // 50 is the desired space between ticks - const yAxis = d3.axisLeft(yScale).ticks(yAxisTicks); - svg.append("g").call(yAxis); - - // Position the legend within the SVG area - svg - .append("text") - .attr("fill", "#000") - .attr("x", innerWidth / 2) - .attr("y", height - margin.bottom / 4) - .attr("text-anchor", "middle") - .attr("font-size", "14px") - .text("Peer Locations"); - - svg - .append("text") - .attr("fill", "#000") - .attr("y", margin.left - 100) - .attr("x", -adjustedHeight / 2) - .attr("transform", "rotate(-90)") - .attr("text-anchor", "middle") - .attr("font-size", "14px") - .text("Amount of Peers"); + const histogram = binsData.map((count, i) => ({ + x0: i * bucketSize, + x1: (i + 1) * bucketSize, + count, + })); + + const xScale = d3.scaleLinear().domain([0, 1]).range([0, innerWidth]); + const legendSpace = 50; + const adjustedHeight = height - legendSpace; + const padding = 10; + const yScale = d3 + .scaleLinear() + .domain([0, d3.max(histogram, (d) => d.count)! + padding]) + .range([adjustedHeight, 0]); + + const colorScale = d3 + .scaleQuantile() + .domain(binsData) + .range(d3.schemeYlGn[9]); + + const bins = svg + .selectAll("rect") + .data(histogram) + .enter() + .append("rect") + .attr("x", (d) => xScale(d.x0!)) + .attr("y", (d) => yScale(d.count)) + .attr("width", innerWidth / histogram.length) + .attr("height", (d) => adjustedHeight - yScale(d.count)) + .attr("fill", (d) => colorScale(d.count)) + .attr("stroke", "black") + .attr("stroke-width", 1); + + const tooltip = container + .append("div") + .attr("class", "bin-tooltip") + .style("background-color", "white") + .style("border", "solid") + .style("border-width", "2px") + .style("border-radius", "5px") + .style("padding", "5px") + .style("opacity", 0) + .style("position", "absolute"); + + bins.on("mouseover", (event: MouseEvent, d) => { + tooltip.transition().duration(200).style("opacity", 0.9); + tooltip + .html( + `Number of peers: ${d.count}, Subrange: [${d.x0.toFixed( + 2 + )}, ${d.x1.toFixed(2)})` + ) + .style("left", event.clientX + window.scrollX + "px") + .style("top", event.clientY + window.scrollY - 150 + "px"); + }) + .on("mousemove", (event, _) => { + tooltip + .style("left", event.clientX + window.scrollX + "px") + .style("top", event.clientY + window.scrollY - 150 + "px"); + }) + .on("mouseout", (_) => { + tooltip.transition().duration(500).style("opacity", 0); + }); + + const xAxisTicks = Math.floor(innerWidth / 50); // 50 is the desired space between ticks + const xAxis = d3.axisBottom(xScale).ticks(xAxisTicks); + svg.append("g") + .attr("transform", `translate(0, ${adjustedHeight})`) + .call(xAxis); + + const yAxisTicks = Math.floor(adjustedHeight / 50); // 50 is the desired space between ticks + const yAxis = d3.axisLeft(yScale).ticks(yAxisTicks); + svg.append("g").call(yAxis); + + // Position the legend within the SVG area + svg.append("text") + .attr("fill", "#000") + .attr("x", innerWidth / 2) + .attr("y", height - margin.bottom / 4) + .attr("text-anchor", "middle") + .attr("font-size", "14px") + .text("Peer Locations"); + + svg.append("text") + .attr("fill", "#000") + .attr("y", margin.left - 100) + .attr("x", -adjustedHeight / 2) + .attr("transform", "rotate(-90)") + .attr("text-anchor", "middle") + .attr("font-size", "14px") + .text("Amount of Peers"); } diff --git a/network-monitor/src/transaction-detail.tsx b/network-monitor/src/transaction-detail.tsx new file mode 100644 index 000000000..5f2350911 --- /dev/null +++ b/network-monitor/src/transaction-detail.tsx @@ -0,0 +1,433 @@ +import { useEffect, useState } from "react"; +import { createRoot } from "react-dom/client"; +import { + TransactionDetailInterface, + TransactionPeerInterface, + TransactionData +} from "./type_definitions"; +import { PeerId } from "./topology"; + +interface TransactionDetailPeersHistoryInterface { + tx_peer_list: Array; +} + +interface FilterInterface { + filter_type: string; + filter_value: string; +} + +interface FilterDictionaryInterface { + [key: string]: FilterInterface; +} + +let ring_mock_data = []; +const TransactionPeersHistory = ({ + tx_peer_list, +}: TransactionDetailPeersHistoryInterface) => { + const [filter, set_filter] = useState({}); + const [filtered_list, set_filtered_list] = useState(tx_peer_list); + + const add_filter = (filter_type: string, filter_value: string) => { + if (check_if_contains_filter(filter_type)) { + return; + } + + filter[filter_type] = { + filter_type, + filter_value, + }; + + set_filter(filter); + + update_filtered_list(); + }; + + const update_filtered_list = () => { + let filtered_list = tx_peer_list; + + Object.keys(filter).forEach((filter_type) => { + const filter_value = filter[filter_type].filter_value; + filtered_list = filtered_list.filter((tx) => { + for (const [key, value] of Object.entries(tx)) { + if (key === filter_type) { + return value === filter_value; + } + } + }); + }); + + set_filtered_list(filtered_list); + }; + + const clear_one_filter = (filter_type: string) => { + delete filter[filter_type]; + update_filtered_list(); + }; + + const clear_all_filters = () => { + set_filter({}); + }; + + useEffect(() => { + update_filtered_list(); + + let ring_mock_data = [ + { + id: new PeerId("1"), + currentLocation: 0.123485, + connectionTimestamp: 1234567890, + connections: [], + history: [], + locationHistory: [], + }, + { + id: new PeerId("2"), + currentLocation: 0.183485, + connectionTimestamp: 1234567890, + connections: [], + history: [], + locationHistory: [], + }, + { + id: new PeerId("3"), + currentLocation: 0.323485, + connectionTimestamp: 1234567890, + connections: [], + history: [], + locationHistory: [], + }, + { + id: new PeerId("4"), + currentLocation: 0.423485, + connectionTimestamp: 1234567890, + connections: [], + history: [], + locationHistory: [], + }, + { + id: new PeerId("5"), + currentLocation: 0.783285, + connectionTimestamp: 1234567890, + connections: [], + history: [], + locationHistory: [], + }, + ]; + + // ringHistogram(ring_mock_data); + + // const graphContainer = d3.select( + // document.getElementById("other-peer-conns-graph") + // ); + + // ringVisualization(ring_mock_data[0], graphContainer, 1.25); + }, [filter]); + + const check_if_contains_filter = (filter_type: string) => { + return filter[filter_type] !== undefined; + }; + + return ( +
+

Transaction Peers History

+ {Object.keys(filter).length > 0 && ( +
+ +
+ )} + + + + + + + + + + + + {filtered_list.map((tx) => ( + + + + + + + + ))} + +
+ Transaction Id + {check_if_contains_filter("transaction_id") && ( + + )} + + Requester + {check_if_contains_filter("requester") && ( + + )} + + Target + {check_if_contains_filter("target") && ( + + )} + + Change Type + {check_if_contains_filter("change_type") && ( + + )} + + Contract Id + {check_if_contains_filter("contract_id") && ( + + )} +
+ add_filter("transaction_id", tx.transaction_id) + } + style={{ + cursor: "pointer", + }} + > + {tx.transaction_id} + + add_filter("requester", tx.requester) + } + style={{ + cursor: "pointer", + }} + > + {tx.requester.slice(-8)} + + add_filter("target", tx.target) + } + style={{ + cursor: "pointer", + }} + > + {tx.target.slice(-8)} + + add_filter("change_type", tx.change_type) + } + style={{ + cursor: "pointer", + }} + > + {tx.change_type} + + add_filter("contract_id", tx.contract_id) + } + style={{ + cursor: "pointer", + }} + > + {tx.contract_id.slice(-8)} +
+
+ ); +}; + +// TODO: use real types +const TransactionHistory = ({ tx_history }: any) => ( +
+

Transaction History

+ + + + + + + + + {/* + + */} + + + + {tx_history && + tx_history.map((change: TransactionData, index: number) => ( + + + + + + + + ))} + +
Transaction IdRequester Peer IdTarget Peer IdTypeContract KeyStatusStartedFinalized
{change.transaction_id.slice(-8)}{change.requester.slice(-8)}{change.target.slice(-8)}{change.change_type}{change.contract_id.slice(-8)}
+
+); + +const TransactionDetail = ({ + transaction, + is_displayed, + close_detail, + peers_history, + tx_history, +}: TransactionDetailInterface) => ( +
+
+ +

Transaction Detail

+
+

ID {transaction.transaction_id}

+

Type {transaction.change_type}

+ {/*

Status {transaction.status}

+

Started {transaction.started}

+

Finalized {transaction.finalized}

*/} +

Requester {transaction.requester}

+

Target {transaction.target}

+

Contract Key {transaction.contract_id}

+
+ +
+

Location Peers

+
+
+ +
+ {/*another_ring_visualization()*/} +
+ + {tx_history && ( + + )} + + {/**/} +
+
+); + +const another_ring_visualization = () => { + // Declare the chart dimensions and margins. + const width = 640; + const height = 400; + const marginTop = 20; + const marginRight = 20; + const marginBottom = 30; + const marginLeft = 40; + + // // Declare the x (horizontal position) scale. + // const x = d3 + // .scaleUtc() + // .domain([new Date("2023-01-01"), new Date("2024-01-01")]) + // .range([marginLeft, width - marginRight]); + + // // Declare the y (vertical position) scale. + // const y = d3 + // .scaleLinear() + // .domain([0, 100]) + // .range([height - marginBottom, marginTop]); + + // // Create the SVG container. + // const svg = d3.create("svg").attr("width", width).attr("height", height); + + // // Add the x-axis. + // svg.append("g") + // .attr("transform", `translate(0,${height - marginBottom})`) + // .call(d3.axisBottom(x)); + + // // Add the y-axis. + // svg.append("g") + // .attr("transform", `translate(${marginLeft},0)`) + // .call(d3.axisLeft(y)); + + let a = ( + + + + + + + + + + + ); + + // Append the SVG element. + return a; +}; + +export default TransactionDetail; diff --git a/network-monitor/src/transactions-data.ts b/network-monitor/src/transactions-data.ts new file mode 100644 index 000000000..407925352 --- /dev/null +++ b/network-monitor/src/transactions-data.ts @@ -0,0 +1,96 @@ +import { + ChangeType, + ContractKey, + TransactionData, + TransactionId, +} from "./type_definitions"; + +export const all_tx = new Map>(); + +export const all_contracts = new Map>(); + +export function handlePutRequest( + transaction_id: string, + contract_id: string, + target: string, + requester: string, + change_type: ChangeType +) { + console.log("Put Request"); + console.log("tx", transaction_id); + console.log("contract key", contract_id); + console.log("target", target); + console.log("requester", requester); + + let obj_data = { + change_type, + transaction_id, + contract_id, + target, + requester, + status: null, + started: null, + finalized: null, + unique_id: + transaction_id + contract_id + target + requester + change_type, + } as TransactionData; + + if ( + all_tx + .get(transaction_id) + ?.find((obj) => obj.unique_id === obj_data.unique_id) + ) { + return; + } + + all_tx.set(transaction_id, [obj_data]); + + const this_contract_data = all_contracts.get(contract_id); + if (!this_contract_data) { + all_contracts.set(contract_id, []); + } + all_contracts.get(contract_id)!.push(obj_data); +} + +export function handlePutSuccess( + transaction_id: string, + contract_id: string, + target: string, + requester: string, + change_type: ChangeType +) { + console.log("Put Success"); + console.log("tx", transaction_id); + console.log("contract key", contract_id); + console.log("target", target); + console.log("requester", requester); + + let obj_data = { + change_type, + transaction_id, + contract_id, + target, + requester, + status: null, + started: null, + finalized: null, + unique_id: + transaction_id + contract_id + target + requester + change_type, + }; + + if ( + all_tx + .get(transaction_id) + ?.find((obj) => obj.unique_id === obj_data.unique_id) + ) { + return; + } + + all_tx.get(transaction_id)!.push(obj_data); + + const this_contract_data = all_contracts.get(contract_id); + if (!this_contract_data) { + all_contracts.set(contract_id, []); + } + all_contracts.get(contract_id)!.push(obj_data); +} diff --git a/network-monitor/src/transactions.tsx b/network-monitor/src/transactions.tsx new file mode 100644 index 000000000..28dffcd80 --- /dev/null +++ b/network-monitor/src/transactions.tsx @@ -0,0 +1,277 @@ +import { useEffect, useState } from "react"; +import { createRoot } from "react-dom/client"; +import TransactionDetail from "./transaction-detail"; +import { all_tx} from "./transactions-data"; +import {TransactionInterface, TransactionStatus, TransactionType, TransactionData, TxPeersTableInterface, OpState, MessageType, TxTableInterface, TransactionPeerInterface, ChangeType } from "./type_definitions"; +import {another_ring_visualization} from "./ring-visualization"; + + + +const mock_transaction: Array = [ + { + id: "123", + peer_id: "0xabc", + type: ChangeType.PUT_SUCCESS, + status: TransactionStatus.Finalized, + started: "12-01-2024", + finalized: "13-01-2024", + contract_id: "0x123", + }, + { + id: "124", + peer_id: "0xdef", + type: ChangeType.PUT_SUCCESS, + status: TransactionStatus.Received, + started: "12-01-2024", + finalized: "13-01-2024", + contract_id: "0x4892", + }, + { + id: "125", + peer_id: "0xabc", + type: ChangeType.PUT_REQUEST, + status: TransactionStatus.Ongoing, + started: "12-02-2024", + finalized: "13-02-2024", + contract_id: "0x783", + }, +]; + + +const mock_peers_in_tx: TxPeersTableInterface = { + "123": [ + // create a mock object + { + peer_id: "0xabc", + location: "0.1789234", + last_state: OpState.BroadcastOngoing, + last_message: MessageType.Broadcasting, + started: "12-01-2024", + finalized: "13-01-2024", + }, + { + peer_id: "0xdef", + location: "0.16234", + last_state: OpState.Finished, + last_message: MessageType.SuccessfulUpdate, + started: "18-01-2024", + finalized: "19-01-2024", + }, + { + peer_id: "0xghi", + location: "0.234234", + last_state: OpState.AwaitingResponse, + last_message: MessageType.RequestUpdate, + started: "19-01-2024", + finalized: "20-01-2024", + }, + { + peer_id: "0xjkl", + location: "0.267127", + last_state: OpState.AwaitingResponse, + last_message: MessageType.RequestUpdate, + started: "21-01-2024", + finalized: "22-01-2024", + }, + { + peer_id: "0xdef", + location: "0.1789234", + last_state: OpState.BroadcastOngoing, + last_message: MessageType.Broadcasting, + started: "12-01-2024", + finalized: "13-01-2024", + }, + { + peer_id: "0xabc", + location: "0.16234", + last_state: OpState.Finished, + last_message: MessageType.SuccessfulUpdate, + started: "18-01-2024", + finalized: "19-01-2024", + }, + { + peer_id: "0xjkl", + location: "0.234234", + last_state: OpState.AwaitingResponse, + last_message: MessageType.RequestUpdate, + started: "19-01-2024", + finalized: "20-01-2024", + }, + { + peer_id: "0xghi", + location: "0.267127", + last_state: OpState.AwaitingResponse, + last_message: MessageType.RequestUpdate, + started: "21-01-2024", + finalized: "22-01-2024", + }, + ], + "124": [ + { + peer_id: "0xdef", + location: "0.1789234", + last_state: OpState.BroadcastOngoing, + last_message: MessageType.Broadcasting, + started: "12-01-2024", + finalized: "13-01-2024", + }, + { + peer_id: "0xabc", + location: "0.16234", + last_state: OpState.Finished, + last_message: MessageType.SuccessfulUpdate, + started: "18-01-2024", + finalized: "19-01-2024", + }, + { + peer_id: "0xghi", + location: "0.234234", + last_state: OpState.ReceivedRequest, + last_message: MessageType.BroadcastTo, + started: "19-01-2024", + finalized: "20-01-2024", + }, + { + peer_id: "0xjkl", + location: "0.267127", + last_state: OpState.AwaitingResponse, + last_message: MessageType.RequestUpdate, + started: "21-01-2024", + finalized: "22-01-2024", + }, + { + peer_id: "0xdef", + location: "0.1789234", + last_state: OpState.Finished, + last_message: MessageType.SuccessfulUpdate, + started: "12-01-2024", + finalized: "13-01-2024", + }, + { + peer_id: "0xabc", + location: "0.16234", + last_state: OpState.Finished, + last_message: MessageType.SuccessfulUpdate, + started: "18-01-2024", + finalized: "19-01-2024", + }, + { + peer_id: "0xjkl", + location: "0.234234", + last_state: OpState.AwaitingResponse, + last_message: MessageType.RequestUpdate, + started: "19-01-2024", + finalized: "20-01-2024", + }, + { + peer_id: "0xghi", + location: "0.267127", + last_state: OpState.BroadcastOngoing, + last_message: MessageType.Broadcasting, + started: "21-01-2024", + finalized: "22-01-2024", + }, + + ], +} + + + +const TransactionsTable = ({ open_tx_detail, tx_list }: TxTableInterface) => ( + + + + + + + + + {/* + + */} + + + + { + tx_list?.map((tx, index) => ( + + + + + + + {/* + + */} + + )) + } + +
Transaction IdRequester Peer IdTarget Peer IdTypeContract KeyStatusStartedFinalized
open_tx_detail(tx.transaction_id)} style={{cursor: "pointer"}}>{tx.transaction_id.slice(-8)}{tx.requester.slice(-8)}{tx.target.slice(-8)}{tx.change_type}{tx.contract_id.slice(-8)}{tx.status}{tx.started}{tx.finalized}
+); + +export function TransactionContainer() { + const [is_detail_open, set_is_detail_open] = useState(false); + const [transaction, set_transaction] = useState(null); + const [transaction_history, set_transaction_history] = useState>([]); + const [peers_history, set_peers_history] = useState>([]); + const [tx_list, set_tx_list] = useState>([]); + + const open_tx_detail = (txid: string) => { + let tx_history = all_tx.get(txid); + if (!tx_history) { + console.error("Transaction not found"); + return; + } + + set_transaction(tx_history[0]); + set_transaction_history(tx_history); + // set_peers_history(mock_peers_in_tx[tx.id]); + set_is_detail_open(true); + window.scrollTo(0, 0); + }; + + const close_detail = () => { + set_is_detail_open(false); + }; + + const load_transaction_list = () => { + let updated_tx_list = []; + + updated_tx_list = Array.from(all_tx.values()); + + updated_tx_list = updated_tx_list.flat(); + + console.log(updated_tx_list); + set_tx_list(updated_tx_list); + } + + document.addEventListener("keydown", (e: any) => { + if (e.key === "Escape") { + close_detail(); + } + }); + + useEffect(() => { + setInterval(() => { + load_transaction_list(); + }, 3000); + }, []); + + return ( +
+ + + {transaction && transaction_history && ( + + )} +
+ ); +} + diff --git a/network-monitor/src/type_definitions.ts b/network-monitor/src/type_definitions.ts new file mode 100644 index 000000000..52fc621d0 --- /dev/null +++ b/network-monitor/src/type_definitions.ts @@ -0,0 +1,85 @@ +export type TransactionId = string; +export type ContractKey = string; + +export enum ChangeType { + PUT_REQUEST = "Put Request", + PUT_SUCCESS = "Put Success", + PUT_FAILURE = "Put Failure", +} + +export type TransactionData = { + change_type: ChangeType; + transaction_id: string; + contract_id: string; + target: string; + requester: string; + status: string | null; + started: string | null; + finalized: string | null; + unique_id: string; +}; + +export interface TransactionInterface { + id: TransactionId; + peer_id: string; + type: ChangeType; + contract_id: ContractKey; + status: string | null; + started: string | null; + finalized: string | null; +} + +export interface TransactionPeerInterface { + peer_id: string; + location: string; + last_state: string; + last_message: string; + started: string; + finalized: string; +} + +export interface TransactionDetailInterface { + transaction: TransactionData; + is_displayed: boolean; + close_detail: () => void; + peers_history?: Array; + tx_history?: Array; +} + +export interface TxTableInterface { + open_tx_detail: (txid: TransactionId) => void; + tx_list?: Array; +} + +export interface TxPeersTableInterface { + [tx_id: TransactionId]: Array; +} + +export enum TransactionType { + Update = "Update", + Put = "Put", + Get = "Get", +} + +export enum TransactionStatus { + Received = "Received", + Finalized = "Finalized", + Ongoing = "Ongoing", +} + +export enum MessageType { + RequestUpdate = "RequestUpdate", + SeekNode = "SeekNode", + BroadcastTo = "BroadcastTo", + Broadcasting = "Broadcasting", + SuccessfulUpdate = "SuccessfulUpdate", + UpdateForward = "UpdateForward", +} + +export enum OpState { + ReceivedRequest = "ReceivedRequest", + AwaitingResponse = "AwaitingResponse", + Finished = "Finished", + PrepareRequest = "PrepareRequest", + BroadcastOngoing = "BroadcastOngoing", +} diff --git a/network-monitor/src/utils.ts b/network-monitor/src/utils.ts new file mode 100644 index 000000000..af8d7fa06 --- /dev/null +++ b/network-monitor/src/utils.ts @@ -0,0 +1,45 @@ +import { ChangeType } from "./type_definitions"; +import { ContractChange } from "./generated/topology"; +import * as fbTopology from "./generated/topology"; + +export const get_change_type = ( + change_type_fbs: fbTopology.ContractChangeType +): ChangeType | null => { + switch (change_type_fbs) { + case fbTopology.ContractChangeType.PutRequest: + return ChangeType.PUT_REQUEST; + case fbTopology.ContractChangeType.PutSuccess: + return ChangeType.PUT_SUCCESS; + case fbTopology.ContractChangeType.PutFailure: + return ChangeType.PUT_FAILURE; + default: + new Error("Invalid change type"); + } + + return null; +}; + +export const parse_put_msg_data = ( + contractChange: ContractChange, + changeType: fbTopology.ContractChangeType +): any => { + let put_request_obj = contractChange.change(new fbTopology.PutRequest()); + + let transaction = put_request_obj.transaction()!; + + let contract_id = contractChange.contractId()!; + + let target = put_request_obj.target()!; + + let requester = put_request_obj.requester()!; + + let change_type = get_change_type(changeType)!; + + return { + transaction, + contract_id, + target, + requester, + change_type, + }; +}; diff --git a/network-monitor/tsconfig.json b/network-monitor/tsconfig.json index 83416a4a8..59fee3a1d 100644 --- a/network-monitor/tsconfig.json +++ b/network-monitor/tsconfig.json @@ -107,6 +107,7 @@ /* Completeness */ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ + "skipLibCheck": true, /* Skip type checking all .d.ts files. */ + "jsx": "react-jsx" } } diff --git a/schemas/flatbuffers/topology.fbs b/schemas/flatbuffers/topology.fbs index aaa676a2e..a0b5cd8e9 100644 --- a/schemas/flatbuffers/topology.fbs +++ b/schemas/flatbuffers/topology.fbs @@ -40,3 +40,62 @@ union Response { table ControllerResponse { response:Response(required); } + + +table PutRequest { + transaction: string(required); + key: string(required); + requester: string(required); + target: string(required); +} + +table UpdateRequest { + transaction: string(required); + key: string(required); + requester: string(required); + target: string(required); +} + +table PutSuccess { + transaction: string(required); + requester: string(required); + target: string(required); + key: string(required); +} + +table PutFailure { + transaction: string(required); + requester: string(required); + target: string(required); + key: string(required); +} + +table UpdateSuccess { + transaction: string(required); + requester: string(required); + target: string(required); + key: string(required); +} + +table UpdateFailure { + transaction: string(required); + requester: string(required); + target: string(required); + key: string(required); +} + +union ContractChangeType { + PutRequest, + PutSuccess, + PutFailure, + UpdateRequest, + UpdateSuccess, + UpdateFailure, +} + +table ContractChange { + contract_id: string(required); + change: ContractChangeType; +} + + diff --git a/schemas/flatbuffers/topology.ts b/schemas/flatbuffers/topology.ts new file mode 100644 index 000000000..587590dc4 --- /dev/null +++ b/schemas/flatbuffers/topology.ts @@ -0,0 +1,18 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +export { AddedConnection } from './topology/added-connection.js'; +export { ContractChange } from './topology/contract-change.js'; +export { ContractChangeType } from './topology/contract-change-type.js'; +export { ControllerResponse } from './topology/controller-response.js'; +export { Error } from './topology/error.js'; +export { Ok } from './topology/ok.js'; +export { PeerChange } from './topology/peer-change.js'; +export { PeerChangeType } from './topology/peer-change-type.js'; +export { PutFailure } from './topology/put-failure.js'; +export { PutRequest } from './topology/put-request.js'; +export { PutSuccess } from './topology/put-success.js'; +export { RemovedConnection } from './topology/removed-connection.js'; +export { Response } from './topology/response.js'; +export { UpdateFailure } from './topology/update-failure.js'; +export { UpdateRequest } from './topology/update-request.js'; +export { UpdateSuccess } from './topology/update-success.js'; diff --git a/schemas/flatbuffers/topology/added-connection.ts b/schemas/flatbuffers/topology/added-connection.ts new file mode 100644 index 000000000..13dca6d07 --- /dev/null +++ b/schemas/flatbuffers/topology/added-connection.ts @@ -0,0 +1,94 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +export class AddedConnection { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):AddedConnection { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsAddedConnection(bb:flatbuffers.ByteBuffer, obj?:AddedConnection):AddedConnection { + return (obj || new AddedConnection()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsAddedConnection(bb:flatbuffers.ByteBuffer, obj?:AddedConnection):AddedConnection { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new AddedConnection()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +transaction():string|null +transaction(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +transaction(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +from():string|null +from(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +from(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +fromLocation():number { + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.readFloat64(this.bb_pos + offset) : 0.0; +} + +to():string|null +to(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +to(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 10); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +toLocation():number { + const offset = this.bb!.__offset(this.bb_pos, 12); + return offset ? this.bb!.readFloat64(this.bb_pos + offset) : 0.0; +} + +static startAddedConnection(builder:flatbuffers.Builder) { + builder.startObject(5); +} + +static addTransaction(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, transactionOffset, 0); +} + +static addFrom(builder:flatbuffers.Builder, fromOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, fromOffset, 0); +} + +static addFromLocation(builder:flatbuffers.Builder, fromLocation:number) { + builder.addFieldFloat64(2, fromLocation, 0.0); +} + +static addTo(builder:flatbuffers.Builder, toOffset:flatbuffers.Offset) { + builder.addFieldOffset(3, toOffset, 0); +} + +static addToLocation(builder:flatbuffers.Builder, toLocation:number) { + builder.addFieldFloat64(4, toLocation, 0.0); +} + +static endAddedConnection(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 6) // from + builder.requiredField(offset, 10) // to + return offset; +} + +static createAddedConnection(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset, fromOffset:flatbuffers.Offset, fromLocation:number, toOffset:flatbuffers.Offset, toLocation:number):flatbuffers.Offset { + AddedConnection.startAddedConnection(builder); + AddedConnection.addTransaction(builder, transactionOffset); + AddedConnection.addFrom(builder, fromOffset); + AddedConnection.addFromLocation(builder, fromLocation); + AddedConnection.addTo(builder, toOffset); + AddedConnection.addToLocation(builder, toLocation); + return AddedConnection.endAddedConnection(builder); +} +} diff --git a/schemas/flatbuffers/topology/contract-change-type.ts b/schemas/flatbuffers/topology/contract-change-type.ts new file mode 100644 index 000000000..028d7b8ca --- /dev/null +++ b/schemas/flatbuffers/topology/contract-change-type.ts @@ -0,0 +1,52 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import { PutFailure } from '../topology/put-failure.js'; +import { PutRequest } from '../topology/put-request.js'; +import { PutSuccess } from '../topology/put-success.js'; +import { UpdateFailure } from '../topology/update-failure.js'; +import { UpdateRequest } from '../topology/update-request.js'; +import { UpdateSuccess } from '../topology/update-success.js'; + + +export enum ContractChangeType { + NONE = 0, + PutRequest = 1, + PutSuccess = 2, + PutFailure = 3, + UpdateRequest = 4, + UpdateSuccess = 5, + UpdateFailure = 6 +} + +export function unionToContractChangeType( + type: ContractChangeType, + accessor: (obj:PutFailure|PutRequest|PutSuccess|UpdateFailure|UpdateRequest|UpdateSuccess) => PutFailure|PutRequest|PutSuccess|UpdateFailure|UpdateRequest|UpdateSuccess|null +): PutFailure|PutRequest|PutSuccess|UpdateFailure|UpdateRequest|UpdateSuccess|null { + switch(ContractChangeType[type]) { + case 'NONE': return null; + case 'PutRequest': return accessor(new PutRequest())! as PutRequest; + case 'PutSuccess': return accessor(new PutSuccess())! as PutSuccess; + case 'PutFailure': return accessor(new PutFailure())! as PutFailure; + case 'UpdateRequest': return accessor(new UpdateRequest())! as UpdateRequest; + case 'UpdateSuccess': return accessor(new UpdateSuccess())! as UpdateSuccess; + case 'UpdateFailure': return accessor(new UpdateFailure())! as UpdateFailure; + default: return null; + } +} + +export function unionListToContractChangeType( + type: ContractChangeType, + accessor: (index: number, obj:PutFailure|PutRequest|PutSuccess|UpdateFailure|UpdateRequest|UpdateSuccess) => PutFailure|PutRequest|PutSuccess|UpdateFailure|UpdateRequest|UpdateSuccess|null, + index: number +): PutFailure|PutRequest|PutSuccess|UpdateFailure|UpdateRequest|UpdateSuccess|null { + switch(ContractChangeType[type]) { + case 'NONE': return null; + case 'PutRequest': return accessor(index, new PutRequest())! as PutRequest; + case 'PutSuccess': return accessor(index, new PutSuccess())! as PutSuccess; + case 'PutFailure': return accessor(index, new PutFailure())! as PutFailure; + case 'UpdateRequest': return accessor(index, new UpdateRequest())! as UpdateRequest; + case 'UpdateSuccess': return accessor(index, new UpdateSuccess())! as UpdateSuccess; + case 'UpdateFailure': return accessor(index, new UpdateFailure())! as UpdateFailure; + default: return null; + } +} diff --git a/schemas/flatbuffers/topology/contract-change.ts b/schemas/flatbuffers/topology/contract-change.ts new file mode 100644 index 000000000..baa2ecec5 --- /dev/null +++ b/schemas/flatbuffers/topology/contract-change.ts @@ -0,0 +1,72 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +import { ContractChangeType, unionToContractChangeType, unionListToContractChangeType } from '../topology/contract-change-type.js'; + + +export class ContractChange { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):ContractChange { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsContractChange(bb:flatbuffers.ByteBuffer, obj?:ContractChange):ContractChange { + return (obj || new ContractChange()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsContractChange(bb:flatbuffers.ByteBuffer, obj?:ContractChange):ContractChange { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new ContractChange()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +contractId():string|null +contractId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +contractId(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +changeType():ContractChangeType { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.readUint8(this.bb_pos + offset) : ContractChangeType.NONE; +} + +change(obj:any):any|null { + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.__union(obj, this.bb_pos + offset) : null; +} + +static startContractChange(builder:flatbuffers.Builder) { + builder.startObject(3); +} + +static addContractId(builder:flatbuffers.Builder, contractIdOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, contractIdOffset, 0); +} + +static addChangeType(builder:flatbuffers.Builder, changeType:ContractChangeType) { + builder.addFieldInt8(1, changeType, ContractChangeType.NONE); +} + +static addChange(builder:flatbuffers.Builder, changeOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, changeOffset, 0); +} + +static endContractChange(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 4) // contract_id + return offset; +} + +static createContractChange(builder:flatbuffers.Builder, contractIdOffset:flatbuffers.Offset, changeType:ContractChangeType, changeOffset:flatbuffers.Offset):flatbuffers.Offset { + ContractChange.startContractChange(builder); + ContractChange.addContractId(builder, contractIdOffset); + ContractChange.addChangeType(builder, changeType); + ContractChange.addChange(builder, changeOffset); + return ContractChange.endContractChange(builder); +} +} diff --git a/schemas/flatbuffers/topology/controller-response.ts b/schemas/flatbuffers/topology/controller-response.ts new file mode 100644 index 000000000..9937bdac4 --- /dev/null +++ b/schemas/flatbuffers/topology/controller-response.ts @@ -0,0 +1,60 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +import { Response, unionToResponse, unionListToResponse } from '../topology/response.js'; + + +export class ControllerResponse { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):ControllerResponse { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsControllerResponse(bb:flatbuffers.ByteBuffer, obj?:ControllerResponse):ControllerResponse { + return (obj || new ControllerResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsControllerResponse(bb:flatbuffers.ByteBuffer, obj?:ControllerResponse):ControllerResponse { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new ControllerResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +responseType():Response { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.readUint8(this.bb_pos + offset) : Response.NONE; +} + +response(obj:any):any|null { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.__union(obj, this.bb_pos + offset) : null; +} + +static startControllerResponse(builder:flatbuffers.Builder) { + builder.startObject(2); +} + +static addResponseType(builder:flatbuffers.Builder, responseType:Response) { + builder.addFieldInt8(0, responseType, Response.NONE); +} + +static addResponse(builder:flatbuffers.Builder, responseOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, responseOffset, 0); +} + +static endControllerResponse(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 6) // response + return offset; +} + +static createControllerResponse(builder:flatbuffers.Builder, responseType:Response, responseOffset:flatbuffers.Offset):flatbuffers.Offset { + ControllerResponse.startControllerResponse(builder); + ControllerResponse.addResponseType(builder, responseType); + ControllerResponse.addResponse(builder, responseOffset); + return ControllerResponse.endControllerResponse(builder); +} +} diff --git a/schemas/flatbuffers/topology/error.ts b/schemas/flatbuffers/topology/error.ts new file mode 100644 index 000000000..b948e1385 --- /dev/null +++ b/schemas/flatbuffers/topology/error.ts @@ -0,0 +1,49 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +export class Error { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):Error { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsError(bb:flatbuffers.ByteBuffer, obj?:Error):Error { + return (obj || new Error()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsError(bb:flatbuffers.ByteBuffer, obj?:Error):Error { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new Error()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +message():string|null +message(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +message(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +static startError(builder:flatbuffers.Builder) { + builder.startObject(1); +} + +static addMessage(builder:flatbuffers.Builder, messageOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, messageOffset, 0); +} + +static endError(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 4) // message + return offset; +} + +static createError(builder:flatbuffers.Builder, messageOffset:flatbuffers.Offset):flatbuffers.Offset { + Error.startError(builder); + Error.addMessage(builder, messageOffset); + return Error.endError(builder); +} +} diff --git a/schemas/flatbuffers/topology/ok.ts b/schemas/flatbuffers/topology/ok.ts new file mode 100644 index 000000000..521b9e037 --- /dev/null +++ b/schemas/flatbuffers/topology/ok.ts @@ -0,0 +1,48 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +export class Ok { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):Ok { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsOk(bb:flatbuffers.ByteBuffer, obj?:Ok):Ok { + return (obj || new Ok()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsOk(bb:flatbuffers.ByteBuffer, obj?:Ok):Ok { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new Ok()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +message():string|null +message(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +message(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +static startOk(builder:flatbuffers.Builder) { + builder.startObject(1); +} + +static addMessage(builder:flatbuffers.Builder, messageOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, messageOffset, 0); +} + +static endOk(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + return offset; +} + +static createOk(builder:flatbuffers.Builder, messageOffset:flatbuffers.Offset):flatbuffers.Offset { + Ok.startOk(builder); + Ok.addMessage(builder, messageOffset); + return Ok.endOk(builder); +} +} diff --git a/schemas/flatbuffers/topology/peer-change-type.ts b/schemas/flatbuffers/topology/peer-change-type.ts new file mode 100644 index 000000000..28ca65445 --- /dev/null +++ b/schemas/flatbuffers/topology/peer-change-type.ts @@ -0,0 +1,40 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import { AddedConnection } from '../topology/added-connection.js'; +import { Error } from '../topology/error.js'; +import { RemovedConnection } from '../topology/removed-connection.js'; + + +export enum PeerChangeType { + NONE = 0, + AddedConnection = 1, + RemovedConnection = 2, + Error = 3 +} + +export function unionToPeerChangeType( + type: PeerChangeType, + accessor: (obj:AddedConnection|Error|RemovedConnection) => AddedConnection|Error|RemovedConnection|null +): AddedConnection|Error|RemovedConnection|null { + switch(PeerChangeType[type]) { + case 'NONE': return null; + case 'AddedConnection': return accessor(new AddedConnection())! as AddedConnection; + case 'RemovedConnection': return accessor(new RemovedConnection())! as RemovedConnection; + case 'Error': return accessor(new Error())! as Error; + default: return null; + } +} + +export function unionListToPeerChangeType( + type: PeerChangeType, + accessor: (index: number, obj:AddedConnection|Error|RemovedConnection) => AddedConnection|Error|RemovedConnection|null, + index: number +): AddedConnection|Error|RemovedConnection|null { + switch(PeerChangeType[type]) { + case 'NONE': return null; + case 'AddedConnection': return accessor(index, new AddedConnection())! as AddedConnection; + case 'RemovedConnection': return accessor(index, new RemovedConnection())! as RemovedConnection; + case 'Error': return accessor(index, new Error())! as Error; + default: return null; + } +} diff --git a/schemas/flatbuffers/topology/peer-change.ts b/schemas/flatbuffers/topology/peer-change.ts new file mode 100644 index 000000000..f375c67eb --- /dev/null +++ b/schemas/flatbuffers/topology/peer-change.ts @@ -0,0 +1,87 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +import { AddedConnection } from '../topology/added-connection.js'; +import { PeerChangeType, unionToPeerChangeType, unionListToPeerChangeType } from '../topology/peer-change-type.js'; + + +export class PeerChange { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):PeerChange { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsPeerChange(bb:flatbuffers.ByteBuffer, obj?:PeerChange):PeerChange { + return (obj || new PeerChange()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsPeerChange(bb:flatbuffers.ByteBuffer, obj?:PeerChange):PeerChange { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new PeerChange()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +currentState(index: number, obj?:AddedConnection):AddedConnection|null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? (obj || new AddedConnection()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null; +} + +currentStateLength():number { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +} + +changeType():PeerChangeType { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.readUint8(this.bb_pos + offset) : PeerChangeType.NONE; +} + +change(obj:any):any|null { + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.__union(obj, this.bb_pos + offset) : null; +} + +static startPeerChange(builder:flatbuffers.Builder) { + builder.startObject(3); +} + +static addCurrentState(builder:flatbuffers.Builder, currentStateOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, currentStateOffset, 0); +} + +static createCurrentStateVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]!); + } + return builder.endVector(); +} + +static startCurrentStateVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); +} + +static addChangeType(builder:flatbuffers.Builder, changeType:PeerChangeType) { + builder.addFieldInt8(1, changeType, PeerChangeType.NONE); +} + +static addChange(builder:flatbuffers.Builder, changeOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, changeOffset, 0); +} + +static endPeerChange(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + return offset; +} + +static createPeerChange(builder:flatbuffers.Builder, currentStateOffset:flatbuffers.Offset, changeType:PeerChangeType, changeOffset:flatbuffers.Offset):flatbuffers.Offset { + PeerChange.startPeerChange(builder); + PeerChange.addCurrentState(builder, currentStateOffset); + PeerChange.addChangeType(builder, changeType); + PeerChange.addChange(builder, changeOffset); + return PeerChange.endPeerChange(builder); +} +} diff --git a/schemas/flatbuffers/topology/put-failure.ts b/schemas/flatbuffers/topology/put-failure.ts new file mode 100644 index 000000000..dfacd429c --- /dev/null +++ b/schemas/flatbuffers/topology/put-failure.ts @@ -0,0 +1,88 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +export class PutFailure { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):PutFailure { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsPutFailure(bb:flatbuffers.ByteBuffer, obj?:PutFailure):PutFailure { + return (obj || new PutFailure()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsPutFailure(bb:flatbuffers.ByteBuffer, obj?:PutFailure):PutFailure { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new PutFailure()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +transaction():string|null +transaction(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +transaction(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +requester():string|null +requester(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +requester(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +target():string|null +target(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +target(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +key():string|null +key(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +key(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 10); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +static startPutFailure(builder:flatbuffers.Builder) { + builder.startObject(4); +} + +static addTransaction(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, transactionOffset, 0); +} + +static addRequester(builder:flatbuffers.Builder, requesterOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, requesterOffset, 0); +} + +static addTarget(builder:flatbuffers.Builder, targetOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, targetOffset, 0); +} + +static addKey(builder:flatbuffers.Builder, keyOffset:flatbuffers.Offset) { + builder.addFieldOffset(3, keyOffset, 0); +} + +static endPutFailure(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 4) // transaction + builder.requiredField(offset, 6) // requester + builder.requiredField(offset, 8) // target + builder.requiredField(offset, 10) // key + return offset; +} + +static createPutFailure(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset, requesterOffset:flatbuffers.Offset, targetOffset:flatbuffers.Offset, keyOffset:flatbuffers.Offset):flatbuffers.Offset { + PutFailure.startPutFailure(builder); + PutFailure.addTransaction(builder, transactionOffset); + PutFailure.addRequester(builder, requesterOffset); + PutFailure.addTarget(builder, targetOffset); + PutFailure.addKey(builder, keyOffset); + return PutFailure.endPutFailure(builder); +} +} diff --git a/schemas/flatbuffers/topology/put-request.ts b/schemas/flatbuffers/topology/put-request.ts new file mode 100644 index 000000000..ce2a1ae0b --- /dev/null +++ b/schemas/flatbuffers/topology/put-request.ts @@ -0,0 +1,88 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +export class PutRequest { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):PutRequest { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsPutRequest(bb:flatbuffers.ByteBuffer, obj?:PutRequest):PutRequest { + return (obj || new PutRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsPutRequest(bb:flatbuffers.ByteBuffer, obj?:PutRequest):PutRequest { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new PutRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +transaction():string|null +transaction(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +transaction(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +key():string|null +key(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +key(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +requester():string|null +requester(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +requester(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +target():string|null +target(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +target(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 10); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +static startPutRequest(builder:flatbuffers.Builder) { + builder.startObject(4); +} + +static addTransaction(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, transactionOffset, 0); +} + +static addKey(builder:flatbuffers.Builder, keyOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, keyOffset, 0); +} + +static addRequester(builder:flatbuffers.Builder, requesterOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, requesterOffset, 0); +} + +static addTarget(builder:flatbuffers.Builder, targetOffset:flatbuffers.Offset) { + builder.addFieldOffset(3, targetOffset, 0); +} + +static endPutRequest(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 4) // transaction + builder.requiredField(offset, 6) // key + builder.requiredField(offset, 8) // requester + builder.requiredField(offset, 10) // target + return offset; +} + +static createPutRequest(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset, keyOffset:flatbuffers.Offset, requesterOffset:flatbuffers.Offset, targetOffset:flatbuffers.Offset):flatbuffers.Offset { + PutRequest.startPutRequest(builder); + PutRequest.addTransaction(builder, transactionOffset); + PutRequest.addKey(builder, keyOffset); + PutRequest.addRequester(builder, requesterOffset); + PutRequest.addTarget(builder, targetOffset); + return PutRequest.endPutRequest(builder); +} +} diff --git a/schemas/flatbuffers/topology/put-success.ts b/schemas/flatbuffers/topology/put-success.ts new file mode 100644 index 000000000..ca1e950e2 --- /dev/null +++ b/schemas/flatbuffers/topology/put-success.ts @@ -0,0 +1,88 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +export class PutSuccess { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):PutSuccess { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsPutSuccess(bb:flatbuffers.ByteBuffer, obj?:PutSuccess):PutSuccess { + return (obj || new PutSuccess()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsPutSuccess(bb:flatbuffers.ByteBuffer, obj?:PutSuccess):PutSuccess { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new PutSuccess()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +transaction():string|null +transaction(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +transaction(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +requester():string|null +requester(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +requester(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +target():string|null +target(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +target(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +key():string|null +key(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +key(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 10); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +static startPutSuccess(builder:flatbuffers.Builder) { + builder.startObject(4); +} + +static addTransaction(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, transactionOffset, 0); +} + +static addRequester(builder:flatbuffers.Builder, requesterOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, requesterOffset, 0); +} + +static addTarget(builder:flatbuffers.Builder, targetOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, targetOffset, 0); +} + +static addKey(builder:flatbuffers.Builder, keyOffset:flatbuffers.Offset) { + builder.addFieldOffset(3, keyOffset, 0); +} + +static endPutSuccess(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 4) // transaction + builder.requiredField(offset, 6) // requester + builder.requiredField(offset, 8) // target + builder.requiredField(offset, 10) // key + return offset; +} + +static createPutSuccess(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset, requesterOffset:flatbuffers.Offset, targetOffset:flatbuffers.Offset, keyOffset:flatbuffers.Offset):flatbuffers.Offset { + PutSuccess.startPutSuccess(builder); + PutSuccess.addTransaction(builder, transactionOffset); + PutSuccess.addRequester(builder, requesterOffset); + PutSuccess.addTarget(builder, targetOffset); + PutSuccess.addKey(builder, keyOffset); + return PutSuccess.endPutSuccess(builder); +} +} diff --git a/schemas/flatbuffers/topology/removed-connection.ts b/schemas/flatbuffers/topology/removed-connection.ts new file mode 100644 index 000000000..30b005cf8 --- /dev/null +++ b/schemas/flatbuffers/topology/removed-connection.ts @@ -0,0 +1,62 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +export class RemovedConnection { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):RemovedConnection { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsRemovedConnection(bb:flatbuffers.ByteBuffer, obj?:RemovedConnection):RemovedConnection { + return (obj || new RemovedConnection()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsRemovedConnection(bb:flatbuffers.ByteBuffer, obj?:RemovedConnection):RemovedConnection { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new RemovedConnection()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +at():string|null +at(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +at(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +from():string|null +from(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +from(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +static startRemovedConnection(builder:flatbuffers.Builder) { + builder.startObject(2); +} + +static addAt(builder:flatbuffers.Builder, atOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, atOffset, 0); +} + +static addFrom(builder:flatbuffers.Builder, fromOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, fromOffset, 0); +} + +static endRemovedConnection(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 4) // at + builder.requiredField(offset, 6) // from + return offset; +} + +static createRemovedConnection(builder:flatbuffers.Builder, atOffset:flatbuffers.Offset, fromOffset:flatbuffers.Offset):flatbuffers.Offset { + RemovedConnection.startRemovedConnection(builder); + RemovedConnection.addAt(builder, atOffset); + RemovedConnection.addFrom(builder, fromOffset); + return RemovedConnection.endRemovedConnection(builder); +} +} diff --git a/schemas/flatbuffers/topology/response.ts b/schemas/flatbuffers/topology/response.ts new file mode 100644 index 000000000..f0ec80263 --- /dev/null +++ b/schemas/flatbuffers/topology/response.ts @@ -0,0 +1,36 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import { Error } from '../topology/error.js'; +import { Ok } from '../topology/ok.js'; + + +export enum Response { + NONE = 0, + Error = 1, + Ok = 2 +} + +export function unionToResponse( + type: Response, + accessor: (obj:Error|Ok) => Error|Ok|null +): Error|Ok|null { + switch(Response[type]) { + case 'NONE': return null; + case 'Error': return accessor(new Error())! as Error; + case 'Ok': return accessor(new Ok())! as Ok; + default: return null; + } +} + +export function unionListToResponse( + type: Response, + accessor: (index: number, obj:Error|Ok) => Error|Ok|null, + index: number +): Error|Ok|null { + switch(Response[type]) { + case 'NONE': return null; + case 'Error': return accessor(index, new Error())! as Error; + case 'Ok': return accessor(index, new Ok())! as Ok; + default: return null; + } +} diff --git a/schemas/flatbuffers/topology/update-failure.ts b/schemas/flatbuffers/topology/update-failure.ts new file mode 100644 index 000000000..f25f2ff89 --- /dev/null +++ b/schemas/flatbuffers/topology/update-failure.ts @@ -0,0 +1,88 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +export class UpdateFailure { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):UpdateFailure { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsUpdateFailure(bb:flatbuffers.ByteBuffer, obj?:UpdateFailure):UpdateFailure { + return (obj || new UpdateFailure()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsUpdateFailure(bb:flatbuffers.ByteBuffer, obj?:UpdateFailure):UpdateFailure { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new UpdateFailure()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +transaction():string|null +transaction(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +transaction(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +requester():string|null +requester(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +requester(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +target():string|null +target(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +target(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +key():string|null +key(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +key(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 10); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +static startUpdateFailure(builder:flatbuffers.Builder) { + builder.startObject(4); +} + +static addTransaction(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, transactionOffset, 0); +} + +static addRequester(builder:flatbuffers.Builder, requesterOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, requesterOffset, 0); +} + +static addTarget(builder:flatbuffers.Builder, targetOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, targetOffset, 0); +} + +static addKey(builder:flatbuffers.Builder, keyOffset:flatbuffers.Offset) { + builder.addFieldOffset(3, keyOffset, 0); +} + +static endUpdateFailure(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 4) // transaction + builder.requiredField(offset, 6) // requester + builder.requiredField(offset, 8) // target + builder.requiredField(offset, 10) // key + return offset; +} + +static createUpdateFailure(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset, requesterOffset:flatbuffers.Offset, targetOffset:flatbuffers.Offset, keyOffset:flatbuffers.Offset):flatbuffers.Offset { + UpdateFailure.startUpdateFailure(builder); + UpdateFailure.addTransaction(builder, transactionOffset); + UpdateFailure.addRequester(builder, requesterOffset); + UpdateFailure.addTarget(builder, targetOffset); + UpdateFailure.addKey(builder, keyOffset); + return UpdateFailure.endUpdateFailure(builder); +} +} diff --git a/schemas/flatbuffers/topology/update-request.ts b/schemas/flatbuffers/topology/update-request.ts new file mode 100644 index 000000000..b634c452d --- /dev/null +++ b/schemas/flatbuffers/topology/update-request.ts @@ -0,0 +1,88 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +export class UpdateRequest { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):UpdateRequest { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsUpdateRequest(bb:flatbuffers.ByteBuffer, obj?:UpdateRequest):UpdateRequest { + return (obj || new UpdateRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsUpdateRequest(bb:flatbuffers.ByteBuffer, obj?:UpdateRequest):UpdateRequest { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new UpdateRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +transaction():string|null +transaction(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +transaction(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +key():string|null +key(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +key(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +requester():string|null +requester(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +requester(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +target():string|null +target(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +target(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 10); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +static startUpdateRequest(builder:flatbuffers.Builder) { + builder.startObject(4); +} + +static addTransaction(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, transactionOffset, 0); +} + +static addKey(builder:flatbuffers.Builder, keyOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, keyOffset, 0); +} + +static addRequester(builder:flatbuffers.Builder, requesterOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, requesterOffset, 0); +} + +static addTarget(builder:flatbuffers.Builder, targetOffset:flatbuffers.Offset) { + builder.addFieldOffset(3, targetOffset, 0); +} + +static endUpdateRequest(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 4) // transaction + builder.requiredField(offset, 6) // key + builder.requiredField(offset, 8) // requester + builder.requiredField(offset, 10) // target + return offset; +} + +static createUpdateRequest(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset, keyOffset:flatbuffers.Offset, requesterOffset:flatbuffers.Offset, targetOffset:flatbuffers.Offset):flatbuffers.Offset { + UpdateRequest.startUpdateRequest(builder); + UpdateRequest.addTransaction(builder, transactionOffset); + UpdateRequest.addKey(builder, keyOffset); + UpdateRequest.addRequester(builder, requesterOffset); + UpdateRequest.addTarget(builder, targetOffset); + return UpdateRequest.endUpdateRequest(builder); +} +} diff --git a/schemas/flatbuffers/topology/update-success.ts b/schemas/flatbuffers/topology/update-success.ts new file mode 100644 index 000000000..535fdff86 --- /dev/null +++ b/schemas/flatbuffers/topology/update-success.ts @@ -0,0 +1,88 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +export class UpdateSuccess { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):UpdateSuccess { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsUpdateSuccess(bb:flatbuffers.ByteBuffer, obj?:UpdateSuccess):UpdateSuccess { + return (obj || new UpdateSuccess()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsUpdateSuccess(bb:flatbuffers.ByteBuffer, obj?:UpdateSuccess):UpdateSuccess { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new UpdateSuccess()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +transaction():string|null +transaction(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +transaction(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +requester():string|null +requester(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +requester(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +target():string|null +target(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +target(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +key():string|null +key(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +key(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 10); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +static startUpdateSuccess(builder:flatbuffers.Builder) { + builder.startObject(4); +} + +static addTransaction(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, transactionOffset, 0); +} + +static addRequester(builder:flatbuffers.Builder, requesterOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, requesterOffset, 0); +} + +static addTarget(builder:flatbuffers.Builder, targetOffset:flatbuffers.Offset) { + builder.addFieldOffset(2, targetOffset, 0); +} + +static addKey(builder:flatbuffers.Builder, keyOffset:flatbuffers.Offset) { + builder.addFieldOffset(3, keyOffset, 0); +} + +static endUpdateSuccess(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 4) // transaction + builder.requiredField(offset, 6) // requester + builder.requiredField(offset, 8) // target + builder.requiredField(offset, 10) // key + return offset; +} + +static createUpdateSuccess(builder:flatbuffers.Builder, transactionOffset:flatbuffers.Offset, requesterOffset:flatbuffers.Offset, targetOffset:flatbuffers.Offset, keyOffset:flatbuffers.Offset):flatbuffers.Offset { + UpdateSuccess.startUpdateSuccess(builder); + UpdateSuccess.addTransaction(builder, transactionOffset); + UpdateSuccess.addRequester(builder, requesterOffset); + UpdateSuccess.addTarget(builder, targetOffset); + UpdateSuccess.addKey(builder, keyOffset); + return UpdateSuccess.endUpdateSuccess(builder); +} +} diff --git a/stdlib b/stdlib index f28e67163..f5597dfd4 160000 --- a/stdlib +++ b/stdlib @@ -1 +1 @@ -Subproject commit f28e6716364b4e1c9ae8837344286393a2da4c82 +Subproject commit f5597dfd440a0470bcd306ce9f50883b42060a6e