Files
khadhroony-solana-project/docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md
2026-08-24 08:37:36 +02:00

16 KiB

Validation 0.2.9 — Yellowstone gRPC standard/provider-neutral

Statut : matrice ouverte par 0.2.9-pre.001. Les colonnes DONE ne seront cochées qu'après preuves réellement exécutées. Le gate d'ouverture a audité le proto/service, les licences, les dépendances et les fournisseurs live gratuits ; il n'a pas ajouté de client gRPC de production.

1. Autorités du gate

Base interne :

v0.2.8 / archive Gitea stable fournie
workspace.package.version initial = 0.2.8
deltas/0.2.8/rel.001.md
prompts/014-V0_2_9_START_PROMPT.md

Sources upstream auditées le 2026-08-23 :

https://github.com/rpcpool/yellowstone-grpc/releases
https://github.com/rpcpool/yellowstone-grpc/blob/master/CHANGELOG.md
https://github.com/rpcpool/yellowstone-grpc/blob/master/LICENSING.md
https://github.com/rpcpool/yellowstone-grpc/blob/master/yellowstone-grpc-proto/proto/geyser.proto
https://github.com/rpcpool/yellowstone-grpc/blob/master/yellowstone-grpc-proto/proto/solana-storage.proto
https://docs.rs/crate/yellowstone-grpc-client/latest
https://docs.rs/crate/yellowstone-grpc-proto/latest

Divergence enregistrée :

snapshot du prompt : GitHub release v14.2.2+solana.4.1.0
réaudit courant    : GitHub release v15.1.2+solana.4.2.0 (2026-08-18)
crate client       : 13.3.0
crate proto        : 12.6.0

2. Baseline stable

Gate Preuve État
cargo fmt --all log opérateur v0.2.8 DONE
audit Rust workspace clean DONE
cargo check --workspace log opérateur DONE
cargo clippy --workspace --all-targets log opérateur DONE
cargo test --workspace log opérateur DONE
Transport unit 335 passed DONE
Transport public API 41 passed DONE
Transport release completeness 34 passed DONE
Transport doctests 4 passed DONE
cargo tree -p ksp-onchain-transport-lib log opérateur DONE
cargo tree --duplicates log opérateur DONE

3. Matrice service Geyser

RPC Forme Classification Scope Preuve cible État
Subscribe bidi standard IN fixture locale + live TODO
SubscribeDeshred bidi Triton extension/pré-exécution malgré présence proto OUT canari d'absence/API TODO
SubscribeReplayInfo unary standard IN fixture unary TODO
Ping unary standard IN fixture unary TODO
GetLatestBlockhash unary standard IN fixture unary TODO
GetBlockHeight unary standard IN fixture unary TODO
GetSlot unary standard IN fixture unary TODO
IsBlockhashValid unary standard IN fixture unary TODO
GetVersion unary standard IN fixture unary TODO

4. SubscribeRequest — coverage normative

4.1 Top-level

Champ Sémantique Scope Preuve
accounts map filter-name -> account filter IN exact wire + bounds
slots map -> slot filter IN exact wire
transactions map -> transaction filter IN exact wire + bounds
transactions_status map -> transaction filter IN exact wire + bounds
blocks map -> block filter IN exact wire + bounds
blocks_meta map -> empty filter IN presence/empty semantics
entry map -> empty filter IN presence/empty semantics
commitment optional Processed/Confirmed/Finalized IN omitted/value exact
accounts_data_slice repeated offset/length IN order + bounds
ping optional id IN Ping/Pong lifecycle
from_slot optional u64 IN reconnect/replay tests

4.2 Accounts

Capacité Scope Preuve
account[] IN order/cardinality/address validation
owner[] IN order/cardinality/address validation
filters[] IN AND semantics preserved structurally
nonempty_txn_signature? IN omitted/false/true
cuckoo_accounts_filter? IN exact wire + dimension/data bounds
memcmp bytes IN exact bytes + bounds
memcmp base58 IN exact string + validation
memcmp base64 IN exact string + validation
datasize IN exact u64
token_account_state IN bool
lamports eq/ne/lt/gt IN oneof exact

4.3 Slots

Capacité Scope Preuve
filter_by_commitment? IN optional semantics
interslot_updates? IN optional semantics
processed/confirmed/finalized IN enum decode
first_shred_received/completed/created_bank/dead IN enum decode + dead_error

4.4 Transactions / transaction_status

Capacité Scope Preuve
vote? IN optional semantics
failed? IN optional semantics
signature? IN exact/validated
account_include[] IN order/bounds
account_exclude[] IN order/bounds
account_required[] IN order/bounds
cuckoo_account_include? IN exact wire + bounds
token_accounts? = ALL IN optional enum
token_accounts? = BALANCE_CHANGED IN optional enum

4.5 Blocks

Capacité Scope Preuve
account_include[] IN order/bounds
include_transactions? IN optional semantics
include_accounts? IN optional semantics
include_entries? IN optional semantics
cuckoo_account_include? IN exact wire + bounds

5. SubscribeUpdate — coverage normative

