//! BFT consensus, deterministically: three members each propose a signed op, all //! proposals reach every member, and each commits to a byte-identical agreed log — //! while a non-member's op is rejected. This exercises the same `Round` the daemon //! drives over QUIC/TCP/socket via `consensus_propose`/`propose`/`commit_round`. use ed25519_dalek::SigningKey; use joule_code_schema::{ContentId, Tier}; use joule_coded::consensus::Round; use joule_core::ops::build_coding_op; /// Build a signed op for `intent` authored by `key`, with its prior. fn member_op(key: &SigningKey, intent: &str) -> (joule_code_cargo::SignedOp, ContentId) { let op = build_coding_op( "consensus", "", intent, intent.to_string(), Tier::L1, key.verifying_key().to_bytes(), ); let prior = op.prior.clone(); (op.sign(key).expect("sign"), prior) } #[test] fn three_members_reach_byte_identical_agreed_log() { let keys: Vec = (1u8..=3).map(|i| SigningKey::from_bytes(&[i; 32])).collect(); let members: Vec<[u8; 32]> = keys.iter().map(|k| k.verifying_key().to_bytes()).collect(); // Each member proposes its own op (distinct author ⇒ distinct op). let proposals: Vec<_> = keys.iter().map(|key| member_op(key, "round-1")).collect(); // Three independent member views each receive all proposals and commit. let mut hashes = Vec::new(); for _ in 0..members.len() { let mut round = Round { members: members.clone(), proposals: Vec::new(), }; for (op, prior) in &proposals { round.accept(op.clone(), prior.clone()).expect("accept valid member op"); } let (hash, committed) = round.commit(); assert_eq!(committed.len(), 3, "all three valid proposals commit"); hashes.push(hash); } assert!( hashes.windows(2).all(|pair| pair[0] == pair[1]), "honest members must agree on a byte-identical log: {hashes:?}" ); // Buffering order does not change the agreed log (commit is op-id ordered). let mut reversed = Round { members: members.clone(), proposals: Vec::new(), }; for (op, prior) in proposals.iter().rev() { reversed.accept(op.clone(), prior.clone()).expect("accept"); } assert_eq!(reversed.commit().0, hashes[0], "order-independent agreed log"); // A non-member's op is rejected before it can enter the round. let intruder = SigningKey::from_bytes(&[9u8; 32]); let (op, prior) = member_op(&intruder, "round-1"); let mut round = Round { members, proposals: Vec::new(), }; assert!( round.accept(op, prior).is_err(), "a non-member proposal must be refused" ); }