Skip to content

feat: PVM update 0.8.0 - #1046

Open
TwEricShen wants to merge 1 commit into
1012-update-to-v080from
refactor/PVM-080-Appendix-AB
Open

feat: PVM update 0.8.0#1046
TwEricShen wants to merge 1 commit into
1012-update-to-v080from
refactor/PVM-080-Appendix-AB

Conversation

@TwEricShen

@TwEricShen TwEricShen commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Part of #1022

Summary

Aligns the PVM implementation with Gray Paper v0.8.0 Appendix A & B, including:

  • Appendix A: basic block boundaries, gaschargedflag, A.9 ROB gas model, A.10 opcode cost tables, unlikely, branch/jump dual-target validation, deblob / 𝔳_inst first-run validation, IntegratedPVMType, etc.
  • Appendix B: host call renumbering (grow_heap inserted at ID=1), per-function linear gas (Appendix H constants), invoke gas refund, machine 63-slot cap, bless / designate / query semantic updates.

The interpreter and recompiler share the same gas engine (GasCostForBlock / GasCostFromPC / blockGasAtPC). The recompiler bakes block gas at compile time (emitBlockGasCheck).


Submodule: gas model test vectors

New submodule:

Field Value
Path pkg/test_data/new-gas-cost-model
Remote https://github.com/koute/new-gas-cost-model.git
Purpose GP A.9 gascostforblock vectors (aligned with koute / w3f/jamtestvectors PR #3)

Required for reviewers / CI (gas tests fail immediately if the vectors directory is missing):

git submodule update --init --recursive pkg/test_data/new-gas-cost-model
# or all submodules
git submodule update --init --recursive

Verify the submodule points at the expected commit:

git submodule status pkg/test_data/new-gas-cost-model

Main changes (PVM)

Area Files / modules Description
A.9 Gas model gas_sim.go, gas_opcode.go, gas_regs.go, gas_model.go ROB pipeline simulation; gascostforblock = max(cycles−3, 1)
A.4 Block gas metering invocation.go, block_info.go Block-entry pre-charge, GasCharged flag, blockGasAtPC cache
A.10 + host gas gas_const.go, host_call_*.go Appendix H constants; MemGas linear billing
Recompiler recompiler/gas.go, compiler.go Per-instruction gas → block-level emitBlockGasCheck
Invoke / inner VM host_call_refine.go, host_call_invoke_test.go BlockBasedInvokeDecodedBlocks, suffix gas, gasChargedForIntegratedResume
Opcode / decode instructions*.go, program_code.go unlikely, branch dual-target, sjump, DeBlobProgramCode(blob, pc)
sbrk → grow_heap host_call_general.go, recompiler emit Opcode 101 semantics removed; heap growth via host call ID=1
Dual backend execution_backend.go, interpreter/, recompiler/ PVM.WithExecutionBackend / SetExecutionBackend
Tooling cmd/pvmtrace/deblob_program.go, scripts/scan_psi_a_program_blobs.py Deblob API signature; scan Ψ_A program blobs from conformance traces

Implementation choice (not spelled out in GP)

Mid-block resume gas: when entry PC is mid-block and gaschargedflag=⊥, charge suffix GasCostFromPC(ι) (not the full containing block). Matches koute gas vectors and recompiler suffix compilation.


Tests

Gas model (koute vectors) — expected all PASS

Data root: pkg/test_data/new-gas-cost-model/

Test function What it checks Vector prefix / dir Count Pass Command
TestGasModelProgramVectors End-to-end ROB / block gas scenarios tests/programs/gas_*.json 23 23/23 go test ./PVM/ -run TestGasModelProgramVectors -count=1
TestGasModelInstVectors Per-opcode block gas tests/programs/inst_*.json 229 229/229 go test ./PVM/ -run TestGasModelInstVectors -count=1
TestGasModelRiscvVectors Programs compiled from RISC-V tests/programs/riscv_*.json 106 106/106 go test ./PVM/ -run TestGasModelRiscvVectors -count=1
TestGasModelMultistepVectors ecalli / paging mid-block cases tests/programs/multistep_*.json 4 4/4 go test ./PVM/ -run TestGasModelMultistepVectors -count=1
TestGasModelIntegrationVectors Large programs + block gas tables integration-tests/*.json 3 3/3 go test ./PVM/ -run TestGasModelIntegrationVectors -count=1
TestGasVectorHarnessSanity JSON harness sanity (deblob, single-block consumed gas) same gas_*.json 23 23/23 go test ./PVM/ -run TestGasVectorHarnessSanity -count=1

Total: 362 program vectors + 3 integration = 365 JSON files in the tree.

Run all gas-related tests:

go test ./PVM/ -count=1 -run 'TestGasModel|TestGasVectorHarnessSanity|TestBlockGasFromCycles|TestGasCost'

Each vector asserts GasCostForBlock(prog, pc) equals the JSON block-gas-costs entry.


Gas model unit tests (non-vector)

Test function What it checks Command
TestBlockGasFromCycles max(cycles−3, 1) formula go test ./PVM/ -run TestBlockGasFromCycles -count=1
TestGasCostSingleTrapBlock Trap block gas = 2 go test ./PVM/ -run TestGasCostSingleTrapBlock -count=1
TestGasCostMoveRegBlock move_reg bypasses ROB go test ./PVM/ -run TestGasCostMoveRegBlock -count=1
TestGasCostBranchToTrap Branch → unlikely/trap costs go test ./PVM/ -run TestGasCostBranchToTrap -count=1
TestInstructionCostEcalli / TestInstRegsEcalli A.10 ecalli cost / reg analysis `go test ./PVM/ -run 'TestInstructionCostEcalli

Invocation / block gas behavior

Test function What it checks Command
TestBlockBasedInvokeDecodedBlocksChargesContainingBlock Production path block charging go test ./PVM/ -run TestBlockBasedInvokeDecodedBlocks -count=1
TestBlockBasedInvokeDecodedBlocksResumesAfterHostCall Suffix gas after host call return same
TestBlockBasedInvoke* / TestDebugSingleStepInvoke* Legacy / trace paths `go test ./PVM/ -run 'TestBlockBasedInvoke
TestBlockGasAtPCUsesCacheAtBlockEntry Cache at block entry go test ./PVM/ -run TestBlockGasAtPCUsesCacheAtBlockEntry -count=1
TestGasChargedForIntegratedResume / TestInvokeInnerTrapDeductsBlockGas Inner invoke flag / gas `go test ./PVM/ -run 'TestGasChargedForIntegratedResume

Host-call gas / v0.8 semantics

Test function What it checks Command
TestAddGasAndUnitGasCost MemGas / unit gas go test ./PVM/ -run TestAddGasAndUnitGasCost -count=1
TestPagesGasCost pages tiered gas go test ./PVM/ -run TestPagesGasCost -count=1
TestLookupLinearGasOOG Linear gas OOG go test ./PVM/ -run TestLookupLinearGasOOG -count=1
TestQueryBlobLengthHUH / TestBlessManagerOnly HUH boundaries `go test ./PVM/ -run 'TestQueryBlobLengthHUH
TestFetchCost fetch tiered gas go test ./PVM/ -run TestFetchCost -count=1

Recompiler (linux/amd64 + CGO)

Test function What it checks Command
TestCompileAllOpcodes All opcodes compile CGO_ENABLED=1 go test ./PVM/recompiler/ -run TestCompileAllOpcodes -count=1
TestExecuteInstructions Compiled execution semantics CGO_ENABLED=1 go test ./PVM/recompiler/ -run TestExecuteInstructions -count=1
TestBlockEntryOOGLeavesGasUnchanged Block OOG leaves gas unchanged CGO_ENABLED=1 go test ./PVM/recompiler/ -run TestBlockEntryOOG -count=1
TestBlockGasChargedAcrossHostCall GasCharged flag across host call CGO_ENABLED=1 go test ./PVM/recompiler/ -run TestBlockGasChargedAcrossHostCall -count=1
TestSuffixBlockGasMatchesGasCostFromPC Suffix compile gas matches A.9 CGO_ENABLED=1 go test ./PVM/recompiler/ -run TestSuffixBlockGasMatchesGasCostFromPC -count=1
Makefile target Recompiler tests in Docker make run-recompiler-test

Interpreter ↔ Recompiler consistency — currently FAIL (known)

Field Details
Test function TestInterpreterVsRecompilerProgramBlobs
What it checks Same MetaCode program blob run through Ψ_M (Accumulate) on interpreter vs recompiler; requires matching Gas + ReasonOrBytes
Data PVM/testdata/psi_a_consistency/blobs/*.bin (30 blobs)
How data was produced scripts/scan_psi_a_program_blobs.py scans large keyvals (MetaCode preimages) from pkg/test_data/jam-conformance/fuzz-reports/0.7.2/traces/
Entry / gas PC=5 (Ψ_A entry), gas=50_000_000
Platform linux && amd64 && cgo
Command make test-backend-consistency or CGO_ENABLED=1 go test -count=1 -timeout 30m -v ./PVM/ -run TestInterpreterVsRecompilerProgramBlobs
Current status Failing; programs PANIC under 0.8.0 semantics (host call IDs shifted +1, grow_heap inserted, etc.) — not an interpreter/recompiler divergence
Note Goal is backend consistency; meaningful only after refreshed 0.8 program blobs

Example blob scan:

python3 scripts/scan_psi_a_program_blobs.py \
  pkg/test_data/jam-conformance/fuzz-reports/0.7.2/traces \
  --limit-folders 30

Suggested reviewer verification order

  1. git submodule update --init --recursive pkg/test_data/new-gas-cost-model
  2. Gas vectors: go test ./PVM/ -run 'TestGasModel|TestGasVectorHarnessSanity' -count=1
  3. PVM unit tests: go test ./PVM/ -count=1 -skip TestInterpreterVsRecompilerProgramBlobs
  4. CGO_ENABLED=1 go test ./PVM/recompiler/... -count=1 (linux/amd64)

Related

@TwEricShen TwEricShen self-assigned this Aug 6, 2026
@TwEricShen TwEricShen mentioned this pull request Aug 6, 2026
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.

1 participant