use std::future::Future;
use hopr_types::{
chain::chain_events::ChainEvent,
internal::prelude::{RedeemableTicket, Ticket},
primitive::prelude::Address,
};
use super::CompoundResult;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct NodeOnchainIdentity {
pub node_address: Address,
pub safe_address: Address,
pub module_address: Address,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ChainOutput<T> {
tx_hash: hopr_types::crypto::prelude::Hash,
output: Option<T>,
}
impl<T> ChainOutput<T> {
pub fn new(tx_hash: hopr_types::crypto::prelude::Hash, output: T) -> Self {
Self {
tx_hash,
output: output.into(),
}
}
pub fn tx_hash(&self) -> &hopr_types::crypto::prelude::Hash {
&self.tx_hash
}
pub fn output(&self) -> Option<&T> {
self.output.as_ref()
}
}
impl ChainOutput<()> {
pub fn new_empty(tx_hash: hopr_types::crypto::prelude::Hash) -> Self {
Self { tx_hash, output: None }
}
}
impl From<hopr_types::crypto::prelude::Hash> for ChainOutput<()> {
fn from(tx_hash: hopr_types::crypto::prelude::Hash) -> Self {
Self::new_empty(tx_hash)
}
}
pub type ChainEventResolver<ChainErr, WaitErr> = (
std::pin::Pin<Box<dyn Future<Output = CompoundResult<ChainEvent, ChainErr, WaitErr>> + Send + 'static>>,
futures::future::AbortHandle,
);
pub type EventWaitResult<ChainErr, WaitErr> = Result<ChainEventResolver<ChainErr, WaitErr>, ChainErr>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum AnnouncementOrigin {
Chain,
DHT,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AnnouncedPeer {
pub address: Address,
pub multiaddresses: Vec<crate::Multiaddr>,
pub origin: AnnouncementOrigin,
}
#[derive(Debug, Clone, strum::EnumIs, strum::EnumTryAs)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum TicketEvent {
WinningTicket(Box<RedeemableTicket>),
RejectedTicket(Box<Ticket>, Option<Address>),
}
#[cfg(test)]
mod tests {
use std::collections::HashSet;
use super::*;
#[test]
fn announcement_origin_should_be_usable_as_hash_key() {
let mut set = HashSet::new();
set.insert(AnnouncementOrigin::Chain);
set.insert(AnnouncementOrigin::DHT);
set.insert(AnnouncementOrigin::Chain);
assert_eq!(set.len(), 2);
}
#[test]
fn announcement_origin_copy_should_preserve_value() {
let origin = AnnouncementOrigin::Chain;
let copied = origin;
assert_eq!(origin, copied);
}
#[test]
fn announced_peer_should_support_equality() {
let addr = Address::default();
let peer_a = AnnouncedPeer {
address: addr,
multiaddresses: vec![],
origin: AnnouncementOrigin::Chain,
};
let peer_b = AnnouncedPeer {
address: addr,
multiaddresses: vec![],
origin: AnnouncementOrigin::Chain,
};
assert_eq!(peer_a, peer_b);
}
#[test]
fn announced_peers_with_different_origins_should_not_be_equal() {
let addr = Address::default();
let chain_peer = AnnouncedPeer {
address: addr,
multiaddresses: vec![],
origin: AnnouncementOrigin::Chain,
};
let dht_peer = AnnouncedPeer {
address: addr,
multiaddresses: vec![],
origin: AnnouncementOrigin::DHT,
};
assert_ne!(chain_peer, dht_peer);
}
#[test]
fn announced_peer_clone_should_be_independent() {
let addr = Address::default();
let peer = AnnouncedPeer {
address: addr,
multiaddresses: vec!["/ip4/1.2.3.4/tcp/9091".parse().unwrap()],
origin: AnnouncementOrigin::Chain,
};
let mut cloned = peer.clone();
cloned.multiaddresses.push("/ip4/5.6.7.8/tcp/9092".parse().unwrap());
assert_eq!(peer.multiaddresses.len(), 1);
assert_eq!(cloned.multiaddresses.len(), 2);
}
}