docs: enrichir la spécification technique avec les types de messages détaillés - Ajout de l'architecture des messages avec Envelope et AnkFlag - Documentation complète de tous les types de messages (Handshake, NewTx, Commit, Faucet, Cipher, Sync, Unknown) - Description détaillée des champs et structures de données - Exemples JSON des formats de messages - Documentation du cache de messages et des types de broadcast - Ajout des types de données complexes (Member, Process, Pcd, Roles, Proof, etc.) - Explication du traitement des messages et de la déduplication
This commit is contained in:
parent
6bf36d4559
commit
cf390e5fb7
@ -320,27 +320,294 @@ fn check_transaction_alone(
|
||||
|
||||
### 5. Module message.rs - Gestion des messages WebSocket
|
||||
|
||||
#### Structure des messages
|
||||
#### Architecture des messages
|
||||
|
||||
Le système de messages de `sdk_relay` utilise une architecture en couches avec des enveloppes (`Envelope`) qui encapsulent différents types de messages selon leur flag.
|
||||
|
||||
#### Structure Envelope
|
||||
|
||||
```rust
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum MessageType {
|
||||
Handshake(HandshakeMessage),
|
||||
NewTx(NewTxMessage),
|
||||
Broadcast(BroadcastMessage),
|
||||
BalanceUpdate(BalanceUpdateMessage),
|
||||
TxDetected(TxDetectedMessage),
|
||||
pub struct Envelope {
|
||||
pub flag: AnkFlag, // Type de message
|
||||
pub content: String, // Contenu JSON du message
|
||||
}
|
||||
```
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#### Types de messages (AnkFlag)
|
||||
|
||||
```rust
|
||||
#[derive(Debug, Serialize, Deserialize, Tsify)]
|
||||
pub enum AnkFlag {
|
||||
NewTx, // 0 - Transaction Bitcoin
|
||||
Faucet, // 1 - Service de faucet
|
||||
Cipher, // 2 - Messages chiffrés
|
||||
Commit, // 3 - Messages de commit
|
||||
Handshake, // 4 - Poignée de main initiale
|
||||
Sync, // 5 - Synchronisation (non implémenté)
|
||||
Unknown, // - Messages inconnus
|
||||
}
|
||||
```
|
||||
|
||||
#### 1. Message Handshake (AnkFlag::Handshake)
|
||||
|
||||
**Structure :**
|
||||
```rust
|
||||
#[derive(Debug, Serialize, Deserialize, Tsify)]
|
||||
pub struct HandshakeMessage {
|
||||
pub version: String,
|
||||
pub capabilities: Vec<String>,
|
||||
pub sp_address: String, // Adresse Silent Payment du client
|
||||
pub peers_list: OutPointMemberMap, // Liste des pairs connectés
|
||||
pub processes_list: OutPointProcessMap, // Liste des processus actifs
|
||||
pub chain_tip: u32, // Hauteur actuelle de la blockchain
|
||||
}
|
||||
```
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
**Champs détaillés :**
|
||||
- **sp_address** : Adresse Silent Payment du client qui se connecte
|
||||
- **peers_list** : Map des pairs connectés (OutPoint → Member)
|
||||
- **processes_list** : Map des processus actifs (OutPoint → Process)
|
||||
- **chain_tip** : Hauteur de la blockchain pour synchronisation
|
||||
|
||||
**Utilisation :** Échange initial lors de la connexion WebSocket pour synchroniser l'état
|
||||
|
||||
#### 2. Message NewTx (AnkFlag::NewTx)
|
||||
|
||||
**Structure :**
|
||||
```rust
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize, Tsify)]
|
||||
pub struct NewTxMessage {
|
||||
pub transaction: String, // Transaction hex
|
||||
pub transaction: String, // Transaction Bitcoin en hex
|
||||
pub tweak_data: Option<String>, // Données de tweak Silent Payment
|
||||
pub error: Option<AnkError>, // Erreur éventuelle
|
||||
}
|
||||
```
|
||||
|
||||
**Champs détaillés :**
|
||||
- **transaction** : Transaction Bitcoin sérialisée en format hexadécimal
|
||||
- **tweak_data** : Données de tweak pour les Silent Payments (optionnel)
|
||||
- **error** : Erreur éventuelle lors du traitement
|
||||
|
||||
**Utilisation :** Diffusion de nouvelles transactions Bitcoin à tous les pairs
|
||||
|
||||
#### 3. Message Commit (AnkFlag::Commit)
|
||||
|
||||
**Structure :**
|
||||
```rust
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Tsify)]
|
||||
pub struct CommitMessage {
|
||||
pub process_id: OutPoint, // Identifiant du processus
|
||||
pub pcd_commitment: PcdCommitments, // Engagements PCD
|
||||
pub roles: Roles, // Rôles des participants
|
||||
pub public_data: Pcd, // Données publiques
|
||||
pub validation_tokens: Vec<Proof>, // Tokens de validation
|
||||
pub error: Option<AnkError>, // Erreur éventuelle
|
||||
}
|
||||
```
|
||||
|
||||
**Champs détaillés :**
|
||||
- **process_id** : Identifiant unique du processus (OutPoint)
|
||||
- **pcd_commitment** : Map des engagements PCD (champ → hash)
|
||||
- **roles** : Définition des rôles et permissions
|
||||
- **public_data** : Données publiques du processus
|
||||
- **validation_tokens** : Preuves cryptographiques de validation
|
||||
- **error** : Erreur éventuelle lors du traitement
|
||||
|
||||
**Utilisation :** Gestion des processus collaboratifs et de leurs états
|
||||
|
||||
#### 4. Message Faucet (AnkFlag::Faucet)
|
||||
|
||||
**Structure :**
|
||||
```rust
|
||||
#[derive(Debug, Serialize, Deserialize, Tsify)]
|
||||
pub struct FaucetMessage {
|
||||
pub sp_address: String, // Adresse Silent Payment
|
||||
pub commitment: String, // Engagement cryptographique
|
||||
pub error: Option<AnkError>, // Erreur éventuelle
|
||||
}
|
||||
```
|
||||
|
||||
**Champs détaillés :**
|
||||
- **sp_address** : Adresse Silent Payment du demandeur
|
||||
- **commitment** : Engagement cryptographique pour éviter les abus
|
||||
- **error** : Erreur éventuelle lors du traitement
|
||||
|
||||
**Utilisation :** Service de faucet pour obtenir des fonds de test
|
||||
|
||||
#### 5. Message Cipher (AnkFlag::Cipher)
|
||||
|
||||
**Structure :** Le contenu est une chaîne JSON contenant des données chiffrées.
|
||||
|
||||
**Champs détaillés :**
|
||||
- **content** : Données chiffrées en format hexadécimal
|
||||
|
||||
**Utilisation :** Communication chiffrée entre pairs pour les messages privés
|
||||
|
||||
#### 6. Message Sync (AnkFlag::Sync)
|
||||
|
||||
**Structure :** Non implémentée actuellement (todo!)
|
||||
|
||||
**Utilisation :** Synchronisation avancée entre pairs (futur)
|
||||
|
||||
#### 7. Message Unknown (AnkFlag::Unknown)
|
||||
|
||||
**Structure :** Messages de type inconnu
|
||||
|
||||
**Utilisation :** Gestion des messages non reconnus
|
||||
|
||||
#### Cache de messages
|
||||
|
||||
```rust
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct MessageCache {
|
||||
store: Mutex<HashMap<String, Instant>>,
|
||||
}
|
||||
```
|
||||
|
||||
**Fonctionnalités :**
|
||||
- **Déduplication** : Évite le traitement multiple du même message
|
||||
- **Expiration** : Messages supprimés après 20 secondes
|
||||
- **Nettoyage automatique** : Toutes les 5 secondes
|
||||
|
||||
#### Types de broadcast
|
||||
|
||||
```rust
|
||||
pub(crate) enum BroadcastType {
|
||||
Sender(SocketAddr), // Envoi au seul expéditeur
|
||||
ExcludeSender(SocketAddr), // Envoi à tous sauf l'expéditeur
|
||||
ToAll, // Envoi à tous les pairs
|
||||
}
|
||||
```
|
||||
|
||||
#### Types de données complexes
|
||||
|
||||
##### OutPointMemberMap et OutPointProcessMap
|
||||
|
||||
```rust
|
||||
// Map des pairs connectés
|
||||
pub type OutPointMemberMap = HashMap<OutPoint, Member>;
|
||||
|
||||
// Map des processus actifs
|
||||
pub type OutPointProcessMap = HashMap<OutPoint, Process>;
|
||||
```
|
||||
|
||||
##### Structure Member
|
||||
|
||||
```rust
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Tsify)]
|
||||
pub struct Member {
|
||||
pub outpoint: OutPoint, // Identifiant unique du membre
|
||||
pub public_key: PublicKey, // Clé publique du membre
|
||||
pub balance: Amount, // Solde actuel
|
||||
pub last_commit: Option<Commit>, // Dernier commit effectué
|
||||
}
|
||||
```
|
||||
|
||||
##### Structure Process
|
||||
|
||||
```rust
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Tsify)]
|
||||
pub struct Process {
|
||||
pub process_id: OutPoint, // Identifiant du processus
|
||||
pub state_id: [u8; 32], // ID de l'état actuel
|
||||
pub roles: Roles, // Rôles des participants
|
||||
pub public_data: Pcd, // Données publiques
|
||||
pub validation_tokens: Vec<Proof>, // Tokens de validation
|
||||
}
|
||||
```
|
||||
|
||||
##### Structure Pcd (Process Control Data)
|
||||
|
||||
```rust
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Tsify)]
|
||||
pub struct Pcd {
|
||||
pub fields: HashMap<String, Field>, // Champs de données
|
||||
pub validation_rules: Vec<ValidationRule>, // Règles de validation
|
||||
}
|
||||
```
|
||||
|
||||
##### Structure Roles
|
||||
|
||||
```rust
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Tsify)]
|
||||
pub struct Roles {
|
||||
pub role_definitions: HashMap<String, RoleDefinition>, // Définitions des rôles
|
||||
}
|
||||
```
|
||||
|
||||
##### Structure Proof
|
||||
|
||||
```rust
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
pub struct Proof {
|
||||
signature: Signature, // Signature Schnorr
|
||||
message: [u8; 32] // Hash du message signé
|
||||
}
|
||||
```
|
||||
|
||||
##### Structure PcdCommitments
|
||||
|
||||
```rust
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Tsify)]
|
||||
pub struct PcdCommitments {
|
||||
pub commitments: HashMap<String, [u8; 32]>, // Map champ → hash
|
||||
}
|
||||
```
|
||||
|
||||
#### Format des messages JSON
|
||||
|
||||
##### Exemple Handshake
|
||||
|
||||
```json
|
||||
{
|
||||
"flag": "Handshake",
|
||||
"content": "{\"sp_address\":\"sp1...\",\"peers_list\":{},\"processes_list\":{},\"chain_tip\":123456}"
|
||||
}
|
||||
```
|
||||
|
||||
##### Exemple NewTx
|
||||
|
||||
```json
|
||||
{
|
||||
"flag": "NewTx",
|
||||
"content": "{\"transaction\":\"02000000...\",\"tweak_data\":null,\"error\":null}"
|
||||
}
|
||||
```
|
||||
|
||||
##### Exemple Commit
|
||||
|
||||
```json
|
||||
{
|
||||
"flag": "Commit",
|
||||
"content": "{\"process_id\":\"...\",\"pcd_commitment\":{},\"roles\":{},\"public_data\":{},\"validation_tokens\":[],\"error\":null}"
|
||||
}
|
||||
```
|
||||
|
||||
#### Traitement des messages
|
||||
|
||||
```rust
|
||||
pub fn process_message(raw_msg: &str, addr: SocketAddr) {
|
||||
// Vérification du cache pour éviter les doublons
|
||||
let cache = MESSAGECACHE.get().expect("Cache should be initialized");
|
||||
if cache.contains(raw_msg) {
|
||||
log::debug!("Message already processed, dropping");
|
||||
return;
|
||||
} else {
|
||||
cache.insert(raw_msg.to_owned());
|
||||
}
|
||||
|
||||
// Parsing de l'enveloppe
|
||||
match serde_json::from_str::<Envelope>(raw_msg) {
|
||||
Ok(ank_msg) => match ank_msg.flag {
|
||||
AnkFlag::Faucet => process_faucet_message(ank_msg, addr),
|
||||
AnkFlag::NewTx => process_new_tx_message(ank_msg, addr),
|
||||
AnkFlag::Cipher => process_cipher_message(ank_msg, addr),
|
||||
AnkFlag::Commit => process_commit_message(ank_msg, addr),
|
||||
AnkFlag::Unknown => process_unknown_message(ank_msg, addr),
|
||||
AnkFlag::Sync => todo!(),
|
||||
AnkFlag::Handshake => log::debug!("Received init message from {}", addr),
|
||||
},
|
||||
Err(_) => log::error!("Failed to parse network message"),
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user