Aller au contenu

PD-52 - Setup connexion Ethereum L2 (Polygon/Arbitrum)

1. Objectif

Definir le contrat fonctionnel, securite et operabilite de la capacite de connexion Ethereum L2 pour ProbatioVault afin de:

  • etablir une connectivite fiable vers Polygon et Arbitrum,
  • permettre la signature et l'emission de transactions de testnet via une cle de custody conforme,
  • garantir la resilence provider (failover),
  • exposer des observables de sante et de couts (latence RPC, gas, solde),
  • preparer la base technique des stories PD-53, PD-55, PD-56 et PD-57.

Elements non directement testables et donc hors perimetre contractuel:

  • perception utilisateur de la "confiance" induite par la blockchain,
  • interpretation juridique definitive de la valeur probatoire selon juridiction.

2. Perimetre / Hors perimetre

Inclus

  • Connectivite RPC vers Polygon et Arbitrum en environnement test.
  • Verification de connectivite par appels blockchain standards.
  • Gestion d'un wallet de service avec signature Ethereum verifiable.
  • Prise en charge contractuelle des 3 scenarios de compatibilite secp256k1 (S1, S2, S3).
  • Estimation de gas pour une transaction type d'ancrage.
  • Emission et confirmation de transaction de test sur testnets cibles.
  • Mecanisme de failover entre provider RPC primaire et secondaire.
  • Exposition d'indicateurs minimaux: latence RPC, gas price, solde wallet, statut provider actif.

Exclu

  • Deploiement et gestion de smart contract (PD-53).
  • Worker d'ancrage periodique et orchestration de lots (PD-55).
  • Generation de preuve Merkle individuelle (PD-56).
  • Verification composite TSA + blockchain (PD-57).
  • Fallback Tezos (PD-58).
  • Transactions mainnet en dehors d'une campagne d'acceptation explicitement autorisee.
  • Gestion de concurrence multi-instance sur le wallet (architecture multi-worker releve de PD-55).

3. Definitions

  • L2: reseau de couche 2 compatible EVM.
  • RPC Provider: endpoint d'acces JSON-RPC a un reseau blockchain.
  • Failover RPC: bascule automatique du provider primaire vers un secondaire.
  • Wallet de service: identite blockchain utilitaire de ProbatioVault pour signatures et transactions.
  • Custody mode: mode de gestion de cle Ethereum parmi S1/S2/S3.
  • S1: cle secp256k1 signee directement par CloudHSM via PKCS#11.
  • S2: cle secp256k1 signee via AWS KMS (ECC_SECG_P256K1) ou Vault Transit.
  • S3: approche hybride avec materiel derive depuis HSM et secret secp256k1 stocke chiffre dans Vault. La preuve de chiffrement au repos est verifiable via l'API Vault sys/seal-status (sealed=false implique encryption at rest active) et les audit logs Vault.
  • Transaction type d'ancrage: transaction eth_sendTransaction vers l'adresse du sender (self-send) avec value=0 et data=keccak256("ProbatioVault:anchor:test:" || timestamp_unix). Ce payload minimal est representatif de l'ecriture d'un engagement sans smart contract.
  • Confirmation: transaction incluse en bloc et observee avec le nombre de confirmations requis.
  • Finalite operationnelle: etat "valide" interne atteint apres seuil de confirmations contractuel.
  • Seuil de confirmations: nombre de blocs apres inclusion necessaires pour declarer la finalite. Valeurs par defaut: Polygon testnet (Amoy) = 5 confirmations (~10 secondes), Arbitrum testnet (Sepolia) = 1 confirmation (soft-finality suffisante sur L2 optimistic).
  • Timeout de detection RPC: duree maximale d'attente de reponse d'un provider avant de le considerer en echec. Valeur par defaut: 2 secondes.
  • Retries avant failover: nombre de tentatives sur le provider primaire avant bascule. Valeur par defaut: 1 retry (soit 2 tentatives totales).
  • Format de signature Ethereum: toutes les signatures produites par le wallet de service DOIVENT etre conformes a EIP-191 (personal_sign avec prefixe \x19Ethereum Signed Message:\n).

4. Invariants (non negociables)

