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
27 changes: 17 additions & 10 deletions crates/labcolors-core/contracts/clean-set-srgb8-v1/receipt-v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,25 +62,32 @@
"sha256": "90e2ca62acac950fc38e711369a9fd3ef24262f7776f1e8ed2aeac92733a4911"
},
{
"bytes": 38023,
"bytes": 7951,
"license": "MIT",
"path": "crates/labcolors-core/src/test_support.rs",
"role": "point_attachment_allocator_oracle",
"sha256": "ec6585496208972e183d3a5bcd1f67bae4d89cc8e6a797d9c6443d8e0754502b"
},
{
"bytes": 37562,
"license": "MIT",
"path": "crates/labcolors-core/src/program/attachment.rs",
"role": "point_attachment_source",
"sha256": "ea0774ed2719c4a5642ddf053b8fcb60ad10ee056b102b26e5884ab57febbe71"
"sha256": "b1bb2f4c25e748ba7c3711454e968bca24ed934f18f00ccdca4a1a2c572bceb7"
},
{
"bytes": 17072,
"bytes": 17406,
"license": "MIT",
"path": "crates/labcolors-core/src/program/attachment/support.rs",
"role": "point_attachment_test_support",
"sha256": "21afe869e4b0e9abacb266ee92dea893a98c48f7da4f58a352ab5b8caca8f231"
"sha256": "df2350e853302ffb636abf01d7c1301331fc76f4708ca00d076ea91dac0b14bb"
},
{
"bytes": 28964,
"bytes": 31748,
"license": "MIT",
"path": "crates/labcolors-core/src/program/attachment/tests.rs",
"role": "point_attachment_tests",
"sha256": "d52f10afab0765e3cfced403b32e9c1294bed152b8f3f6b831c972da90b4f2e2"
"sha256": "6ea55c62333a803929fd4b96245362148a555ca2ac5261721a6fad6de9bf7eac"
},
{
"bytes": 162073,
Expand Down Expand Up @@ -139,18 +146,18 @@
"sha256": "6c95324eb05476f35f75375a9af0b2b4a41b8b2978c46e67d2ce1aea5adde342"
},
{
"bytes": 39567,
"bytes": 39653,
"license": "MIT",
"path": "scripts/verify_clean_set_receipt.py",
"role": "verifier_source",
"sha256": "6e07ec6d9d72e5cfe084773b27e45cf6ea7df8c98eca860d19f8646a893afd62"
"sha256": "1fe3cb719f883b7968bf05bbf613353235445e55ad7942bb7f8a83145cb97b09"
},
{
"bytes": 31977,
"bytes": 32018,
"license": "MIT",
"path": "scripts/test_verify_clean_set_receipt.py",
"role": "verifier_tests",
"sha256": "0c54a269c5412baf24f393c6d38a695ad0143d7d1e62fdf0ce8da2a15132dbcd"
"sha256": "337fe7585aa44359c2a90655fafbd0b4fbbd4fdf8bd30a9735df6640010d9e29"
}
],
"excluded_claims": [
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0401de26bd038c26fc2948042b6e48f3feebd95b0377dfca32ab36983f80580a receipt-v1.json
369e1cf175ac10ab96ca1f6cb82e131e4c24fc43c698a0d853ccabdebb0386d5 receipt-v1.json
19 changes: 6 additions & 13 deletions crates/labcolors-core/src/program/attachment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,11 @@ pub(crate) enum PointSinkIntentV1<'a, SinkOutputId, Stamp> {
/// scope одной атомарной публикацией. Любой отказ сохраняет прежние наблюдаемые
/// scope→value snapshot, revision и равный по [`Eq`] Stamp.
pub(crate) trait PreparedPointSinkWriteV1 {
type Stamp: Clone + Eq;
type Stamp: Copy + Eq;
type Error;

/// Stamp точного снимка, который опубликует успешный install.
fn proposed_stamp(&self) -> &Self::Stamp;
fn proposed_stamp(&self) -> Self::Stamp;

/// Единственная fallible-операция после parsing, allocations и CAS setup.
///
Expand All @@ -179,7 +179,7 @@ pub(crate) trait PreparedPointSinkWriteV1 {
/// Линейное владение одним точным физическим point-sink scope.
pub(crate) trait LinearPointSinkLeaseV1: sink_private::Sealed {
type OutputId: Copy + Eq;
type Stamp: Clone + Eq;
type Stamp: Copy + Eq;
type Error;
type Prepared<'lease>: PreparedPointSinkWriteV1<Stamp = Self::Stamp, Error = Self::Error>
where
Expand Down Expand Up @@ -511,9 +511,6 @@ where
committed_render_patch: Vec<AttachedRenderPatchEntryV1<L::OutputId>>,
scratch_render_patch: Vec<AttachedRenderPatchEntryV1<L::OutputId>>,
published_stamp: Option<PublishedAttachmentStampV1<L::Stamp>>,
// Прошлый control block переносится сюда после install и освобождается до
// следующей транзакции, но не в infallible commit tail.
retired_stamp: Option<PublishedAttachmentStampV1<L::Stamp>>,
// Вытеснённые Session evidence и transaction owner после install только
// переносятся сюда и освобождаются до следующего prepare.
retired_session: Option<CoreDeferredSessionRetirementV1>,
Expand Down Expand Up @@ -788,7 +785,6 @@ where
committed_render_patch,
scratch_render_patch,
published_stamp: None,
retired_stamp: None,
retired_session: None,
_owner_pin: owner_pin,
})
Expand All @@ -797,7 +793,6 @@ where
/// Готовит, атомарно устанавливает и infallibly публикует целый update.
pub(crate) fn update(&mut self, update: UpdateV1<'_>) -> AttachmentUpdateResultV1<'_, L> {
drop(self.retired_session.take());
drop(self.retired_stamp.take());
let transition = self
.session
.prepare_update(update)
Expand Down Expand Up @@ -869,13 +864,13 @@ where
PreparedAttachmentUpdateV1::new(transition, sink_prepared);
let next_stamp = PublishedAttachmentStampV1 {
revision: action.revision(),
sink: prepared.proposed_stamp().clone(),
sink: prepared.proposed_stamp(),
};
if matches!(&action, PreparedPatchActionV1::ConfirmExact { .. }) {
let expected = confirmed_stamp.ok_or(AttachmentUpdateErrorV1::InternalInvariant(
AttachmentInvariantV1::MissingPublishedStamp,
))?;
if &next_stamp.sink != expected {
if next_stamp.sink != *expected {
return Err(AttachmentUpdateErrorV1::InternalInvariant(
AttachmentInvariantV1::ConfirmStampMismatch,
));
Expand All @@ -899,8 +894,6 @@ where
}
PreparedPatchActionV1::ConfirmExact { .. } => {}
}
let previous_stamp = self.published_stamp.take();
self.retired_stamp = previous_stamp;
let published_stamp = self.published_stamp.insert(next_stamp);
installed_sink.finish_after_session();

Expand Down Expand Up @@ -1004,7 +997,7 @@ where
Self { transition, sink }
}

fn proposed_stamp(&self) -> &L::Stamp {
fn proposed_stamp(&self) -> L::Stamp {
self.sink.proposed_stamp()
}

Expand Down
54 changes: 29 additions & 25 deletions crates/labcolors-core/src/program/attachment/support.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{
cell::{Cell, RefCell},
rc::Rc,
sync::atomic::{AtomicU64, Ordering},
};

use super::*;
Expand All @@ -18,19 +19,15 @@ impl TestSinkOutputIdV1 {
}
}

#[derive(Debug, Clone)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct TestPublishedStampV1 {
sequence: u64,
epoch: Rc<()>,
}

impl PartialEq for TestPublishedStampV1 {
fn eq(&self, other: &Self) -> bool {
self.sequence == other.sequence && Rc::ptr_eq(&self.epoch, &other.epoch)
}
epoch: u64,
}

impl Eq for TestPublishedStampV1 {}
// Stamp должен оставаться Copy, поэтому test sink получает неповторимую эпоху
// из монотонного issuer-а, а не владеет Rc и не выводит identity из адреса.
static NEXT_TEST_SINK_EPOCH: AtomicU64 = AtomicU64::new(1);

impl TestPublishedStampV1 {
fn next(&self) -> Result<Self, InMemoryPointSinkErrorV1> {
Expand All @@ -39,7 +36,7 @@ impl TestPublishedStampV1 {
.sequence
.checked_add(1)
.ok_or(InMemoryPointSinkErrorV1::StampExhausted)?,
epoch: Rc::clone(&self.epoch),
epoch: self.epoch,
})
}
}
Expand Down Expand Up @@ -105,6 +102,7 @@ struct TestSinkSharedV1 {
misreport_next_confirm_proposed_stamp: Cell<bool>,
panic_on_retirement_drop: Cell<bool>,
retirement_drop_count: Cell<usize>,
measure_terminal_tail: Cell<bool>,
}

pub(crate) struct InMemoryPointSinkLeaseV1 {
Expand All @@ -128,7 +126,7 @@ impl InMemoryPointSinkProbeV1 {
}

pub(crate) fn stamp(&self) -> TestPublishedStampV1 {
self.shared.state.borrow().stamp.clone()
self.shared.state.borrow().stamp
}

pub(crate) fn intent_counts(&self) -> TestIntentCountsV1 {
Expand Down Expand Up @@ -182,12 +180,23 @@ impl InMemoryPointSinkProbeV1 {
pub(crate) fn retirement_drop_count(&self) -> usize {
self.shared.retirement_drop_count.get()
}

pub(crate) fn checkpoint_next_terminal_tail(&self) {
assert!(
!self.shared.measure_terminal_tail.replace(true),
"terminal-tail measurements cannot overlap"
);
}
}

pub(crate) fn in_memory_point_sink(
owned_scope: &[u32],
) -> (InMemoryPointSinkLeaseV1, InMemoryPointSinkProbeV1) {
let epoch = Rc::new(());
let epoch = NEXT_TEST_SINK_EPOCH
.fetch_update(Ordering::Relaxed, Ordering::Relaxed, |current| {
current.checked_add(1)
})
.unwrap_or_else(|_| panic!("test sink epoch space exhausted"));
Comment thread
coderabbitai[bot] marked this conversation as resolved.
let shared = Rc::new(TestSinkSharedV1 {
state: RefCell::new(TestSinkStateV1 {
snapshot: Vec::new(),
Expand All @@ -208,6 +217,7 @@ pub(crate) fn in_memory_point_sink(
misreport_next_confirm_proposed_stamp: Cell::new(false),
panic_on_retirement_drop: Cell::new(false),
retirement_drop_count: Cell::new(0),
measure_terminal_tail: Cell::new(false),
});
(
InMemoryPointSinkLeaseV1 {
Expand Down Expand Up @@ -266,7 +276,7 @@ impl LinearPointSinkLeaseV1 for InMemoryPointSinkLeaseV1 {
drop(self.retired.take());
let (base_stamp, current_revision, busy) = {
let state = self.shared.state.borrow();
(state.stamp.clone(), state.revision, self.shared.busy.get())
(state.stamp, state.revision, self.shared.busy.get())
};
if busy {
return Err(InMemoryPointSinkErrorV1::Busy);
Expand Down Expand Up @@ -311,7 +321,7 @@ impl LinearPointSinkLeaseV1 for InMemoryPointSinkLeaseV1 {
{
published_stamp.next()?
} else {
published_stamp.clone()
*published_stamp
};
(
TestStagingV1::ConfirmExact { revision },
Expand Down Expand Up @@ -397,9 +407,6 @@ enum TestStagingV1 {

struct TestSinkRetirementV1 {
_staging: Option<TestStagingV1>,
_retired_stamp: Option<TestPublishedStampV1>,
_proposed: Option<TestPublishedStampV1>,
_base_stamp: Option<TestPublishedStampV1>,
probe: Option<Rc<TestSinkSharedV1>>,
}

Expand Down Expand Up @@ -430,9 +437,8 @@ impl PreparedPointSinkWriteV1 for InMemoryPreparedPointSinkWriteV1<'_> {
type Stamp = TestPublishedStampV1;
type Error = InMemoryPointSinkErrorV1;

fn proposed_stamp(&self) -> &Self::Stamp {
fn proposed_stamp(&self) -> Self::Stamp {
self.proposed
.as_ref()
.unwrap_or_else(|| unreachable!("proposed stamp читается до install"))
}

Expand Down Expand Up @@ -503,15 +509,16 @@ impl PreparedPointSinkWriteV1 for InMemoryPreparedPointSinkWriteV1<'_> {
state.revision = prior_revision;
return Err(InMemoryPointSinkErrorV1::RejectedInstallAfterSwap);
}
drop(state);
if self.lease.shared.measure_terminal_tail.replace(false) {
crate::test_support::reset_allocator_events();
}
Ok(())
}

fn finish_after_session(mut self) {
let retirement = TestSinkRetirementV1 {
_staging: self.staging.take(),
_retired_stamp: self.retired_stamp.take(),
_proposed: self.proposed.take(),
_base_stamp: self.base_stamp.take(),
probe: self.retirement_probe.take(),
};
self.lease.retired = Some(retirement);
Expand All @@ -524,9 +531,6 @@ impl Drop for InMemoryPreparedPointSinkWriteV1<'_> {
fn drop(&mut self) {
if !self.finished {
drop(self.staging.take());
drop(self.retired_stamp.take());
drop(self.proposed.take());
drop(self.base_stamp.take());
drop(self.retirement_probe.take());
self.lease.shared.busy.set(false);
}
Expand Down
Loading
Loading