Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
9e60e3f
fix(zk): bind C0 proofs to canonical request context
hmzakhalid Jul 11, 2026
35019a4
fix(slashing): use honest quorum for accusation votes
hmzakhalid Jul 11, 2026
099ef90
fix(storage): fail closed on corrupt event log records
hmzakhalid Jul 11, 2026
11a756f
fix(net): keep broadcast consumers alive after lag
hmzakhalid Jul 11, 2026
ad96bbd
fix(zk): validate canonical DKG H and N shapes
hmzakhalid Jul 11, 2026
e7f400e
fix(sdk): subscribe to finalized sortition event
hmzakhalid Jul 11, 2026
b858f36
fix(startup): enforce a configurable readiness deadline
hmzakhalid Jul 11, 2026
3e092e0
fix(evm): serialize nonce allocation across writers
hmzakhalid Jul 11, 2026
6b0a307
fix(events): replace probabilistic dedup with bounded exact IDs
hmzakhalid Jul 11, 2026
bfa34c2
fix(net): bound and advance historical sync requests
hmzakhalid Jul 13, 2026
ea5b225
fix(dappnode): fail closed on credentials and health
hmzakhalid Jul 11, 2026
d95e79a
fix(zk): bind share proofs to canonical party signers
hmzakhalid Jul 11, 2026
52117c4
fix(aggregation): bind share senders to party slots
hmzakhalid Jul 11, 2026
7f4f290
fix(evm): fail closed on bounded startup buffers
hmzakhalid Jul 11, 2026
54fc1f2
fix(evm): defer live logs until confirmed
hmzakhalid Jul 11, 2026
e298030
fix(net): bound startup buffering by count and bytes
hmzakhalid Jul 11, 2026
f37451b
fix(shutdown): drain and flush durable state
hmzakhalid Jul 11, 2026
e72602e
fix(config): preserve large finalization delays
hmzakhalid Jul 11, 2026
49578d9
fix(net): reject unauthorized internal gossip events
hmzakhalid Jul 11, 2026
e0c73ab
fix(storage): add acknowledged atomic batch writes
hmzakhalid Jul 11, 2026
bc62534
fix(wallet): preserve autowallet node identities
hmzakhalid Jul 11, 2026
c124ba8
fix(storage): isolate and acknowledge snapshot batches
hmzakhalid Jul 11, 2026
a6fb687
fix(sync): restore full logical clock state
hmzakhalid Jul 11, 2026
b4126ae
fix(sync): reject incomplete EVM history
hmzakhalid Jul 11, 2026
fae83d0
fix(sync): reject unversioned persisted state
hmzakhalid Jul 11, 2026
d0f5f1d
fix(serialization): bound external bincode decoding
hmzakhalid Jul 11, 2026
dafe5a7
fix(net): reject expired DHT documents
hmzakhalid Jul 11, 2026
073c44c
fix(bfv): bind proofs to supported parameters
hmzakhalid Jul 11, 2026
a874c78
fix(evm): fail closed on missing block timestamps
hmzakhalid Jul 11, 2026
ff71d0e
fix(evm): reject reverted transaction receipts
hmzakhalid Jul 11, 2026
6c70941
fix(sync): replay aggregates in global timestamp order
hmzakhalid Jul 11, 2026
ffba237
fix(net): bind DHT metadata to document payloads
hmzakhalid Jul 11, 2026
9d1ae22
fix(net): backpressure remote actor ingress
hmzakhalid Jul 11, 2026
75e9f0e
fix(slashing): defer and coalesce replayed submissions
hmzakhalid Jul 11, 2026
5486d5b
fix(program-server): require authenticated compute requests
hmzakhalid Jul 11, 2026
94353e5
fix(supervisor): report exits and drain children gracefully
hmzakhalid Jul 11, 2026
f047287
fix(request): preserve and release buffered event order
hmzakhalid Jul 11, 2026
1657745
fix(sync): fence startup recovery phases
hmzakhalid Jul 11, 2026
94bc180
fix(zk): count C3 proofs by threshold share rows
hmzakhalid Jul 11, 2026
3c95c64
test(zk): use committee-scoped node-fold artifacts
hmzakhalid Jul 11, 2026
1d2ecd0
fix(deps): apply compatible RustSec patches
hmzakhalid Jul 11, 2026
3e98e08
fix(logging): update tracing subscriber
hmzakhalid Jul 11, 2026
c3facf6
fix(logging): redact sensitive tracing fields
hmzakhalid Jul 11, 2026
8f35d14
fix(evm): update typed-data ABI hashing
hmzakhalid Jul 11, 2026
0742060
fix(build): synchronize Rust consumer lockfiles
hmzakhalid Jul 11, 2026
64d44b1
fix(sync): allow atomic identity bootstrap before schema stamp
hmzakhalid Jul 11, 2026
c96ac0c
fix(dev): wire program server authentication to callers
hmzakhalid Jul 11, 2026
b090ae6
revert(program-server): remove development bearer auth
hmzakhalid Jul 11, 2026
a206b9f
fix(zk): restore committee slots before C6 verification
hmzakhalid Jul 11, 2026
00cd862
fix(zk): restore C0 verification context after restart
hmzakhalid Jul 11, 2026
d74cd2d
fix(sync): make startup replay end-to-end backpressured
hmzakhalid Jul 13, 2026
6032567
fix(net): upgrade libp2p transport stack
hmzakhalid Jul 13, 2026
fa0deb3
refactor(builder): construct node handles with named fields
hmzakhalid Jul 13, 2026
4ffe4fb
docs(crates): record final architecture and audit ledger
hmzakhalid Jul 11, 2026
36438db
refactor: organize ciphernode crates by capability [skip-line-limit] …
hmzakhalid Jul 14, 2026
7e1ad35
fix(aggregator): normalize expelled committee addresses
hmzakhalid Jul 14, 2026
4de3ec1
fix(evm): skip unsupported E3 versions safely
hmzakhalid Jul 14, 2026
e67d950
fix(net): keep live ingress running after lag
hmzakhalid Jul 14, 2026
5b552a2
fix(events): dedupe redelivery by stable identity
hmzakhalid Jul 14, 2026
c13e928
fix(cli): keep provisioning secrets out of argv
hmzakhalid Jul 14, 2026
762fccb
fix(storage): recover only uncommitted event-log tails
hmzakhalid Jul 14, 2026
4cca970
fix(dappnode): bridge legacy state through schema v1
hmzakhalid Jul 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
624 changes: 298 additions & 326 deletions Cargo.lock