ID Regle Justification
INV-52-01 Les reseaux cibles obligatoires de PD-52 sont Polygon et Arbitrum. Alignement epic PD-187.
INV-52-02 Toute operation blockchain de PD-52 est executee sur testnet uniquement (chain IDs: Polygon Amoy=80002, Arbitrum Sepolia=421614). Maitrise du risque financier et operationnel.
INV-52-03 La cle privee ne doit jamais etre presente en clair dans code, variables d'environnement, logs, traces applicatives ou historique git. Exigence securite critique.
INV-52-04 Un et un seul custody mode (S1, S2 ou S3) doit etre selectionne explicitement avant emission de transaction. Si plusieurs modes sont configures simultanement, le systeme refuse de demarrer avec erreur CUSTODY_MODE_AMBIGUOUS. Eliminer l'ambiguite face au risque secp256k1.
INV-52-05 Si le custody mode selectionne est indisponible, l'emission de transaction est refusee avec erreur explicite. Eviter signatures degradantes/non conformes.
INV-52-06 Le mecanisme RPC doit supporter un provider primaire et au moins un provider secondaire par reseau. Continuite de service.
INV-52-07 En cas d'indisponibilite provider primaire, la bascule vers secondaire doit etre automatique et transparente pour l'appelant applicatif. Le temps total de bascule (detection + retry + switch) ne doit pas depasser 5 secondes. Robustesse contractuelle.
INV-52-08 Les donnees emises on-chain dans PD-52 sont limitees a des hash et metadonnees techniques non identifiantes. Le systeme DOIT rejeter toute tentative d'emission de payload contenant des donnees non conformes (validation entrante obligatoire). Confidentialite et conformite.
INV-52-09 Une transaction n'est pas consideree finalisee tant que le seuil de confirmations n'est pas atteint (Polygon=5, Arbitrum=1). Protection contre reorg.
INV-52-10 Les metriques de sante minimales (latence RPC, gas price, solde wallet, provider actif) doivent etre exposables a la demande via un endpoint HTTP /health/blockchain retournant un objet JSON. Exploitabilite operationnelle.
INV-52-11 Toute erreur d'appel RPC ou de signature doit produire un code d'erreur deterministic et journalisable sans fuite de secret. Diagnostic fiable et securise.
INV-52-12 Les tests contractuels de PD-52 doivent etre executes en CI avant acceptation. Learning PD-7, refus automatique sinon.
INV-52-13 Le seuil de confirmations par reseau est configurable par variable d'environnement, avec les valeurs par defaut specifiees en §3. Adaptabilite operationnelle.

5. Flux nominaux

FN-52-01 - Verification de connectivite multi-reseaux

  1. Le systeme cible Polygon testnet puis Arbitrum testnet.
  2. Pour chaque reseau, il execute 10 appels consecutifs eth_blockNumber.
  3. Chaque appel retourne un numero de bloc valide.

Resultat attendu: succes de 10/10 appels sur chaque reseau.

FN-52-02 - Selection et validation du custody mode

  1. Le systeme lit le mode de custody configure (S1, S2 ou S3).
  2. Si plusieurs modes sont configures, il refuse de demarrer avec CUSTODY_MODE_AMBIGUOUS.
  3. Il execute un test de capacite de signature secp256k1 pour ce mode.
  4. Il publie l'etat "mode valide" ou "mode invalide".

Resultat attendu: un mode unique valide est declare avant tout envoi de transaction.

FN-52-03 - Signature de reference du wallet

  1. Le systeme soumet un message canonique de test au wallet de service.
  2. Le wallet retourne une signature Ethereum conforme EIP-191.
  3. La signature est verifiee comme correspondante a l'adresse attendue via ecrecover.

Resultat attendu: signature verifiable sans acces au secret prive.

FN-52-04 - Estimation de gas transaction type

  1. Le systeme construit une transaction type d'ancrage (self-send avec hash en data).
  2. Il calcule une estimation de gas via eth_estimateGas.
  3. Il conserve l'estimation pour comparaison avec le gas reel apres execution.

Resultat attendu: estimation disponible et comparables aux mesures reelles.

FN-52-05 - Emission et confirmation transaction testnet

  1. Le systeme emet une transaction de test sur un reseau cible.
  2. Il suit le hash de transaction jusqu'a inclusion.
  3. Il attend le seuil de confirmations contractuel (Polygon=5, Arbitrum=1).
  4. Il marque la transaction finalisee.

