Skip to content

feat: PQVM-native R3 implementation — whitepaper alignment, consensus hardening, docs#49

Merged
LucienSong merged 12 commits into
ShellDAO:mainfrom
LucienSong:feat/pqvm-native-r3
May 23, 2026
Merged

feat: PQVM-native R3 implementation — whitepaper alignment, consensus hardening, docs#49
LucienSong merged 12 commits into
ShellDAO:mainfrom
LucienSong:feat/pqvm-native-r3

Conversation

@LucienSong
Copy link
Copy Markdown
Contributor

Summary

This PR consolidates three rounds of whitepaper-driven implementation work, bringing shell-chain to full alignment with the ShellDAO whitepaper specification as of R3.

Changes

Bug Fixes

  • fix(stark): Port Reference-mode address slice to 32-byte v0.23.0 format
  • fix(wpoa): Push WPoA finality to RPC finalized_number Arc

Features

  • feat: Implement whitepaper-specified protocol targets (Round 1)
    • PQVM native opcodes (PQVERIFY, PQSIGN, etc.)
    • Algorithm registry crate (crates/crypto/src/algorithm_registry.rs)
    • ML-DSA-65 as sole primary signing algorithm; SLH-DSA as fallback
  • feat: Implement Round 2 whitepaper gap targets
    • Epoch-based rotation skeleton
    • Shard scaffolding
    • PQVM execution improvements
  • feat: Implement Round 3 whitepaper gap targets
    • View-change protocol (crates/consensus/src/view_change.rs)
    • Challenge/response lifecycle (crates/node/src/node/challenge_lifecycle.rs)
    • Sharding/finality fixes

Maintenance

  • chore: Audit cleanup — remove dead code, align docs to R3 design
  • docs: Align all documentation to whitepaper specification
  • docs: Align PQVM terminology (PQVM not EVM, SoA not PoA)
  • docs: Align ML-DSA-65 as primary signing algorithm across all docs

Testing

Existing test suite passes. New consensus and crypto modules include unit tests.

Related

Implements whitepaper sections §4 (Consensus), §5 (PQVM), §6 (Cryptography).

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

LucienSong and others added 9 commits May 23, 2026 23:03
stark_sources.rs:40 used h[..20].copy_from_slice() which panics when
tx.from is the new 32-byte BLAKE3 address (v0.23.0+). Updated to use
addr.len().min(32) to safely copy any address length.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
After handle_wpoa_vote advances FinalityState, the shared
finalized_number Arc used by the RPC eth_getBlockByNumber("finalized")
handler was never updated. The only write site was the PoA attestation
path (NetworkMessage::NewAttestation), leaving the RPC stuck at 0 when
running under --consensus-engine wpoa.

Fix: update the finalized_number Arc immediately after every
handle_wpoa_vote call (three sites: post-produce self-vote, post-import
self-vote, and incoming WPoaVote from peers).

Tested on SG3 single-validator testnet: finalized now advances in
lockstep with head (finalized == head after each block).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- pqvm-opcodes: add PQVERIFY (0xB0), PQHASH (0xB1), PQADDR (0xB2) native
  opcode dispatch in crates/evm/src/pqvm_opcodes.rs; wire into executor
  instruction table via register_pq_opcodes(); add tests for success,
  invalid input, stack underflow, and gas metering

- wpoa-defaults: change NodeConfig::for_network and CLI run.rs fallback
  from PoA to WPoA as the default consensus engine; PoA remains available
  via explicit opt-in; add 6 regression tests for WPoA default and
  heartbeat/max-idle behavior

- storage-profiles: add whitepaper_name() to StorageProfile returning
  'pruned' for Light; add 'pruned' and 'rolling' aliases in from_str()
  for white-paper naming; surface whitepaper_name() in RPC
  StorageProfileInfo.profile (P2P wire kept as as_str() for compat);
  add 5 alias/naming tests