Variante Champs structurants Scope Preuve
account account info, slot, is_startup IN exact decode
slot slot, parent?, status, dead_error? IN exact decode
transaction signature, vote, transaction, meta, index, slot IN exact decode
transaction_status slot, signature, vote, index, err IN exact decode
block hash/rewards/time/height/parents/counts + tx/accounts/entries IN exact decode + bounds
ping marker IN lifecycle
pong id IN lifecycle
block_meta metadata/counts IN exact decode
entry slot/index/hash/counts IN exact decode

Top-level à préserver :

filters[]
created_at
oneof absent/inconnu -> comportement explicitement testé

6. solana-storage.proto — nested wire utile

Le backend doit préserver les champs nécessaires des structures imbriquées actuelles, sans exposer les types upstream comme contrat public :

ConfirmedBlock
ConfirmedTransaction
Transaction
Message
MessageHeader
MessageAddressTableLookup
TransactionStatusMeta
TransactionError
InnerInstructions / InnerInstruction
CompiledInstruction
TokenBalance / UiTokenAmount
ReturnData
Reward / Rewards
UnixTimestamp
BlockHeight
NumPartitions

États optionnels/legacy particulièrement sensibles :

compute_units_consumed?
cost_units?
inner_instructions_none
log_messages_none
return_data_none
loaded writable/readonly addresses
commission / commission_bps

Preuve cible : fixtures issues du wire Protobuf + cas old/current + malformed/oversized, sans conversion JSON arbitraire.

7. Unary RPC matrix

RPC Request exact Response exact État
ReplayInfo empty first_available? TODO
Ping count count TODO
LatestBlockhash commitment? slot/hash/last_valid_height TODO
BlockHeight commitment? block_height TODO
Slot commitment? slot TODO
IsBlockhashValid blockhash + commitment? slot + bool TODO
Version empty version TODO

8. Dépendances / licence

Gate Décision pre.001 Preuve suivante
repository default AGPL-3.0-only LICENSING.md
client subtree Apache-2.0 LICENSING.md
proto subtree Apache-2.0 LICENSING.md
strategy A client+proto rejetée comme default documenté
strategy B proto+Tonic KSP retenue pre.002 compile/tree
strategy C vendored proto fallback seulement aucun vendoring pre.001
system protoc non attendu avec crate publiée vérifier build réel
raw upstream types public interdit par défaut public API canary
executable Yellowstone deps interdit dependency firewall

Versions observées :

yellowstone-grpc-client 13.3.0
yellowstone-grpc-proto  12.6.0
tonic                   0.14.x (0.14.6 latest observé)
prost/prost-types       0.14.x (0.14.4 latest observé)

9. Architecture / ownership

Invariant Preuve cible État
backend gRPC distinct HTTP/WS source/API canary TODO
aucun WsProtocolKind gRPC source scan TODO
Transport owns gRPC dependency graph TODO
Config -> Transport seulement ownership test TODO
Transport -X-> Config ownership test TODO
Transport -X-> std::env KSP_* ownership test TODO
Logging façade KSP only logging ownership TODO
no raw Tonic client escape hatch public API canary TODO
no provider-specific public types public API/completeness TODO

10. Settings, bounds et redaction

À fermer par tests :

endpoint schemes TLS/non-TLS explicitement validés
connect timeout > 0
unary timeout > 0
close timeout > 0
max inbound/outbound > 0 et plafonnés
request/update queue capacities > 0 et plafonnées
reconnect attempt/backoff bornés
filter-group count
filter-name length/uniqueness
metadata key/value count/size
account/owner/include/exclude/required counts
memcmp/data slice bounds
Cuckoo dimensions/data bounds

Security canaries :

endpoint URL Debug redacted
secret metadata Debug/Display absent
Status message/details distants non recopiés aveuglément en context
TLS/connect error sans credential/URI sensible
request/update Debug sans payload arbitraire sensible
snapshot sans endpoint secret ni remote internals inutiles

11. Lifecycle / backpressure / replay

Cas Attendu État
stream open session bornée TODO
request mutation ordre déterministe TODO
server Ping -> client request ping -> Pong explicite TODO
server half-close terminal/reconnect selon policy TODO
client close cleanup borné TODO
receiver drop cleanup capacité TODO
slow subscription pas de queue infinie TODO
inbound oversized rejet avant allocation excessive TODO
outbound oversized rejet avant write TODO
reconnect budget borné TODO
resubscribe order déterministe TODO
from_slot utilisé sans promesse lossless TODO
ReplayInfo informatif TODO
duplicates observables TODO
gaps observables TODO
divergent node history couverture documentée TODO
shutdown during reconnect aucune nouvelle connexion après shutdown TODO

Claims interdits sans nouvelle preuve :

exactly-once
lossless
historical replay complet
ordre global sans gap

12. Config V3

Décision de gate :

V1 HTTP reste lisible
V2 HTTP+WS reste lisible
V3 ajoute gRPC explicitement

Shape conceptuelle à matérialiser :