Resultat attendu: transaction confirmee dans le delai contractuel.

FN-52-06 - Failover provider

  1. Le provider primaire devient indisponible pendant un appel.
  2. Le systeme detecte l'echec apres timeout (2s) + 1 retry.
  3. Il bascule sur le secondaire.
  4. L'appel applicatif est servi par le provider secondaire.

Resultat attendu: bascule en moins de 5 secondes sans intervention manuelle.

FN-52-07 - Exposition des observables operationnels

  1. Un appel HTTP GET /health/blockchain est execute.
  2. Le systeme retourne un objet JSON avec les metriques minimales contractuelles.
  3. Les metriques sont horodatees et coherentes avec l'etat runtime.

Resultat attendu: metriques exploitables pour supervision et alerting.

5bis. Diagrammes

SD-52-01 - Etats d'une transaction blockchain

Cycle de vie d'une transaction depuis son emission jusqu'a sa finalite ou son abandon. Ref: INV-52-09 (seuil de confirmations), ERR-52-08 (reorg), INV-52-02 (testnet only).

stateDiagram-v2
    [*] --> PENDING : emit tx (FN-52-05)
    PENDING --> INCLUDED : tx incluse en bloc
    INCLUDED --> CONFIRMED : confirmations < seuil
    CONFIRMED --> FINALIZED : seuil atteint\n(Polygon=5, Arbitrum=1)\n[INV-52-09]
    FINALIZED --> [*]

    INCLUDED --> REORG : reorg detectee\n[ERR-52-08]
    CONFIRMED --> REORG : reorg detectee\n[ERR-52-08]
    REORG --> INCLUDED : tx reapparait\nen nouveau bloc
    REORG --> ABANDONED : tx absente\napres 60s timeout\n[ERR-52-08]
    ABANDONED --> [*]

    PENDING --> REJECTED : gas ceiling\n[ERR-52-07]\nou payload invalide\n[ERR-52-14]\nou mainnet\n[ERR-52-13]
    REJECTED --> [*]

SD-52-02 - Etats du provider RPC (failover)

Bascule automatique entre provider primaire et secondaire. Ref: INV-52-06, INV-52-07 (bascule < 5s), ERR-52-01, ERR-52-02.

stateDiagram-v2
    [*] --> PRIMARY_ACTIVE : demarrage
    PRIMARY_ACTIVE --> PRIMARY_FAILED : timeout 2s\n+ 1 retry echoue\n[INV-52-07]
    PRIMARY_FAILED --> SECONDARY_ACTIVE : bascule auto\n< 5s total\n[ERR-52-01]
    SECONDARY_ACTIVE --> PRIMARY_ACTIVE : health check\nprimaire retabli
    SECONDARY_ACTIVE --> ALL_UNAVAILABLE : secondaire\negalement en echec\n[ERR-52-02]
    ALL_UNAVAILABLE --> PRIMARY_ACTIVE : provider retabli

SQ-52-01 - Emission et confirmation de transaction (FN-52-05)

Flux multi-service couvrant la signature, l'emission et le suivi de confirmation. Ref: INV-52-03 (pas de secret en clair), INV-52-04 (custody mode unique), INV-52-09 (seuil confirmations).

sequenceDiagram
    participant App as Appelant applicatif
    participant BC as BlockchainService
    participant Custody as CustodyProvider<br/>(S1/S2/S3)
    participant RPC as RPC Provider<br/>(primaire/secondaire)

    App->>BC: emitAnchorTx(hash)
    BC->>BC: validatePayload(hash) [INV-52-08]
    BC->>BC: checkChainId == testnet [INV-52-02]
    BC->>Custody: signTransaction(txData) [INV-52-04]
    Custody-->>BC: signedTx (secret jamais expose [INV-52-03])
    BC->>RPC: eth_sendRawTransaction(signedTx)
    RPC-->>BC: txHash
    BC-->>App: txHash + status=PENDING

    loop Suivi confirmations
        BC->>RPC: eth_getTransactionReceipt(txHash)
        RPC-->>BC: receipt (blockNumber, confirmations)
    end

    alt Seuil atteint [INV-52-09]
        BC-->>App: status=FINALIZED
    else Reorg detectee [ERR-52-08]
        BC-->>App: status=REORG
    end

