update
This commit is contained in:
@@ -388,6 +388,8 @@ pub async fn load(
|
||||
};
|
||||
|
||||
retain_join_root(&mut state, &entry.seed);
|
||||
adopt_list_material(&mut state, &entry.seed);
|
||||
adopt_list_material(&mut state, &entry.current);
|
||||
|
||||
cache::save_state(client, &state).await?;
|
||||
held.insert(entry.community_id, state);
|
||||
@@ -396,6 +398,27 @@ pub async fn load(
|
||||
Ok(held.into_values().collect())
|
||||
}
|
||||
|
||||
/// Take the snapshot authority and retained roots a List entry names.
|
||||
fn adopt_list_material(state: &mut CommunityState, material: &JoinMaterial) {
|
||||
if material.root_epoch.0 > 0
|
||||
&& let Some(refounder) = material.refounder()
|
||||
{
|
||||
state.refounders.insert(refounder);
|
||||
}
|
||||
|
||||
for root in material.held_roots() {
|
||||
if root.epoch >= state.root_epoch || root.epoch.0 == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(refounder) = root.refounder {
|
||||
state.refounders.insert(refounder);
|
||||
}
|
||||
|
||||
retain_root(state, root.epoch, root.key, root.control_pk);
|
||||
}
|
||||
}
|
||||
|
||||
fn retain_join_root(state: &mut CommunityState, seed: &JoinMaterial) {
|
||||
if seed.root_epoch >= state.root_epoch {
|
||||
return;
|
||||
@@ -967,6 +990,50 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
/// A List entry that names the npub whose Refounding minted its epoch hands
|
||||
/// this client the authority its Guestbook snapshot is honored on, which is
|
||||
/// how a device that never held the rotation still reads the seeded roster.
|
||||
/// (What the fold then does with that authority is the neighboring test.)
|
||||
#[test]
|
||||
fn a_list_entrys_refounder_becomes_the_snapshot_authority() {
|
||||
smol::block_on(async {
|
||||
let client = client();
|
||||
let keys = Keys::generate();
|
||||
let signer = UniversalSigner::new(keys.clone());
|
||||
let refounder = Keys::generate();
|
||||
|
||||
let joined = held(
|
||||
CommunityId::from_bytes([0x42; 32]),
|
||||
Keys::generate().public_key(),
|
||||
);
|
||||
let mut rotated = joined.clone();
|
||||
rotated.root_epoch = Epoch(2);
|
||||
rotated.community_root = [0x44; 32];
|
||||
|
||||
let mut entry = list_entry(&rotated, "coop");
|
||||
entry.seed = list_entry(&joined, "coop").seed;
|
||||
entry.added_at = joined.added_at_ms;
|
||||
entry.current.extra.insert(
|
||||
"refounder".to_owned(),
|
||||
serde_json::Value::String(refounder.public_key().to_hex()),
|
||||
);
|
||||
|
||||
let list = CommunityList::default().joined(entry);
|
||||
store_fragment(&client, &signer, &list).await;
|
||||
|
||||
let loaded = load(&client, &signer, keys.public_key())
|
||||
.await
|
||||
.expect("loads");
|
||||
let state = loaded
|
||||
.iter()
|
||||
.find(|state| state.id == joined.id)
|
||||
.expect("loaded");
|
||||
|
||||
assert_eq!(state.root_epoch, Epoch(2));
|
||||
assert!(state.refounders.contains(&refounder.public_key()));
|
||||
});
|
||||
}
|
||||
|
||||
/// A List that has rotated on keeps the root of our join: the material is
|
||||
/// the community as we were given it, and the planes that root addressed
|
||||
/// stay readable only while it is held.
|
||||
|
||||
Reference in New Issue
Block a user