Commit Graph

308 Commits

Author SHA1 Message Date
CleverWild
d916997ef3 fix(crypto): return None from shamir_threshold for an empty committee 2026-09-08 16:11:42 +02:00
CleverWild
f32da65467 refactor(proposal): put DB access behind a mockable ProposalStore trait 2026-09-08 16:11:42 +02:00
CleverWild
fa2df36fbe refactor(proposal): publish approved proposals on the bus instead of executing them 2026-08-27 17:45:13 +02:00
CleverWild
2b2c225b35 chore: normalize line endings to LF 2026-08-27 17:30:20 +02:00
CleverWild
9e9672a1b1 refactor(crypto): extract governance vote message and verification helpers 2026-08-27 16:44:22 +02:00
CleverWild
0d29d0d532 refactor(db): declare unixepoch instead of formatting a SQL fragment 2026-08-27 14:08:48 +02:00
CleverWild
e9496da78c perf(proposal): replace the per-proposal tally loop with one grouped query 2026-08-27 14:00:14 +02:00
CleverWild
c0546fa17f refactor(db): use diesel exists() instead of counting rows 2026-08-27 13:50:02 +02:00
CleverWild
71081b6ee7 refactor(proposal): use id newtypes across the governance path 2026-08-27 13:42:14 +02:00
CleverWild
8421a09d9f refactor(db!: store the one-off transaction signature by component 2026-08-27 12:46:40 +02:00
CleverWild
15b826310b refactor(db): replace the proposal payload blob with typed child tables 2026-08-27 00:45:35 +02:00
CleverWild
5698d1cfb3 feat(proposal): reject proposals with an excessive TTL 2026-08-26 16:47:12 +02:00
CleverWild
6884a59325 refactor(proposal): type ProposalSummary::kind as ProposalKindTag 2026-08-26 16:32:43 +02:00
CleverWild
b364d95489 refactor(proposal): drop the Quorum prefix from VoteOutcome variants 2026-08-26 15:30:48 +02:00
CleverWild
d64478b301 refactor(proposal): replace UpdateShamirParameters with parameterless TriggerRekey 2026-08-26 15:26:17 +02:00
CleverWild
aa884339f7 refactor(proposal): remove the ApproveServerUpdate proposal kind 2026-08-26 14:53:38 +02:00
CleverWild
180f93c1a7 refactor(proposal): derive ProposalKindTag from ProposalKind with strum 2026-08-26 14:36:41 +02:00
CleverWild
a501283b0c refactor(crypto): replace byte-slice signing contexts with SigningContext enum 2026-08-26 14:08:32 +02:00
CleverWild
f881102f0a refactor(proposal): drop the expired status, enforce expiry on every vote 2026-08-26 13:01:44 +02:00
CleverWild
f13c1cf9d1 fix(db): require share_salt to be supplied by the daemon 2026-08-26 13:01:44 +02:00
CleverWild
f03997ea56 chore(lints): fix regression caused by rust 1.98.0 2026-08-26 13:01:44 +02:00
CleverWild
957c5096df chore(deps): bump kameo version 2026-08-26 13:01:44 +02:00
CleverWild
36249129d1 feat(vault)!: implement full Shamir re-key flow and governance execution (§3.3–§3.5)
- Add `rekey.proto` with `ContributePassphrase` / `ContributeRecoveryPassphrase` / `RekeyResult`
- Wire `rekey` as a 4th vault stream payload in `vault.proto` and gRPC dispatch
- Add `RekeyRootKey` message to `Vault` actor: generates new random seal key, re-encrypts root key, writes new `root_key_history` row
- Add `StartRekey`, `ContributeRekey`, `ContributeRecoveryRekey` messages to `VaultCoordinator`; `finalize_rekey` uses threshold-1 fast path identical to bootstrap
- `execute_replace_operator` now UPDATEs `operator_identity.public_key` in-place (avoids FK constraint violation), deletes stale `operator` share row, then triggers `StartRekey`
- `execute_update_shamir_parameters` triggers `StartRekey` instead of warning stub
- `ProposalKind::ReplaceOperator` carries `old_operator_id`; encode/decode updated accordingly
- `GlobalActors::spawn` extracts `vault_coordinator` before `Ok(Self { … })` so it can be cloned into `ProposalManager::new`
- Add `handle_rekey` in session handlers forwarding passphrase contributions to `VaultCoordinator`
- Fix test: rename `replace_operator_inserts_identity_row` → `replace_operator_updates_pubkey_and_starts_rekey`, assert count stays 1 and pubkey is updated
2026-08-26 13:01:44 +02:00
CleverWild
3817a080c9 refactor(proposal): replace string kind dispatch with ProposalKindTag enum (strum) 2026-08-26 13:01:44 +02:00
CleverWild
e1d060dd06 feat(vault): add recovery passphrase handling for bootstrap and unseal processes 2026-08-26 13:01:44 +02:00
CleverWild
e121708d28 fix(crypto): handle 1-of-N Shamir split when ordinary_count=1 2026-08-26 13:01:44 +02:00
CleverWild
6e3fa736e0 feat(server): recovery operators with sleeping/wakeup mechanism (§3.5/§3.6) 2026-08-26 13:01:44 +02:00
CleverWild
19a62e7195 feat(server): key-rotation proposals require full quorum (§3.3) 2026-08-26 13:01:44 +02:00
CleverWild
57200cbc50 feat(server): two-operator vault requires at least one recovery share 2026-08-26 13:01:44 +02:00
CleverWild
291ef2e831 refactor(server): typed pubkey len via u32::try_from in ReplaceOperator 2026-08-26 13:01:44 +02:00
CleverWild
d12109c2c9 feat(server): ProposalKind::ApproveOneOffTransaction 2026-08-26 13:01:44 +02:00
CleverWild
277fb3c92d feat(server): ProposalKind::ApprovePersistentGrant 2026-08-26 13:01:44 +02:00
CleverWild
9e42097683 feat(server): ProposalKind::UpdateShamirParameters 2026-08-26 13:01:44 +02:00
CleverWild
25b86b14e9 feat(server): ProposalKind::ReplaceOperator 2026-08-26 13:01:44 +02:00
CleverWild
ba8748a17b feat(server): ProposalKind ::GrantWalletAccess and ::ApproveServerUpdate 2026-08-26 13:01:44 +02:00
CleverWild
3e61d807b4 test(server): governance integration tests 2026-08-26 13:01:44 +02:00
CleverWild
e6459aade8 feat(server::grpc): wire governance RPCs through operator session 2026-08-26 13:01:44 +02:00
CleverWild
f16d0a26e2 feat(server): introduce ProposalManager actor with quorum voting logic 2026-08-26 13:01:44 +02:00
CleverWild
074e6501ec feat(crypto): expose governance signing context and make shamir_threshold pub const 2026-08-26 13:01:44 +02:00
CleverWild
b2632661f8 feat(db): add proposal and proposal_vote tables 2026-08-26 13:01:44 +02:00
CleverWild
966b4c8828 feat(proto): add governance proposal/vote RPC definitions 2026-08-26 13:01:44 +02:00
CleverWild
b6c91c56eb housekepping: add fixme for start_bootstrap's operator_id 2026-08-26 13:01:44 +02:00
CleverWild
240fd3eb63 refactor(server::crypto): use fixed-size [u8; 32] and KeyCell throughout seal key API 2026-08-26 13:01:44 +02:00
CleverWild
80ba30d430 fix(server::tests): tighten unseal test seal_key params to &[u8; 32] 2026-08-26 13:01:44 +02:00
CleverWild
59cb65f3e1 feat(server::grpc): wire Shamir committee bootstrap and unseal proto messages
Adds DeclareCommittee and ContributePassphrase variants to bootstrap.proto,
ContributePassphrase to unseal.proto, and AwaitingContributions result codes
to both. Implements corresponding inbound converters and outbound reply
mappings. VaultGate handlers delegate to VaultCoordinator.
2026-08-26 13:01:44 +02:00
CleverWild
83075e9df7 feat(server): introduce VaultCoordinator for multi-operator Shamir bootstrap/unseal
VaultCoordinator collects operator passphrases, splits the seal key into
Shamir shares on bootstrap (encrypting each share with the operator's
passphrase via Argon2 + XChaCha20-Poly1305), and reconstructs the seal
key from threshold shares on unseal. Adds vsss-rs 5.4.0 and rand_core 0.6
dependencies.
2026-08-26 13:01:44 +02:00
CleverWild
fc7f2b1a03 refactor(server::actors::vault): clean up Bootstrap/TryUnseal, remove Bootstrapping state
Bootstrap and TryUnseal now accept a SafeCell<Vec<u8>> seal key directly.
The Bootstrapping intermediate state is removed — multi-operator coordination
is the responsibility of VaultCoordinator, which calls Bootstrap atomically
once all shares are collected.
2026-08-26 13:01:44 +02:00
CleverWild
0695ec96a8 feat(server::crypto): add Shamir secret sharing utilities
Wraps vsss_rs Gf256::split_array / combine_array into thin split_key /
combine_shares helpers. Also widens derive_key salt parameter from &[u8;16]
to &[u8] to accommodate the 32-byte share salts.
2026-08-26 13:01:44 +02:00
CleverWild
8159902027 feat(server::db): add share_salt column to operator table
Each operator row now stores a 32-byte random salt used to derive the
per-operator share encryption key from their passphrase (Argon2 KDF).
2026-08-26 13:01:44 +02:00
CleverWild
928799fa07 feat(server::actors::evm): implement operator_delete_grant
Sets revoked_at on the evm_basic_grant row; returns NotFound if the grant
does not exist. Wires the handler in OperatorSession replacing the todo!().
2026-08-26 13:01:44 +02:00