[NONEVM-2651] Fix contract versioning#218
Conversation
| name: Verify Contract Version Updates | ||
| runs-on: ubuntu-latest | ||
| if: github.event_name == 'pull_request' | ||
|
|
||
| steps: | ||
| - name: Check out PR code | ||
| uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 | ||
| with: | ||
| path: "pr-branch" | ||
|
|
||
| - name: Check out base branch code | ||
| uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 | ||
| with: | ||
| ref: ${{ github.event.pull_request.base.sha }} | ||
| path: "base-branch" | ||
|
|
||
| - name: Set up Python | ||
| uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 | ||
| with: | ||
| python-version: "3.9" | ||
|
|
||
| - name: Install Nix | ||
| uses: cachix/install-nix-action@02a151ada4993995686f9ed4f1be7cfbb229e56f # v31 | ||
| with: | ||
| nix_path: nixpkgs=channel:nixos-unstable | ||
|
|
||
| - name: Check contract versions | ||
| run: | | ||
| pr-branch/.github/scripts/check-contract-versions.py \ | ||
| --pr-dir pr-branch \ | ||
| --base-dir base-branch \ | ||
| --verbose |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 8 months ago
To fix the problem, add a permissions block to the workflow or directly within the check-contract-versions job, specifying the least required privileges. Since none of the steps in the workflow (and particularly the check-contract-versions job) require write access to repository contents or GitHub APIs, you should set contents: read as a minimal and safe default. You can add a top-level permissions block if all jobs require only read access, but to minimize changes and adhere closely to CodeQL's recommendation, add permissions: contents: read to the check-contract-versions job. This change should be made within the .github/workflows/contracts-build.yml file, at the appropriate indentation level so that the permissions block is a sibling to runs-on.
| @@ -44,6 +44,8 @@ | ||
| check-contract-versions: | ||
| name: Verify Contract Version Updates | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| if: github.event_name == 'pull_request' | ||
|
|
||
| steps: |
40ee8c8 to
8de1a56
Compare
There was a problem hiding this comment.
Pull Request Overview
This PR implements comprehensive contract versioning for CCIP contracts by adding unique IDs to enable multiple deployments and enforcing version updates when contracts change.
Key changes:
- Added ID field to all CCIP contract storage structures to support multiple deployments
- Implemented automated version enforcement through bytecode comparison in CI/CD
- Added code and codeHash getter methods to all contracts for better introspection
Reviewed Changes
Copilot reviewed 31 out of 31 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| scripts/.core_version | Updates core version hash reference |
| pkg/ccip/bindings/*/*.go | Adds ID field to Go binding structs for all CCIP contracts |
| deployment/ccip/**/*.go | Updates deployment operations to include contract IDs |
| contracts/wrappers/ccip/*.ts | Adds ID field to TypeScript contract wrappers |
| contracts/contracts/**/*.tolk | Adds ID field, CONTRACT_VERSION constant, and code/codeHash getters to Tolk contracts |
| contracts/tests/**/*.ts | Updates test data to include ID fields |
| .github/workflows/contracts-build.yml | Adds CI job for contract version validation |
| .github/scripts/check-contract-versions*.py | Implements automated contract version checking scripts |
Comments suppressed due to low confidence (1)
.github/scripts/check-contract-versions-old.py:1
- The code is duplicated with very similar violation creation logic in multiple places. Consider extracting this into a helper function to reduce code duplication and improve maintainability.
#!/usr/bin/env python3
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| ) | ||
| return result | ||
| except subprocess.CalledProcessError as e: | ||
| print(f"Command failed in {cwd}: {' '.join(cmd) if isinstance(cmd, list) else cmd}") |
There was a problem hiding this comment.
The error message formatting will fail when cmd is a string because it tries to join a string character by character. The condition should check the type before attempting to join.
| print(f"Command failed in {cwd}: {' '.join(cmd) if isinstance(cmd, list) else cmd}") | |
| print(f"Command failed in {cwd}: {' '.join(cmd) if isinstance(cmd, (list, tuple)) else cmd}") |
a89f33c to
70e0546
Compare
| - name: Set up Python | ||
| uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 | ||
| with: | ||
| python-version: "3.9" |
There was a problem hiding this comment.
How much additional time will this add to the build? I know Python can be fun to work with, but have we considered using Go?
There was a problem hiding this comment.
+1 re: Python - this could have been just a bash script. It should be ok to use Python for scripting (vs. bash), but we can improve the packaging and setup here by adding the Python env dependencies to Nix vs. having custom local setup and GHA actions/setup-python.
nicolasgnr
left a comment
There was a problem hiding this comment.
LGTM
My only concern is the potential overhead Python may add to the overall pipeline execution time, as well as the approach to determining changes. While using bytecode differences is likely the most accurate method, it may also be more expensive than some simpler implementations. We can always reconsider this approach if needed and propose an alternative solution in the near future
| - name: Set up Python | ||
| uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 | ||
| with: | ||
| python-version: "3.9" |
There was a problem hiding this comment.
+1 re: Python - this could have been just a bash script. It should be ok to use Python for scripting (vs. bash), but we can improve the packaging and setup here by adding the Python env dependencies to Nix vs. having custom local setup and GHA actions/setup-python.
| import "../lib/utils"; | ||
| import "../lib/access/access_control"; | ||
|
|
||
| const CONTRACT_VERSION = "0.0.1"; |
There was a problem hiding this comment.
This CONTRACT_VERSION label now becomes a magic string and needs some underlying understanding how to use/break. Maybe using an explicit lint tag in a comment would help.
| const CONTRACT_VERSION = "0.0.1"; | |
| ///lint:bytecode-version-check | |
| const MY_VERSION_CONST = "0.0.1"; |
| } | ||
|
|
||
| // Returns the sha256 hash of the current code of the contract. | ||
| get fun codeHash(): int { |
There was a problem hiding this comment.
Why do we now require adding these getters to all contracts? Isn't this redundant functionality to be hosted in the contracts and the info (code) can easily be sourced by a client (form an compiled artifact or address)?
NONEVM-2651