Skip to content

Commit fe5bc5c

Browse files
committed
perf: implement bounded 0.31 cost optimizations and measured regression gates
1 parent c4a4ec1 commit fe5bc5c

67 files changed

Lines changed: 4783 additions & 1009 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/ci.yml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ on:
66
branches:
77
- main
88
- master
9+
- "0.30"
10+
- "0.31"
911
- "nightly-*"
1012
tags:
1113
- "v*"
@@ -36,6 +38,8 @@ jobs:
3638
--health-retries 10
3739
env:
3840
CARGO_INCREMENTAL: "0"
41+
WRANGLER_HIDE_BANNER: "true"
42+
WRANGLER_SEND_METRICS: "false"
3943
CARGO_TARGET_DIR: /tmp/cellscript-ci-target
4044
CELLSCRIPT_BACKEND_SHAPE_REPORT: /tmp/cellscript-backend-shape/backend-shape-report.json
4145
CKB_SDK_RUST_REF: v5.1.0

‎.github/workflows/release.yml‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,22 @@ jobs:
2424
name: Release gate
2525
runs-on: ubuntu-latest
2626
timeout-minutes: 180
27+
services:
28+
postgres:
29+
image: postgres:17-alpine
30+
env:
31+
POSTGRES_DB: cellscript_registry_test
32+
POSTGRES_USER: cellscript_test
33+
POSTGRES_PASSWORD: cellscript_test_password
34+
ports:
35+
- 5432:5432
36+
options: >-
37+
--health-cmd "pg_isready -U cellscript_test -d cellscript_registry_test"
38+
--health-interval 5s
39+
--health-timeout 5s
40+
--health-retries 10
41+
env:
42+
REGISTRY_TEST_DATABASE_URL: postgresql://cellscript_test:cellscript_test_password@127.0.0.1:5432/cellscript_registry_test
2743
steps:
2844
- name: Check out tagged source
2945
uses: actions/checkout@v4

‎BRANCHES.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
`0.30` commit `8d6e200caa58d81429912df925a9322f691cb41d`. Its
77
[cost decisions](docs/CELLSCRIPT_0_31_COST_DECISIONS.md) define the next work:
88
measurement, immediate planning, shared decoders, private adapter frames, and
9-
scalar slot reuse. These are accepted decisions, not implemented optimizations.
10-
Cargo versions and the pinned toolchain remain unchanged for this planning step.
9+
scalar slot reuse. The implementation and remaining acceptance work are tracked
10+
in [the cost implementation report](docs/CELLSCRIPT_0_31_COST_IMPLEMENTATION.md).
11+
Cargo versions and the pinned toolchain remain unchanged during development.
1112
The requested branch layout makes `0.31` the GitHub default branch.
1213

1314
`0.30` is retained as the release baseline. Its complete local release gate

‎CHANGELOG.md‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# Changelog
22

3+
## Unreleased — 0.31 cost work
4+
5+
Implement deterministic RV64 immediate plans, shared policy decoders behind
6+
direct action stubs, bounded private adapter frames, and CFG-liveness scalar
7+
slot reuse. Keep witness formats and the outer 4,096-byte loading boundary.
8+
Lowering record v9 and the independent checker bind the changed machine shapes.
9+
10+
Cost-report v2 adds measured nonzero group exits, explicit unavailable results,
11+
static call-chain bounds, expanded policy/scalar sweeps, and multi-Script
12+
accounting with frozen per-metric ceilings. See the
13+
[implementation and acceptance report](docs/CELLSCRIPT_0_31_COST_IMPLEMENTATION.md).
14+
These changes are development work; 0.31 has not been released.
15+
316
## 0.30.0 - Capability closure
417

518
Publication and the website update were authorized on 2026-09-21, subject to a
@@ -9,6 +22,13 @@ for the accepted compatibility boundary and publication channels.
922
The entries below retain the evidence state at each implementation step. The
1023
release notes and capability ledger record the current acceptance state.
1124

25+
- Correct runtime-error sidecars so generated label ordinals are not mistaken
26+
for exit codes. Validate large policy dispatchers after conditional-branch
27+
relaxation, with mutations that reject changed conditions, skip distances,
28+
and call destinations. Generated contract instructions remain unchanged.
29+
Run the Registry PostgreSQL suite in the release workflow and require the
30+
latest migration and its interface lookup index.
31+
1232
- Restore the edition 2026 generic declaration contract from 0.25; apply the
1333
stricter public layout declaration boundary only to edition 2027 owners.
1434
Preserve constraint spelling and explicit abilities during formatting, and

‎crates/cellscript-artifact-checker/src/checker.rs‎

