Architecture du Mempool
Le mempool gère les transactions en attente, depuis leur admission jusqu'à leur notation et leur extraction pour la production de blocs.
Pipeline
Réseau (gossipsub /savitri/tx/1)
│
▼
Prévalidation (sans état)
│ format de signature, limites de taille
▼
Contrôle d'admission
│ vérification de quota, plafond par expéditeur
▼
Validation avec état
│ nonce, solde, limites de frais
▼
Notation par lot SIMD
│ fee * 0.7 + class * 0.3
▼
Cache de scores (LRU)
│
▼
Pool en attente
│
▼
drain_for_block_production()
│ top-N par score, final_validation
▼
Proposeur de bloc
Classes de transactions
| Classe | Priorité | Cas d'usage |
|---|---|---|
FederatedUpdate | 1,0 (la plus haute) | Mises à jour de modèles FL |
Financial | 0,8 | Transferts de tokens |
Governance | 0,7 | Votes, propositions |
IoTData | 0,5 | Données de capteurs |
Quotas d'admission
| Classe | Maximum en attente | Plafond par expéditeur |
|---|---|---|
| Financial | 50 000 | 512 |
| IoT | 100 000 | 512 |
| Global | 100 000 | 512 |
La fonction drain_fair_batch() appelle record_removal() pour décrémenter correctement les compteurs de classe lors de l'extraction des transactions (corrigé au Round 6).
Notation SIMD
Formule de score
score = fee_normalized * fee_weight + class_priority * class_weight
Par défaut : fee_weight = 0.7, class_weight = 0.3.
Implémentation spécifique à l'architecture
| Architecture | Intrinsèques | Voies | Lot minimum |
|---|---|---|---|
| x86_64 (AVX2+FMA) | _mm256_set1_pd, _mm256_fmadd_pd | 4 doubles | 32 |
| ARM (NEON) | vdupq_n_f64, vfmaq_f64 | 2 doubles | 32 |
| Repli | Boucle scalaire | 1 | Toujours |
Pour les lots de moins de 32 transactions, le calcul scalaire est utilisé car la surcharge d'initialisation SIMD dépasse le bénéfice.
Poids adaptatifs (optionnel)
Avec l'indicateur de fonctionnalité adaptive_weights, les poids s'ajustent selon :
- Distribution des frais : Si les frais sont concentrés au niveau élevé, augmenter fee_weight
- Diversité des classes : Si de nombreuses classes différentes, augmenter class_weight
- Débit historique : Ajustement basé sur les blocs récents
Paramètres :
base_fee_weight = 0.7
base_class_weight = 0.3
adaptation_rate = 0.1 (lissage)
fee_threshold_high = 2,000,000,000
fee_threshold_low = 500,000,000
class_diversity_threshold = 0.5
Cache de scores
Le cache LRU évite de recalculer les scores :
| Paramètre | Développement | Production |
|---|---|---|
| Taille du cache | 100 entrées | 10 000 entrées |
| TTL | 60 secondes | 300 secondes |
Gestion des nonces
Flux standard
- La transaction arrive avec le nonce N
- Vérification :
N >= account.storage_nonce - Suivi dans
pending_noncesHashMap lors de l'extraction - Validation du nonce après la finalisation du bloc
Tolérance aux écarts
Un écart de nonce jusqu'à 5000 est accepté pour la reprise après des blocages prolongés (augmenté de 1000 au Round 11).
Correctif de démarrage à froid
Lorsque storage_nonce=0 ET pending_nonces=0, le nonce disponible le plus bas est accepté comme point de départ. Cela gère le cas où des transactions ont été extraites mais le bloc n'a jamais été validé par un proposeur précédent.
Réinitialisation du nonce
Le générateur de transactions réinitialise le nonce local lorsque local_nonce > storage_nonce + 200 (MAX_NONCE_AHEAD). Auparavant, les nonces locaux pouvaient dériver à 2000+ alors que le stockage était à 84, entraînant le rejet de toutes les transactions.
Prévention des rejeux
Les hachages de transactions sont suivis pour prévenir les attaques par rejeu. Une fois qu'un hachage de transaction est vu, les soumissions en double sont rejetées.
Validation des frais
FeeLimits {
min_fee: 100_000_000_000_000, // 0.0001 SAVT
max_fee: 1_000_000_000_000_000_000, // 1.0 SAVT
}
Indicateurs de fonctionnalité
| Indicateur | Description |
|---|---|
simd | Notation optimisée SIMD (par défaut) |
cache | Cache de scores (par défaut) |
adaptive_weights | Ajustement dynamique des poids |