SQ-52-02 - Failover RPC (FN-52-06)

Bascule transparente vers le provider secondaire en cas d'indisponibilite. Ref: INV-52-06, INV-52-07 (< 5s), ERR-52-01.

sequenceDiagram
    participant App as Appelant applicatif
    participant BC as BlockchainService
    participant P1 as Provider primaire
    participant P2 as Provider secondaire

    App->>BC: appel RPC
    BC->>P1: requete JSON-RPC
    P1--xBC: timeout 2s [INV-52-07]
    BC->>P1: retry (1 tentative)
    P1--xBC: echec [ERR-52-01]
    BC->>P2: bascule auto + requete JSON-RPC
    P2-->>BC: reponse OK
    BC-->>App: reponse (< 5s total) [INV-52-07]

SQ-52-03 - Selection et validation du custody mode (FN-52-02)

Validation au demarrage que le mode de custody est unique et operationnel. Ref: INV-52-04 (mode unique), INV-52-05 (mode indisponible), ERR-52-03/10/11.

sequenceDiagram
    participant Srv as Service (startup)
    participant Cfg as Configuration
    participant HSM as CloudHSM (S1)
    participant KMS as AWS KMS / Vault (S2)
    participant VLT as Vault Transit (S3)

    Srv->>Cfg: lire custody_mode
    alt Aucun mode configure
        Cfg-->>Srv: CUSTODY_MODE_MISSING [ERR-52-03]
        Srv->>Srv: ABORT demarrage
    else Plusieurs modes configures
        Cfg-->>Srv: CUSTODY_MODE_AMBIGUOUS [ERR-52-10]
        Srv->>Srv: ABORT demarrage [INV-52-04]
    else Mode inconnu
        Cfg-->>Srv: CUSTODY_MODE_UNKNOWN [ERR-52-11]
        Srv->>Srv: ABORT demarrage
    else Mode S1
        Srv->>HSM: test signature secp256k1
        HSM-->>Srv: signature OK / KO [INV-52-05]
    else Mode S2
        Srv->>KMS: test signature secp256k1
        KMS-->>Srv: signature OK / KO [INV-52-05]
    else Mode S3
        Srv->>VLT: test signature + seal-status
        VLT-->>Srv: signature OK + sealed=false [INV-52-05]
    end

6. Cas d'erreur

ID Cas d'erreur Code erreur Reponse attendue
ERR-52-01 Echec RPC sur provider primaire RPC_PRIMARY_FAILED Bascule automatique vers secondaire, erreur non bloquante si secondaire disponible.
ERR-52-02 Echec RPC sur tous les providers d'un reseau RPC_UNAVAILABLE Retour d'erreur bloquante explicite, appel marque en echec.
ERR-52-03 Custody mode non defini CUSTODY_MODE_MISSING Aucune signature tentee, demarrage refuse.
ERR-52-04 Custody mode defini mais capacite secp256k1 invalide CUSTODY_MODE_INVALID Emission transaction interdite.
ERR-52-05 Signature non verifiable pour l'adresse configuree SIGNATURE_VERIFICATION_FAILED Mode marque non conforme.
ERR-52-06 Solde wallet insuffisant pour gas estime INSUFFICIENT_FUNDS Transaction non emise.
ERR-52-07 Depassement du plafond gas configurable GAS_PRICE_CEILING_EXCEEDED Transaction rejetee (politique stricte). Pas de mise en queue — l'appelant doit reessayer ulterieurement.
ERR-52-08 Transaction incluse puis reorg avant finalite TRANSACTION_REORG Etat transaction repasse a non finalisee, suivi continue jusqu'a nouvelle finalite. Si la transaction ne reapparait pas dans un nouveau bloc apres 60 secondes, elle est marquee TRANSACTION_ABANDONED.
ERR-52-09 Fuite potentielle de secret detectee dans logs de test SECRET_LEAK_DETECTED Echec immediate de la campagne d'acceptation, non-conformite securite.
ERR-52-10 Plusieurs custody modes configures simultanement CUSTODY_MODE_AMBIGUOUS Refus de demarrage du service.
ERR-52-11 Custody mode inconnu (ni S1, ni S2, ni S3) CUSTODY_MODE_UNKNOWN Refus de demarrage du service.
ERR-52-12 Endpoint RPC mal configure (URL invalide) RPC_INVALID_ENDPOINT Refus de demarrage du service.
ERR-52-13 Tentative d'emission sur mainnet MAINNET_FORBIDDEN Transaction bloquee, alerte securite emise.
ERR-52-14 Payload de transaction non conforme (donnees non-hash) PAYLOAD_VALIDATION_FAILED Transaction rejetee avant emission.

7. Criteres d'acceptation (testables)

ID Critere Observable
CA-52-01 Connectivite Polygon testnet validee. 10 appels consecutifs eth_blockNumber reussis sur Polygon.
CA-52-02 Connectivite Arbitrum testnet validee. 10 appels consecutifs eth_blockNumber reussis sur Arbitrum.
CA-52-03 Un custody mode unique S1/S2/S3 est explicitement selectionne et valide. Journal de selection unique + resultat test de capacite secp256k1 positif.
CA-52-04 Signature wallet de reference verifiable. Signature EIP-191 recuperee et verification reussie contre l'adresse attendue via ecrecover.
CA-52-05 Estimation gas exploitable. Ecart relatif entre gas estime et gas consomme < 25% sur transaction type.
CA-52-06 Transaction testnet confirmee dans le delai cible. Temps emission -> confirmation <= 30 secondes sur environnement de test de reference.
CA-52-07 Failover RPC respecte le SLA de bascule. Bascule primaire->secondaire observee en < 5 secondes (timeout 2s + 1 retry + switch), appel applicatif servi.
CA-52-08 Metriques minimales exposees. Presence de latence RPC, gas price, solde wallet et provider actif sur endpoint JSON /health/blockchain.
CA-52-09 Absence de secret prive en clair. Audit logs/config/code/historique git sans cle privee brute ni materiel secret exploitable.
CA-52-10 Donnees on-chain limitees a hash/non-identifiant. Inspection des payloads transaction: aucun champ contenant donnees personnelles ou metadonnees identifiantes.
CA-52-11 Gestion reorg conforme a la finalite. Cas de test reorg: transaction non finalisee tant que seuil confirmations non atteint (Polygon=5, Arbitrum=1).
CA-52-12 Campagne de tests contractuels executee en CI. Pipeline CI vert incluant tests unitaires + integration; couverture unitaire >= 80%.
CA-52-13 Validation de payload entrante operationnelle. Tentative d'emission de donnees non conformes rejetee avec PAYLOAD_VALIDATION_FAILED.

8. Scenarios de test (Given / When / Then)

TC-52-01 - Connectivite Polygon (CA-52-01, INV-52-01)

Given un endpoint RPC Polygon testnet valide When 10 appels consecutifs eth_blockNumber sont executes Then les 10 appels retournent un numero de bloc valide.

TC-52-02 - Connectivite Arbitrum (CA-52-02, INV-52-01)

Given un endpoint RPC Arbitrum testnet valide When 10 appels consecutifs eth_blockNumber sont executes Then les 10 appels retournent un numero de bloc valide.

TC-52-03 - Validation scenario S1 (CA-52-03, INV-52-04)

Given le mode S1 configure When un test de signature secp256k1 est lance via CloudHSM/PKCS#11 Then le mode est marque valide uniquement si la signature est verifiable.

TC-52-04 - Validation scenario S2 (CA-52-03, INV-52-04)

Given le mode S2 configure When un test de signature secp256k1 est lance via KMS ou Vault Transit Then le mode est marque valide uniquement si la signature est verifiable.

TC-52-05 - Validation scenario S3 (CA-52-03, INV-52-04)

Given le mode S3 configure When un test de signature secp256k1 est lance sur le materiel chiffre derive Then le mode est marque valide uniquement si la signature est verifiable et le secret reste chiffre au repos (verifiable via Vault sys/seal-status).

TC-52-06 - Signature wallet verifiable (CA-52-04, INV-52-03)

Given un message canonique de test et une adresse wallet attendue When le wallet signe le message en format EIP-191 Then la verification cryptographique via ecrecover retrouve l'adresse attendue.

TC-52-07 - Estimation gas (CA-52-05)