Lines changed: 144 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5453,7 +5453,6 @@ fn commitment_machine_error(message: impl Into<String>) -> CheckerError {
54535453

54545454
const POLICY_WRAPPER_ENTRY_ID: &str = "wrapper:_cellscript_entry";
54555455
const POLICY_ENTRY_FRAME_BYTES: u32 = 4_192;
5456-
const POLICY_ADAPTER_FRAME_BYTES: u32 = 5_376;
54575456
const POLICY_ARGS_POINTER_OFFSET: i32 = 4_144;
54585457
const POLICY_ARGS_LENGTH_OFFSET: i32 = 4_152;
54595458
const POLICY_TAG_OFFSET: i32 = 4_160;
@@ -6540,6 +6539,19 @@ fn bounded_group_input_machine_error(message: impl Into<String>) -> CheckerError
65406539
}
65416540

65426541
fn validate_policy_dispatch_machine_contract(record: &VerifiedLoweringRecord, elf: &ParsedElf) -> Result<(), CheckerError> {
6542+
if !matches!(record.typed_semantics.foundation.entry_contract.dispatch, EntryDispatchContract::PolicyWitnessV1(_)) {
6543+
return Ok(());
6544+
}
6545+
if let Some((logical_record, logical_elf)) =
6546+
crate::policy_machine::normalize_relaxed_branches(record, elf).map_err(policy_machine_error)?
6547+
{
6548+
validate_policy_dispatch_logical_machine_contract(&logical_record, &logical_elf)
6549+
} else {
6550+
validate_policy_dispatch_logical_machine_contract(record, elf)
6551+
}
6552+
}
6553+
6554+
fn validate_policy_dispatch_logical_machine_contract(record: &VerifiedLoweringRecord, elf: &ParsedElf) -> Result<(), CheckerError> {
65436555
let EntryDispatchContract::PolicyWitnessV1(contract) = &record.typed_semantics.foundation.entry_contract.dispatch else {
65446556
return Ok(());
65456557
};
@@ -7152,6 +7164,7 @@ fn validate_policy_action_adapters(
71527164
}
71537165
let all_action_starts =
71547166
contract.variants.iter().map(|variant| entry_start(record, &variant.entry_id)).collect::<Result<BTreeSet<_>, _>>()?;
7167+
let mut shared_bindings: BTreeMap<String, (Value, BTreeSet<u64>)> = BTreeMap::new();
71557168
for (adapter, variant) in adapters.into_iter().zip(&contract.variants) {
71567169
let entry = record
71577170
.typed_semantics
@@ -7160,7 +7173,8 @@ fn validate_policy_action_adapters(
71607173
.find(|entry| entry.id == variant.entry_id)
71617174
.ok_or_else(|| policy_machine_error("policy variant has no typed action entry"))?;
71627175
let expected_outgoing = policy_outgoing_argument_bytes(entry, &record.typed_semantics)?;
7163-
let expected_record_frame = POLICY_ADAPTER_FRAME_BYTES
7176+
let (private_frame, private_capacity) = crate::policy::private_adapter_layout(entry, &record.typed_semantics)?;
7177+
let expected_record_frame = private_frame
71647178
.checked_add(expected_outgoing)
71657179
.ok_or_else(|| policy_machine_error("policy adapter recorded frame overflows u32"))?;
71667180
if adapter.frame_size_bytes != expected_record_frame || adapter.outgoing_argument_bytes != 0 {
@@ -7174,31 +7188,93 @@ fn validate_policy_action_adapters(
71747188
return Err(policy_machine_error("policy positional adapter blocks disagree on frame size"));
71757189
}
71767190
let base = entry_start(record, &adapter.id)?;
7177-
let prologue = instructions_from(elf, base, 9)?;
7178-
if !matches_large_sp_adjust(prologue, 0, -(POLICY_ADAPTER_FRAME_BYTES as i32))
7179-
|| !matches_large_stack_store(prologue, 3, 1, POLICY_ADAPTER_FRAME_BYTES as i32 - 8)
7191+
let saved_ra = private_frame as i32 - 8;
7192+
let save_address = base + sp_adjust_instruction_bytes(-(private_frame as i32));
7193+
if !matches_sp_adjust_at(elf, base, -(private_frame as i32))? || !matches_stack_slot_at(elf, save_address, 1, saved_ra, false)?
71807194
{
71817195
return Err(policy_machine_error("policy adapter prologue no longer owns a bounded private copy frame"));
71827196
}
7183-
let fail = unique_policy_block(record, &adapter.id, ".Lentry_witness_fail_")?;
7197+
let decoder_call_start = save_address + stack_slot_instruction_bytes(saved_ra);
7198+
let shared_decoder = elf.control_flow.iter().find(|flow| flow.address == decoder_call_start + 4).and_then(|flow| {
7199+
record.entries.iter().find(|candidate| {
7200+
candidate.name.starts_with(".Lpolicy_shared_decoder_") && entry_start(record, &candidate.id).ok() == Some(flow.target)
7201+
})
7202+
});
7203+
let decoder_owner = if let Some(decoder) = shared_decoder {
7204+
if !is_auipc(instruction_at(elf, decoder_call_start)?.word, 1)
7205+
|| !is_jalr_call(instruction_at(elf, decoder_call_start + 4)?.word)
7206+
|| decoder.kind != EntryKind::Runtime
7207+
|| decoder.frame_size_bytes != 0
7208+
|| decoder.outgoing_argument_bytes != 0
7209+
{
7210+
return Err(policy_machine_error("shared decoder call or borrowed-frame contract changed"));
7211+
}
7212+
let decoder_blocks: Vec<_> = record.blocks.iter().filter(|block| block.owner_entry == decoder.id).collect();
7213+
if decoder_blocks.iter().any(|block| block.frame_size_bytes != 0 || block.outgoing_argument_bytes != 0)
7214+
|| elf
7215+
.stack_adjustments
7216+
.iter()
7217+
.any(|adjustment| decoder_blocks.iter().any(|block| block.range.contains(adjustment.address)))
7218+
|| elf.instructions.iter().any(|instruction| {
7219+
decoder_blocks.iter().any(|block| block.range.contains(instruction.address))
7220+
&& matches!(instruction.word & 0x7f, 0x6f | 0x67)
7221+
&& (instruction.word >> 7) & 31 != 0
7222+
})
7223+
{
7224+
return Err(policy_machine_error("shared decoder may neither move sp nor call another function"));
7225+
}
7226+
let projections = entry
7227+
.params
7228+
.iter()
7229+
.map(|param| crate::policy::builder_parameter_projection(param, entry, &record.typed_semantics))
7230+
.collect::<Result<Vec<_>, _>>()?;
7231+
let key =
7232+
serde_json::json!({"params":entry.params,"projection":projections,"frame":private_frame,"capacity":private_capacity});
7233+
let (expected, callers) = shared_bindings.entry(decoder.id.clone()).or_insert_with(|| (key.clone(), BTreeSet::new()));
7234+
if *expected != key {
7235+
return Err(policy_machine_error("different parameter contracts share one positional decoder"));
7236+
}
7237+
callers.insert(decoder_call_start + 4);
7238+
let decoder_done = unique_policy_block(record, &decoder.id, ".Lentry_witness_done_")?;
7239+
if instruction_at(elf, decoder_done.range.start)?.word != 0x0000_8067 {
7240+
return Err(policy_machine_error("shared decoder must return with its borrowed frame intact"));
7241+
}
7242+
&decoder.id
7243+
} else {
7244+
&adapter.id
7245+
};
7246+
let fail = unique_policy_block(record, decoder_owner, ".Lentry_witness_fail_")?;
71847247
let done = unique_policy_block(record, &adapter.id, ".Lentry_witness_done_")?;
7185-
let has_payload = entry.params.iter().any(|param| matches!(param.source.as_str(), "default" | "witness"));
7248+
let has_payload =
7249+
private_capacity > 0 && entry.params.iter().any(|param| matches!(param.source.as_str(), "default" | "witness"));
71867250
if has_payload {
7187-
let copy = unique_policy_block(record, &adapter.id, ".Lpolicy_args_copy_")?;
7188-
let prefix_address =
7189-
copy.range.start.checked_sub(24).ok_or_else(|| policy_machine_error("policy adapter copy prefix underflows"))?;
7190-
let prefix = instructions_from(elf, prefix_address, 6)?;
7191-
if !is_lui(prefix[0].word, 5, 0x0000_1000)
7192-
|| !is_bltu(prefix[1].word, 5, 11)
7193-
|| !flow_targets(elf, prefix[1].address, fail.range.start)
7194-
|| !is_sd(prefix[2].word, 11, 2, 0)
7195-
|| !is_addi(prefix[3].word, 5, 10, 0)
7196-
|| !is_addi(prefix[4].word, 6, 2, 8)
7197-
|| !is_addi(prefix[5].word, 7, 0, 0)
7251+
let copy = unique_policy_block(record, decoder_owner, ".Lpolicy_args_copy_")?;
7252+
let bound_instructions = if private_capacity <= 2047 || private_capacity == 4096 { 1 } else { 2 };
7253+
let prefix_address = copy
7254+
.range
7255+
.start
7256+
.checked_sub((5 + bound_instructions) * 4)
7257+
.ok_or_else(|| policy_machine_error("policy adapter copy prefix underflows"))?;
7258+
let prefix = instructions_from(elf, prefix_address, (5 + bound_instructions) as usize)?;
7259+
let bound_matches = if private_capacity <= 2047 {
7260+
is_addi(prefix[0].word, 5, 0, private_capacity as i32)
7261+
} else if private_capacity == 4096 {
7262+
is_lui(prefix[0].word, 5, 0x1000)
7263+
} else {
7264+
is_lui(prefix[0].word, 5, 0x1000) && is_addi(prefix[1].word, 5, 5, private_capacity as i32 - 4096)
7265+
};
7266+
let start = bound_instructions as usize;
7267+
if !bound_matches
7268+
|| !is_bltu(prefix[start].word, 5, 11)
7269+
|| !flow_targets(elf, prefix[start].address, fail.range.start)
7270+
|| !is_sd(prefix[start + 1].word, 11, 2, 0)
7271+
|| !is_addi(prefix[start + 2].word, 5, 10, 0)
7272+
|| !is_addi(prefix[start + 3].word, 6, 2, 8)
7273+
|| !is_addi(prefix[start + 4].word, 7, 0, 0)
71987274
{
71997275
return Err(policy_machine_error("policy adapter no longer bounds and privately copies selected args"));
72007276
}
7201-
let copied = unique_policy_block(record, &adapter.id, ".Lpolicy_args_copied_")?;
7277+
let copied = unique_policy_block(record, decoder_owner, ".Lpolicy_args_copied_")?;
72027278
let loop_words = instructions_from(elf, copy.range.start, 7)?;
72037279
if !is_bgeu(loop_words[0].word, 7, 11)
72047280
|| !flow_targets(elf, loop_words[0].address, copied.range.start)
@@ -7212,11 +7288,14 @@ fn validate_policy_action_adapters(
72127288
{
72137289
return Err(policy_machine_error("policy adapter selected-args copy loop changed"));
72147290
}
7215-
} else if !is_bne(prologue[7].word, 11, 0)
7216-
|| !flow_targets(elf, prologue[7].address, fail.range.start)
7217-
|| !is_sd(prologue[8].word, 0, 2, 0)
7218-
{
7219-
return Err(policy_machine_error("payload-free policy adapter no longer requires empty args"));
7291+
} else {
7292+
let empty_guard = if shared_decoder.is_some() { entry_start(record, decoder_owner)? } else { decoder_call_start };
7293+
if !is_bne(instruction_at(elf, empty_guard)?.word, 11, 0)
7294+
|| !flow_targets(elf, empty_guard, fail.range.start)
7295+
|| !is_sd(instruction_at(elf, empty_guard + 4)?.word, 0, 2, 0)
7296+
{
7297+
return Err(policy_machine_error("payload-free policy adapter no longer requires empty args"));
7298+
}
72207299
}
72217300

72227301
let target = entry_start(record, &variant.entry_id)?;
@@ -7233,6 +7312,13 @@ fn validate_policy_action_adapters(
72337312
)));
72347313
}
72357314
let call = action_calls[0];
7315+
if shared_decoder.is_some() {
7316+
let outgoing_adjustment =
7317+
if expected_outgoing == 0 { 0 } else { sp_adjust_instruction_bytes(-(expected_outgoing as i32)) };
7318+
if call.address != decoder_call_start + 8 + outgoing_adjustment + 4 {
7319+
return Err(policy_machine_error("shared decoder arguments must flow directly to the bound action call"));
7320+
}
7321+
}
72367322
if call.address < 4
72377323
|| !is_auipc(instruction_at(elf, call.address - 4)?.word, 1)
72387324
|| !is_jalr_call(instruction_at(elf, call.address)?.word)
@@ -7262,14 +7348,22 @@ fn validate_policy_action_adapters(
72627348
if !is_jal_zero(instruction_at(elf, completion)?.word) || !flow_targets(elf, completion, done.range.start) {
72637349
return Err(policy_machine_error("policy adapter call no longer completes through its exact done block"));
72647350
}
7265-
let done_words = instructions_from(elf, done.range.start, 8)?;
7266-
if !matches_large_stack_load(done_words, 0, 1, POLICY_ADAPTER_FRAME_BYTES as i32 - 8)
7267-
|| !matches_large_sp_adjust(done_words, 4, POLICY_ADAPTER_FRAME_BYTES as i32)
7268-
|| done_words[7].word != 0x0000_8067
7351+
let restore = done.range.start + stack_slot_instruction_bytes(saved_ra);
7352+
if !matches_stack_slot_at(elf, done.range.start, 1, saved_ra, true)?
7353+
|| !matches_sp_adjust_at(elf, restore, private_frame as i32)?
7354+
|| instruction_at(elf, restore + sp_adjust_instruction_bytes(private_frame as i32))?.word != 0x0000_8067
72697355
{
72707356
return Err(policy_machine_error("policy adapter completion no longer restores its private frame"));
72717357
}
72727358
}
7359+
for decoder in record.entries.iter().filter(|entry| entry.name.starts_with(".Lpolicy_shared_decoder_")) {
7360+
let (_, callers) = shared_bindings.get(&decoder.id).ok_or_else(|| policy_machine_error("unbound shared policy decoder"))?;
7361+
let target = entry_start(record, &decoder.id)?;
7362+
let incoming: BTreeSet<_> = elf.control_flow.iter().filter(|flow| flow.target == target).map(|flow| flow.address).collect();
7363+
if callers.len() < 2 || &incoming != callers {
7364+
return Err(policy_machine_error("shared decoder has an undeclared caller or no repeated layout"));
7365+
}
7366+
}
72737367
Ok(())
72747368
}
72757369

@@ -7411,6 +7505,28 @@ fn sp_adjust_instruction_bytes(delta: i32) -> u64 {
74117505
}
74127506
}
74137507

