Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@

### Fixed

- A worldline frontier retains the state root computed by its last executable-operation Action commit and returns it without hashing until the graph is next accessed mutably. An Action tick after the first now hashes the whole reachable state once instead of twice. Debug builds hash again to check each retained root, so they do not get the saving. The graph field of `WorldlineState` is private to its module so that every mutation goes through the accessor that drops the retained root.

- A filesystem WAL writer that takes over an existing log syncs its segment files before reading them as recovered history. A record that an earlier writer wrote and never synced was readable after reopen and was reported as a durable acceptance; a later power loss could still lose it.

- A scheduler pass that commits executable-operation Actions hashes the worldline's whole reachable state twice instead of three times. The root before the commit is the root the pass already computed for the frontier basis; the commit no longer computes it again.
Expand Down
25 changes: 20 additions & 5 deletions crates/warp-core/src/coordinator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7751,7 +7751,10 @@ mod tests {
{
let frontier = runtime.worldlines.frontier_mut(&worldline_b).unwrap();
let broken_root = frontier.state.root.warp_id;
assert!(frontier.state.warp_state.delete_instance(&broken_root));
assert!(frontier
.state
.warp_state_mut()
.delete_instance(&broken_root));
}
SchedulerCoordinator::super_tick(&mut runtime, &mut provenance, &mut engine).unwrap_err();

Expand Down Expand Up @@ -7842,7 +7845,10 @@ mod tests {
{
let frontier = runtime.worldlines.frontier_mut(&worldline_b).unwrap();
let broken_root = frontier.state.root.warp_id;
assert!(frontier.state.warp_state.delete_instance(&broken_root));
assert!(frontier
.state
.warp_state_mut()
.delete_instance(&broken_root));
}

let mut provenance = mirrored_provenance(&runtime);
Expand Down Expand Up @@ -7999,7 +8005,10 @@ mod tests {
{
let frontier = runtime.worldlines.frontier_mut(&worldline_b).unwrap();
let broken_root = frontier.state.root.warp_id;
assert!(frontier.state.warp_state.delete_instance(&broken_root));
assert!(frontier
.state
.warp_state_mut()
.delete_instance(&broken_root));
}

let mut provenance = mirrored_provenance(&runtime);
Expand Down Expand Up @@ -8088,7 +8097,10 @@ mod tests {
{
let frontier = runtime.worldlines.frontier_mut(&worldline_b).unwrap();
let broken_root = frontier.state.root.warp_id;
assert!(frontier.state.warp_state.delete_instance(&broken_root));
assert!(frontier
.state
.warp_state_mut()
.delete_instance(&broken_root));
}

let mut provenance = mirrored_provenance(&runtime);
Expand Down Expand Up @@ -8167,7 +8179,10 @@ mod tests {
{
let frontier = runtime.worldlines.frontier_mut(&worldline_b).unwrap();
let broken_root = frontier.state.root.warp_id;
assert!(frontier.state.warp_state.delete_instance(&broken_root));
assert!(frontier
.state
.warp_state_mut()
.delete_instance(&broken_root));
}

let mut provenance = mirrored_provenance(&runtime);
Expand Down
15 changes: 9 additions & 6 deletions crates/warp-core/src/echo_operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6299,8 +6299,11 @@ pub(crate) fn commit_scheduler_action_batch_to_state_v1(
.map(u32::try_from)
.collect::<Result<Vec<_>, _>>()
.map_err(|_| EchoOperationCommitErrorV1::TooManyCandidates)?;
patch.apply_journaled(&mut state.warp_state, journal)?;
state.apply_patch_journaled(&patch, journal)?;
let state_root_after = state.state_root();
// The next reading of this frontier's root, for example the basis of the
// next tick, does not hash the state again.
state.retain_state_root(state_root_after);
let parents = state
.last_snapshot
.as_ref()
Expand Down Expand Up @@ -6618,12 +6621,12 @@ pub(crate) fn commit_prepared_to_state(
vec![Vec::new()],
);
// Nothing after this application can fail, so the journal is not kept.
prepared.patch.apply_journaled(
&mut state.warp_state,
state.apply_patch_journaled(
&prepared.patch,
&mut crate::tick_patch::StateJournal::default(),
)?;
let state_root_after =
crate::snapshot::compute_state_root_for_warp_state(&state.warp_state, state.root());
let state_root_after = state.state_root();
state.retain_state_root(state_root_after);
let parents = state
.last_snapshot
.as_ref()
Expand Down Expand Up @@ -8618,7 +8621,7 @@ mod tests {
);

state
.warp_state
.warp_state_mut()
.store_mut(&root_warp)
.expect("the fixture retains its root store")
.set_node_attachment(
Expand Down
14 changes: 10 additions & 4 deletions crates/warp-core/src/echo_operation/observed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,10 @@ mod tests {
local_id: crate::make_node_id("unrelated"),
}
};
let store = state.warp_state.store_mut(&changed.warp_id).expect("store");
let store = state
.warp_state_mut()
.store_mut(&changed.warp_id)
.expect("store");
store.insert_node(
changed.local_id,
NodeRecord {
Expand Down Expand Up @@ -336,7 +339,10 @@ mod tests {
local_id: crate::make_node_id("second-observation"),
};
for length in [1_900, 2_000] {
let store = state.warp_state.store_mut(&first.warp_id).expect("store");
let store = state
.warp_state_mut()
.store_mut(&first.warp_id)
.expect("store");
store.insert_node(
second.local_id,
NodeRecord {
Expand Down Expand Up @@ -391,7 +397,7 @@ mod tests {
let node = *state.root();
for length in [0, 23, 24, 255, 256, 512] {
state
.warp_state
.warp_state_mut()
.store_mut(&node.warp_id)
.expect("store")
.set_node_attachment(
Expand All @@ -413,7 +419,7 @@ mod tests {
let (_, mut state, _, _, _, _) = super::super::tests::projected_create_fixture(1_024);
let node = *state.root();
state
.warp_state
.warp_state_mut()
.store_mut(&node.warp_id)
.expect("store")
.set_node_attachment(
Expand Down
16 changes: 6 additions & 10 deletions crates/warp-core/src/engine_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ struct RuntimeCommitStateGuard<'a> {
impl<'a> RuntimeCommitStateGuard<'a> {
fn enter(engine: &'a mut Engine, state: &'a mut WorldlineState) -> Self {
let saved_engine_state =
std::mem::replace(&mut engine.state, std::mem::take(&mut state.warp_state));
std::mem::replace(&mut engine.state, std::mem::take(state.warp_state_mut()));
let state_before_runtime_commit = engine.state.clone();
let saved_state_root = state.root;
let saved_root = engine.current_root;
Expand Down Expand Up @@ -614,7 +614,7 @@ impl<'a> RuntimeCommitStateGuard<'a> {
}

fn finish_success(&mut self) {
*self.state = WorldlineState {
*self.state = WorldlineState::from_parts(crate::worldline_state::WorldlineStateParts {
warp_state: std::mem::replace(
&mut self.engine.state,
self.saved_engine_state
Expand Down Expand Up @@ -650,9 +650,7 @@ impl<'a> RuntimeCommitStateGuard<'a> {
committed_ingress: self
.committed_ingress
.take("runtime commit guard missing committed ingress"),
#[cfg(any(test, feature = "host_test"))]
state_root_computations: crate::worldline_state::TestCallCount::default(),
};
});
self.engine.current_root = self.saved_root;
self.engine.tx_counter = self.saved_tx_counter;
self.engine.scheduler = self
Expand All @@ -670,7 +668,7 @@ impl<'a> RuntimeCommitStateGuard<'a> {
return;
}

*self.state = WorldlineState {
*self.state = WorldlineState::from_parts(crate::worldline_state::WorldlineStateParts {
warp_state: self
.state_before_runtime_commit
.take("runtime commit guard missing pre-commit state"),
Expand Down Expand Up @@ -704,9 +702,7 @@ impl<'a> RuntimeCommitStateGuard<'a> {
committed_ingress: self
.committed_ingress
.take("runtime commit guard missing committed ingress"),
#[cfg(any(test, feature = "host_test"))]
state_root_computations: crate::worldline_state::TestCallCount::default(),
};
});
self.engine.state = self
.saved_engine_state
.take("runtime commit guard missing saved engine state");
Expand Down Expand Up @@ -2261,7 +2257,7 @@ impl Engine {
/// Returns a snapshot view over an external worldline frontier state.
#[must_use]
pub fn snapshot_for_state(&self, state: &WorldlineState) -> Snapshot {
let state_root = compute_state_root(&state.warp_state, &state.root);
let state_root = compute_state_root(state.warp_state(), &state.root);
let parents: Vec<Hash> = state
.last_snapshot
.as_ref()
Expand Down
6 changes: 3 additions & 3 deletions crates/warp-core/src/trusted_runtime_host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7137,7 +7137,7 @@ mod tests {

let mut node_occupied_parent = parent_state.clone();
node_occupied_parent
.warp_state
.warp_state_mut()
.store_mut(&node.warp_id)
.expect("the fixture retains its descendant store")
.insert_node(
Expand All @@ -7158,7 +7158,7 @@ mod tests {

let mut attachment_occupied_parent = parent_state.clone();
attachment_occupied_parent
.warp_state
.warp_state_mut()
.store_mut(&node.warp_id)
.expect("the fixture retains its descendant store")
.set_node_attachment(
Expand All @@ -7180,7 +7180,7 @@ mod tests {

let mut fully_occupied_parent = node_occupied_parent;
fully_occupied_parent
.warp_state
.warp_state_mut()
.store_mut(&node.warp_id)
.expect("the fixture retains its descendant store")
.set_node_attachment(
Expand Down
8 changes: 4 additions & 4 deletions crates/warp-core/src/worldline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ impl WorldlineTickPatchV1 {
});
}

apply_ops_to_state(&mut state.warp_state, &self.ops)?;
apply_ops_to_state(state.warp_state_mut(), &self.ops)?;
Ok(())
}
}
Expand Down Expand Up @@ -408,7 +408,7 @@ mod tests {
};

state
.warp_state
.warp_state_mut()
.store_mut(&warp_id)
.expect("root store missing")
.insert_node(
Expand Down Expand Up @@ -466,7 +466,7 @@ mod tests {
let ty = make_type_id("EdgeType");

let store = state
.warp_state
.warp_state_mut()
.store_mut(&warp_id)
.expect("root store missing");
store.insert_node(from_id, NodeRecord { ty });
Expand Down Expand Up @@ -589,7 +589,7 @@ mod tests {
let ty = make_type_id("TestType");

state
.warp_state
.warp_state_mut()
.store_mut(&warp_id)
.expect("root store missing")
.insert_node(node_id, NodeRecord { ty });
Expand Down
Loading
Loading