Repository navigation
Conversation
Freeze the bytecode compiled from every script fixture, with each case's vars blob, inputs and output, and check that this build runs it to the same result or rejects it with UnsupportedBytecodeVersionError. A guard fails when CurrentBytecodeVersion has no freeze.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The ledger stores the compiled bytecode (program and vars blobs) in its Raft log and re-runs it when a node restarts. So a build that can read a blob must run it to the same result as the build that wrote it. Nothing checked that: every VM test recompiles with the current compiler, so a change to the decoder, the verifier or
Execthat alters what existing 0.1 bytecode does, without a version bump, went unnoticed.What
testdata/bytecode/0.1/: the bytecode compiled from every script fixture (225 programs, 237 cases, 136 KB), with each case's vars blob, inputs and the output it produced. Layout:0.1, or0.1-<suffix>for a later freeze at the same version) and is never edited once committed. The asset-scaling fixtures are skipped: the compiler has no lowering for them yet.bytecode_corpus_test.go(module root, public API only, the same calls the ledger makes):TestBytecodeCorpus: for every frozen case, decode, verify and run the blobs and compare with the frozen output. A blob this build cannot read must be rejected withUnsupportedBytecodeVersionError, which is what makes the ledger recompile from source. For the current version, re-encoding the decoded blobs must give back the same bytes.TestBytecodeCorpusHasCurrentVersion: fails whenCurrentBytecodeVersionhas no freeze.TestFreezeBytecodeCorpus: the writer, skipped unlessNUMSCRIPT_FREEZE_BYTECODE=1.just freeze-bytecode [suffix]: runs the compiler suite first, then writes a new directory. It refuses to overwrite an existing one.compiler-architecture.md: a "Frozen bytecode" section with the rules below.Rules
CurrentBytecodeVersion(enforced by the guard test).TestBytecodeCorpuson a readable directory means this build runs existing bytecode differently. Either the change is a bug, or the bytecode version has to be bumped so that older blobs are rejected.Checked
AddIntsubtract instead: 84 frozen cases fail. Bumping the version to 0.2 without freezing: the guard fails and every 0.1 entry passes as rejected. Both reverted.go test ./...green; the root package is green under-race.