7508+
fn stack_slot_instruction_bytes(offset: i32) -> u64 {
7509+
if (-2048..=2047).contains(&offset) {
7510+
4
7511+
} else {
7512+
16
7513+
}
7514+
}
7515+
7516+
fn matches_stack_slot_at(elf: &ParsedElf, address: u64, register: u32, offset: i32, load: bool) -> Result<bool, CheckerError> {
7517+
if (-2048..=2047).contains(&offset) {
7518+
let word = instruction_at(elf, address)?.word;
7519+
Ok(if load { is_ld(word, register, 2, offset) } else { is_sd(word, register, 2, offset) })
7520+
} else {
7521+
let words = instructions_from(elf, address, 4)?;
7522+
Ok(if load {
7523+
matches_large_stack_load(words, 0, register, offset)
7524+
} else {
7525+
matches_large_stack_store(words, 0, register, offset)
7526+
})
7527+
}
7528+
}
7529+
74147530
fn matches_sp_adjust_at(elf: &ParsedElf, address: u64, delta: i32) -> Result<bool, CheckerError> {
74157531
if (-2_048..=2_047).contains(&delta) {
74167532
Ok(is_addi(instruction_at(elf, address)?.word, 2, 2, delta))

‎crates/cellscript-artifact-checker/src/lib.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ mod checker;
33
mod elf;
44
mod failure;
55
mod policy;
6+
mod policy_machine;
67
mod schema;
78

89
pub use checker::{

‎crates/cellscript-artifact-checker/src/policy.rs‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,35 @@ pub const POLICY_SELECTOR_FIELD: &str = "input_type.records[type,current-script-
1919
const MAX_COMMON_CALL_DEPTH: usize = 256;
2020
const MAX_COMMON_CALLEE_BLOCKS: usize = 262_144;
2121

22+
/// Independently derive the private decoder's fixed payload reservation.
23+
/// Unknown layouts and Script-argument users retain the old bounded frame.
24+
pub(crate) fn private_adapter_layout(entry: &TypedSemanticEntry, typed: &TypedSemanticRecord) -> Result<(u32, u32), CheckerError> {
25+
let fallback = (5376, 4096);
26+
let mut payload = 0u64;
27+
for param in &entry.params {
28+
if param.source == "lockargs" {
29+
return Ok(fallback);
30+
}
31+
let projection = builder_parameter_projection(param, entry, typed)?;
32+
if projection["cell_bound_abi"] == true || param.reference {
33+
continue;
34+
}
35+
let width = projection["fixed_byte_len"].as_u64().or(policy_abi_type(&param.ty, 0)?.static_width());
36+
let Some(width) = width else {
37+
return Ok(fallback);
38+
};
39+
let Some(total) = payload.checked_add(width) else {
40+
return Ok(fallback);
41+
};
42+
payload = total;
43+
}
44+
let capacity = if payload == 0 { 0 } else { payload.saturating_add(8) };
45+
if capacity > 4096 {
46+
return Ok(fallback);
47+
}
48+
Ok((((8 + capacity + 8).next_multiple_of(16)) as u32, capacity as u32))
49+
}
50+
2251
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2352
#[serde(deny_unknown_fields)]
2453
pub struct PolicyWitnessContract {

0 commit comments

Comments
 (0)