- algorithm-registry: create crates/crypto/src/algorithm_registry.rs
  with AlgorithmRegistry, AlgorithmStatus, AlgorithmEntry,
  is_algorithm_allowed(); route AA validation through registry instead
  of direct ALLOWED_ALGORITHMS.contains(); expose shell_getAlgorithmRegistry
  RPC method; governance lifecycle deferred to a future round

- stark-boundary-guards: add 4 scaffold boundary tests to recursive_air.rs
  confirming ScaffoldRecursiveProver always returns NotImplemented; add
  2 boundary tests to prover_service.rs confirming Active/Scaffold L2
  modes do not store recursive proof settlements

All crates build clean (cargo fmt --check, cargo test --workspace pass).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- stark-settled-source: enforce canonical settlement check in L2 proof
  source binding; soft-pass recursive proof decode until verifier ready
- net-stats-rpc: dynamic peer count and listen address in
  shell_getNetworkStats
- wpoa-offline-slash: detect and slash offline validators at epoch
  boundaries using last_proposed_by tracking
- wpoa-weight-governance: setValidatorWeight governance via system
  contract with weighted quorum voting
- crypto-mldsa-uniform: ML-DSA-65 uniform routing across precompiles,
  PQVM opcodes, and P2P attestation handlers; precompile 0x0001 wire
  format kept ABI-stable (no sig_type prefix change)
- wpoa-finality-weight: weight-based attestation quorum in
  finality/fork-choice (>2/3 total weight threshold)
- pqvm-selfdestruct-removal: SELFDESTRUCT (0xFF) and CALLCODE (0xF2)
  hard-removed from PQVM instruction table

All 1 ignored + all crate test suites pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- econ-slash-weight: bps-based weight reduction in PoaEngine/WpoaEngine;
  slash_weights HashMap tracks per-authority reduction; validator_weights
  returns effective weights after slashing
- stark-challenge-lifecycle: ChallengeRecord OPEN→RESOLVED/SLASHED state
  machine with T_c=7200 block timeout; event_loop wires in periodic
  check_timeouts + slashing on expiry
- storage-trie-pruning: prune_state_trie() deletes trie snapshots in
  pruning.rs; world_state prune_state_before() removes old snapshots
- wpoa-view-change: view_change.rs ViewChangeMessage/ViewChangeState,
  round-robin select_proposer, quorum tracking; WpoaEngine wired in
  handle_view_change_message + event_loop broadcasts on timeout
- algo-registry-governance: mutable AlgorithmRegistry with global_mut(),
  propose/activate/deprecate lifecycle; system-contract selectors for
  proposeAlgorithmActivation/deprecateAlgorithm with on-chain storage keys
  and quorum handling; shell_getAlgorithmRegistry returns live JSON array
- bandwidth: fix outbound_limit_triggers flaky test (use rate=1 so 1 token
  takes 1s to refill, immune to sub-ms timing jitter)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- ACCOUNT_ABSTRACTION_GUIDE: fix address format (32-byte BLAKE3, not 20-byte pq1...)
- SYSTEM_CONTRACTS: fix 32-byte addresses, add algo governance quorum rules
- SMART_CONTRACT_GUIDE: clarify PQVM (not full Cancun), add PQVERIFY/PQHASH/PQADDR opcodes
- PQ_CRYPTO_GUIDE: remove Hybrid Schemes (Research) section, add governance quorum details
- BENCHMARKS: update v0.15.0 → v0.23.x, add whitepaper reference proof sizes
- PROVER_GUIDE: add L2StarkMode table (Disabled/Scaffold/Active)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- README: ML-DSA-65 primary, Dilithium3 legacy-compatible active path, SPHINCS+ fallback
- AGENTS: same algorithm ordering in crate map and what-this-repo-is section
- docs/keystore-format.md: mldsa65 is primary, dilithium3 is legacy-compatible
- crates/crypto/src/signature.rs: MlDsa65 doc comment reflects active primary status
- crates/node/src/node/event_loop.rs: remove stale F-042/F-107 issue markers

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 23, 2026 15:05
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR advances shell-chain to the R3 whitepaper target by updating consensus (weighted finality + view-change), PQVM execution surfaces (native opcodes + precompile table + legacy opcode removals), cryptography governance (runtime algorithm registry), and storage operations (state-trie snapshot pruning), alongside broad documentation alignment to the new semantics (32-byte 0x addresses, PQVM terminology, ML-DSA-65 primary).