Given une transaction type d'ancrage (self-send avec hash) When le systeme estime le gas puis execute la transaction Then l'ecart relatif entre estimation et gas reel est inferieur a 25%.

TC-52-08 - Confirmation transaction (CA-52-06, INV-52-09)

Given une transaction test emise sur testnet When le suivi de transaction est actif Then la transaction est confirmee en <= 30 secondes et finalisee apres seuil de confirmations (Polygon=5, Arbitrum=1).

TC-52-09 - Failover automatique (CA-52-07, INV-52-07)

Given un provider primaire indisponible et un secondaire operationnel When un appel RPC est execute Then la bascule vers secondaire est realisee en moins de 5 secondes (timeout 2s + 1 retry + switch).

TC-52-10 - Observabilite minimale (CA-52-08, INV-52-10)

Given le service en execution When l'endpoint /health/blockchain est consulte Then latence RPC, gas price, solde wallet et provider actif sont presents et horodates en JSON.

TC-52-11 - Confidentialite secrets (CA-52-09, INV-52-03)

Given une campagne de tests complete When les logs, traces, configurations et historique git sont audites Then aucun secret prive en clair n'est detectable.

TC-52-12 - Donnees on-chain minimales (CA-52-10, INV-52-08)

Given une transaction type observee When son payload est inspecte Then seuls des hash et metadonnees techniques non identifiantes sont presents.

9. Hypotheses explicites

ID Hypothese Impact si faux
H-52-01 Les endpoints RPC testnet Polygon et Arbitrum sont disponibles pendant les campagnes de test. Impossibilite de demontrer CA-52-01/02 de maniere fiable.
H-52-02 Un mecanisme d'obtention de fonds testnet est operationnel pour le wallet de service. CA-52-06 et CA-52-07 deviennent non executables.
H-52-03 Le mode de custody choisi dispose des droits IAM/Vault/HSM necessaires en environnement de test. Echec de signature, blocage sur CA-52-03/04.
H-52-04 Le seuil de confirmations est definissable par configuration deploiement. CA-52-11 ne peut pas etre valide de facon uniforme.
H-52-05 La CI dispose d'un environnement d'integration testnet stable et rejouable. CA-52-12 peut etre partiellement non demonstrable.
H-52-06 Les outils d'audit de logs sont capables de detecter les motifs de fuite de secret attendus. CA-52-09 risque de faux negatif.
H-52-07 Le custody mode initial pour l'acceptation v1 est S2 (AWS KMS). Simplification de l'integration ; S1 (HSM) reserve pour production.

10. Points resolus

Les points suivants ont ete clarifies dans cette version de la specification :

  1. Seuil de confirmations : Polygon=5, Arbitrum=1 (defini en §3 et INV-52-09).
  2. Transaction type d'ancrage : self-send avec data=keccak256("ProbatioVault:anchor:test:" || timestamp) (defini en §3).
  3. Politique GAS_PRICE_CEILING_EXCEEDED : rejet strict, pas de mise en queue (defini en ERR-52-07).
  4. Custody mode initial : S2 (AWS KMS) recommande pour v1 (defini en H-52-07).
  5. Preuve S3 chiffre au repos : via Vault sys/seal-status et audit logs (defini en §3).
  6. Endpoint observabilite : /health/blockchain retournant JSON (defini en INV-52-10).
  7. Seuil solde critique : 0.01 ETH equivalent (a definir en configuration, hors scope spec).
  8. Independance verification : utilisation de Vault externe + audit logs (conforme PD-37).
  9. Timeout de detection : 2 secondes, 1 retry avant failover (defini en §3 et FN-52-06).
  10. Format de signature : EIP-191 obligatoire (defini en §3 et FN-52-03).
  11. Catalogue codes d'erreur : 14 codes definis en §6.
  12. Validation payload entrante : obligatoire via INV-52-08 et ERR-52-14.

References

  • Epic : PD-187 - BLOCKCHAIN
  • JIRA : PD-52
  • Repos concernes : ProbatioVault-backend, ProbatioVault-infra
  • Documents associes : PD-52-besoin.md, learnings PD-36/PD-7/PD-37
  • Correction Gate 3 v1 : 2026-02-12 (resolution de 12 ecarts)