Rust implementation of NextGraph, a Decentralized and local-first web 3.0 ecosystem
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nextgraph-rs/p2p-net/src/types.rs

1941 lines
50 KiB

// Copyright (c) 2022-2023 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// This code is partly derived from work written by TG x Thoth from P2Pcollab.
// Copyright 2022 TG x Thoth
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
//! P2P network protocol types
//!
//! Corresponds to the BARE schema
use core::fmt;
use std::{
any::{Any, TypeId},
net::IpAddr,
};
use crate::{actor::EActor, actors::*, errors::ProtocolError};
use p2p_repo::types::*;
use serde::{Deserialize, Serialize};
//
// COMMON TYPES FOR MESSAGES
//
pub type DirectPeerId = PubKey;
/// Peer ID: public key of the node, or an encrypted version of it
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)]
pub enum PeerId {
DIRECT(DirectPeerId),
FORWARDED([u8; 32]),
}
/// Overlay ID
///
/// - for read overlays that need to be discovered by public key:
/// BLAKE3 hash over the repository public key (of root doc)
/// - for write overlays:
/// BLAKE3 keyed hash over the repository public key
/// - key: BLAKE3 derive_key ("NextGraph OverlayId BLAKE3 key", repo_secret, root_secret)
pub type OverlayId = Digest;
/// Overlay session ID
///
/// Used as a component for key derivation.
/// Each peer generates it randomly when (re)joining the overlay network.
pub type SessionId = u64;
/// Topic ID: public key of the topic
pub type TopicId = PubKey;
/// User ID: user account for broker
pub type UserId = PubKey;
/// Client ID: client of a user
pub type ClientId = PubKey;
/// IPv4 address
pub type IPv4 = [u8; 4];
/// IPv6 address
pub type IPv6 = [u8; 16];
/// IP address
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub enum IP {
IPv4(IPv4),
IPv6(IPv6),
}
impl fmt::Display for IP {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let t: IpAddr = self.try_into().unwrap();
write!(f, "{}", t)
}
}
impl From<&IpAddr> for IP {
#[inline]
fn from(ip: &IpAddr) -> IP {
match ip {
IpAddr::V4(v4) => IP::IPv4(v4.octets()),
IpAddr::V6(v6) => IP::IPv6(v6.octets()),
}
}
}
impl From<&IP> for IpAddr {
#[inline]
fn from(ip: &IP) -> IpAddr {
match ip {
IP::IPv4(v4) => IpAddr::from(*v4),
IP::IPv6(v6) => IpAddr::from(*v6),
}
}
}
/// IP transport protocol
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub enum TransportProtocol {
WS,
QUIC,
Local,
}
/// IP transport address
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct IPTransportAddr {
pub ip: IP,
pub port: u16,
pub protocol: TransportProtocol,
}
/// Network address
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub enum NetAddr {
IPTransport(IPTransportAddr),
}
//
// OVERLAY MESSAGES
//
/// Overlay connection request
///
/// Sent to an existing overlay member to initiate a session
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum OverlayConnect {
V0(),
}
/// Overlay disconnection request
///
/// Sent to a connected overlay member to terminate a session
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum OverlayDisconnect {
V0(),
}
/// Content of TopicAdvertV0
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct TopicAdvertContentV0 {
/// Topic public key
pub topic: TopicId,
/// Peer public key
pub peer: PeerId,
}
/// Topic advertisement by a publisher
///
/// Flooded to all peers in overlay
/// Creates subscription routing table entries
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct TopicAdvertV0 {
pub content: TopicAdvertContentV0,
/// Signature over content by topic key
pub sig: Sig,
}
/// Topic advertisement by a publisher
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum TopicAdvert {
V0(TopicAdvertV0),
}
/// Topic subscription request by a peer
///
/// Forwarded towards all publishers along subscription routing table entries
/// that are created by TopicAdverts
/// Creates event routing table entries along the path
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct SubReqV0 {
/// Random ID generated by the subscriber
pub id: u64,
/// Topic public key
pub topic: TopicId,
}
/// Topic subscription request by a peer
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum SubReq {
V0(SubReqV0),
}
/// Topic subscription acknowledgement by a publisher
///
/// Sent to all subscribers in an Event.
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct SubAckV0 {
/// SubReq ID to acknowledge
pub id: u64,
}
/// Topic subscription acknowledgement by a publisher
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum SubAck {
V0(SubAckV0),
}
/// Topic unsubscription request by a subscriber
///
/// A broker unsubscribes from upstream brokers
/// when it has no more subscribers left
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct UnsubReqV0 {
/// Topic public key
pub topic: TopicId,
}
/// Topic unsubscription request by a subscriber
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum UnsubReq {
V0(UnsubReqV0),
}
/// Topic unsubscription acknowledgement
/// Sent to the requestor in response to an UnsubReq
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct UnsubAckV0 {
/// Topic public key
pub topic: TopicId,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum UnsubAck {
V0(UnsubAckV0),
}
/// Branch change notification
/// Contains a chunk of a newly added Commit or File referenced by a commit.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ChangeV0 {
/// Block with encrypted content
pub content: Block,
/// Encrypted key for the Commit object in content
/// Only set for the root block of the object
/// The key is encrypted using ChaCha20:
/// - key: BLAKE3 derive_key ("NextGraph Event ObjectRef ChaCha20 key",
/// branch_pubkey + branch_secret + publisher_pubkey)
/// - nonce: commit_seq
pub key: Option<SymKey>,
}
/// Body of EventContentV0
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum EventBodyV0 {
SubAck,
Change,
}
/// Content of EventV0
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct EventContentV0 {
/// Pub/sub topic
pub topic: TopicId,
/// Publisher pubkey encrypted with ChaCha20:
/// - key: BLAKE3 derive_key ("NextGraph Event Publisher ChaCha20 key",
/// repo_pubkey + repo_secret +
/// branch_pubkey + branch_secret)
pub publisher: [u8; 32], // PubKey
/// Commit sequence number of publisher
pub seq: u32,
/// Event body
pub body: EventBodyV0,
}
/// Pub/sub event published in a topic
///
/// Forwarded along event routing table entries
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct EventV0 {
pub content: EventContentV0,
/// Signature over content by topic key
pub sig: Sig,
}
/// Pub/sub event published in a topic
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum Event {
V0(EventV0),
}
/// Object search in a pub/sub topic
///
/// Sent along the reverse path of a pub/sub topic
/// from a subscriber to all publishers.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct BlockSearchTopicV0 {
/// Topic to forward the request in
pub topic: TopicId,
/// List of Object IDs to request
pub ids: Vec<ObjectId>,
/// Whether or not to include all children recursively in the response
pub include_children: bool,
/// List of Peer IDs the request traversed so far
pub path: Vec<PeerId>,
}
/// Object request by ID
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum BlockSearchTopic {
V0(BlockSearchTopicV0),
}
/// Block search along a random walk
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct BlockSearchRandomV0 {
/// List of Block IDs to request
pub ids: Vec<BlockId>,
/// Whether or not to include all children recursively in the response
pub include_children: bool,
/// Number of random nodes to forward the request to at each step
pub fanout: u8,
/// List of Peer IDs the request traversed so far
pub path: Vec<PeerId>,
}
/// Block request by ID using a random walk
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum BlockSearchRandom {
V0(BlockSearchRandomV0),
}
/// Response to a BlockSearch* request
///
/// Follows request path with possible shortcuts.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct BlockResultV0 {
/// Response path
pub path: Vec<PeerId>,
/// Resulting Object(s)
pub payload: Vec<Block>,
}
/// Response to a BlockSearch* request
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum BlockResult {
V0(BlockResultV0),
}
/// Request latest events corresponding to the branch heads in a pub/sub topic
///
/// In response an Event is sent for each commit chunk that belong to branch heads
/// that are not present in the requestor's known heads
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct BranchHeadsReqV0 {
/// Topic public key of the branch
pub topic: TopicId,
/// Known heads
pub known_heads: Vec<ObjectId>,
}
/// Request latest events corresponding to the branch heads in a pub/sub topic
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum BranchHeadsReq {
V0(BranchHeadsReqV0),
}
/// Branch synchronization request
///
/// In response a stream of `Block`s of the requested Objects are sent
/// that are not present in the requestor's known heads and commits
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct BranchSyncReqV0 {
/// Heads to request, including all their dependencies
pub heads: Vec<ObjectId>,
/// Fully synchronized until these commits
pub known_heads: Vec<ObjectId>,
/// Known commit IDs since known_heads
pub known_commits: BloomFilter,
}
/// Branch synchronization request
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum BranchSyncReq {
V0(BranchSyncReqV0),
}
impl BranchSyncReq {
pub fn heads(&self) -> &Vec<ObjectId> {
match self {
BranchSyncReq::V0(o) => &o.heads,
}
}
pub fn known_heads(&self) -> &Vec<ObjectId> {
match self {
BranchSyncReq::V0(o) => &o.known_heads,
}
}
pub fn known_commits(&self) -> &BloomFilter {
match self {
BranchSyncReq::V0(o) => &o.known_commits,
}
}
}
/// Events the requestor needs, see EventReqV0
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct NeedEventsV0 {
/// Publisher ID
pub publisher: Digest,
/// First sequence number to request
pub from: u32,
/// Last sequence number to request
pub to: u32,
}
/// Events the responder has, see EventRespV0
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct HaveEventsV0 {
/// Publisher ID
pub publisher: Digest,
/// First sequence number to send
pub from: u32,
/// Last sequence number to send
pub to: u32,
}
/// Request missed events for a pub/sub topic
/// for the specified range of publisher sequence numbers
///
/// In response an EventResp then a stream of Events are sent
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct EventReqV0 {
/// Topic public key
pub topic: TopicId,
/// Events needed by the requestor
pub need: Vec<NeedEventsV0>,
}
/// Request missed events for a pub/sub topic
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum EventReq {
V0(EventReqV0),
}
/// Response to an EventReq
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct EventRespV0 {
/// Events the responder has
pub have: Vec<HaveEventsV0>,
}
/// Response to an EventReq
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum EventResp {
V0(EventRespV0),
}
/// Content of OverlayRequestV0
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum OverlayRequestContentV0 {
EventReq(EventReq),
BranchHeadsReq(BranchHeadsReq),
BranchSyncReq(BranchSyncReq),
}
/// Request sent to an overlay
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OverlayRequestV0 {
/// Request ID
pub id: i64,
/// Request content
pub content: OverlayRequestContentV0,
}
/// Request sent to an overlay
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum OverlayRequest {
V0(OverlayRequestV0),
}
/// Content of OverlayResponseV0
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum OverlayResponseContentV0 {
EmptyResponse(()),
Block(Block),
EventResp(EventResp),
Event(Event),
}
/// Request sent to an overlay
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OverlayResponseV0 {
/// Request ID
pub id: i64,
/// Result
pub result: u16,
/// Response content
pub content: OverlayResponseContentV0,
}
/// Request sent to an OverlayRequest
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum OverlayResponse {
V0(OverlayResponseV0),
}
/// Content of PeerAdvertV0
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PeerAdvertContentV0 {
/// Peer ID
pub peer: PeerId,
/// Topic subscriptions
pub subs: BloomFilter128,
/// Network addresses
pub address: Vec<NetAddr>,
/// Version number
pub version: u32,
/// App-specific metadata (profile, cryptographic material, etc)
#[serde(with = "serde_bytes")]
pub metadata: Vec<u8>,
}
/// Peer advertisement
///
/// Sent periodically across the overlay along random walks.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PeerAdvertV0 {
/// Peer advertisement content
pub content: PeerAdvertContentV0,
/// Signature over content by peer's private key
pub sig: Sig,
/// Time-to-live, decremented at each hop
pub ttl: u8,
}
/// Peer advertisement
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum PeerAdvert {
V0(PeerAdvertV0),
}
impl PeerAdvert {
pub fn version(&self) -> u32 {
match self {
PeerAdvert::V0(o) => o.content.version,
}
}
pub fn peer(&self) -> &PeerId {
match self {
PeerAdvert::V0(o) => &o.content.peer,
}
}
}
/// Content of OverlayMessagePaddedV0
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum OverlayMessageContentV0 {
OverlayConnect(OverlayConnect),
OverlayDisconnect(OverlayDisconnect),
PeerAdvert(PeerAdvert),
TopicAdvert(TopicAdvert),
SubReq(SubReq),
SubAck(SubAck),
UnsubReq(UnsubReq),
UnsubAck(UnsubAck),
Event(Event),
BlockSearchTopic(BlockSearchTopic),
BlockSearchRandom(BlockSearchRandom),
BlockResult(BlockResult),
OverlayRequest(OverlayRequest),
OverlayResponse(OverlayResponse),
}
/// Padded content of OverlayMessageV0
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OverlayMessageContentPaddedV0 {
pub content: OverlayMessageContentV0,
/// Optional padding
#[serde(with = "serde_bytes")]
pub padding: Vec<u8>,
}
/// Overlay message
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OverlayMessageV0 {
/// Overlay ID
pub overlay: OverlayId,
/// Session ID
pub session: SessionId,
/// Padded content encrypted with ChaCha20
/// - overlay_secret: BLAKE3 derive_key ("NextGraph Overlay BLAKE3 key",
/// repo_pubkey + repo_secret)
/// - key: BLAKE3 derive_key ("NextGraph OverlayMessage ChaCha20 key",
/// overlay_secret + session_id)
/// - nonce: per-session message sequence number of sending peer
pub content: OverlayMessageContentPaddedV0,
/// BLAKE3 MAC
/// BLAKE3 keyed hash over the encrypted content
/// - key: BLAKE3 derive_key ("NextGraph OverlayMessage BLAKE3 key",
/// overlay_secret + session_id)
pub mac: Digest,
}
/// Overlay message
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum OverlayMessage {
V0(OverlayMessageV0),
}
//
// BROKER PROTOCOL
//
/// Content of AddUserV0
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct AddUserContentV0 {
/// User pub key
pub user: PubKey,
}
/// Add user account
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct AddUserV0 {
pub content: AddUserContentV0,
/// Signature by admin key
pub sig: Sig,
}
/// Add user account
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum AddUser {
V0(AddUserV0),
}
impl AddUser {
pub fn content_v0(&self) -> AddUserContentV0 {
match self {
AddUser::V0(o) => o.content,
}
}
pub fn sig(&self) -> Sig {
match self {
AddUser::V0(o) => o.sig,
}
}
pub fn user(&self) -> PubKey {
match self {
AddUser::V0(o) => o.content.user,
}
}
}
/// Content of DelUserV0
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct DelUserContentV0 {
/// User pub key
pub user: PubKey,
}
/// Delete user account
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct DelUserV0 {
pub content: DelUserContentV0,
/// Signature by admin key
pub sig: Sig,
}
/// Delete user account
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum DelUser {
V0(DelUserV0),
}
impl DelUser {
pub fn content_v0(&self) -> DelUserContentV0 {
match self {
DelUser::V0(o) => o.content,
}
}
pub fn sig(&self) -> Sig {
match self {
DelUser::V0(o) => o.sig,
}
}
pub fn user(&self) -> PubKey {
match self {
DelUser::V0(o) => o.content.user,
}
}
}
/// Content of `AddClientV0`
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct AddClientContentV0 {
/// Client pub key
pub client: PubKey,
}
/// Add a client
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct AddClientV0 {
pub content: AddClientContentV0,
/// Signature by user key
pub sig: Sig,
}
/// Add a client
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum AddClient {
V0(AddClientV0),
}
impl AddClient {
pub fn content_v0(&self) -> AddClientContentV0 {
match self {
AddClient::V0(o) => o.content,
}
}
pub fn sig(&self) -> Sig {
match self {
AddClient::V0(o) => o.sig,
}
}
pub fn client(&self) -> PubKey {
match self {
AddClient::V0(o) => o.content.client,
}
}
}
/// Content of `DelClientV0`
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct DelClientContentV0 {
/// Client pub key
pub client: PubKey,
}
/// Remove a client
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct DelClientV0 {
pub content: DelClientContentV0,
/// Signature by user key
pub sig: Sig,
}
/// Remove a client
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum DelClient {
V0(DelClientV0),
}
impl DelClient {
pub fn content_v0(&self) -> DelClientContentV0 {
match self {
DelClient::V0(o) => o.content,
}
}
pub fn sig(&self) -> Sig {
match self {
DelClient::V0(o) => o.sig,
}
}
pub fn client(&self) -> PubKey {
match self {
DelClient::V0(o) => o.content.client,
}
}
}
/// Content of `BrokerRequestV0`
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum BrokerRequestContentV0 {
AddUser(AddUser),
DelUser(DelUser),
AddClient(AddClient),
DelClient(DelClient),
}
impl BrokerRequestContentV0 {
pub fn type_id(&self) -> TypeId {
match self {
BrokerRequestContentV0::AddUser(a) => a.type_id(),
BrokerRequestContentV0::DelUser(a) => a.type_id(),
BrokerRequestContentV0::AddClient(a) => a.type_id(),
BrokerRequestContentV0::DelClient(a) => a.type_id(),
}
}
}
/// Broker request
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct BrokerRequestV0 {
/// Request ID
pub id: i64,
/// Request content
pub content: BrokerRequestContentV0,
}
/// Broker request
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum BrokerRequest {
V0(BrokerRequestV0),
}
impl BrokerRequest {
pub fn id(&self) -> i64 {
match self {
BrokerRequest::V0(o) => o.id,
}
}
pub fn set_id(&mut self, id: i64) {
match self {
BrokerRequest::V0(v0) => {
v0.id = id;
}
}
}
pub fn type_id(&self) -> TypeId {
match self {
BrokerRequest::V0(o) => o.content.type_id(),
}
}
pub fn content_v0(&self) -> BrokerRequestContentV0 {
match self {
BrokerRequest::V0(o) => o.content.clone(),
}
}
}
/// Content of `BrokerResponseV0`
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum BrokerResponseContentV0 {
EmptyResponse(()),
}
/// Response to a `BrokerRequest`
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct BrokerResponseV0 {
/// Request ID
pub id: i64,
/// Result (including but not limited to Result)
pub result: u16,
pub content: BrokerResponseContentV0,
}
/// Response to a `BrokerRequest`
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum BrokerResponse {
V0(BrokerResponseV0),
}
impl BrokerResponse {
pub fn id(&self) -> i64 {
match self {
BrokerResponse::V0(o) => o.id,
}
}
pub fn set_id(&mut self, id: i64) {
match self {
BrokerResponse::V0(v0) => {
v0.id = id;
}
}
}
pub fn result(&self) -> u16 {
match self {
BrokerResponse::V0(o) => o.result,
}
}
}
/// Request to join an overlay
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OverlayJoinV0 {
/// Overlay secret
pub secret: SymKey,
/// Repository the overlay belongs to.
/// Only set for local brokers.
pub repo_pubkey: Option<PubKey>,
/// Peers to connect to
pub peers: Vec<PeerAdvert>,
}
/// Request to join an overlay
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum OverlayJoin {
V0(OverlayJoinV0),
}
impl OverlayJoin {
pub fn repo_pubkey(&self) -> Option<PubKey> {
match self {
OverlayJoin::V0(o) => o.repo_pubkey,
}
}
pub fn secret(&self) -> SymKey {
match self {
OverlayJoin::V0(o) => o.secret,
}
}
pub fn peers(&self) -> &Vec<PeerAdvert> {
match self {
OverlayJoin::V0(o) => &o.peers,
}
}
}
/// Request to leave an overlay
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum OverlayLeave {
V0(),
}
/// Overlay status request
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum OverlayStatusReq {
V0(),
}
/// Overlay status response
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OverlayStatusRespV0 {
/// Whether or not the broker has joined the overlay
pub joined: bool,
/// List of peers currently connected in the overlay
pub peers: Vec<PeerAdvert>,
}
/// Overlay status response
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum OverlayStatusResp {
V0(OverlayStatusRespV0),
}
/// Request a Block by ID
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct BlockGetV0 {
/// Block ID to request
pub id: BlockId,
/// Whether or not to include all children recursively
pub include_children: bool,
/// Topic the object is referenced from
pub topic: Option<PubKey>,
}
/// Request an object by ID
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum BlockGet {
V0(BlockGetV0),
}
impl BlockGet {
pub fn id(&self) -> BlockId {
match self {
BlockGet::V0(o) => o.id,
}
}
pub fn include_children(&self) -> bool {
match self {
BlockGet::V0(o) => o.include_children,
}
}
pub fn topic(&self) -> Option<PubKey> {
match self {
BlockGet::V0(o) => o.topic,
}
}
}
/// Request to store an object
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum BlockPut {
V0(Block),
}
impl BlockPut {
pub fn block(&self) -> &Block {
match self {
BlockPut::V0(o) => &o,
}
}
}
/// Request to pin an object
///
/// Brokers maintain an LRU cache of objects,
/// where old, unused objects might get deleted to free up space for new ones.
/// Pinned objects are retained, regardless of last access.
/// Note that expiry is still observed in case of pinned objects.
/// To make an object survive its expiry,
/// it needs to be copied with a different expiry time.
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct ObjectPinV0 {
pub id: ObjectId,
}
/// Request to pin an object
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum ObjectPin {
V0(ObjectPinV0),
}
impl ObjectPin {
pub fn id(&self) -> ObjectId {
match self {
ObjectPin::V0(o) => o.id,
}
}
}
/// Request to unpin an object
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct ObjectUnpinV0 {
pub id: ObjectId,
}
/// Request to unpin an object
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum ObjectUnpin {
V0(ObjectUnpinV0),
}
impl ObjectUnpin {
pub fn id(&self) -> ObjectId {
match self {
ObjectUnpin::V0(o) => o.id,
}
}
}
/// Request to copy an object with a different expiry time
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct ObjectCopyV0 {
/// Object ID to copy
pub id: ObjectId,
/// New expiry time
pub expiry: Option<Timestamp>,
}
/// Request to copy an object with a different expiry time
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum ObjectCopy {
V0(ObjectCopyV0),
}
impl ObjectCopy {
pub fn id(&self) -> ObjectId {
match self {
ObjectCopy::V0(o) => o.id,
}
}
pub fn expiry(&self) -> Option<Timestamp> {
match self {
ObjectCopy::V0(o) => o.expiry,
}
}
}
/// Request to delete an object
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct ObjectDelV0 {
pub id: ObjectId,
}
/// Request to delete an object
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum ObjectDel {
V0(ObjectDelV0),
}
impl ObjectDel {
pub fn id(&self) -> ObjectId {
match self {
ObjectDel::V0(o) => o.id,
}
}
}
/// Request subscription to a `Topic`
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct TopicSubV0 {
/// Topic to subscribe
pub topic: PubKey,
/// Publisher need to provide a signed `TopicAdvert` for the PeerId of the broker
pub advert: Option<TopicAdvert>,
}
/// Request subscription to a `Topic`
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum TopicSub {
V0(TopicSubV0),
}
/// Request unsubscription from a `Topic`
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct TopicUnsubV0 {
/// Topic to unsubscribe
pub topic: PubKey,
}
/// Request unsubscription from a `Topic`
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum TopicUnsub {
V0(TopicUnsubV0),
}
/// Connect to an already subscribed `Topic`, and start receiving its `Event`s
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct TopicConnectV0 {
/// Topic to connect
pub topic: PubKey,
}
/// Connect to an already subscribed `Topic`, and start receiving its `Event`s
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum TopicConnect {
V0(TopicConnectV0),
}
/// Disconnect from a Topic, and stop receiving its `Event`s
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct TopicDisconnectV0 {
/// Topic to disconnect
pub topic: PubKey,
}
/// Disconnect from a Topic, and stop receiving its `Event`s
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum TopicDisconnect {
V0(TopicDisconnectV0),
}
/// Content of `BrokerOverlayRequestV0`
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum BrokerOverlayRequestContentV0 {
OverlayConnect(OverlayConnect), // FIXME remove
OverlayStatusReq(OverlayStatusReq),
OverlayJoin(OverlayJoin),
OverlayLeave(OverlayLeave),
TopicSub(TopicSub),
TopicUnsub(TopicUnsub),
TopicConnect(TopicConnect),
TopicDisconnect(TopicDisconnect),
Event(Event),
BlockGet(BlockGet),
BlockPut(BlockPut),
ObjectPin(ObjectPin),
ObjectUnpin(ObjectUnpin),
ObjectCopy(ObjectCopy),
ObjectDel(ObjectDel),
BranchHeadsReq(BranchHeadsReq),
BranchSyncReq(BranchSyncReq),
}
/// Broker overlay request
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct BrokerOverlayRequestV0 {
/// Request ID
pub id: i64,
/// Request content
pub content: BrokerOverlayRequestContentV0,
}
/// Broker overlay request
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum BrokerOverlayRequest {
V0(BrokerOverlayRequestV0),
}
impl BrokerOverlayRequest {
pub fn id(&self) -> i64 {
match self {
BrokerOverlayRequest::V0(o) => o.id,
}
}
pub fn set_id(&mut self, id: i64) {
match self {
BrokerOverlayRequest::V0(v0) => {
v0.id = id;
}
}
}
pub fn content_v0(&self) -> &BrokerOverlayRequestContentV0 {
match self {
BrokerOverlayRequest::V0(o) => &o.content,
}
}
}
/// Content of `BrokerOverlayResponseV0`
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum BrokerOverlayResponseContentV0 {
EmptyResponse(()),
Block(Block),
ObjectId(ObjectId),
OverlayStatusResp(OverlayStatusResp),
}
/// Response to a `BrokerOverlayRequest`
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct BrokerOverlayResponseV0 {
/// Request ID
pub id: i64,
/// Result (including but not limited to Result)
pub result: u16,
/// Response content
pub content: BrokerOverlayResponseContentV0,
}
/// Response to a `BrokerOverlayRequest`
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum BrokerOverlayResponse {
V0(BrokerOverlayResponseV0),
}
impl BrokerOverlayResponse {
pub fn id(&self) -> i64 {
match self {
BrokerOverlayResponse::V0(o) => o.id,
}
}
pub fn set_id(&mut self, id: i64) {
match self {
BrokerOverlayResponse::V0(v0) => {
v0.id = id;
}
}
}
pub fn result(&self) -> u16 {
match self {
BrokerOverlayResponse::V0(o) => o.result,
}
}
pub fn block(&self) -> Option<&Block> {
match self {
BrokerOverlayResponse::V0(o) => match &o.content {
BrokerOverlayResponseContentV0::Block(b) => Some(b),
_ => panic!("this not a block response"),
},
}
}
pub fn object_id(&self) -> ObjectId {
match self {
BrokerOverlayResponse::V0(o) => match &o.content {
BrokerOverlayResponseContentV0::ObjectId(id) => id.clone(),
_ => panic!("this not an objectId reponse"),
},
}
}
}
/// Content of `BrokerOverlayMessageV0`
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum BrokerOverlayMessageContentV0 {
BrokerOverlayRequest(BrokerOverlayRequest),
BrokerOverlayResponse(BrokerOverlayResponse),
Event(Event),
}
/// Broker message for an overlay
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct BrokerOverlayMessageV0 {
pub overlay: OverlayId,
pub content: BrokerOverlayMessageContentV0,
}
/// Broker message for an overlay
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum BrokerOverlayMessage {
V0(BrokerOverlayMessageV0),
}
impl BrokerOverlayMessage {
pub fn content_v0(&self) -> &BrokerOverlayMessageContentV0 {
match self {
BrokerOverlayMessage::V0(o) => &o.content,
}
}
pub fn overlay_request(&self) -> &BrokerOverlayRequest {
match self {
BrokerOverlayMessage::V0(o) => match &o.content {
BrokerOverlayMessageContentV0::BrokerOverlayRequest(r) => &r,
_ => panic!("not an overlay request"),
},
}
}
pub fn overlay_id(&self) -> OverlayId {
match self {
BrokerOverlayMessage::V0(o) => o.overlay,
}
}
pub fn is_request(&self) -> bool {
match self {
BrokerOverlayMessage::V0(o) => matches!(
o.content,
BrokerOverlayMessageContentV0::BrokerOverlayRequest { .. }
),
}
}
pub fn is_response(&self) -> bool {
match self {
BrokerOverlayMessage::V0(o) => matches!(
o.content,
BrokerOverlayMessageContentV0::BrokerOverlayResponse { .. }
),
}
}
pub fn id(&self) -> i64 {
match self {
BrokerOverlayMessage::V0(o) => match &o.content {
BrokerOverlayMessageContentV0::BrokerOverlayResponse(r) => r.id(),
BrokerOverlayMessageContentV0::BrokerOverlayRequest(r) => r.id(),
BrokerOverlayMessageContentV0::Event(_) => {
panic!("it is an event")
}
},
}
}
pub fn set_id(&mut self, id: i64) {
match self {
BrokerOverlayMessage::V0(o) => match &mut o.content {
BrokerOverlayMessageContentV0::BrokerOverlayResponse(ref mut r) => r.set_id(id),
BrokerOverlayMessageContentV0::BrokerOverlayRequest(ref mut r) => r.set_id(id),
BrokerOverlayMessageContentV0::Event(_) => {
panic!("it is an event")
}
},
}
}
pub fn result(&self) -> u16 {
match self {
BrokerOverlayMessage::V0(o) => match &o.content {
BrokerOverlayMessageContentV0::BrokerOverlayResponse(r) => r.result(),
BrokerOverlayMessageContentV0::BrokerOverlayRequest(r) => {
panic!("it is not a response");
}
BrokerOverlayMessageContentV0::Event(_) => {
panic!("it is not a response");
}
},
}
}
pub fn block<'a>(&self) -> Option<&Block> {
match self {
BrokerOverlayMessage::V0(o) => match &o.content {
BrokerOverlayMessageContentV0::BrokerOverlayResponse(r) => r.block(),
BrokerOverlayMessageContentV0::BrokerOverlayRequest(r) => {
panic!("it is not a response");
}
BrokerOverlayMessageContentV0::Event(_) => {
panic!("it is not a response");
}
},
}
}
pub fn object_id<'a>(&self) -> ObjectId {
match self {
BrokerOverlayMessage::V0(o) => match &o.content {
BrokerOverlayMessageContentV0::BrokerOverlayResponse(r) => r.object_id(),
BrokerOverlayMessageContentV0::BrokerOverlayRequest(r) => {
panic!("it is not a response");
}
BrokerOverlayMessageContentV0::Event(_) => {
panic!("it is not a response");
}
},
}
}
}
/// Content of BrokerMessageV0
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum BrokerMessageContentV0 {
BrokerRequest(BrokerRequest),
BrokerResponse(BrokerResponse),
BrokerOverlayMessage(BrokerOverlayMessage),
}
/// Broker message
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct BrokerMessageV0 {
/// Message content
pub content: BrokerMessageContentV0,
/// Optional padding
#[serde(with = "serde_bytes")]
pub padding: Vec<u8>,
}
/// Broker message
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum BrokerMessage {
V0(BrokerMessageV0),
Close, //TODO: remove Close.
}
impl BrokerMessage {
pub fn type_id(&self) -> TypeId {
match self {
BrokerMessage::V0(a) => match &a.content {
BrokerMessageContentV0::BrokerOverlayMessage(p) => p.type_id(),
BrokerMessageContentV0::BrokerResponse(p) => p.type_id(),
BrokerMessageContentV0::BrokerRequest(p) => p.type_id(),
},
BrokerMessage::Close => TypeId::of::<BrokerMessage>(),
}
}
pub fn is_close(&self) -> bool {
match self {
BrokerMessage::V0(o) => false,
BrokerMessage::Close => true,
}
}
/// Get the content
pub fn content(&self) -> BrokerMessageContentV0 {
match self {
BrokerMessage::V0(o) => o.content.clone(),
BrokerMessage::Close => panic!("Close not implemented"),
}
}
pub fn is_request(&self) -> bool {
match self {
BrokerMessage::V0(o) => match &o.content {
BrokerMessageContentV0::BrokerOverlayMessage(p) => p.is_request(),
BrokerMessageContentV0::BrokerResponse(_) => false,
BrokerMessageContentV0::BrokerRequest(_) => true,
},
BrokerMessage::Close => panic!("Close not implemented"),
}
}
pub fn is_response(&self) -> bool {
match self {
BrokerMessage::V0(o) => match &o.content {
BrokerMessageContentV0::BrokerOverlayMessage(p) => p.is_response(),
BrokerMessageContentV0::BrokerResponse(_) => true,
BrokerMessageContentV0::BrokerRequest(_) => false,
},
BrokerMessage::Close => panic!("Close not implemented"),
}
}
pub fn id(&self) -> i64 {
match self {
BrokerMessage::V0(o) => match &o.content {
BrokerMessageContentV0::BrokerOverlayMessage(p) => p.id(),
BrokerMessageContentV0::BrokerResponse(r) => r.id(),
BrokerMessageContentV0::BrokerRequest(r) => r.id(),
},
BrokerMessage::Close => panic!("Close not implemented"),
}
}
pub fn set_id(&mut self, id: i64) {
match self {
BrokerMessage::V0(o) => match &mut o.content {
BrokerMessageContentV0::BrokerOverlayMessage(ref mut p) => p.set_id(id),
BrokerMessageContentV0::BrokerResponse(ref mut r) => r.set_id(id),
BrokerMessageContentV0::BrokerRequest(ref mut r) => r.set_id(id),
},
BrokerMessage::Close => panic!("Close not implemented"),
}
}
pub fn result(&self) -> u16 {
match self {
BrokerMessage::V0(o) => match &o.content {
BrokerMessageContentV0::BrokerOverlayMessage(p) => p.result(),
BrokerMessageContentV0::BrokerResponse(r) => r.result(),
BrokerMessageContentV0::BrokerRequest(_) => {
panic!("it is not a response");
}
},
BrokerMessage::Close => panic!("Close not implemented"),
}
}
pub fn is_overlay(&self) -> bool {
match self {
BrokerMessage::V0(o) => match &o.content {
BrokerMessageContentV0::BrokerOverlayMessage(p) => true,
BrokerMessageContentV0::BrokerResponse(r) => false,
BrokerMessageContentV0::BrokerRequest(r) => false,
},
BrokerMessage::Close => panic!("Close not implemented"),
}
}
pub fn response_block(&self) -> Option<&Block> {
match self {
BrokerMessage::V0(o) => match &o.content {
BrokerMessageContentV0::BrokerOverlayMessage(p) => p.block(),
BrokerMessageContentV0::BrokerResponse(r) => {
panic!("it doesn't have a response block. it is not an overlay response");
}
BrokerMessageContentV0::BrokerRequest(_) => {
panic!("it is not a response");
}
},
BrokerMessage::Close => panic!("Close not implemented"),
}
}
pub fn response_object_id(&self) -> ObjectId {
match self {
BrokerMessage::V0(o) => match &o.content {
BrokerMessageContentV0::BrokerOverlayMessage(p) => p.object_id(),
BrokerMessageContentV0::BrokerResponse(r) => {
panic!("it doesn't have a response ObjectId. it is not an overlay response");
}
BrokerMessageContentV0::BrokerRequest(_) => {
panic!("it is not a response");
}
},
BrokerMessage::Close => panic!("Close not implemented"),
}
}
}
//
// EXTERNAL REQUESTS
//
/// Request object(s) by ID from a repository by non-members
///
/// The request is sent by a non-member to an overlay member node,
/// which has a replica of the repository.
///
/// The response includes the requested objects and all their children recursively,
/// and optionally all object dependencies recursively.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ExtObjectGetV0 {
/// Repository to request the objects from
pub repo: PubKey,
/// List of Object IDs to request, including their children
pub ids: Vec<ObjectId>,
/// Whether or not to include all children recursively
pub include_children: bool,
/// Expiry time after which the link becomes invalid
pub expiry: Option<Timestamp>,
}
/// Request object(s) by ID from a repository by non-members
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ExtObjectGet {
V0(ExtObjectGetV0),
}
/// Branch heads request
pub type ExtBranchHeadsReq = BranchHeadsReq;
/// Branch synchronization request
pub type ExtBranchSyncReq = BranchSyncReq;
/// Content of ExtRequestV0
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ExtRequestContentV0 {
ExtObjectGet(ExtObjectGet),
ExtBranchHeadsReq(ExtBranchHeadsReq),
ExtBranchSyncReq(ExtBranchSyncReq),
}
/// External Request Payload V0
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ExtRequestPayload {
content: ExtRequestContentV0,
// ...
}
/// External request with its request ID
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ExtRequestV0 {
/// Request ID
pub id: i64,
/// Request payload
pub payload: ExtRequestPayload,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ExtRequest {
V0(ExtRequestV0),
}
impl ExtRequest {
pub fn id(&self) -> i64 {
match self {
ExtRequest::V0(v0) => v0.id,
}
}
pub fn set_id(&mut self, id: i64) {
match self {
ExtRequest::V0(v0) => {
v0.id = id;
}
}
}
}
/// Content of ExtResponseV0
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ExtResponseContentV0 {
Block(Block),
EventResp(EventResp),
Event(Event),
}
/// Response to an ExtRequest
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ExtResponseV0 {
/// Request ID
pub id: i64,
/// Result code
pub result: u16,
/// Response content
pub content: Option<ExtResponseContentV0>,
}
/// Response to an ExtRequest
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ExtResponse {
V0(ExtResponseV0),
}
impl ExtResponse {
pub fn id(&self) -> i64 {
match self {
ExtResponse::V0(v0) => v0.id,
}
}
pub fn set_id(&mut self, id: i64) {
match self {
ExtResponse::V0(v0) => {
v0.id = id;
}
}
}
}
impl TryFrom<ProtocolMessage> for ExtResponse {
type Error = ProtocolError;
fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
if let ProtocolMessage::ExtResponse(ext_res) = msg {
Ok(ext_res)
} else {
Err(ProtocolError::InvalidValue)
}
}
}
///
/// PROTOCOL MESSAGES
///
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ProtocolMessage {
Noise(Noise),
Start(StartProtocol),
ServerHello(ServerHello),
ClientAuth(ClientAuth),
AuthResult(AuthResult),
ExtRequest(ExtRequest),
ExtResponse(ExtResponse),
BrokerMessage(BrokerMessage),
}
impl ProtocolMessage {
pub fn id(&self) -> i64 {
match self {
ProtocolMessage::Noise(_) => 0,
ProtocolMessage::Start(_) => 0,
ProtocolMessage::ServerHello(_) => 0,
ProtocolMessage::ClientAuth(_) => 0,
ProtocolMessage::AuthResult(_) => 0,
ProtocolMessage::ExtRequest(ext_req) => ext_req.id(),
ProtocolMessage::ExtResponse(ext_res) => ext_res.id(),
ProtocolMessage::BrokerMessage(broker_msg) => broker_msg.id(),
}
}
pub fn set_id(&mut self, id: i64) {
match self {
ProtocolMessage::Noise(_) => panic!("cannot set ID"),
ProtocolMessage::Start(_) => panic!("cannot set ID"),
ProtocolMessage::ServerHello(_) => panic!("cannot set ID"),
ProtocolMessage::ClientAuth(_) => panic!("cannot set ID"),
ProtocolMessage::AuthResult(_) => panic!("cannot set ID"),
ProtocolMessage::ExtRequest(ext_req) => ext_req.set_id(id),
ProtocolMessage::ExtResponse(ext_res) => ext_res.set_id(id),
ProtocolMessage::BrokerMessage(broker_msg) => broker_msg.set_id(id),
}
}
pub fn type_id(&self) -> TypeId {
match self {
ProtocolMessage::Noise(a) => a.type_id(),
ProtocolMessage::Start(a) => a.type_id(),
ProtocolMessage::ServerHello(a) => a.type_id(),
ProtocolMessage::ClientAuth(a) => a.type_id(),
ProtocolMessage::AuthResult(a) => a.type_id(),
ProtocolMessage::ExtRequest(a) => a.type_id(),
ProtocolMessage::ExtResponse(a) => a.type_id(),
ProtocolMessage::BrokerMessage(a) => a.type_id(),
}
}
pub fn get_actor(&self) -> Box<dyn EActor> {
match self {
//ProtocolMessage::Noise(a) => a.get_actor(),
ProtocolMessage::Start(a) => a.get_actor(),
// ProtocolMessage::ServerHello(a) => a.get_actor(),
// ProtocolMessage::ClientAuth(a) => a.get_actor(),
// ProtocolMessage::AuthResult(a) => a.get_actor(),
// ProtocolMessage::ExtRequest(a) => a.get_actor(),
// ProtocolMessage::ExtResponse(a) => a.get_actor(),
// ProtocolMessage::BrokerMessage(a) => a.get_actor(),
_ => unimplemented!(),
}
}
}
///
/// AUTHENTICATION MESSAGES
///
/// Content of ClientAuthV0
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ClientAuthContentV0 {
/// User pub key
pub user: PubKey,
/// Client pub key
pub client: PubKey,
/// Nonce from ServerHello
#[serde(with = "serde_bytes")]
pub nonce: Vec<u8>,
}
/// Client authentication
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ClientAuthV0 {
/// Authentication data
pub content: ClientAuthContentV0,
/// Signature by client key
pub sig: Sig,
}
/// Client authentication
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ClientAuth {
V0(ClientAuthV0),
}
impl ClientAuth {
pub fn content_v0(&self) -> ClientAuthContentV0 {
match self {
ClientAuth::V0(o) => o.content.clone(),
}
}
pub fn sig(&self) -> Sig {
match self {
ClientAuth::V0(o) => o.sig,
}
}
pub fn user(&self) -> PubKey {
match self {
ClientAuth::V0(o) => o.content.user,
}
}
pub fn client(&self) -> PubKey {
match self {
ClientAuth::V0(o) => o.content.client,
}
}
pub fn nonce(&self) -> &Vec<u8> {
match self {
ClientAuth::V0(o) => &o.content.nonce,
}
}
}
impl From<ClientAuth> for ProtocolMessage {
fn from(msg: ClientAuth) -> ProtocolMessage {
ProtocolMessage::ClientAuth(msg)
}
}
/// Authentication result
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AuthResultV0 {
pub result: u16,
#[serde(with = "serde_bytes")]
pub metadata: Vec<u8>,
}
/// Authentication result
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum AuthResult {
V0(AuthResultV0),
}
impl AuthResult {
pub fn result(&self) -> u16 {
match self {
AuthResult::V0(o) => o.result,
}
}
pub fn metadata(&self) -> &Vec<u8> {
match self {
AuthResult::V0(o) => &o.metadata,
}
}
}
impl From<AuthResult> for ProtocolMessage {
fn from(msg: AuthResult) -> ProtocolMessage {
ProtocolMessage::AuthResult(msg)
}
}
//
// DIRECT / OUT-OF-BAND MESSAGES
//
/// Link/invitation to the repository
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RepoLinkV0 {
/// Repository public key ID
pub id: PubKey,
/// Repository secret
pub secret: SymKey,
/// Peers to connect to
pub peers: Vec<PeerAdvert>,
}
/// Link/invitation to the repository
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum RepoLink {
V0(RepoLinkV0),
}
impl RepoLink {
pub fn id(&self) -> PubKey {
match self {
RepoLink::V0(o) => o.id,
}
}
pub fn secret(&self) -> SymKey {
match self {
RepoLink::V0(o) => o.secret,
}
}
pub fn peers(&self) -> Vec<PeerAdvert> {
match self {
RepoLink::V0(o) => o.peers.clone(),
}
}
}
/// Link to object(s) or to a branch from a repository
/// that can be shared to non-members
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ObjectLinkV0 {
/// Request to send to an overlay peer
pub req: ExtRequest,
/// Keys for the root blocks of the requested objects
pub keys: Vec<ObjectRef>,
}
/// Link to object(s) or to a branch from a repository
/// that can be shared to non-members
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ObjectLink {
V0(ObjectLinkV0),
}
/// Owned repository with private key
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RepoKeysV0 {
/// Repository private key
pub key: PrivKey,
/// Repository secret
pub secret: SymKey,
/// Peers to connect to
pub peers: Vec<PeerAdvert>,
}
/// Owned repository with private key
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum RepoKeys {
V0(RepoKeysV0),
}