diff --git a/src/network.rs b/src/network.rs index a141d15..0e888ce 100644 --- a/src/network.rs +++ b/src/network.rs @@ -1,20 +1,17 @@ use std::collections::HashMap; -use aes_gcm::aead::{Aead, Payload}; -use aes_gcm::{Aes256Gcm, KeyInit}; -use anyhow::{Error, Result}; -use js_sys::Date; +use anyhow::Result; use rand::{thread_rng, RngCore}; use serde::{Deserialize, Serialize}; -use serde_json::{Map, Value}; +use serde_json::Value; use sp_client::bitcoin::consensus::serialize; -use sp_client::bitcoin::hex::{DisplayHex, FromHex}; +use sp_client::bitcoin::hex::DisplayHex; use sp_client::bitcoin::{OutPoint, Transaction}; use tsify::Tsify; -use crate::crypto::AAD; use crate::error::AnkError; use crate::pcd::{Member, RoleDefinition}; +use crate::process::Process; use crate::signature::Proof; #[derive(Debug, Serialize, Deserialize, Tsify)] @@ -24,7 +21,7 @@ pub enum AnkFlag { Faucet, Cipher, Commit, - Init, + Handshake, Unknown, } @@ -35,7 +32,7 @@ impl From<&str> for AnkFlag { "Faucet" => Self::Faucet, "Cipher" => Self::Cipher, "Commit" => Self::Commit, - "Init" => Self::Init, + "Handshake" => Self::Handshake, _ => Self::Unknown, } } @@ -54,7 +51,7 @@ impl AnkFlag { 1 => Self::Faucet, 2 => Self::Cipher, 3 => Self::Commit, - 4 => Self::Init, + 4 => Self::Handshake, _ => Self::Unknown, } } @@ -65,7 +62,7 @@ impl AnkFlag { Self::Faucet => "Faucet", Self::Cipher => "Cipher", Self::Commit => "Commit", - Self::Init => "Init", + Self::Handshake => "Handshake", Self::Unknown => "Unknown", } } @@ -171,6 +168,28 @@ impl NewTxMessage { } } +#[derive(Debug, PartialEq, Serialize, Deserialize, Tsify)] +#[tsify(into_wasm_abi, from_wasm_abi)] +pub struct HandshakeMessage { + pub sp_address: String, + pub peers_list: HashMap, + pub processes_list: HashMap, +} + +impl HandshakeMessage { + pub fn new(sp_address: String, peers_list: HashMap, processes_list: HashMap) -> Self { + Self { + sp_address, + peers_list, + processes_list, + } + } + + pub fn to_string(&self) -> String { + serde_json::to_string(self).unwrap() + } +} + #[derive(Debug, Serialize, Deserialize)] pub struct Envelope { pub flag: AnkFlag, diff --git a/src/pcd.rs b/src/pcd.rs index b6cbef0..80067ab 100644 --- a/src/pcd.rs +++ b/src/pcd.rs @@ -1,6 +1,7 @@ use anyhow::{Error, Result}; use rs_merkle::{algorithms::Sha256, MerkleTree}; use std::collections::{HashMap, HashSet}; +use std::hash::{Hash as StdHash, Hasher}; use aes_gcm::{ aead::{Aead, Payload}, @@ -22,12 +23,34 @@ use crate::{ signature::{AnkHash, AnkValidationNoHash, AnkValidationYesHash, Proof}, }; -#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Tsify)] +#[derive(Debug, Default, Clone, Serialize, Deserialize, Tsify)] #[tsify(into_wasm_abi, from_wasm_abi)] pub struct Member { sp_addresses: Vec, } +impl PartialEq for Member { + fn eq(&self, other: &Self) -> bool { + let self_set: HashSet<_> = self.sp_addresses.iter().collect(); + let other_set: HashSet<_> = other.sp_addresses.iter().collect(); + self_set == other_set + } +} + +impl Eq for Member {} + +impl StdHash for Member { + fn hash(&self, state: &mut H) { + // Convert to a set to ensure order independence + let set: HashSet<_> = self.sp_addresses.iter().collect(); + let mut unique_items: Vec<_> = set.into_iter().collect(); + unique_items.sort_unstable(); // Sort to ensure consistent hashing + for item in unique_items { + item.hash(state); + } + } +} + impl Member { pub fn new(sp_addresses: Vec) -> Result { if sp_addresses.is_empty() { diff --git a/src/prd.rs b/src/prd.rs index 52e80d8..18cedb0 100644 --- a/src/prd.rs +++ b/src/prd.rs @@ -27,6 +27,7 @@ pub enum PrdType { Response, // Validate (or disagree) with a prd update Confirm, // Confirm we received an update TxProposal, // Send a psbt asking for recipient signature + Request // asks for the prd update for some state, } sha256t_hash_newtype! { @@ -51,7 +52,7 @@ impl AnkPrdHash { } } -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Tsify)] +#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize, Tsify)] #[tsify(into_wasm_abi, from_wasm_abi)] #[allow(non_camel_case_types)] pub struct Prd { @@ -86,7 +87,7 @@ impl Prd { pub fn new_update( root_commitment: OutPoint, - sender: String, // Should take Member as argument + sender: Member, roles: HashMap, keys: Map, pcd_commitments: Value, @@ -94,7 +95,7 @@ impl Prd { Self { prd_type: PrdType::Update, root_commitment: root_commitment.to_string(), - sender, + sender: serde_json::to_string(&sender).unwrap(), validation_tokens: vec![], keys, pcd_commitments, @@ -105,14 +106,14 @@ impl Prd { pub fn new_response( root_commitment: OutPoint, - sender: String, + sender: Member, validation_tokens: Vec, pcd_commitments: Value, ) -> Self { Self { prd_type: PrdType::Response, root_commitment: root_commitment.to_string(), - sender, + sender: serde_json::to_string(&sender).unwrap(), validation_tokens: validation_tokens, keys: Map::new(), pcd_commitments, @@ -138,6 +139,16 @@ impl Prd { } } + pub fn new_request(root_commitment: OutPoint, sender: Member, state_ids: Vec<[u8; 32]>) -> Self { + Self { + prd_type: PrdType::Request, + root_commitment: root_commitment.to_string(), + sender: serde_json::to_string(&sender).unwrap(), + payload: serde_json::to_string(&state_ids).unwrap(), + ..Default::default() + } + } + pub fn extract_from_message(plain: &[u8], local_address: SilentPaymentAddress) -> Result { let prd: Prd = serde_json::from_slice(plain)?;