Large diffs are not rendered by default.

13 changes: 7 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ exclude = [
"templates/default"
]
resolver = "3"
msrv = "1.91.1"

[workspace.metadata.release]
shared-version = true
Expand Down Expand Up @@ -126,13 +125,13 @@ actix = "=0.13.5"
actix-web = "=4.11.0"
aes-gcm = "=0.10.3"
alloy = { version = "=1.0.41", features = ["node-bindings", "full"] }
alloy-primitives = { version = "=1.3.0", default-features = false, features = [
alloy-primitives = { version = "=1.4.1", default-features = false, features = [
"rlp",
"serde",
"std",
] }
alloy-sol-types = "=1.3.0"
alloy-dyn-abi = "=1.3.0"
alloy-sol-types = "=1.4.1"
alloy-dyn-abi = "=1.4.1"
argon2 = "=0.5.3"
ark-ff = "0.5.0"
ark-bn254 = "0.5.0"
Expand Down Expand Up @@ -202,14 +201,16 @@ tokio = { version = "=1.46.1", features = ["full"] }
toml = "=0.8.23"
tracing = "=0.1.41"
tracing-opentelemetry = "=0.30.0"
tracing-subscriber = { version = "=0.3.19", features = ["env-filter", "time"] }
tracing-subscriber = { version = "=0.3.20", features = ["env-filter", "time"] }
tracing-test = { version = "=0.2.5", features = ["no-env-filter"] }
url = "=2.5.4"
vfs = { git = "https://github.com/ryardley/rust-vfs.git", features = ["async-vfs"] }
libp2p = { version = "=0.54.1", features = [
libc = "=0.2.180"
libp2p = { version = "=0.56.0", features = [
"gossipsub",
"identify",
"dns",
"ed25519",
"kad",
"macros",
"mdns",
Expand Down
65 changes: 65 additions & 0 deletions agent/ACTOR_AUDIT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Ciphernode Actor Audit

This audit records the repository-wide thin-actor and source-layout review. Read it with
[`ARCHITECTURE.md`](ARCHITECTURE.md), which defines the target, and
[`CRATES_ARCHITECTURE.md`](CRATES_ARCHITECTURE.md), which describes the implementation.

## Method

An actor is thin when it has one runtime reason to change: mailbox serialization, routing,
scheduling, lifecycle, or supervision. Line count is evidence, not the definition. Roughly 300
production lines triggers a responsibility review; tests, generated bindings, and cohesive
cryptographic algorithms are judged separately.

The audit checked all nine crates that originally contained `src/actors/`. Before this refactor,
17 production actor modules were over the review threshold; the largest were `ThresholdKeyshare`
(2,198 lines), `PublicKeyAggregator` (1,591), `ProofRequestActor` (1,344), and
`ThresholdPlaintextAggregator` (1,029).

The first extraction made the actors thin but retained layer-first `actors/`, `workflow/`, and
`domain/` trees. That made placement hard to infer because one protocol capability was scattered
across several top-level folders. The follow-up layout groups implementation by capability and uses
the same role vocabulary inside each capability. Root compatibility files preserve established
Rust paths; they do not own implementation. Inline test suites were also moved beside the roles
they exercise so production responsibility size remains visible.

## Findings by crate

| Crate | Actors reviewed | Result |
| --- | --- | --- |
| `e3-aggregator` | committee finalizer, keyshare/decryption buffers, public-key aggregator, plaintext aggregator | `committee_finalization`, `public_key_aggregation`, and `plaintext_aggregation` each contain their actor, handlers, workflow/state, semantic effects, and tests. |
| `e3-evm` | parser/router/hub, chain gateway, readers, registry/interfold/slashing writers, log fetcher | Each chain capability owns its actor plus events/workflow/effects. `log_fetching` is explicitly an adapter capability; provider and transaction work is no longer hidden below actor `runtime/`. |
| `e3-keyshare` | encryption/share/decryption collectors, `ThresholdKeyshare` | The `threshold_keyshare` capability contains the request-local coordinator, collectors, persisted state, pure DKG calculations, handlers, and semantically named effect operations. Transient async-gap data remains grouped in `PendingKeyshareWork`. |
| `e3-net` | event buffer/translator, sync manager, document publisher/converter | Admission, readiness, rebroadcast, historical sync, conversion, and DHT/gossip effects are isolated. The actors now own transport ordering and lifecycle rather than document-validation policy. |
| `e3-request` | lifecycle coordinator, E3 router | `routing` and `lifecycle` contain predictable actor/workflow roles; context construction, snapshots, and the request event buffer are named beside routing instead of hidden in a generic runtime package. |
| `e3-slashing` | accusation manager, commitment consistency checker | `accusation_voting` and `commitment_consistency` each co-locate the actor shell with deterministic workflow decisions and adjacent tests. |
| `e3-sortition` | sortition, ciphernode selector | `sortition` contains actor, registry, selection backend, ticket rules, and retention; `ciphernode_selection` contains its actor and handlers. |
| `e3-sync` | bootstrap/replay functions and messages | This crate has no Actix actor. The `sync` capability honestly names its service, state, workflow, preflight, history collection, and tests. |
| `e3-zk-prover` | proof requester, share verifier, C0 verifier, node proof aggregator, ZK worker, commitment links | Proof capabilities co-locate actor, handlers, state/workflow, effects, and tests. Effect files use semantic proof-operation names instead of unexplained `c0`–`c7` filenames; pure commitment links have their own capability. |

## State classification applied

- Persisted workflow state: aggregation and keyshare state enums stored through repositories.
- Derivable state: canonical committee/preset caches rebuilt from repositories and replay.
- Ephemeral effect state: correlation IDs, collector addresses, timer handles, early-arrival buffers,
and in-flight submission guards. These are grouped and named rather than mixed into protocol
state.
- External authority: EVM contract state. Writer preflights provide cross-restart idempotency where
no durable local outbox exists.

`Persistable::try_mutate` now accepts the snapshot write into the bounded store mailbox before it
exposes the new value in memory. This does not turn snapshots into an external-effect outbox; the
append-only event log and chain remain the stated authorities. Synchronous `BusHandle` publication
still uses the existing burst-tolerant `do_send` path and is recorded as backpressure debt.

## Deliberate residuals

This refactor does not split files only to satisfy a number. Generated ABI bindings, circuit witness
construction, and cohesive FHE/math algorithms may exceed 300 lines. Large non-actor composition or
infrastructure coordinators—notably `CiphernodeBuilder`, `NetInterface`, and the multithread task
pool—need their own behavior-preserving projects if their responsibilities are changed.

The remaining architectural gap is durable effect intent. Transaction submission and some
cryptographic work still rely on replay plus external preflight instead of a versioned local
intent/result outbox. That is a schema and recovery change, not a safe file-movement refactor, and
must be implemented with migration and crash-matrix tests.
Loading
Loading