10 KiB
Delta 0.3.13-pre.002 — runtime resources multi-source bornées
Base requise
delivery précédente : 0.3.13-pre.001
Cargo base : 0.3.13-pre.1
delta base : deltas/0.3.13/pre.001.md
archive delta base : ksp-general-0.3.13-pre.001.zip
SHA-256 delta base : ca57546f19bd47b5d3b832a51905159497a5e601c186460db22b04364a1835c4
Le gate opérateur fourni après application de pre.001 est vert : fmt, audits Rust/Markdown, check workspace, Clippy strict, tests Worker, arbres normal/features et duplicates ont été exécutés sans anomalie signalée.
Objectif
Matérialiser le contrat pre.002 défini par le plan 034 sans démarrer prématurément les nouvelles familles live :
collection runtime privée bornée 1..32
identité logique déterministe par source
source discriminant capability-owned
validation globale avant spawn
rejet des doublons logiques
rejet cross-network
aucun nouveau client réseau
aucune nouvelle dépendance
Le supervisor simultané appartient toujours à pre.007.
Type de livraison
0.3.13-pre.002
Cargo : 0.3.13-pre.2
archive : ksp-general-0.3.13-pre.002.zip
Runtime resources multi-source
RawTransactionIngestRuntimeResources ne contient plus directement un unique champ Yellowstone. Il possède désormais une collection privée :
Vec<RawTransactionIngestLiveSource>
Le discriminant privé initial est :
Yellowstone(RawTransactionIngestYellowstoneSource)
Il est volontairement capability-owned ; aucun provider n'entre dans l'enum Worker.
Surface publique ajoutée :
MAX_RAW_TRANSACTION_INGEST_LIVE_SOURCES = 32
RawTransactionIngestRuntimeResources::source_count()
RawTransactionIngestRuntimeResources::try_push_yellowstone_source(...)
try_push_yellowstone_source est transactionnel : le candidat est entièrement rejeté sans mutation de la collection si la borne, le réseau ou l'identité logique sont invalides.
Identité logique Yellowstone
Chaque RawTransactionIngestYellowstoneSource possède maintenant un source_key: [u8; 32] privé.
Le hash SHA-256 est dérivé uniquement de données sûres :
KSP domain separator
source family = yellowstone
network
provider identity sûre
endpoint identity sûre
commitment
identité opaque de YellowstoneSubscribeRequest
Le rôle et le pool HTTP d'hydration sont volontairement exclus du source_key : ils ne définissent pas une nouvelle source live Yellowstone. Ainsi, deux subscriptions identiques ne deviennent pas artificiellement distinctes par simple changement de stratégie d'hydration.
Sont explicitement absents du matériau en clair et de Debug :
URL
API key / credential
header
transaction payload
remote error material
request identity bytes
source_key bytes/hash
Concernant source_key, le Debug de la source n'en publie que la longueur ; ses autres champs Debug restent les identités sûres déjà admises par le contrat stable. Le Debug de l'aggregate runtime publie seulement source_count.
Identité déterministe de SubscribeRequest dans Transport
ksp-onchain-transport-lib expose YellowstoneSubscribeRequestIdentity comme valeur opaque et YellowstoneSubscribeRequest::identity().
Canonicalisation de l'identité :
sept familles de filtres séparées
ordre déterministe fourni par les BTreeMap KSP
nom de filtre length-framed
protobuf exact de chaque filtre length-framed
options communes protobuf encodées après vidage des sept maps
Les bytes internes restent privés. L'identité implémente Hash afin que le Worker puisse l'incorporer à son SHA-256 sans escape hatch de sérialisation.
Aucune dépendance n'est ajoutée : le codage réutilise prost réexporté par yellowstone-grpc-proto, déjà dépendance de Transport.
Validation globale avant spawn
Avant activation, RawTransactionIngestRuntimeResources::validate_network impose :
collection non vide
source_count <= 32
chaque source sur le réseau Worker
source_key unique dans la collection
Les erreurs restent mappées sur le contrat stable ERROR_CODE_RAW_TRANSACTION_INGEST_RUNTIME_INVALID avec conditions internes stables, sans valeurs sensibles.
Gate volontaire d'activation multi-source
Le plan final exige que toutes les sources configurées soient démarrées simultanément. Cette responsabilité est explicitement réservée à pre.007.
Pour éviter un comportement faux en pre.002 :
1 source Yellowstone : voie productive stable conservée
2..32 sources : composition/validation possible
start avec 2..32 sources : fail closed avant spawn
jamais de démarrage silencieux de la première source seulement
Condition interne :
runtime_resources.multi_source_activation_pending
Ce gate sera supprimé uniquement par la tranche supervisor/source inventory.
Preuves déterministes ajoutées
Transport :
identité de request stable malgré ordre d'insertion
identité différente si le filtre logique change
Debug identité redacted
surface identité disponible depuis crate root
aucun bytes()/as_bytes() public
Worker :
source_key stable pour identité logique identique
source_key sensible au request fingerprint
source_key sensible à l'endpoint identity sûre
32 sources exactement acceptées
33e rejetée sans mutation
duplicate source identity rejetée
source cross-network rejetée
Debug aggregate limité à source_count
activation multi-source fail-closed avant pre.007
public API canary pour bound/count/push
release export inventory mis à jour
Compatibilité et non-régression
La construction historique :
RawTransactionIngestRuntimeResources::new(yellowstone_source)
reste valide et crée un aggregate d'une source.
La voie productive stable start_with_runtime_resources continue donc à fonctionner pour une seule source Yellowstone sans changement de Common RAW, Store, Config ni protocole réseau.
Fichiers ajoutés
deltas/0.3.13/pre.002.md
Fichiers modifiés
Cargo.toml
crates/ksp-onchain-transport-lib/src/grpc_subscribe.rs
crates/ksp-onchain-transport-lib/src/lib.rs
crates/ksp-onchain-transport-lib/tests/public_api.rs
crates/ksp-onchain-transport-lib/tests/release_completeness.rs
crates/ksp-onchain-transport-lib/unit_tests/grpc_subscribe.rs
crates/ksp-worker-raw-transaction-ingest-lib/src/lib.rs
crates/ksp-worker-raw-transaction-ingest-lib/src/runtime.rs
crates/ksp-worker-raw-transaction-ingest-lib/src/runtime_resources.rs
crates/ksp-worker-raw-transaction-ingest-lib/tests/public_api.rs
crates/ksp-worker-raw-transaction-ingest-lib/tests/release_completeness.rs
crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/runtime_resources.rs
docs/plans/034-V0_3_13_MULTI_SOURCE_LIVE_CONVERGENCE_PLAN.md
docs/validation/030-V0_3_13_MULTI_SOURCE_LIVE_CONVERGENCE.md
Fichiers supprimés
aucun
Versions de fichiers incrémentées
grpc_subscribe.rs transport src : 8 -> 9
transport lib.rs : 46 -> 47
transport public_api.rs : 51 -> 52
transport release_completeness.rs : 43 -> 44
transport unit grpc_subscribe.rs : 5 -> 6
worker lib.rs : 17 -> 18
worker runtime.rs : 11 -> 12
worker runtime_resources.rs : 12 -> 13
worker public_api.rs : 11 -> 12
worker release_completeness.rs : 9 -> 10
worker unit runtime_resources.rs : 11 -> 12
plan 034 : 1 -> 2
validation 030 : 1 -> 2
Audit intermédiaire et corrections
La première passe statique après introduction de l'identité Transport a détecté une rustdoc devenue non adjacente au YellowstoneSubscribeRequest. La structure documentaire a été corrigée avant poursuite.
Une passe ultérieure après ajout des canaris externes a détecté uniquement :
2 fins de fichier avec newline supplémentaire
1 double ligne vide entre items Rust
Ces trois écarts de format ont été corrigés avant la validation finale.
Aucun état intermédiaire en échec n'est présenté comme PASS.
Validations exécutées localement après correction finale
python3 scripts/audit_rust_workspace_rules.py
PASS : General Rust rule audit clean
PASS : Rust export completeness audit 0 candidate
PASS : KSP workspace Rust rule audit clean
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas
PASS : Markdown table audit clean (340 tables, 829 files)
supplemental normative definition-id scan
PASS : 489 definitions, 489 unique, 0 duplicate definition id
pre-packaging exhaustive diff scan
PASS : 14 fichiers modifiés, 1 ajouté, 0 supprimé
PASS : chaque header de version des 13 fichiers versionnés modifiés est incrémenté exactement de +1
PASS : aucune nouvelle occurrence de unsafe/unwrap/expect/panic/todo/unimplemented dans les lignes Rust production ajoutées
Les caches Python recréés par les scripts d'audit sont supprimés après la dernière passe et ne font pas partie de la livraison. L'archive delta est ensuite contrôlée par inventaire exact, test ZIP et scan des chemins/artefacts.
Validations non exécutées localement
Le toolchain Rust n'est pas installé dans l'environnement d'assemblage courant :
cargo fmt --all -- --check
cargo check --workspace
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test -p ksp-onchain-transport-lib
cargo test -p ksp-worker-raw-transaction-ingest-lib
cargo tree -p ksp-worker-raw-transaction-ingest-lib --edges normal
cargo tree -p ksp-worker-raw-transaction-ingest-lib -e features
cargo tree --duplicates
Statut : NON EXÉCUTÉ LOCAL, jamais PASS.
Décisions prises
conserver 1..32 comme borne runtime P0
source identity opaque et non publique côté Worker
faire posséder l'identité exacte SubscribeRequest par Transport
ne pas ajouter prost comme dépendance Worker/Transport supplémentaire
valider toutes les sources avant spawn
rejeter duplicate identity et cross-network avant mutation
fail closed pour activation >1 jusqu'à pre.007
ne pas démarrer un sous-ensemble silencieux
ne modifier ni Common RAW ni Store API
Questions ouvertes
Aucune nouvelle question bloquante pour pre.003.
Restent volontairement dans leurs tranches prévues :
logsSubscribe standard + hydration : pre.003
blockSubscribe standard : pre.004
Helius transactionSubscribe : pre.005
HTTP polling : pre.006
supervisor simultané / source inventory : pre.007
convergence globale / observations multiples : pre.008