Changes:

  • Add/extend R3 protocol components: algorithm registry governance + RPC exposure, wPoA view-change, proof challenge lifecycle, and weighted slashing/finality.
  • Introduce PQVM execution updates: native PQ opcodes, revised precompile table, and removal of legacy EVM opcodes/precompiles.
  • Add pruned/light state-trie snapshot deletion and update docs/config defaults to match the R3 model (addresses, consensus defaults, storage profiles).

Reviewed changes

Copilot reviewed 63 out of 64 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
UPGRADE.md Updates upgrade guidance and version to v0.23.0, including address-format note.
README.md Refreshes project positioning/feature list to PQVM-native + R3 semantics.
docs/SYSTEM_CONTRACTS.md Updates system-contract docs for 32-byte address space + new registry/governance calls.
docs/stark-aggregation.md Documents explicit proof challenge lifecycle and timeout.
docs/SMART_CONTRACT_GUIDE.md Adds PQVM opcode/precompile guidance and updates address format in examples.
docs/rpc-reference.md Adds shell_getAlgorithmRegistry to the RPC reference.
docs/PROVER_GUIDE.md Documents L2StarkMode and updates prover/address derivation notes.
docs/PQ_CRYPTO_GUIDE.md Shifts docs to ML-DSA-65 primary, 32-byte addresses, and algorithm registry governance.
docs/keystore-format.md Updates keystore guidance to ML-DSA-65 primary / Dilithium legacy.
docs/JSON_RPC_API.md Updates RPC docs for 32-byte 0x address canonical format and adds method notes.
docs/CONSENSUS_DETAILS.md Documents weighted quorum finality, slash weights, view-change, and challenge lifecycle.
docs/BLOCK_PRUNING_AND_COMPRESSION.md Updates pruning docs to describe snapshot reachability pruning.
docs/BENCHMARKS.md Updates benchmark baseline version and adds whitepaper reference sizes.
docs/ACCOUNT_ABSTRACTION_GUIDE.md Updates AA guide for 32-byte address derivation and PQVM boundary shims.
crates/storage/src/world_state.rs Adds snapshot node reachability collection and deletion helpers (RLP parsing).
crates/storage/src/rocks_db.rs Removes dead ALL_CFS constant.
crates/storage/src/chain_store.rs Updates pruning/refcount commentary for current pruning strategy.
crates/storage/Cargo.toml Adds rlp dependency for trie node decoding.
crates/stark-prover/src/recursive_air.rs Adds tests ensuring scaffold recursive prover can’t “succeed”.
crates/rpc/src/types.rs Updates storage profile names to whitepaper canonical (pruned vs legacy light).
crates/rpc/src/handler/shell_api.rs Adds validator-weight proposal RPC, live peer count stats, and algorithm registry endpoint.
crates/rpc/src/handler/mod.rs Removes dead helper and adds/extends network stats tests.
crates/rpc/src/handler/eth.rs Updates getCompilers documentation comment.
crates/rpc/src/api.rs Adds RPC methods for validator weight proposals + algorithm registry exposure.
crates/node/src/pruning.rs Adds pruned/rolling storage profile aliases + implements prune_state_trie().
crates/node/src/prover_service.rs Makes L2 task processing public and adds boundary tests for scaffold mode.
crates/node/src/node/system_rewards.rs Hardens L2 source binding using settled-source tracking; adjusts recursive verification behavior.
crates/node/src/node/stark_sources.rs Updates reference-mode pk-hash derivation for 32-byte addresses.
crates/node/src/node/p2p_handlers.rs Adds algorithm inference for signatures + weighted attestations and signed view-change handling.
crates/node/src/node/mod.rs Wires challenge lifecycle, offline tracking, weighted finality fields, and pruning integration.
crates/node/src/node/event_loop.rs Implements view-change timeout broadcasting, challenge tracking/slashing, and RPC finalized propagation.
crates/node/src/node/challenge_lifecycle.rs New in-process challenge lifecycle state machine with tests.
crates/node/src/node/block_producer.rs Tracks last proposed block per validator for offline detection.
crates/node/src/node/block_importer.rs Tracks last proposed block on import for offline detection.
crates/node/src/config.rs Defaults dev/test/mainnet configs to WPoA and adds tests for defaults/heartbeat.
crates/network/src/message.rs Updates network message enum to carry signed ViewChangeMessage.
crates/network/src/libp2p_service.rs Routes view-change messages under consensus/attestation topic kind.
crates/network/src/bandwidth.rs Stabilizes a timing-sensitive bandwidth test.
crates/evm/src/tx_validation.rs Renames docs/comments to PQVM/revm terminology.
crates/evm/src/state_db.rs Removes dead PQ-address remapping helpers.
crates/evm/src/precompiles.rs Replaces standard precompiles with PQ suite and updates verification helpers/tests.
crates/evm/src/pqvm_opcodes.rs Adds PQVM native opcodes (PQVERIFY/PQHASH/PQADDR) and unit tests.
crates/evm/src/lib.rs Exposes PQVM opcode constants and new system-contract helpers.
crates/evm/src/executor.rs Installs PQVM opcodes, disables CALLCODE/SELFDESTRUCT, and updates execution-path tests.
crates/evm/src/aa_validation.rs Switches algorithm checks to runtime registry (is_algorithm_allowed).
crates/crypto/src/signature.rs Updates ML-DSA-65 docstring to reflect primary algorithm status.
crates/crypto/src/multi.rs Adds verify_signature() helper and signature-type inference from address.
crates/crypto/src/lib.rs Exposes algorithm registry module and new helper exports.
crates/crypto/src/algorithm_registry.rs New global runtime algorithm registry with lifecycle transitions + tests.
crates/core/src/receipt.rs Updates receipt comments to PQVM/revm terminology.
crates/core/src/block.rs Updates block header comments to PQVM/revm terminology.
crates/consensus/src/wpoa.rs Adds view-change state handling and weight-aware slashing/weights.
crates/consensus/src/view_change.rs New view-change message/state implementation with timeout/quorum tests.
crates/consensus/src/poa.rs Makes PoA slashing weight-aware and keeps slashed set for observability.
crates/consensus/src/lib.rs Exposes view-change module/types/constants.
crates/consensus/src/fork_choice.rs Switches fork choice scoring from attestation count to attested weight.
crates/consensus/src/engine.rs Extends consensus trait with view-change hooks and timeout/progress signaling.
crates/cli/src/commands/run.rs Defaults consensus selection to WPoA unless explicitly overridden to PoA.
crates/cli/src/commands/backup.rs Gates dir_size() behind rocksdb feature.
CHANGELOG.md Adds v0.23.0 release notes and summarizes new R3 features/fixes.
Cargo.lock Bumps workspace crate versions to 0.23.0 and adds rlp dependency.
AGENTS.md Updates repo SSoT to PQVM terminology, ML-DSA-65 primary, and whitepaper precedence.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 242 to 247
return false;
}
let message = &input[4 + pk_len + 4..4 + pk_len + 4 + msg_len];
let sig_bytes = &input[4 + pk_len + 4 + msg_len..];
let signature = PQSignature::new(SignatureType::Dilithium3, sig_bytes.to_vec());
DilithiumVerifier
.verify(public_key, message, &signature)
.unwrap_or(false)
verify_signature(SignatureType::Dilithium3, public_key, message, sig_bytes).unwrap_or(false)
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b5e78b5: test reply

