-
Notifications
You must be signed in to change notification settings - Fork 34
Versioning #263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Versioning #263
Changes from all commits
068611c
052ccc3
ba17bab
386e423
cd5b1e9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| # Compiler Versioning | ||
|
|
||
| The SimplicityHL compiler enforces strict version compatibility to prevent contracts from silently breaking due to compiler updates, semantic changes, or new language features. | ||
|
|
||
| Every `.simf` file must begin with a compiler version directive: | ||
| ```rust | ||
| simc ">=0.6.0"; | ||
| ``` | ||
|
|
||
| ## Semantic Versioning (SemVer) | ||
|
|
||
| The compiler uses standard Semantic Versioning rules to evaluate whether a file is compatible with the currently running compiler. You can use operators to define acceptable ranges: | ||
|
|
||
| * **Caret (`^`) or Bare strings:** `^0.6.0` or `0.6.0`. Allows patch-level and minor-level updates that do not modify the left-most non-zero digit. (e.g., `^0.6.0` allows `0.6.1`, but rejects `0.7.0`). | ||
| * **Tilde (`~`):** `~0.6.0`. Allows only patch-level updates. (e.g., `~0.6.0` allows `0.6.1`, but rejects `0.6.2` if it introduces new minor features). | ||
| * **Exact (`=`):** `=0.6.0`. Strictly requires this exact version of the compiler. | ||
| * **Inequalities (`>`, `>=`, `<`, `<=`):** `>=0.6.0`. Allows any compiler version equal to or newer than `0.6.0`. | ||
| * **Wildcards (`*`, `x`):** `0.x.x`. Allows any version matching the specified major release. | ||
| * **Multiple Bounds:** `>=0.6.0, <1.0.0`. You can combine operators with a comma. | ||
|
|
||
| ### Pre-release versions | ||
| If the compiler is currently on a pre-release version (e.g., `0.6.0-rc.0`), it will only match against contracts that explicitly request that exact pre-release base, or contracts that safely encompass the base version. | ||
|
|
||
| ## Multi-File Enforcement | ||
|
|
||
| Version checking is performed eagerly immediately after the initial syntax parsing, before dependency resolution and semantic analysis occur. When building a multi-file project, the compiler driver evaluates the version directive of the `main.simf` entry point, as well as the directives of every external library file imported via the `--dep` flag. | ||
|
|
||
| If *any* file in the dependency graph requires a compiler version that is incompatible with the currently running compiler, the driver immediately halts compilation. | ||
|
|
||
| This mathematical guarantee ensures that an older, stable library cannot be accidentally compiled with an incompatible compiler without the developer's explicit consent. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| simc ">=0.6.0"; | ||
|
|
||
| fn sum(elt: u32, acc: u32) -> u32 { | ||
| let (_, acc): (bool, u32) = jet::add_32(elt, acc); | ||
| acc | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| simc ">=0.6.0"; | ||
|
|
||
| fn main() { | ||
| let ab: u16 = <(u8, u8)>::into((0x10, 0x01)); | ||
| let c: u16 = 0x1001; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| simc ">=0.6.0"; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this not just be Can we guarantee it will work on
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I explained the reason here: #263 (comment) |
||
|
|
||
| use crate::math::add; | ||
|
|
||
| fn main() { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| simc ">=0.6.0"; | ||
|
|
||
| pub fn add(a: u32, b: u32) -> u32 { | ||
| let (_, sum): (bool, u32) = jet::add_32(a, b); | ||
| sum | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| simc ">=0.6.0"; | ||
|
|
||
| pub fn hash(x: u32, y: u32) -> u32 { | ||
| jet::xor_32(x, y) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| simc ">=0.6.0"; | ||
|
|
||
| use math::simple_op::hash as temp_hash; | ||
|
|
||
| pub fn get_root(tx1: u32, tx2: u32) -> u32 { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,14 @@ | ||
| simc ">=0.6.0"; | ||
|
|
||
| /* | ||
| * PAY TO PUBLIC KEY | ||
| * | ||
| * The coins move if the person with the given public key signs the transaction. | ||
| * | ||
| * https://docs.ivylang.org/bitcoin/language/ExampleContracts.html#lockwithpublickey | ||
| */ | ||
|
|
||
|
|
||
| fn main() { | ||
| jet::bip_0340_verify((param::ALICE_PUBLIC_KEY, jet::sig_all_hash()), witness::ALICE_SIGNATURE) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| simc ">=0.6.0"; | ||
|
|
||
| fn main() { | ||
| let complex_pattern: Either<(u32, u32, (u1, u1)), [u1; 8]> = Left((32, 3, (0, 1))); | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| simc ">=0.6.0"; | ||
|
|
||
| use math::arithmetic::add; | ||
| use crypto::hashes::sha256; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| simc ">=0.6.0"; | ||
|
|
||
| pub fn add(a: u32, b: u32) -> u32 { | ||
| let (_, res): (bool, u32) = jet::add_32(a, b); | ||
| res | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| simc ">=0.6.0"; | ||
|
|
||
| pub use temp::constants::utils::two as smth; | ||
| use temp::funcs::{get_five, Smth}; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| simc ">=0.6.0"; | ||
|
|
||
| pub use crate::funcs::Smth; | ||
|
|
||
| pub fn two() -> Smth { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| simc ">=0.6.0"; | ||
|
|
||
| pub type Smth = u32; | ||
|
|
||
| pub fn get_five() -> u32 { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is incredibly limiting to new developers to enforce this. Surely this should be opt-in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not fully understand how it will work. If we load a file without a version, then how are we supposed to determine it? Do we assume that it is always correct? What if the functionality in that file becomes deprecated? What if we have some vulnerabilities in the file? Thus, I think we need to make it mandatory for users to use versions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me walk through the two concrete scenarios:
Case 1: File uses newer syntax (e.g., pub or use, introduced in simc 0.6.0)
If no version is specified, the file simply fails to compile on older compilers with a syntax error. The simc field doesn't change this outcome - it just gives a much better error message ("this file requires simc >= 0.6.0") instead of a confusing parser error.
Case 2: File uses deprecated or removed functionality
Same story: without a version constraint, the file fails to compile once that feature is removed. The simc field lets authors signal simc >=0.5.0, <0.6.0 to make that explicit, but it's still an error either way.
On vulnerabilities: the simc version field controls compilation compatibility, not runtime security. Vulnerabilities in Simplicity programs are addressed at the consensus/jet layer, independently of the compiler version.
So omitting the simc field is never silently wrong - the compiler still catches incompatibilities. Making it mandatory adds friction for new developers who just want to write a simple program, and requires them to understand version semantics before writing their first line of code. Keeping it as may means it's there when you need better error messages, but doesn't block the happy path.