crates/monetize-server/src/estate_order/tests/fleet_front.rs
//! **P3-FLEET (plan §8, decided 2026-10-24): `SoldEstate` folded into `Fleet`; H16 deleted the old
//! door after its one release of overlap.**
//!
//! A sold estate's front called five `SoldEstate` RPCs (Upgrade, Recharge, TakeMaterial,
//! UpdateTake, UpdateReport), each an `EstateCall` signed by the estate's client key. They are
//! now `Fleet.Ask` kinds (`upgrade`, `recharge`, `material`, `update_take`, `update_report`),
//! signed as a `FleetCall` of `role = front`, the old door's answer carried encoded in
//! `FleetAskAnswer.answer`.
//!
//! * **A front does everything over Fleet alone**: an estate's whole update (twin live, main
//! keep-booted, front live), its material take and a recharge refused by name, through the
//! real `Fleet` service and nothing else.
//! * **H16: the old `SoldEstate` door is gone** (it was served for one release, R3+R4): a front
//! door fed no product calls nothing, by name.
//! * **Only the front asks**, signed by its fleet key or the estate's client key; any other
//! signer is UNAUTHENTICATED, and a main that asks a front's ask is refused by name.
use super::paired_update::runs_older;
use super::*;
use crate::services::fleet::FleetService;
use ed25519_dalek::Signer as _;
use monetize_embed::fleet::{ask, fleet_call_message, Ask, FleetCall, FrontAsk};
use monetize_proto as pb;
use monetize_proto::fleet_server::Fleet as _;
use prost::Message as _;
/// The estate's client key's seed, as the kit handed it to its front.
fn client_seed(r: &Rig) -> [u8; 32] {
let hexed = r
.kit
.handed
.lock()
.unwrap()
.get(crate::custody::handoff::ESTATE_CLIENT)
.cloned()
.expect("the estate was handed its client key");
let text = String::from_utf8(hexed).unwrap();
let t = text.trim();
(0..t.len())
.step_by(2)
.map(|i| u8::from_str_radix(&t[i..i + 2], 16).unwrap())
.collect::<Vec<u8>>()
.try_into()
.expect("32 bytes")
}
/// A front's (or any box's) `Fleet.Ask` of `kind`, signed by `seed` as `role` of acme now.
fn asked(r: &Rig, seed: &[u8; 32], role: &str, kind: &str, body: FrontAsk) -> pb::FleetSigned {
let product = r
.state
.fleet
.guardian()
.unwrap()
.store
.product_of("acme")
.expect("the guardian knows acme");
let body = serde_json::to_string(&Ask {
kind: kind.into(),
body: serde_json::to_value(&body).unwrap(),
})
.unwrap();
let c = FleetCall {
product,
instance: "acme".into(),
role: role.into(),
call: "ask".into(),
body,
at_unix_ms: r.clock.load(Ordering::SeqCst),
};
let signature = ed25519_dalek::SigningKey::from_bytes(seed)
.sign(&fleet_call_message(&c))
.to_bytes()
.to_vec();
pb::FleetSigned {
product: c.product,
instance: c.instance,
role: c.role,
call: c.call,
body: c.body,
at_unix_ms: c.at_unix_ms,
signature,
box_key: Vec::new(),
}
}
fn rt() -> tokio::runtime::Runtime {
tokio::runtime::Builder::new_multi_thread()
.worker_threads(2)
.enable_all()
.build()
.unwrap()
}
/// **The front over the Fleet door**: each of the five calls a `Fleet.Ask`, the answer decoded
/// from `answer` as the old door's message.
struct OverFleet<'a> {
r: &'a Rig,
seed: [u8; 32],
rt: tokio::runtime::Runtime,
}
impl OverFleet<'_> {
fn ask(&self, kind: &str, body: FrontAsk) -> Result<pb::FleetAskAnswer, tonic::Status> {
let req = asked(self.r, &self.seed, "front", kind, body);
self.rt
.block_on(FleetService(self.r.state.clone()).ask(tonic::Request::new(req)))
.map(|a| a.into_inner())
}
fn take(&self) -> Result<pb::EstateUpdateTakeResponse, tonic::Status> {
self.ask(ask::UPDATE_TAKE, FrontAsk::default()).map(|a| {
pb::EstateUpdateTakeResponse::decode(a.answer.as_slice())
.expect("an update take's answer")
})
}
fn report(&self, role: &str, outcome: &update::Outcome) -> Result<String, tonic::Status> {
let carries = update::report_carries(outcome, "");
self.ask(
ask::UPDATE_REPORT,
FrontAsk {
role: role.into(),
carries,
..Default::default()
},
)
.map(|a| {
pb::EstateUpdateReportResponse::decode(a.answer.as_slice())
.expect("a report's answer")
.words
})
}
fn upgrade(&self, role: &str, done: bool) -> Result<pb::EstateUpgradeResponse, tonic::Status> {
self.ask(
ask::UPGRADE,
FrontAsk {
role: role.into(),
done,
..Default::default()
},
)
.map(|a| {
pb::EstateUpgradeResponse::decode(a.answer.as_slice()).expect("an upgrade's answer")
})
}
fn recharge(
&self,
role: &str,
seed: &str,
) -> Result<pb::EstateRechargeResponse, tonic::Status> {
self.ask(
ask::RECHARGE,
FrontAsk {
role: role.into(),
seed: seed.into(),
..Default::default()
},
)
.map(|a| {
pb::EstateRechargeResponse::decode(a.answer.as_slice()).expect("a recharge's answer")
})
}
fn material(&self, done: bool) -> Result<pb::EstateTakeMaterialResponse, tonic::Status> {
self.ask(
ask::MATERIAL,
FrontAsk {
done,
..Default::default()
},
)
.map(|a| {
pb::EstateTakeMaterialResponse::decode(a.answer.as_slice())
.expect("a material's answer")
})
}
}
/// A delivered acme whose boxes run an older release, an update to `r10` opened by the operator,
/// and its front's material marked kept (the front drives every box, F8).
fn updating(name: &str) -> Rig {
let r = delivered(name, release_cfg("r10", true));
runs_older(&r.state, "acme");
// Its front polls (the shop knows a front that takes its update; else the front is kept first).
assert!(!take(&r, &client_of(&r, "acme")).unwrap().open);
let u = update::start(&r.state, "acme", "", "operator").expect("the operator opens an update");
assert_eq!(u.release, "r10-gunnar", "{}", u.line());
{
let _pen = r.state.estates.pen("acme");
let mut run = r.state.estates.get("acme").unwrap();
run.material_taken_at_ms = run.material_taken_at_ms.max(1);
save(&r.state, &run).unwrap();
}
r
}
fn closed(r: &Rig) {
let run = r.state.estates.get("acme").unwrap();
assert!(run.update.is_none(), "closed: {:#?}", run.update);
assert_eq!(
run.updates.last().unwrap().state,
update::state::DONE,
"{}",
run.updates.last().unwrap().line()
);
assert_eq!(
run.release_of.get("main").map(String::as_str),
Some("r10-gunnar")
);
}
/// ★ **A front does everything over Fleet alone** — the whole update (twin live, the main
/// keep-booted through `upgrade` and its `done`, the front live), the material ask and a
/// recharge of a standing box (refused by name, as the old door refuses it), each a `Fleet.Ask`
/// of `role = front` signed by the estate's client key, the old door never called.
#[test]
fn a_front_does_everything_over_fleet_alone() {
let r = updating("p3fleet-alone");
let f = OverFleet {
seed: client_seed(&r),
r: &r,
rt: rt(),
};
let t = f.take().expect("the front takes the update over Fleet");
assert!(
t.open && t.role == "twin" && t.release == "r10-gunnar",
"{t:?}"
);
assert!(
t.app.is_some(),
"the live app rides the encoded answer: {t:?}"
);
f.report("twin", &update::Outcome::Done("live".into()))
.expect("the twin's step");
assert_eq!(f.take().unwrap().role, "main");
let up = f
.upgrade("main", false)
.expect("the shop keep-boots the main over Fleet");
assert!(up.upgraded && !up.server.is_empty(), "{up:?}");
assert!(
f.upgrade("main", true)
.unwrap()
.words
.contains("re-admitted"),
"the upgrade's done"
);
f.report("main", &update::Outcome::Done("keep".into()))
.expect("the main's step");
f.report("front", &update::Outcome::Done("live".into()))
.expect("the front's step");
closed(&r);
assert!(!f.take().unwrap().open, "nothing open");
// A standing box is upgraded, never laid again: refused by name, the old door's words.
let e = f.recharge("main", "SEED").unwrap_err();
assert_eq!(e.code(), tonic::Code::FailedPrecondition, "{e:?}");
assert!(
e.message().contains("still stands at the provider"),
"{}",
e.message()
);
// The material: answered over Fleet (taken, or refused by name).
match f.material(false) {
Ok(_) => {}
Err(e) => assert_eq!(
e.code(),
tonic::Code::FailedPrecondition,
"refused by name: {e:?}"
),
}
}
/// ★ **Only the estate's front asks a front's ask**: a call under another key is
/// UNAUTHENTICATED in the Fleet door's one sentence; a front pinned with its own fleet key asks
/// with it; a box proven as the main (its pinned fleet key) is refused by name; and the old
/// guardian path still refuses a front's ask that reached it.
#[test]
fn only_the_estates_front_asks_a_fronts_ask() {
let r = updating("p3fleet-who");
let f = OverFleet {
seed: [0x33; 32],
r: &r,
rt: rt(),
};
let e = f.take().unwrap_err();
assert_eq!(e.code(), tonic::Code::Unauthenticated, "{e:?}");
assert_eq!(
e.message(),
monetize_guardian::FleetRefusal::Unauthenticated.to_string(),
"the one sentence, no estate named"
);
// The front's own fleet key, pinned in a window (an estate installed after the fold).
let g = r.state.fleet.guardian().unwrap().clone();
let now = r.clock.load(Ordering::SeqCst);
for (role, seed) in [("front", [0x44u8; 32]), ("main", [0x55u8; 32])] {
g.store.open_pin("acme", role, now + 60_000).unwrap();
let mut first = asked(&r, &seed, role, ask::UPDATE_TAKE, FrontAsk::default());
first.box_key = ed25519_dalek::SigningKey::from_bytes(&seed)
.verifying_key()
.to_bytes()
.to_vec();
let a = r.rt_ask(first);
if role == "front" {
assert!(
pb::EstateUpdateTakeResponse::decode(
a.expect("the front's own fleet key").answer.as_slice()
)
.unwrap()
.open
);
} else {
let e = a.unwrap_err();
assert_eq!(e.code(), tonic::Code::FailedPrecondition, "{e:?}");
assert!(
e.message().contains("is the estate's front's ask"),
"{}",
e.message()
);
}
}
let by_main = asked(&r, &[0x55; 32], "main", ask::GROW_SET, FrontAsk::default());
assert_ne!(
r.rt_ask(by_main).map(|_| ()).unwrap_err().code(),
tonic::Code::Unauthenticated,
"the main's own asks are its own (grow_set)"
);
// The guardian's own path never does a front's ask.
let c = FleetCall {
product: g.store.product_of("acme").unwrap(),
instance: "acme".into(),
role: "front".into(),
call: "ask".into(),
body: serde_json::to_string(&Ask {
kind: ask::UPDATE_TAKE.into(),
body: serde_json::json!({}),
})
.unwrap(),
at_unix_ms: now,
};
let sig = ed25519_dalek::SigningKey::from_bytes(&[0x44; 32])
.sign(&fleet_call_message(&c))
.to_bytes()
.to_vec();
match crate::fleet::ask(&r.state, &g, &c, &sig) {
Err(monetize_guardian::FleetRefusal::Refused(w)) => {
assert!(w.contains("a front's ask"), "{w}")
}
other => panic!("the guardian path took a front's ask: {other:?}"),
}
}
impl Rig {
fn rt_ask(&self, s: pb::FleetSigned) -> Result<pb::FleetAskAnswer, tonic::Status> {
rt().block_on(FleetService(self.state.clone()).ask(tonic::Request::new(s)))
.map(|a| a.into_inner())
}
}
/// ★ **Who the call is proven by** ([`sold::Caller`]): the old door verifies the client key's
/// `EstateCall`; the Fleet door's call is already proven. Either way an unknown or never-laid
/// estate is the one sentence [`sold::NOT_SIGNED`] names.
#[test]
fn the_caller_is_proven_by_the_door_it_came_through() {
let r = delivered("p3fleet-caller", cfg());
let run = r.state.estates.get("acme").unwrap();
let call = monetize::sign::EstateCall {
v: 1,
call: update::CALL_UPDATE_TAKE.into(),
estate: "acme".into(),
members: vec![],
gib: 0,
at_unix_ms: 0,
carries: String::new(),
};
let now = r.clock.load(Ordering::SeqCst);
let (at, sig) = signed(
&r,
&client_of(&r, "acme"),
update::CALL_UPDATE_TAKE,
"acme",
&[],
0,
);
assert_eq!(
sold::Caller::Signed {
at_ms: at,
signature: &sig
}
.run(Some(&run), &call, now)
.unwrap()
.company,
"acme"
);
assert_eq!(
sold::Caller::Signed {
at_ms: at,
signature: &[0; 64]
}
.run(Some(&run), &call, now)
.unwrap_err(),
sold::SoldRefusal::NotSigned
);
assert_eq!(
sold::Caller::Fleet
.run(Some(&run), &call, now)
.unwrap()
.company,
"acme"
);
assert_eq!(
sold::Caller::Fleet.run(None, &call, now).unwrap_err(),
sold::SoldRefusal::NotSigned
);
let mut unlaid = run.clone();
unlaid.laid = None;
assert_eq!(
sold::Caller::Fleet
.run(Some(&unlaid), &call, now)
.unwrap_err(),
sold::SoldRefusal::NotSigned
);
assert_eq!(sold::front_role_of(&r.state, &run), "front");
assert!(sold::client_key_of(&run).is_some());
assert_eq!(crate::fleet::company_of_instance(&r.state, "acme"), "acme");
assert_eq!(
crate::fleet::company_of_instance(&r.state, "nobody"),
"nobody"
);
}
/// The shared front door ([`monetize_estate_side::sold_door::ShopDoor`]) as an estate's front is
/// fed it: the door, the company and, from P3-FLEET on, the product it signs `Fleet` asks as.
fn fed_door(
r: &Rig,
door: &str,
product: Option<&str>,
) -> monetize_estate_side::sold_door::ShopDoor {
let product = product
.map(|p| format!("product = \"{p}\"\n"))
.unwrap_or_default();
let feed = std::collections::BTreeMap::from([
(
monetize_estate_side::sold_door::FEED_SHOP_DOOR.to_string(),
format!("door = \"{door}\"\ncompany = \"acme\"\n{product}"),
),
(
"secret.shop_client_key".to_string(),
monetize_estate_side::hex(&client_seed(r)),
),
]);
let clock = r.clock.clone();
monetize_estate_side::sold_door::ShopDoor::from_feed(&feed)
.expect("a door is fed")
.expect("and usable")
.with_clock(std::sync::Arc::new(move || {
clock.load(Ordering::SeqCst) as i64
}))
}
/// The update done box by box through `door` (the shared front's own calls): twin live, main
/// keep-booted, front live.
fn update_through(door: &monetize_estate_side::sold_door::ShopDoor) {
let t = door.update_take().expect("the take");
assert!(t.open && t.role == "twin", "{t:?}");
door.update_report("twin", "done:live", "")
.expect("the twin");
assert_eq!(door.update_take().unwrap().role, "main");
assert!(door.upgrade("main", false).expect("the keep boot").upgraded);
door.upgrade("main", true).expect("its done");
door.update_report("main", "done:keep", "")
.expect("the main");
door.update_report("front", "done:live", "")
.expect("the front");
assert!(!door.update_take().unwrap().open);
let e = door.recharge_box("main", "SEED", false).unwrap_err();
assert!(
e.starts_with("refused: ") && e.contains("still stands at the provider"),
"{e}"
);
}
/// ★ **Across the crates, over the real wire**: the shared front door (monetize-estate-side)
/// fed its product does the whole update against a ONE box that mounts `Fleet` ALONE; H16: a
/// door fed no product calls nothing (there is no old door to fall back to), by name.
#[test]
fn the_shared_front_door_updates_an_estate_over_fleet_alone_and_a_door_with_no_product_calls_nothing(
) {
let rt = rt();
let listen = |rt: &tokio::runtime::Runtime| {
let l = rt
.block_on(tokio::net::TcpListener::bind("127.0.0.1:0"))
.unwrap();
let at = format!("http://{}", l.local_addr().unwrap());
(tokio_stream::wrappers::TcpListenerStream::new(l), at)
};
let r = updating("p3fleet-wire-fleet");
let product = r
.state
.fleet
.guardian()
.unwrap()
.store
.product_of("acme")
.unwrap();
let (incoming, at) = listen(&rt);
rt.spawn(
tonic::transport::Server::builder()
.add_service(pb::fleet_server::FleetServer::new(FleetService(
r.state.clone(),
)))
.serve_with_incoming(incoming),
);
let door = fed_door(&r, &at, Some(&product));
assert!(door.on_fleet());
update_through(&door);
closed(&r);
let r = updating("p3fleet-wire-noproduct");
let (incoming, at) = listen(&rt);
rt.spawn(
tonic::transport::Server::builder()
.add_service(pb::fleet_server::FleetServer::new(FleetService(
r.state.clone(),
)))
.serve_with_incoming(incoming),
);
let door = fed_door(&r, &at, None);
assert!(!door.on_fleet(), "fed no product");
assert_eq!(
door.update_take().unwrap_err(),
monetize_estate_side::sold_door::NO_PRODUCT
);
let moved = door.or_over_fleet(&product);
update_through(&moved);
closed(&r);
}
/// An operator site `gunnar-rs` (company `gunnarrs`, its boxes pulling as the label
/// `gunnar-rs`), laid and paid, its boxes on an older release, an update to `r10` opened by the
/// operator and its front's material kept.
fn site_updating(name: &str) -> (Arc<AppState>, Arc<FakeKit>, Arc<AtomicU64>) {
let (state, pay, _cloud, kit, _dir, clock, _mails) =
super::site_rig_with_cfg(name, false, release_cfg("r10", true));
let run = site::start_site(
&state,
"gunnar-rs",
"ops@mock.invalid",
&EstateSizes::default(),
)
.expect("the operator's site order is taken");
pay.authorize(&run.handle.clone().unwrap().id);
drive(&state, "gunnarrs");
let run = state.estates.get("gunnarrs").unwrap();
assert_eq!(run.phase, phase::CAPTURED, "{:#?}", run.history);
assert_eq!(
(run.company.as_str(), run.fleet_name()),
("gunnarrs", "gunnar-rs"),
"the company is not the fleet's name"
);
let g = state.fleet.guardian().unwrap();
assert_eq!(
g.store.product_of("gunnar-rs").as_deref(),
Some("gunnar"),
"the fleet knows the site by its label"
);
assert_eq!(
g.store.product_of("gunnarrs"),
None,
"and not by its company"
);
runs_older(&state, "gunnarrs");
// Its front polls (the shop knows a front that takes its update; else the front is kept first).
assert!(
!update::take_as(&state, "gunnarrs", sold::Caller::Fleet)
.unwrap()
.open
);
update::start(&state, "gunnarrs", "", "operator").expect("the operator opens an update");
{
let _pen = state.estates.pen("gunnarrs");
let mut run = state.estates.get("gunnarrs").unwrap();
run.material_taken_at_ms = run.material_taken_at_ms.max(1);
save(&state, &run).unwrap();
}
(state, kit, clock)
}
/// The shared front door as an operator site's front was fed BEFORE P3-FLEET 6/8 (3dcd6154,
/// 2026-10-25): `shop_door.toml` names the company and no `product`; the fed `fleet_instance`
/// is the site's label. Its product's front then calls `or_over_fleet` (Holger's `door_of`,
/// Gunnar's front), which signs as the COMPANY.
fn site_door_fed_before_the_fold(
kit: &FakeKit,
clock: &Arc<AtomicU64>,
door: &str,
) -> monetize_estate_side::sold_door::ShopDoor {
let hexed = kit
.handed
.lock()
.unwrap()
.get(crate::custody::handoff::ESTATE_CLIENT)
.cloned()
.expect("the site was handed its client key");
let feed = std::collections::BTreeMap::from([
(
monetize_estate_side::sold_door::FEED_SHOP_DOOR.to_string(),
format!("door = \"{door}\"\ncompany = \"gunnarrs\"\n"),
),
(
"secret.shop_client_key".to_string(),
String::from_utf8(hexed).unwrap().trim().to_string(),
),
(
monetize_estate_side::sold_door::FEED_FLEET_INSTANCE.to_string(),
"gunnar-rs".to_string(),
),
]);
let clock = clock.clone();
monetize_estate_side::sold_door::ShopDoor::from_feed(&feed)
.expect("a door is fed")
.expect("and usable")
.with_clock(std::sync::Arc::new(move || {
clock.load(Ordering::SeqCst) as i64
}))
.or_over_fleet("gunnar")
}
/// ★ **R6-FIX-4: a ONE box serves the fronts one release behind.** An operator site's front fed
/// before the fold signs its `Fleet.Ask` as its run's COMPANY (`gunnarrs`), while the fleet
/// knows the site by its label (`gunnar-rs`). Such a front's update pull (`update_take`), its
/// reports, its keep boot (`upgrade`), a recharge and its material are answered over Fleet, as
/// the old `SoldEstate` door answered them, proven by the estate's client key. (Prod, R6 step 3:
/// test2.holger.rs's front on Holger f8101408 pulled UNAUTHENTICATED, fell back to the deleted
/// SoldEstate door and got a 404.) A signer that is not the estate's client key is still
/// UNAUTHENTICATED as the company, and a front fed its product (signing as the label) is as
/// before.
#[test]
fn an_operator_sites_front_fed_before_the_fold_asks_as_its_company_and_is_answered() {
let rt = rt();
let (state, kit, clock) = site_updating("r6fix4-site-company");
let l = rt
.block_on(tokio::net::TcpListener::bind("127.0.0.1:0"))
.unwrap();
let at = format!("http://{}", l.local_addr().unwrap());
rt.spawn(
tonic::transport::Server::builder()
.add_service(pb::fleet_server::FleetServer::new(FleetService(
state.clone(),
)))
.serve_with_incoming(tokio_stream::wrappers::TcpListenerStream::new(l)),
);
let door = site_door_fed_before_the_fold(&kit, &clock, &at);
assert_eq!(
(
door.on_fleet(),
door.fleet_product().as_deref(),
door.fleet_instance().as_deref()
),
(true, Some("gunnar"), Some("gunnarrs")),
"the old front's encoding: instance = the company"
);
update_through(&door);
let run = state.estates.get("gunnarrs").unwrap();
assert!(run.update.is_none(), "closed: {:#?}", run.update);
assert_eq!(
run.release_of.get("main").map(String::as_str),
Some("r10-gunnar")
);
match door.take_material(false) {
Ok(_) => {}
Err(e) => assert!(
e.starts_with("refused: "),
"the material is answered, or refused by name: {e}"
),
}
// Another key, as the company: still the one UNAUTHENTICATED sentence.
let body = serde_json::to_string(&Ask {
kind: ask::UPDATE_TAKE.into(),
body: serde_json::to_value(FrontAsk::default()).unwrap(),
})
.unwrap();
let c = FleetCall {
product: "gunnar".into(),
instance: "gunnarrs".into(),
role: "front".into(),
call: "ask".into(),
body,
at_unix_ms: clock.load(Ordering::SeqCst),
};
let signature = ed25519_dalek::SigningKey::from_bytes(&[0x33; 32])
.sign(&fleet_call_message(&c))
.to_bytes()
.to_vec();
let forged = pb::FleetSigned {
product: c.product.clone(),
instance: c.instance.clone(),
role: c.role.clone(),
call: c.call.clone(),
body: c.body.clone(),
at_unix_ms: c.at_unix_ms,
signature,
box_key: Vec::new(),
};
let e = rt
.block_on(FleetService(state.clone()).ask(tonic::Request::new(forged)))
.unwrap_err();
assert_eq!(e.code(), tonic::Code::Unauthenticated, "{e:?}");
// The wrong product, as the company, is not this site's.
let mut wrong = c.clone();
wrong.product = "holger".into();
let hexed = kit
.handed
.lock()
.unwrap()
.get(crate::custody::handoff::ESTATE_CLIENT)
.cloned()
.unwrap();
let t = String::from_utf8(hexed).unwrap();
let seed: [u8; 32] = (0..64)
.step_by(2)
.map(|i| u8::from_str_radix(&t.trim()[i..i + 2], 16).unwrap())
.collect::<Vec<u8>>()
.try_into()
.unwrap();
let signature = ed25519_dalek::SigningKey::from_bytes(&seed)
.sign(&fleet_call_message(&wrong))
.to_bytes()
.to_vec();
let w = pb::FleetSigned {
product: wrong.product,
instance: wrong.instance,
role: wrong.role,
call: wrong.call,
body: wrong.body,
at_unix_ms: wrong.at_unix_ms,
signature,
box_key: Vec::new(),
};
assert_eq!(
rt.block_on(FleetService(state.clone()).ask(tonic::Request::new(w)))
.unwrap_err()
.code(),
tonic::Code::Unauthenticated,
"another product as the company"
);
// A front fed its product signs as the label: answered, as before.
let hexed = kit
.handed
.lock()
.unwrap()
.get(crate::custody::handoff::ESTATE_CLIENT)
.cloned()
.unwrap();
let feed = std::collections::BTreeMap::from([
(
monetize_estate_side::sold_door::FEED_SHOP_DOOR.to_string(),
format!("door = \"{at}\"\ncompany = \"gunnarrs\"\nproduct = \"gunnar\"\n"),
),
(
"secret.shop_client_key".to_string(),
String::from_utf8(hexed).unwrap().trim().to_string(),
),
(
monetize_estate_side::sold_door::FEED_FLEET_INSTANCE.to_string(),
"gunnar-rs".to_string(),
),
]);
let c2 = clock.clone();
let new = monetize_estate_side::sold_door::ShopDoor::from_feed(&feed)
.unwrap()
.unwrap()
.with_clock(std::sync::Arc::new(move || {
c2.load(Ordering::SeqCst) as i64
}));
assert_eq!(new.fleet_instance().as_deref(), Some("gunnar-rs"));
assert!(
!new.update_take()
.expect("the new front's pull, as the label")
.open
);
}
/// ★ **R6-FIX-4: a company is resolved only when it names ONE estate.** A front asking as a
/// company that another run also answers to (here a second operator-site run whose label is
/// that company) is refused by name ([`"[front-company-ambiguous]"`]), never answered
/// for either estate.
#[test]
fn a_front_asking_as_an_ambiguous_company_is_refused_by_name() {
let rt = rt();
let (state, kit, clock) = site_updating("r6fix4-site-ambiguous");
{
let _pen = state.estates.pen("other");
let mut other = state.estates.get("gunnarrs").unwrap();
other.company = "other".into();
other.estate = "gunnarrs".into();
other.site_order = true;
save(&state, &other).unwrap();
}
let l = rt
.block_on(tokio::net::TcpListener::bind("127.0.0.1:0"))
.unwrap();
let at = format!("http://{}", l.local_addr().unwrap());
rt.spawn(
tonic::transport::Server::builder()
.add_service(pb::fleet_server::FleetServer::new(FleetService(
state.clone(),
)))
.serve_with_incoming(tokio_stream::wrappers::TcpListenerStream::new(l)),
);
let door = site_door_fed_before_the_fold(&kit, &clock, &at);
let e = door.update_take().unwrap_err();
assert!(
e.starts_with("refused: ") && e.contains(crate::fleet::FRONT_COMPANY_AMBIGUOUS),
"{e}"
);
assert!(
state.estates.get("gunnarrs").unwrap().update.is_some(),
"nothing taken for either estate"
);
}
/// ★ **RA5-44: an unproven ask learns nothing of the ambiguity.** `front_by_company`
/// answered `[front-company-ambiguous]` (and how many estates the name maps to) BEFORE any
/// signature was checked; a signer that is none of the candidate estates' keys gets the one
/// UNAUTHENTICATED every other unproven ask gets.
#[test]
fn an_unproven_ask_as_an_ambiguous_company_is_unauthenticated() {
let rt = rt();
let (state, _kit, clock) = site_updating("ra5-44-ambiguous-unproven");
{
let _pen = state.estates.pen("other");
let mut other = state.estates.get("gunnarrs").unwrap();
other.company = "other".into();
other.estate = "gunnarrs".into();
other.site_order = true;
save(&state, &other).unwrap();
}
let body = serde_json::to_string(&Ask {
kind: ask::UPDATE_TAKE.into(),
body: serde_json::to_value(FrontAsk::default()).unwrap(),
})
.unwrap();
let c = FleetCall {
product: "gunnar".into(),
instance: "gunnarrs".into(),
role: "front".into(),
call: "ask".into(),
body,
at_unix_ms: clock.load(Ordering::SeqCst),
};
let signature = ed25519_dalek::SigningKey::from_bytes(&[0x33; 32])
.sign(&fleet_call_message(&c))
.to_bytes()
.to_vec();
let forged = pb::FleetSigned {
product: c.product.clone(),
instance: c.instance.clone(),
role: c.role.clone(),
call: c.call.clone(),
body: c.body.clone(),
at_unix_ms: c.at_unix_ms,
signature,
box_key: Vec::new(),
};
let e = rt
.block_on(FleetService(state.clone()).ask(tonic::Request::new(forged)))
.unwrap_err();
assert_eq!(e.code(), tonic::Code::Unauthenticated, "{e:?}");
assert!(
!e.message().contains(crate::fleet::FRONT_COMPANY_AMBIGUOUS),
"{e:?}"
);
}
/// **The ONE box's edge, as it cut the call** (edda `estate-front::web`, RA5-22): every byte
/// carried both ways, and a connection silent for `idle` closed — prod's is 120 s; a front's
/// Upgrade that waits on a 4-6 min keep boot sends nothing in between.
fn idle_cutting_edge(
rt: &tokio::runtime::Runtime,
to: std::net::SocketAddr,
idle: std::time::Duration,
) -> String {
use tokio::io::{AsyncReadExt as _, AsyncWriteExt as _};
let l = rt
.block_on(tokio::net::TcpListener::bind("127.0.0.1:0"))
.unwrap();
let at = format!("http://{}", l.local_addr().unwrap());
rt.spawn(async move {
while let Ok((mut a, _)) = l.accept().await {
tokio::spawn(async move {
let Ok(mut b) = tokio::net::TcpStream::connect(to).await else { return };
let (mut ab, mut bb) = ([0u8; 16 * 1024], [0u8; 16 * 1024]);
loop {
tokio::select! {
n = a.read(&mut ab) => match n { Ok(n) if n > 0 => { if b.write_all(&ab[..n]).await.is_err() { return } } _ => return },
n = b.read(&mut bb) => match n { Ok(n) if n > 0 => { if a.write_all(&bb[..n]).await.is_err() { return } } _ => return },
_ = tokio::time::sleep(idle) => return,
}
}
});
}
});
at
}
/// ★ **REL-T2-1 (prod 2026-10-29: test2.gunnar.rs three tries, holger.rs failed)**: the front's
/// Upgrade rides the ONE box's edge, which closes a connection silent past its idle bound. The
/// shop's keep boot runs on after the cut, so the shared front door starts the Upgrade and polls
/// it: the cut is never the update's failure, the box is keep-booted ONCE (a poll while it runs
/// is answered "already running", and one after it "already runs"), the front is told
/// `upgraded` so it re-admits the box, and the update closes.
#[test]
fn a_keep_boot_longer_than_the_edges_idle_cut_is_polled_to_done_never_failed() {
let rt = rt();
let r = updating("relt21-edge-cut");
r.cloud.keep_boot_ms.store(1_500, Ordering::SeqCst);
let product = r
.state
.fleet
.guardian()
.unwrap()
.store
.product_of("acme")
.unwrap();
let l = rt
.block_on(tokio::net::TcpListener::bind("127.0.0.1:0"))
.unwrap();
let server = l.local_addr().unwrap();
rt.spawn(
tonic::transport::Server::builder()
.add_service(pb::fleet_server::FleetServer::new(FleetService(
r.state.clone(),
)))
.serve_with_incoming(tokio_stream::wrappers::TcpListenerStream::new(l)),
);
let edge = idle_cutting_edge(&rt, server, std::time::Duration::from_millis(400));
let polling = monetize_estate_side::sold_door::Polling {
ask: std::time::Duration::from_secs(10),
every: std::time::Duration::from_millis(100),
within: std::time::Duration::from_secs(60),
};
let door = fed_door(&r, &edge, Some(&product)).with_polling(polling);
assert_eq!(door.update_take().unwrap().role, "twin");
door.update_report("twin", "done:live", "")
.expect("the twin");
assert_eq!(door.update_take().unwrap().role, "main");
let up = door.upgrade("main", false).expect(
"the keep boot outlived the edge's idle cut, and the front polled it to the shop's answer",
);
assert!(
up.upgraded,
"the front re-admits the box its cut ask keep-booted: {up:?}"
);
assert_eq!(
r.cloud.keep_booted.lock().unwrap().len(),
1,
"the main was keep-booted once, polls never boot it again"
);
assert!(
door.upgrade("main", true)
.unwrap()
.words
.contains("re-admitted"),
"the upgrade's done"
);
door.update_report("main", "done:keep", "")
.expect("the main");
door.update_report("front", "done:live", "")
.expect("the front");
closed(&r);
}