Dissemination
Send new blocks directly. Their pointers reveal what a peer knows, so missing history can be repaired.
From protocol research to a non-breaking consensus prototype inside the f1r3node ecosystem.
The protocol
Cordial Miners is a family of Byzantine Atomic Broadcast protocols. Instead of forcing every event into one chain, miners cooperatively build a DAG and derive the same safe order locally.
Send new blocks directly. Their pointers reveal what a peer knows, so missing history can be repaired.
Conflicting blocks may exist in the DAG, but approval rules keep tainted branches out of final output.
Final leaders anchor τ, which topologically converts eligible DAG history into a stable local sequence.
The host stack
It is a reusable node stack for quickly building the shard that best fits a domain.
A domain chain can reuse networking, APIs, execution, storage, and validator infrastructure while selecting the consensus path and policies it needs. Cordial Miners proves that boundary by running as an explicit prototype mode alongside CBC Casper.
slide 04 · consensus architecture
The core lesson from DAG/BFT study: reachability tells what a block can see, but finality also needs Byzantine-aware support predicates.
Cordial Miners cannot treat simple DAG ancestry as enough. It must combine causal reachability, validator support, equivocation exclusion, and safe leader selection before a local τ can become final output.
Tracks causal evidence across the blocklace and the partial view each miner holds.
Asks whether enough non-equivocating validator support makes that evidence safe.
Chains inherit one parent; Cordial Miners reasons over many parents and conflicts.
Reviewed how consensus-facing state stays separated from runtime-facing execution, storage, and API components in f1r3node.
Discussed the intended Cordial Miners integration shape with the f1r3node team and aligned around clear architecture boundaries.
slide 05 · intern guidance
Created the first major issue structure so interns could work from clear boundaries: workspace split first, protocol math second, consensus safety third.
Defined the Cargo workspace split: keep consensus math isolated in cordial-miners-core and node wiring in cordial-miners-adapter.
Scoped the generic blocklace data model and deterministic causal traversal primitives needed before higher-level Cordial Miners rules can be trusted.
Separated core cordiality/equivocation predicates and durable evidence tracking from adapter-side slashing transaction encoding.
slide 06 · F1R3FLY integration
The later issues made the plan concrete: finality and ordering rules had to end in a bridge that f1r3node can propose, persist, test, and operate.
Framed weighted cordial operators, leader finality, deterministic tau, and pruning/checkpoint behavior as the path from DAG evidence to stable output.
Connected core protocol math to live-node concerns: gRPC ingest, proposer flow with RSpace, crypto, storage, and conformance testing.
slide 07 · architecture refactor
feat: core/adapter workspace setup with generic consensus traits #32 turned the planning issues into Rust architecture: pure protocol math in core, f1r3node-facing wiring in adapters, and a factory seam for runtime selection.
cordial-miners-core owns blocklace, reachability, cordiality,
approval, ratification, finality, ordering, pruning, and validation.
ConsensusEngine, BlockProvider, and ValidatorSet let tests, repositories, RSpace-backed nodes, and
future replay tools call the same core abstractly.
cordial-f1r3node-adapter and cordial-f1r3space-adapter own translation, ingestion, proposer,
persistence, runtime, crypto, and slashing bridges.
ConsensusFactory.build(kind) → Box<dyn AdapterConsensusEngine>crates/cordial-miners-core crates/cordial-f1r3node-adapter crates/cordial-f1r3space-adapterslide 08 · intern PR review
Issue 1: Build gRPC-to-Blocklace Adapter It created the first clean boundary from f1r3node network block messages into Cordial Miners blocklace blocks.
message_to_block(...) maps protobuf/wire shape into core blocklace
format without database writes, inserts, or finality updates.
Checks 32-byte hashes, recomputed content hash, identity hash, signatures, and structurally valid parent creator keys before consensus mutation.
Covered valid mapping, corrupted hashes, invalid signatures, wrong creator keys, predecessor chains, determinism, and adapter rejection.
slide 09 · crypto adapter
F1r3fly Crypto Adapter implemented the core CryptoVerifier trait with f1r3node-compatible signature checking.
blocklace.insert(block, verifier)verify_block(content, signature, creator)recompute hash(content)Secp256k1Scheme / Ed25519SchemeEmpty algorithm names default to Secp256k1, explicit strings select the scheme, and unknown algorithms fail instead of silently accepting bad input.
The adapter recomputes the block hash from content during verification, rejects empty signatures, and catches tampered content after signing.
slide 10 · PR #54 safety ladder
Approval, Ratification and Super Ratification it moved the project from valid block
ingestion toward Byzantine-aware support inside cordial-miners-core.
Messages may arrive late, so every block carries a local DAG view through its predecessor closure. The predicates must be safe on partial views and still converge as honest nodes eventually receive the same blocklace evidence.
A block sees the target and does not see an incomparable conflict from that creator.
A block's closure contains a stake supermajority of blocks approving the target.
A witness set contains a stake supermajority of blocks ratifying the target.
slide 11 · approver model
In approves(blocklace, approver, target), the approver is not a
special role or vote message. It is the block whose predecessor history judges
whether it safely supports another block.
conflict(t,t') := same_creator and incomparable(t,t') and observed_by(approver,t')approves(b,t) := observes(b,t) and no observed t' conflicts with tThe creator may make many blocks. Each block has its own DAG view, so approval is checked from a block identity and its observed predecessor closure.
PR #54 corrected the rule toward same creator, incomparable with target, and observed by the approver. Conflicts can happen across branches, not only rounds.
slide 12 · ratification math
Ratification aggregates approval. Super-ratification aggregates knowledge that ratification happened. Under eventual synchrony, lagging honest nodes can catch up to the same final leader evidence before tau ordering.
sum(weight(approvers)) * 3 > total_weight * 2sum(weight(ratifiers)) * 3 > total_weight * 2Two conflicting ratifications would need overlapping supermajorities. Honest overlap cannot approve both because approval rejects observed equivocation.
It proves that enough stake has seen enough ratification. That meta-knowledge is what later finality logic can use before tau ordering.
gRPC ingestion prepares valid core blocks. Approval, ratification, and super-ratification interpret those blocks after they enter the blocklace.
slide 13 · PR #62 weighted ratification
PR #62 Add weighted ratification variants it preserved the paper-native predicates while adding f1r3node-compatible stake accounting.
The original predicates treat each miner as one support unit. That is useful for proving the Cordial Miners protocol shape.
f1r3node is Proof-of-Stake oriented, so the weighted variants measure support by total validator bond weight.
Approval stays DAG and Byzantine-aware. Only the support accounting changes from "how many creators" to "how much bonded stake."
weighted_approving_creators(...) Collects positive-weight creators whose blocks approve the target.
weighted_ratifies(...) Checks whether a ratifier's closure has enough weighted approval.
weighted_super_ratifies(...) Checks whether witnesses contain enough weighted ratifiers.
is_weighted_supermajority(...) Applies the strict stake threshold without floating point math.
slide 14 · weighted implementation
The weighted path receives HashMap<NodeId, u64>: a decision-context
bond map. Unknown and zero-weight creators are ignored, and each creator is counted
once with HashSet<NodeId>.
support_weight * 3 > total_weight * 2A=4, B=3, C=3; {A,B}=7/10 passes, {B,C}=6/10 failsIf one validator creates multiple approving blocks, its bond contributes once. Support is by creator weight, not block count.
Weights are u64, but sums and multiplication use u128 checked arithmetic so overflow cannot create a false supermajority.
PR #62 did not implement leader finality, tau ordering, networking, or proposal. It added the stake-aware support predicates those later steps can use.
slide 15 · PR #79 checkpoint pruning
PR #79 Add Checkpoint DAG pruning keeps the active blocklace bounded: after a final leader is known, old ancestors
can leave the in-memory HashMap while tau output is preserved.
Before removing ancestors, the blocklace stores compact checkpoint_order_prefix and checkpoint_weighted_order_prefix identity sequences.
checkpoint_after_weighted_finality(...) finds the weighted final
leader, computes weighted_tau, stores its prefix, then prunes.
Unknown, backward, or disconnected checkpoints are rejected, and retained live blocks keep any predecessors they still reference.
final leader tau / weighted_tau prefix prune observed ancestors observe() stops at checkpointslide 16 · PR #90 LMDB persistence
PR #90 Feat lmdb added a disk-backed repository for Cordial blocks. The consensus core still owns blocklace rules; the adapter owns durable storage and restart recovery.
<data_dir>/blocklace/The node supplies the data directory. LMDB creates its environment files under the Cordial blocklace subdirectory.
cordial-blocksStores bincode(BlockIdentity) to bincode(Block), enough
to reconstruct predecessor links after restart.
cordial-metaStores finalized_cursor as a compact finality bookmark, not as the
block body itself.
bincode is local disk serialization for LMDB persistence. It is not the
node-to-node wire format; f1r3node network boundaries use protobuf/prost shapes.
slide 17 · restart recovery
PR #90 makes restart possible by reopening LMDB, reading persisted Cordial blocks, sorting them so predecessors appear before children, then replaying them into the in-memory blocklace.
The write path persists a block before in-memory insertion. If the process crashes after commit, recovery can replay the durable block.
Blocklace::insert requires predecessors to exist first, so recovery
sorts by DAG height before replay.
BlocklaceRepository sits behind Arc<dyn ...>, so
LMDB can be attached without coupling consensus math to heed.
put_block(block) before engine.insert(block) Ok(None) means missing; Err means storage or decode failure corrupt scan entries warn and skip; direct corrupt get returns Bincode errorslide 18 · slashing boundary
The f1r3node adapter keeps slashing outside the pure blocklace protocol. Core consensus detects conflicting same-creator blocks; the adapter prepares that evidence for f1r3node-facing consequences.
Approval rejects a target when the approver observes an incomparable block from the same creator. That is the DAG-level equivocation signal.
The slashing module belongs with f1r3node wiring, alongside block
translation, crypto bridge, proposer, repository, and runtime bridge modules.
f1r3node-specific code can decide how equivocation evidence maps to validator accounting, penalties, or transaction/runtime behavior.
block_translation crypto_bridge grpc_ingest repository runtime_bridge slashingslide 19 · PR #98 Docker demo
PR #98 Integrate Cordial Miners runtime, demos, and conformance coverage packaged the runtime-facing integration surface: adapter conformance tests, standalone Cordial startup, and a four-node local-intercept demo.
--consensus cordial-minersCBC Casper stays the default. The demo starts the Cordial path only through the explicit consensus selection and adapter wiring.
docker/four-node-intercept.ymlFour local runtimes intercept proposals, expose block views, and exercise the Cordial ordering path without claiming production peer replacement.
verify-four-node-order.shThe script waits for HTTP APIs, checks network and validator status, reads each block view, then compares the ordered projection across all nodes.
The evidence target is local convergence: all four runtimes report the same ordered Cordial view. That is useful demo proof, while full production f1r3node networking hardening remains out of scope for this PR.
slide 20 · f1r3node contribution track
The quarter had two connected f1r3node tracks: upstream Rust-node recovery in PR #63 and fork-side runtime abstraction in Nama21yo/f1r3node. Both kept CBC Casper as the default path while making failure recovery and Cordial integration easier to test.
A stale validator leaves Running, re-enters initialization,
requests ApprovedBlock, and rebuilds from the majority chain.
The fork adds ConsensusKind, adapter traits, packet routing, and
runtime setup so Cordial Miners can be selected explicitly.
42 passed, 0 failedPR #63 includes stale recovery tests, minority-fork regression coverage, Rholang payload-capture coverage, and CI/advisory follow-up.
The adapter abstraction is contribution work on the fork. Describe it as runtime-selectable integration work, not merged upstream f1r3node behavior.
The shared value is a safer integration boundary: validators can recover from a dead minority branch, while node APIs gain a clear place to route Casper or Cordial behavior without changing the default consensus mode.