globals.grpc_defaults
profiles[].grpc_endpoints[]
endpoint.metadata[]         # public/non-secret
endpoint.secret_metadata[]  # Config-owned secret provenance

Canaries :

Gate État
V1 backward readable TODO
V2 backward readable TODO
V3 schema strict TODO
gRPC endpoint mapping TODO
secret provenance enforced TODO
safe projection redacted TODO
no Transport -> Config TODO
.env.example inventory if new env vars TODO

13. Fournisseurs live gratuits / durables

Provider Cluster gRPC gratuit confirmé Nature Priorité 0.2.9 Verdict
PublicNode / Allnodes-backed Mainnet + Testnet endpoint public, pas de plan payant requis observé 1 IN smoke
OrbitFlare Devnet Free $0, 10 RPS/1 TPS, unlimited credits 2 IN smoke secondaire
Tatum Mainnet Free durable mais 100K lifetime credits, 5 subscriptions 3 opérateur optionnel
Helius aucun sur Free Devnet Developer, Mainnet Business OUT free
Shyft aucun sur Free Free indique No gRPC Access OUT free
Alchemy aucun sur Free PAYG/Enterprise requis OUT free
QuickNode aucun sur Free Scale/Business ou add-on payant OUT free
Chainstack aucun sur Free add-on Yellowstone payant, Growth+ OUT free
ERPC aucun durable plan Geyser payant, trial 1 jour OUT free
NodeFlare endpoint gRPC présent plan Yellowstone mensuel payant OUT free
Bitquery pas Yellowstone standard CoreCast custom, stream gratuit non garanti OUT 0.2.9
Solinfra non confirmé free tier + Yellowstone annoncés, entitlement gRPC free non explicite recheck CANDIDAT

Sources provider :

https://publicnode.com/
https://solana-yellowstone-grpc.publicnode.com/
https://orbitflare.com/pricing
https://docs.tatum.io/reference/solana-grpc
https://tatum.io/pricing
https://www.helius.dev/pricing
https://shyft.to/solana-rpc-grpc-pricing
https://www.alchemy.com/docs/reference/yellowstone-grpc-quickstart
https://www.quicknode.com/docs/solana/solana-grpc/overview
https://chainstack.com/pricing/
https://erpc.global/en/grpc/
https://nodeflare.app/solana
https://docs.bitquery.io/docs/grpc/solana/introduction/
https://solinfra.dev/

Smoke PublicNode

Cible principale officiellement affichée :

solana-yellowstone-grpc.publicnode.com:443

Testnet GRPC est officiellement listé. L'endpoint exact doit être confirmé avant commit d'un profil durable.

Smoke OrbitFlare

Credential : jamais versionné. La clé/header gRPC exacte doit être confirmée depuis la documentation/live au moment du smoke ; le contrat Transport reste generic secret metadata.

14. Non-régressions obligatoires

Surface héritée Attendu final État
HTTP current 52 typed TODO final
HTTP historical 14 Deprecated/Removed TODO final
Standard WS 18 opérations / 9 familles TODO final
Helius WS 7 standard + transaction TODO final
Helius heartbeat Ping 60 s TODO final
Config V1/V2 backward read TODO final
Wallet/Wallet Desk aucune dépendance protocolaire Yellowstone directe TODO final

15. Forecast / preuve par tranche

pre.001 DONE  audit + matrices + dependencies/license + providers + sizing
pre.002 TODO  deps/settings/errors/facade + cargo tree
pre.003 TODO  TLS/metadata + local fixture + 7 unary
pre.004 TODO  Subscribe common + Cuckoo/token/from_slot/bounds
pre.005 TODO  accounts + slots
pre.006 TODO  transactions + transaction_status
pre.007 TODO  blocks + block_meta + entry
pre.008 TODO  bidi lifecycle/backpressure/half-close/shutdown
pre.009 TODO  reconnect/replay/gap/duplicate/equivocation
pre.010 TODO  Config V3
pre.011 TODO  live PublicNode/OrbitFlare + compliance + final cargo graphs
pre.012 TODO  docs/workspace final/prompt 0.2.10
rel.001 TODO stable

16. Gate pre.001

Critère du prompt Verdict
base stable v0.2.8 confirmée PASS
baseline opérateur enregistrée PASS
upstream courant relu PASS
divergence snapshot/latest enregistrée PASS
service/proto exhaustif inventorié PASS
standard vs provider extension classifié PASS
SubscribeDeshred classifié PASS / OUT
unary RPCs classifiés PASS / 7 IN
replay/from_slot audités PASS
strategy dependency choisie PASS / B
licence auditée avant ajout PASS
features/MSRV/transitifs audit initial PASS / materialisation pre.002
architecture distincte WS PASS
metadata/auth neutral PASS
Config shape décidée PASS / V3
resource/backpressure policy décidée PASS
smoke ownership décidé PASS
providers gratuits audités PASS
release dimensionnée PASS
forecast recalibré PASS
split criteria écrits PASS
aucune implémentation lourde prématurée PASS

Verdict pre.001 : gate positif ; pre.002 peut matérialiser la stratégie B sous validation Cargo.