From fa352e30093bb996e1fd16395f52322091786a45 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Sun, 10 May 2026 00:20:34 +0400 Subject: [PATCH 1/2] soldeer migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirrors the level-1/2 leaves. Dependencies: - forge-std → forge-std-1.16.1 (soldeer) The lib/rain.math.binary submodule was unused — no source file imports anything from it — so it gets dropped along with .gitmodules and lib/forge-std. CI: drop the bespoke matrix; consume rainix's composite rainix-sol reusable; add the publish wrapper. Verified: forge build clean. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/git-clean.yaml | 9 +- .github/workflows/publish-soldeer.yaml | 9 ++ .github/workflows/rainix.yaml | 39 +------- .gitignore | 4 +- .gitmodules | 6 -- .soldeerignore | 26 +++++ README.md | 77 ++++++++++++--- REUSE.toml | 29 +++--- flake.lock | 127 ++++++++++++++++++++----- flake.nix | 20 ++-- foundry.toml | 14 ++- lib/forge-std | 1 - lib/rain.math.binary | 1 - remappings.txt | 1 + soldeer.lock | 6 ++ src/lib/LibCodeGen.sol | 2 +- src/lib/LibFs.sol | 2 +- src/lib/LibHexString.sol | 2 +- 18 files changed, 252 insertions(+), 123 deletions(-) create mode 100644 .github/workflows/publish-soldeer.yaml delete mode 100644 .gitmodules create mode 100644 .soldeerignore delete mode 160000 lib/forge-std delete mode 160000 lib/rain.math.binary create mode 100644 remappings.txt create mode 100644 soldeer.lock diff --git a/.github/workflows/git-clean.yaml b/.github/workflows/git-clean.yaml index 0987091..135371d 100644 --- a/.github/workflows/git-clean.yaml +++ b/.github/workflows/git-clean.yaml @@ -1,15 +1,12 @@ name: Git is clean on: [push] - jobs: git-clean: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: - submodules: recursive fetch-depth: 0 - - uses: nixbuild/nix-quick-install-action@v30 with: nix_conf: | @@ -26,12 +23,10 @@ jobs: # before trying to save a new cache # 1G = 1073741824 gc-max-store-size-linux: 1G - + - run: nix develop -c forge soldeer install - run: nix develop -c forge script ./script/BuildPointers.sol - # Format the repo after generating pointers so that the pointer files are # formatted too. - run: nix develop -c forge fmt - # Check if the repo is clean after generating pointers and formatting. - - run: git diff --exit-code \ No newline at end of file + - run: git diff --exit-code diff --git a/.github/workflows/publish-soldeer.yaml b/.github/workflows/publish-soldeer.yaml new file mode 100644 index 0000000..b57bdc2 --- /dev/null +++ b/.github/workflows/publish-soldeer.yaml @@ -0,0 +1,9 @@ +name: Publish to Soldeer +on: + push: + tags: + - "v*" +jobs: + publish: + uses: rainlanguage/rainix/.github/workflows/publish-soldeer.yaml@main + secrets: inherit diff --git a/.github/workflows/rainix.yaml b/.github/workflows/rainix.yaml index 08de8a6..612abd5 100644 --- a/.github/workflows/rainix.yaml +++ b/.github/workflows/rainix.yaml @@ -1,39 +1,6 @@ -name: Rainix CI +name: rainix on: [push] - jobs: rainix: - strategy: - matrix: - os: [ubuntu-latest] - task: [rainix-sol-test, rainix-sol-static, rainix-sol-legal] - fail-fast: false - runs-on: ${{ matrix.os }} - env: - DEPLOYMENT_KEY: ${{ github.ref == 'refs/heads/main' && secrets.PRIVATE_KEY || secrets.PRIVATE_KEY_DEV }} - steps: - - uses: actions/checkout@v4 - with: - submodules: recursive - fetch-depth: 0 - - - uses: nixbuild/nix-quick-install-action@v30 - with: - nix_conf: | - keep-env-derivations = true - keep-outputs = true - - name: Restore and save Nix store - uses: nix-community/cache-nix-action@v6 - with: - # restore and save a cache using this key - primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }} - # if there's no cache hit, restore a cache by this prefix - restore-prefixes-first-match: nix-${{ runner.os }}- - # collect garbage until the Nix store size (in bytes) is at most this number - # before trying to save a new cache - # 1G = 1073741824 - gc-max-store-size-linux: 1G - - - run: nix develop -c rainix-sol-prelude - - name: Run ${{ matrix.task }} - run: nix develop -c ${{ matrix.task }} \ No newline at end of file + uses: rainlanguage/rainix/.github/workflows/rainix-sol.yaml@main + secrets: inherit diff --git a/.gitignore b/.gitignore index 668aefc..0f9f079 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ cache -out \ No newline at end of file +dependencies +out +.pre-commit-config.yaml diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 602c8f3..0000000 --- a/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "lib/rain.math.binary"] - path = lib/rain.math.binary - url = https://github.com/rainlanguage/rain.math.binary -[submodule "lib/forge-std"] - path = lib/forge-std - url = https://github.com/foundry-rs/forge-std diff --git a/.soldeerignore b/.soldeerignore new file mode 100644 index 0000000..9f5c68a --- /dev/null +++ b/.soldeerignore @@ -0,0 +1,26 @@ +.DS_Store +.coderabbitai.yaml +.gas-snapshot +.git +.github +.gitignore +.gitmodules +.pre-commit-config.yaml +.soldeerignore +.vscode +CLAUDE.md +/audit +/cache +/dependencies +/docs +/flake.lock +/flake.nix +/foundry.lock +/foundry.toml +/lib +/out +/remappings.txt +/slither.config.json +/soldeer.lock +/target +/test diff --git a/README.md b/README.md index 63ca88d..edcfea0 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,68 @@ # rain.sol.codegen -Solidity native tooling to generate Solidity code. +Solidity-native tooling to generate Solidity source. Builds a valid `.sol` file +(pragma + foundry-clean formatting) that hosts the constant caches for prebuilt +function-pointer tables — needed for runtime gas efficiency in the Rain +interpreter. -Notably builds a valid Solidity file (pragma, etc.) that passes foundry -formatting cleanly, that can build the constant caches needed for prebuilt -function pointer tables to ensure runtime gas efficiency. +Also exposes interfaces (interpreter, sub-parsers, externs) for Rain contracts +to implement against the generated code. -Includes interfaces for the interpreter and sub parsers/externs for Rain -contracts to implement and be compatible with the code generation functions here. +`script/BuildPointers.sol` is an example implementation; +`.github/workflows/git-clean.yaml` is an example CI guard that fails when the +committed pointer artifacts drift from a fresh regeneration. -`script/BuildPointers.sol` includes an example implementation and -`.github/workflows/git-clean.yaml` an example CI action to show how to build -pointers cleanly and ensure that the source code does not become out of sync with -the built artifacts when merging new code. +Generated code is imported downstream by contracts that themselves expose +pointers, which pointers feed back into the generation. This cycle means +pointers may need to be regenerated several times until they reach a fixed point +where neither pointer values nor the codehash of any consuming contract shift. -Generated code is intended to be imported downstream into contracts that may -themselves expose pointers to be included in the generated code. This circular -dependency means the pointers may need to be built several times until they -produce a stable output where the pointers do not move, and therefore do not -break the codehash over the contract that includes the pointers. +## Install + +Via [soldeer](https://soldeer.xyz): + +```sh +forge soldeer install rain-sol-codegen~ +``` + +## Develop + +This repo uses [nix](https://nixos.org/download.html). The default shell is the +slim `sol-shell` from [rainix](https://github.com/rainlanguage/rainix). + +```sh +nix develop # enter the shell +forge soldeer install # install deps declared in foundry.toml +forge build +``` + +Tasks: + +- `rainix-sol-static` — slither +- `rainix-sol-legal` — `reuse lint` + +This repo has no `forge test` suite — the code is tooling exercised by +downstream consumers' generated artifacts. + +Use the nix-pinned `forge` for all development. + +## Publish + +Tag `v` on `main`. The +[`Publish to Soldeer`](.github/workflows/publish-soldeer.yaml) wrapper delegates +to rainix's reusable workflow, which derives the package name from the repo name +(`rain.sol.codegen` → `rain-sol-codegen`). + +## License + +DecentraLicense 1.0 (DCL-1.0) — full text in +[`LICENSES/`](LICENSES/LicenseRef-DCL-1.0.txt). Roughly `CAL-1.0` +([opensource.org](https://opensource.org/license/cal-1-0)) plus user-data +disclosure obligations consistent with permissionless-blockchain assumptions. + +This repo is [REUSE 3.2](https://reuse.software/spec-3.2/) compliant. Verify +locally: + +```sh +nix develop -c rainix-sol-legal +``` diff --git a/REUSE.toml b/REUSE.toml index d951b24..ba0e95e 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -2,19 +2,22 @@ version = 1 [[annotations]] path = [ - ".gas-snapshot", - ".github/workflows/**/", - ".gitignore", - ".gitmodules", - "audit/**/", - "README.md", - "flake.lock", - "flake.nix", - "foundry.toml", - "slither.config.json", - "REUSE.toml", - "src/lib/LibCodeGen.sol", - "foundry.lock", + ".gas-snapshot", + ".github/workflows/**/", + ".gitignore", + ".gitmodules", + ".soldeerignore", + "audit/**/", + "README.md", + "flake.lock", + "flake.nix", + "foundry.toml", + "remappings.txt", + "slither.config.json", + "REUSE.toml", + "src/lib/LibCodeGen.sol", + "foundry.lock", + "soldeer.lock", ] SPDX-FileCopyrightText = "Copyright (c) 2020 Rain Open Source Software Ltd" SPDX-License-Identifier = "LicenseRef-DCL-1.0" diff --git a/flake.lock b/flake.lock index b88de52..91cd50b 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,21 @@ { "nodes": { + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1767039857, + "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=", + "owner": "NixOS", + "repo": "flake-compat", + "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "flake-compat", + "type": "github" + } + }, "flake-utils": { "inputs": { "systems": "systems" @@ -75,11 +91,11 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1769324704, - "narHash": "sha256-aef15vEgiMEls1hTMt46rJuKNSO2cIOfiP99patq9yc=", + "lastModified": 1773213477, + "narHash": "sha256-Pv1Z3QqGkSGEUV+9pM5vYIiI7VJo7Tfm6ZmR+JSp1zo=", "owner": "shazow", "repo": "foundry.nix", - "rev": "e830409ba1bdecdc5ef9a1ec92660fc2da9bc68d", + "rev": "3c73daa86c823d706824fd9bbcb85aa23fd0f668", "type": "github" }, "original": { @@ -88,6 +104,48 @@ "type": "github" } }, + "git-hooks-nix": { + "inputs": { + "flake-compat": "flake-compat", + "gitignore": "gitignore", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1774104215, + "narHash": "sha256-EAtviqz0sEAxdHS4crqu7JGR5oI3BwaqG0mw7CmXkO8=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "f799ae951fde0627157f40aec28dec27b22076d0", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "rainix", + "git-hooks-nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1666753130, @@ -120,11 +178,27 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1769364508, - "narHash": "sha256-Wy8EVYSLq5Fb/rYH3LRxAMCnW75f9hOg2562AXVFmPk=", + "lastModified": 1770073757, + "narHash": "sha256-Vy+G+F+3E/Tl+GMNgiHl9Pah2DgShmIUBJXmbiQPHbI=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "47472570b1e607482890801aeaf29bfb749884f6", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1776017067, + "narHash": "sha256-oEp8fqJweZd5doqvH/aBAtc6NzZh+fh0tOhR09gQXck=", "owner": "nixos", "repo": "nixpkgs", - "rev": "6077bc4fb29be43d525984f63b69d37b9b1e62fe", + "rev": "a5a7cf16648d79134eb4da0e3354b08913917b2f", "type": "github" }, "original": { @@ -133,7 +207,7 @@ "type": "github" } }, - "nixpkgs_3": { + "nixpkgs_4": { "locked": { "lastModified": 1744536153, "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", @@ -149,13 +223,13 @@ "type": "github" } }, - "nixpkgs_4": { + "nixpkgs_5": { "locked": { - "lastModified": 1766653575, - "narHash": "sha256-TPgxCS7+hWc4kPhzkU5dD2M5UuPhLuuaMNZ/IpwKQvI=", + "lastModified": 1771923393, + "narHash": "sha256-Fy0+UXELv9hOE8WjYhJt8fMDLYTU2Dqn3cX4BwoGBos=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "3c1016e6acd16ad96053116d0d3043029c9e2649", + "rev": "ea7f1f06811ce7fcc81d6c6fd4213150c23edcf2", "type": "github" }, "original": { @@ -169,17 +243,18 @@ "inputs": { "flake-utils": "flake-utils_2", "foundry": "foundry", - "nixpkgs": "nixpkgs_2", + "git-hooks-nix": "git-hooks-nix", + "nixpkgs": "nixpkgs_3", "nixpkgs-old": "nixpkgs-old", "rust-overlay": "rust-overlay", "solc": "solc" }, "locked": { - "lastModified": 1770274701, - "narHash": "sha256-00kymonJVHUtCBBaXMqmVF3b78dtDdXJg8K7P2U9lbA=", + "lastModified": 1778356755, + "narHash": "sha256-1mMP/qepO/oyFx1zAAYGDXeWqIiGbIUtL+EzJdb7h18=", "owner": "rainprotocol", "repo": "rainix", - "rev": "51c1c74a0e6bc5c49336b02ef97684d01e1e8ad4", + "rev": "db62d884566bef2d69eab976217caf6c1bcd1d75", "type": "github" }, "original": { @@ -196,14 +271,14 @@ }, "rust-overlay": { "inputs": { - "nixpkgs": "nixpkgs_3" + "nixpkgs": "nixpkgs_4" }, "locked": { - "lastModified": 1769309768, - "narHash": "sha256-AbOIlNO+JoqRJkK1VrnDXhxuX6CrdtIu2hSuy4pxi3g=", + "lastModified": 1773216618, + "narHash": "sha256-iZlowevS+xKLGOXtZwpIrz3SWe7PtoGUfEeVZNib+WE=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "140c9dc582cb73ada2d63a2180524fcaa744fad5", + "rev": "07d7dc6fcc5eae76b4fb0e19d4afd939437bec97", "type": "github" }, "original": { @@ -215,15 +290,15 @@ "solc": { "inputs": { "flake-utils": "flake-utils_4", - "nixpkgs": "nixpkgs_4", + "nixpkgs": "nixpkgs_5", "solc-macos-amd64-list-json": "solc-macos-amd64-list-json" }, "locked": { - "lastModified": 1768831671, - "narHash": "sha256-0mmlYRtZK+eomevkQCCH7PL8QlSuALZQsjLroCWGE08=", + "lastModified": 1772085240, + "narHash": "sha256-+NEcuhT2A0QQumVx9Ze6g2iuNicyuW028Jq/HUJHGh4=", "owner": "hellwolf", "repo": "solc.nix", - "rev": "80ad871b93d15c7bccf71617f78f73c2d291a9c7", + "rev": "d3cc119973e484ea366f4b997b404bb00d7829ca", "type": "github" }, "original": { @@ -235,13 +310,13 @@ "solc-macos-amd64-list-json": { "flake": false, "locked": { - "narHash": "sha256-P+ZslplK4cQ/wnV/wykVKb+yTCviI0eylA3sk9uHmRo=", + "narHash": "sha256-oEiXc95EghuYCudzkPA9XBFOnMdgWFfTO2/4XUfSTpc=", "type": "file", - "url": "https://github.com/argotorg/solc-bin/raw/a11f1ad/macosx-amd64/list.json" + "url": "https://github.com/argotorg/solc-bin/raw/83cb756/macosx-amd64/list.json" }, "original": { "type": "file", - "url": "https://github.com/argotorg/solc-bin/raw/a11f1ad/macosx-amd64/list.json" + "url": "https://github.com/argotorg/solc-bin/raw/83cb756/macosx-amd64/list.json" } }, "systems": { diff --git a/flake.nix b/flake.nix index 640ac76..ce576f2 100644 --- a/flake.nix +++ b/flake.nix @@ -6,12 +6,14 @@ flake-utils.url = "github:numtide/flake-utils"; }; - outputs = { self, flake-utils, rainix }: - flake-utils.lib.eachDefaultSystem (system: - { - packages = rainix.packages.${system}; - devShells = rainix.devShells.${system}; - } - ); - -} \ No newline at end of file + outputs = + { + flake-utils, + rainix, + ... + }: + flake-utils.lib.eachDefaultSystem (system: { + packages = rainix.packages.${system}; + devShells.default = rainix.devShells.${system}.sol-shell; + }); +} diff --git a/foundry.toml b/foundry.toml index 243c448..d887c17 100644 --- a/foundry.toml +++ b/foundry.toml @@ -1,7 +1,7 @@ [profile.default] src = 'src' out = 'out' -libs = ['lib'] +libs = ['dependencies'] # See more config options https://github.com/foundry-rs/foundry/tree/master/config @@ -23,9 +23,13 @@ cbor_metadata = false evm_version = "cancun" -fs_permissions = [ - { access = "read-write", path = "src/generated" }, -] +fs_permissions = [{ access = "read-write", path = "src/generated" }] [fuzz] -runs = 2048 \ No newline at end of file +runs = 2048 + +[dependencies] +forge-std = "1.16.1" + +[soldeer] +recursive_deps = false diff --git a/lib/forge-std b/lib/forge-std deleted file mode 160000 index 1801b05..0000000 --- a/lib/forge-std +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1801b0541f4fda118a10798fd3486bb7051c5dd6 diff --git a/lib/rain.math.binary b/lib/rain.math.binary deleted file mode 160000 index 122a490..0000000 --- a/lib/rain.math.binary +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 122a490bb1869c7533f108cb8b371d75de9db60f diff --git a/remappings.txt b/remappings.txt new file mode 100644 index 0000000..f4f4742 --- /dev/null +++ b/remappings.txt @@ -0,0 +1 @@ +forge-std-1.16.1/=dependencies/forge-std-1.16.1/ diff --git a/soldeer.lock b/soldeer.lock new file mode 100644 index 0000000..e9184e4 --- /dev/null +++ b/soldeer.lock @@ -0,0 +1,6 @@ +[[dependencies]] +name = "forge-std" +version = "1.16.1" +url = "https://soldeer-revisions.s3.amazonaws.com/forge-std/1_16_1_08-05-2026_08:51:16_forge-std-1.16.zip" +checksum = "839b61832925c7152c7b6dffbfa4998d9e606211179bd8f604733124e8a7cb57" +integrity = "60e55d10150354ca4a1e2985c5456c834b92b82ef85ab0e1d92a7786cddbd219" diff --git a/src/lib/LibCodeGen.sol b/src/lib/LibCodeGen.sol index ceb442b..12877e4 100644 --- a/src/lib/LibCodeGen.sol +++ b/src/lib/LibCodeGen.sol @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd pragma solidity ^0.8.25; -import {Vm} from "forge-std/Vm.sol"; +import {Vm} from "forge-std-1.16.1/src/Vm.sol"; import {IOpcodeToolingV1} from "../interface/IOpcodeToolingV1.sol"; import {IParserToolingV1} from "../interface/IParserToolingV1.sol"; import {ISubParserToolingV1} from "../interface/ISubParserToolingV1.sol"; diff --git a/src/lib/LibFs.sol b/src/lib/LibFs.sol index 778d3c0..3b8ca02 100644 --- a/src/lib/LibFs.sol +++ b/src/lib/LibFs.sol @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd pragma solidity ^0.8.25; -import {Vm} from "forge-std/Vm.sol"; +import {Vm} from "forge-std-1.16.1/src/Vm.sol"; import {LibCodeGen} from "./LibCodeGen.sol"; /// @title LibFs diff --git a/src/lib/LibHexString.sol b/src/lib/LibHexString.sol index b3b7b25..5c9f3d2 100644 --- a/src/lib/LibHexString.sol +++ b/src/lib/LibHexString.sol @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd pragma solidity ^0.8.25; -import {Vm} from "forge-std/Vm.sol"; +import {Vm} from "forge-std-1.16.1/src/Vm.sol"; /// @title LibHexString /// @notice A library for converting bytes to hexadecimal strings. Uses the From 6b2d94906367d1984170e9bc559f81d8f811c265 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Sun, 10 May 2026 00:26:26 +0400 Subject: [PATCH 2/2] ci: rewrite BuildPointers.sol forge-std import to soldeer path Missed in the soldeer migration commit; git-clean failed because BuildPointers.sol kept the old "forge-std/Script.sol" import. Co-Authored-By: Claude Opus 4.7 (1M context) --- script/BuildPointers.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/BuildPointers.sol b/script/BuildPointers.sol index 01db584..5301ab7 100644 --- a/script/BuildPointers.sol +++ b/script/BuildPointers.sol @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd pragma solidity =0.8.25; -import {Script} from "forge-std/Script.sol"; +import {Script} from "forge-std-1.16.1/src/Script.sol"; import {LibFs} from "../src/lib/LibFs.sol"; import {LibCodeGen} from "../src/lib/LibCodeGen.sol"; import {CodeGennable} from "../test/concrete/CodeGennable.sol";