ShellPrecompiles::new(spec),
);
let mut instructions = EthInstructions::new_mainnet_with_spec(spec);
remove_legacy_opcodes(&mut instructions);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b5e78b5: added install_pqvm_opcodes(&mut instructions) before remove_legacy_opcodes in the AA inner-call EVM setup so PQVERIFY/PQHASH/PQADDR are available inside AA bundles.

Comment on lines +501 to +506
/// W.5: Handle an incoming signed wPoA view-change message from a peer.
pub fn handle_wpoa_view_change(
&self,
msg: ViewChangeMessage,
verifier: &dyn Verifier,
) -> Result<bool, NodeError> {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b5e78b5: handle_wpoa_view_change now rejects messages whose block_number != head + 1 before forwarding to consensus.

Comment on lines +377 to 409
// Check 3: recursive proof verification (best-effort; requires
// feature = "recursive"). Until the real prover is wired in, the
// scaffold returns NotImplemented — treated as a soft pass so that
// testnet L2 settlements can proceed. Source-binding checks (1 & 2)
// above are the canonical gate for now.
if let Ok(rec_proof) = serde_json::from_slice::<shell_stark_prover::RecursiveProof>(
&amendment.proof.proof_bytes,
)
.map_err(|e| {
NodeError::Startup(format!(
"STARK L2 amendment: failed to decode recursive proof bytes: {e}"
))
})?;
match prover.verify_aggregation(&rec_proof, &pub_inputs) {
Ok(()) => {}
Err(shell_stark_prover::RecursiveProverError::NotImplemented) => {
// Scaffold: verification is not yet active. Log clearly and
// reject L2 settlements until the real verifier is in place.
self.metrics.stark_settlements_rejected.inc();
return Err(NodeError::Startup(
"STARK L2 amendment rejected: recursive proof verifier is not yet \
implemented (feature = \"recursive\" not enabled)"
.into(),
));
}
Err(e) => {
self.metrics.stark_settlements_rejected.inc();
return Err(NodeError::Startup(format!(
"STARK L2 recursive proof verification failed: {e}"
)));
) {
match prover.verify_aggregation(&rec_proof, &pub_inputs) {
Ok(()) => {}
Err(shell_stark_prover::RecursiveProverError::NotImplemented) => {
// Recursive verifier is not yet active; soft-pass.
tracing::debug!(
block_hash = %amendment.block_hash,
"STARK L2 recursive proof verifier not yet active — \
source-binding checks passed, soft-accepting"
);
}
Err(e) => {
self.metrics.stark_settlements_rejected.inc();
return Err(NodeError::Startup(format!(
"STARK L2 recursive proof verification failed: {e}"
)));
}
}
} else {
// Proof bytes are not decodable as a RecursiveProof — soft-pass
// until the encoding is finalised.
tracing::debug!(
block_hash = %amendment.block_hash,
"STARK L2 proof_bytes are not a RecursiveProof — soft-accepting"
);
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b5e78b5: validate_l2_proof_source_binding now hard-rejects when proof_bytes fails to decode as RecursiveProof, returning NodeError::Startup instead of soft-passing.

Comment on lines +300 to +319
let chain_store = ChainStore::new(Arc::clone(&store));
let Some(head) = chain_store.get_head_block()? else {
return Ok(StateTriePruneResult::default());
};

let mut old_roots = Vec::new();
let mut retained_roots = HashSet::new();
for block_number in 0..=head.number() {
let Some(block_hash) = chain_store.get_block_hash_by_number(block_number)? else {
continue;
};
let Some(header) = chain_store.get_header_by_hash(&block_hash)? else {
continue;
};
if block_number < keep_below_block {
old_roots.push(header.state_root);
} else {
retained_roots.insert(header.state_root);
}
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b5e78b5: retained-roots loop now starts at keep_below_block (not 0), and old-roots eviction handles only the one newly-expired block — reducing complexity from O(chain_height) to O(window_size).

Comment thread docs/SMART_CONTRACT_GUIDE.md Outdated
Comment on lines +114 to +118
| Opcode | Hex | Gas | Description |
|--------|-----|-----|-------------|
| `PQVERIFY` | `0xB0` | 3000 | Verify a PQ signature on-chain |
| `PQHASH` | `0xB1` | 200 | BLAKE3 hash of input data |
| `PQADDR` | `0xB2` | 100 | Derive a 32-byte address from algo_id + pubkey |
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b5e78b5: gas table updated — PQVERIFY: 46,000; PQHASH: 30+6×⌈len/32⌉ words; PQADDR: 200.

Comment thread docs/SMART_CONTRACT_GUIDE.md Outdated
Comment on lines +123 to +132
### Precompile addresses (0x0001–0x0006)

| Address | Function | Input wire format |
|---------|----------|------------------|
| `0x...0001` | ML-DSA-65 Verify | `[4-byte pk_len][pk][4-byte msg_len][msg][sig]` |
| `0x...0002` | SLH-DSA-SHA2-256f Verify | `[4-byte pk_len][pk][4-byte msg_len][msg][sig]` |
| `0x...0003` | BLAKE3 Hash | raw bytes → 32-byte digest |
| `0x...0004` | Dilithium3 Verify | `[4-byte pk_len][pk][4-byte msg_len][msg][sig]` |
| `0x...0005` | PQ Address Derive | `[1-byte algo_id][pubkey]` → 32-byte address |
| `0x...0006` | Reserved | — |
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b5e78b5: first precompile table corrected — 0x0001 ML-DSA-family verify, 0x0002 SLH-DSA verify, 0x0003 ML-DSA batch, 0x0004 BLAKE3-256, 0x0005 BLAKE3-512, 0x0006 PQ address derive.

Comment thread docs/SMART_CONTRACT_GUIDE.md Outdated
Comment on lines +349 to +356
| Address | Function | Gas model |
|---------|----------|-----------|
| `0x0000000000000000000000000000000000000001` | ML-DSA-65 verify | flat `46,000` |
| `0x0000000000000000000000000000000000000002` | SLH-DSA-SHA2-256f verify | flat `2,300,000` |
| `0x0000000000000000000000000000000000000003` | BLAKE3 hash | `30 + 6 × words` |
| `0x0000000000000000000000000000000000000004` | Dilithium3 verify | flat `46,000` |
| `0x0000000000000000000000000000000000000005` | PQ address derive | flat `200` |
| `0x0000000000000000000000000000000000000006` | Reserved | — |
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b5e78b5: second PQ precompile suite table updated to match runtime layout (0x0001–0x0006 with correct labels and gas models).

Comment thread docs/JSON_RPC_API.md
Comment on lines 871 to 877
{
"jsonrpc": "2.0",
"id": 1,
"result": [
"pq1qyqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqy0vusna",
"pq1qyqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqg7j66z6"
"0x0000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000002"
]
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b5e78b5: all example validator addresses updated to 32-byte format (0x + 64 lowercase hex chars).

LucienSong and others added 3 commits May 24, 2026 00:06
- fix(consensus): add Default impl for ViewChangeState (clippy new_without_default)
- fix(pqvm): correct doc list item indentation (clippy doc_overindented_list_items)
- fix(precompiles): dispatch MlDsa65 first in verify_mldsa65(), fall back to Dilithium3
- fix(executor): install PQVM opcodes in AA inner-call EVM instances
- fix(p2p): reject view-change messages for non-current block heights
- fix(rewards): hard-reject L2 proof_bytes that fail RecursiveProof decode
- perf(pruning): reduce prune_state_trie from O(chain_height) to O(window_size)
- docs: align SMART_CONTRACT_GUIDE precompile/gas tables with implementation
- docs: update JSON_RPC_API validator address examples to 32-byte format

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…fier and pruning backlog

- system_rewards: soft-pass non-decodable RecursiveProof with warning log
  (hard-reject is correct only when recursive verifier is active; current
  scaffold returns NotImplemented, making the decode gate premature)
- pruning: collect all old roots in 0..keep_below_block (not just evicted-1)
  to correctly handle first-run and catch-up scenarios; retained-roots loop
  remains bounded to keep_below_block..=head (the actual O(n²) fix)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@LucienSong LucienSong merged commit 2b752e6 into ShellDAO:main May 23, 2026
3 checks passed
@LucienSong LucienSong deleted the feat/pqvm-native-r3 branch May 23, 2026 18:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants