Files
2026-09-10 09:50:42 +02:00

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