5.5 KiB
Delta 0.2.5-pre.006 — persistence native async/no-clobber
Base
0.2.5-pre.5.fix.1
Le checkpoint opérateur de cette base a validé cargo fmt --all, cargo check --workspace, cargo clippy --workspace --all-targets, cargo test -p ksp-wallet-lib, cargo test --workspace et l'audit Cargo tree. Une seule génération ed25519-dalek 2.2.0 est utilisée et solana-address 2.7.0 est unifié entre Core et solana-keypair.
Version technique
workspace.package.version = 0.2.5-pre.6
Objet
Cette tranche matérialise la persistence native .kspwallet sans Config, environnement, Transport ou Tauri :
create_wallet_file_v1(path, ...)
open_wallet_view_file_v1(path, ...)
open_wallet_owner_file_v1(path, ...)
inspect_locked_wallet_file_v1(path)
Le chemin est toujours fourni explicitement par le caller. Wallet ne possède et ne découvre aucun répertoire par défaut.
Persistence retenue
tempfile ^3.27 est ajouté sous [workspace.dependencies] puis consommé par ksp-wallet-lib avec tempfile.workspace = true.
La création native suit :
create crypto in-memory
-> serialize locked JSON
-> NamedTempFile dans le même répertoire que la destination
-> write_all
-> sync_all(temp)
-> persist_noclobber(destination)
-> sync_all(fichier publié)
-> parent-directory sync best-effort sur Unix
create ne propose aucun overwrite. Une destination existante retourne wallet.destination_exists même sous concurrence.
La documentation upstream de tempfile 3.27.0 précise que persist_noclobber ne peut pas être présenté comme atomique sur absolument toutes les plateformes/filesystems et peut laisser un hard-link temporaire dans certains scénarios de crash. KSP conserve donc une documentation explicite de cette limite : no-clobber est le contrat, tandis que la durabilité power-loss universelle n'est pas revendiquée.
Async / lecture bornée
Les opérations filesystem bloquantes sont regroupées dans tokio::task::spawn_blocking; aucune feature Tokio filesystem supplémentaire n'est requise.
La lecture :
- ouvre le fichier dans la frontière blocking ;
- vérifie d'abord la taille metadata ;
- utilise ensuite une lecture bornée à
KSPWALLET_MAX_FILE_BYTES + 1afin de couvrir aussi un fichier qui grossirait pendant la lecture ; - rejette un document surdimensionné avant parsing/KDF.
Les wrappers fichier délèguent ensuite aux flows pre.005 déjà validés et n'introduisent aucune seconde implémentation crypto.
Fault / concurrence
Nouveaux canaries déterministes :
- première publication no-clobber conservée face à une seconde tentative ;
- fault injecté après
sync_all(temp)mais avant publication : aucune destination partielle ; - cleanup du temp lors d'un retour d'erreur ordinaire ;
- huit créateurs concurrents : exactement un succès et sept
destination_exists; - rejet pré-parser d'un fichier supérieur à 1 MiB ;
- création publique vers fichier puis projection locked ;
- le vecteur complet
pre.005peut être publié puis ouvert par les nouvelles API VIEW et OWNER depuis fichier.
Un kill/power-loss brutal peut laisser un artifact temporaire selon l'OS/filesystem ; la tranche ne prétend pas simuler ni garantir le cleanup après arrêt non déroulé.
Frontières conservées
Wallet -> ksp-core-lib
Wallet -> ksp-logging-lib
Wallet -> primitives crypto/Solana retenues
Wallet -> tempfile
Wallet -X-> Config
Wallet -X-> Transport
Wallet -X-> ExecutionPolicy
Wallet -X-> Store
Wallet -X-> Tauri
Wallet -X-> tracing direct
Wallet -X-> solana-pubkey direct
Pubkey reste consommée exclusivement via ksp_core_lib::Pubkey. solana-keypair reste propriété de Wallet parce qu'il encapsule du matériau secret et une capacité de signature ; aucune keypair brute n'est remontée dans Core.
Replace administratif
pre.006 n'expose volontairement pas une primitive publique générale d'overwrite/replace. Le remplacement atomique d'un wallet existant sera introduit en pre.007 à travers les seules opérations autorisées : administration OWNER et self-rotation du password VIEW. Cela évite de donner à un consumer de niveau inférieur une primitive arbitraire replace(path, bytes).
Fichiers ajoutés
crates/ksp-wallet-lib/src/persistence.rs
crates/ksp-wallet-lib/unit_tests/persistence.rs
deltas/0.2.5/pre.006.md
Fichiers modifiés
Cargo.toml
ROADMAP.md
crates/ksp-wallet-lib/Cargo.toml
crates/ksp-wallet-lib/src/lib.rs
crates/ksp-wallet-lib/tests/dependency_boundary.rs
crates/ksp-wallet-lib/tests/public_api.rs
docs/formats/KSPWALLET_V1.md
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
docs/plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md
Validation opérateur requise
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-wallet-lib
cargo test --workspace
cargo tree -p ksp-wallet-lib
cargo tree -p ksp-wallet-lib -d
cargo tree -i tempfile@3.27.0
Points à contrôler dans le tree : pas de nouvelle dépendance Config/Transport/Tauri, tempfile uniquement par Wallet dans cette tranche et aucune duplication crypto nouvelle injustifiée.
Suite
Après validation, 0.2.5-pre.007 porte :
signature Solana publique sans getter secret
alias/notes OWNER
rotation password VIEW par VIEW
rotation password VIEW par OWNER sans ancien password VIEW
rotation password OWNER
suppression/recréation VIEW
révocation forte VIEW avec rekey metadata
replace atomique lié aux mutations autorisées