open-standards/smart-byte/smart-byte-rs/crates/smart-byte-state/src/demo.rs
Transaction Science f9fbd5a3af
Some checks failed
smart-byte conformance gate / Validate conformance JSON files (pull_request) Successful in 4s
smart-byte conformance gate / Second implementation reproduces every vector (pull_request) Successful in 5s
smart-byte conformance gate / Spec changes require vector-pack updates (pull_request) Successful in 4s
smart-byte conformance gate / VERSIONS.md and README.md must exist (pull_request) Successful in 3s
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Successful in 4s
standards workspaces build + test / eoc-rs (pull_request) Successful in 1m51s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m24s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m41s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m10s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 3m38s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 7m45s
standards workspaces build + test / aac-rs (pull_request) Successful in 4m3s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 1m51s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 2m3s
standards workspaces build + test / map-rs (pull_request) Successful in 5m27s
standards workspaces build + test / mesh-rs (pull_request) Successful in 2m19s
standards workspaces build + test / openpay (pull_request) Successful in 10m49s
standards workspaces build + test / arl-rs (pull_request) Successful in 47m4s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 46m44s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 42m33s
standards workspaces build + test / joulehook-rs (pull_request) Failing after 18m22s
standards workspaces build + test / sense-rs (pull_request) Successful in 10m25s
standards workspaces build + test / macOS energy backend (jcp-energy) (pull_request) Successful in 4m56s
smart-byte: governance, burns and transfers between clusters, with vectors
smart-byte-state implements cluster_state.md:
- governance: Change and Proposal, electorates, the quorum, the time lock;
- burns: Burn and the retired record;
- exports: ExportStatement and Certificate;
- the import checks.

smart-byte-core: Transition::sign_export and the destination member. The
envelope compares frames within a cluster only.

smart-byte-lockstep: the committing nodes sign each committed frame's export
certificates. The certificates are built from a committing node's report,
never from a node whose state diverged.

state_vectors.json grows to 23 vectors (state-013 to state-023 new,
state-011 extended) and is regenerated in place; v1 is DRAFT. Every new check
has a vector that fails an implementation leaving it out. The README
documents the 14 new error classes, and the regeneration log records the
change.

crosscheck/verify_v1.py implements governance, burns, exports and imports
from the spec text. It reproduces every vector, 117 of them, both plain and
under -O.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-01 11:48:44 -04:00

162 lines
5.1 KiB
Rust

//! A deterministic workload for simulations and tests: one issuer, a ring of
//! holders, and the bytes the issuer mints to them passed around the ring.
//!
//! Frame 0 carries every party's inception and the mints; each later frame
//! moves every byte one holder along. Keys derive from labels, so the same
//! workload produces the same inputs — and so the same state hashes — on
//! every run.
use smart_byte_core::keys::IndexedSignature;
use smart_byte_core::ownership::Transition;
use smart_byte_core::{Aid, Blake3Hash, Cargo, Envelope, JouleCost, Said, Signer, SigningKey};
use smart_byte_keri_witness::{Controller, KeyEvent, KeyPair, Threshold};
use crate::input::Input;
use crate::state::State;
/// The cargo type the demo issuer is registered for: USD.
pub const USD: u64 = 1;
/// The demo cluster's identifier.
pub fn cluster() -> Said {
Said::hash(b"smart-byte demo cluster")
}
fn key(label: &str) -> KeyPair {
let seed = Said::hash(format!("smart-byte demo key {label}").as_bytes()).0;
KeyPair::from_signing(SigningKey::from_bytes(&seed))
}
/// A party: its controller (whose current keys sign) and its inception, as
/// an input.
struct Party {
controller: Controller,
inception: Vec<u8>,
}
impl Party {
fn new(label: &str) -> Self {
let (controller, icp) = Controller::incept(
vec![key(&format!("{label}-0"))],
vec![key(&format!("{label}-1"))],
Threshold(1),
Threshold(1),
vec![],
Threshold(0),
)
.expect("a one-key inception");
let event = KeyEvent::Inception(icp);
let signatures: Vec<IndexedSignature> = controller
.sign_event(&event)
.expect("the controller signs its inception")
.into_iter()
.map(|(index, signature)| IndexedSignature {
index: u64::from(index),
signature,
})
.collect();
Party {
inception: Input::key_event(&event, &signatures),
controller,
}
}
fn signer(&self) -> Signer {
self.controller.signer()
}
fn aid(&self) -> Aid {
self.controller.aid
}
}
/// A byte in the workload: its identity, owner and history hash.
struct Held {
identity: Said,
owner: usize,
history: Blake3Hash,
}
/// The workload.
pub struct Workload {
issuer: Party,
holders: Vec<Party>,
bytes: Vec<Held>,
mints: Vec<Vec<u8>>,
}
impl Workload {
/// One issuer, `holders` holders, and `per_holder` USD bytes minted to
/// each.
pub fn new(holders: usize, per_holder: usize) -> Self {
let issuer = Party::new("issuer");
let holders: Vec<Party> = (0..holders.max(1))
.map(|i| Party::new(&format!("holder-{i}")))
.collect();
let mut bytes = Vec::new();
let mut mints = Vec::new();
for (owner, holder) in holders.iter().enumerate() {
for k in 0..per_holder {
let nonce: [u8; 16] =
Said::hash(format!("smart-byte demo nonce {owner}-{k}").as_bytes()).0[..16]
.try_into()
.expect("sixteen bytes");
let micros = 1_000_000 * (1 + (owner * per_holder + k) as i64);
let byte = Envelope::issue(
&issuer.signer(),
holder.aid(),
nonce,
Cargo::usd_micros(micros),
JouleCost::default(),
);
mints.push(Input::mint(&byte.provenance));
bytes.push(Held {
identity: byte.identity(),
owner,
history: byte.identity().0,
});
}
}
Workload {
issuer,
holders,
bytes,
mints,
}
}
/// The genesis state of the demo cluster: the issuer registered for USD,
/// no peers, and no governance delay.
pub fn genesis(&self) -> State {
State::genesis(cluster(), [(self.issuer.aid(), USD)], [], 0)
}
/// Frame `frame`'s inputs. Frame 0 incepts every party and mints; each
/// later frame moves every byte to the next holder. Frames must be taken
/// in order.
pub fn frame(&mut self, frame: u64) -> Vec<Vec<u8>> {
if frame == 0 {
let mut inputs = vec![self.issuer.inception.clone()];
inputs.extend(self.holders.iter().map(|h| h.inception.clone()));
inputs.extend(self.mints.iter().cloned());
return inputs;
}
let ring = self.holders.len();
self.bytes
.iter_mut()
.map(|held| {
let to = (held.owner + 1) % ring;
let t = Transition::sign(
&self.holders[held.owner].signer(),
&held.identity,
held.history,
self.holders[to].aid(),
frame,
);
held.owner = to;
held.history = t.next_history_hash();
Input::transfer(&held.identity, &t)
})
.collect()
}
}