Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions foundry.lock
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
{
"lib/rain.interpreter.interface": {
"rev": "3c834ad7cc3e8e102cd6b353456b0f55200a47dc"
"rev": "2d06b797698d3ed2555e93162176479127a02b1a"
},
"lib/rain.lib.memkv": {
"rev": "ce43236a4a483a240cc9f554be90cbcc360c6735"
"rev": "90efd9409786b50d691209c172ce3f4b74a54996"
},
"lib/rain.metadata": {
"rev": "0fc7d0f21e28ab5360b23ba45a298d56313c5ab5"
"rev": "ce6a8fc92676cbd7eeb0019a22026e10fcd4273d"
},
"lib/rain.string": {
"rev": "85d0074c8cd1fdca3285366c15bc9b44b84ad5e9"
"rev": "0b1ca08aed6d9c06b83fe127a7d20ee7002ead28"
},
"lib/sol.lib.binmaskflag": {
"rev": "4c56ec185932b904fd7334990d63ef0544536cc6"
"rev": "3b0bbf05e38ee4a31ca65070e41b299fa6bcdf9e"
}
}
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ libs = ['lib']
# See more config options https://github.com/foundry-rs/foundry/tree/master/config

solc = "0.8.25"
evm_version = "paris"
evm_version = "cancun"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Examine foundry.toml and verify the EVM version change details

echo "=== Current foundry.toml (full file) ==="
cat foundry.toml

echo ""
echo "=== Check for git history of foundry.toml ==="
git log --oneline -n 10 -- foundry.toml 2>/dev/null || echo "Git history not available"

echo ""
echo "=== Check for test files ==="
find . -name "*.t.sol" -o -name "*test*" -type f | head -20

echo ""
echo "=== Check for lib/rain.interpreter.interface references ==="
grep -r "rain.interpreter.interface" . --include="*.toml" --include="*.sol" 2>/dev/null | head -10

Repository: rainlanguage/rain.interpreter

Length of output: 202


🏁 Script executed:

#!/bin/bash
# Check if contracts exist and understand the project structure

echo "=== Project structure (top-level) ==="
ls -la | grep -E "^d|\.toml|\.md"

echo ""
echo "=== Check for src directory and contracts ==="
find . -maxdepth 2 -name "*.sol" -type f 2>/dev/null | head -20

echo ""
echo "=== Solidity files count by directory ==="
find . -name "*.sol" -type f | xargs dirname | sort | uniq -c | sort -rn | head -10

Repository: rainlanguage/rain.interpreter

Length of output: 1381


🏁 Script executed:

#!/bin/bash
# Read foundry.toml to see the actual EVM version

echo "=== foundry.toml content ==="
cat -n foundry.toml

echo ""
echo "=== Git diff for foundry.toml (if available) ==="
git diff HEAD~1 foundry.toml 2>/dev/null || git show HEAD:foundry.toml 2>/dev/null | head -20

echo ""
echo "=== Git log for foundry.toml ==="
git log --oneline foundry.toml 2>/dev/null | head -10

Repository: rainlanguage/rain.interpreter

Length of output: 2742


🏁 Script executed:

#!/bin/bash
# Check for test running and compilation capabilities

echo "=== Check if forge is available ==="
which forge 2>/dev/null || echo "forge not in PATH"

echo ""
echo "=== Check test directory structure ==="
find ./test -maxdepth 2 -type f -name "*.sol" | head -10

echo ""
echo "=== Look for test configuration or patterns ==="
grep -r "pragma solidity" ./test --include="*.sol" | head -5

Repository: rainlanguage/rain.interpreter

Length of output: 751


🏁 Script executed:

#!/bin/bash
# Get more detailed git history to see what changed

echo "=== Git show for foundry.toml previous commits ==="
git show HEAD~1:foundry.toml 2>/dev/null | grep -A 2 "evm_version" || echo "Previous version not accessible"

echo ""
echo "=== Current branch info ==="
git branch -a
git status

echo ""
echo "=== Check git log with patch for foundry.toml ==="
git log -p --follow -S "evm_version" foundry.toml 2>/dev/null | head -100

Repository: rainlanguage/rain.interpreter

Length of output: 416


🏁 Script executed:

#!/bin/bash
# Check PR/branch context for understanding the change motivation

echo "=== Check for PR or branch-specific documentation ==="
find . -maxdepth 2 -name "*.md" -type f | xargs grep -l "evm\|cancun\|paris" 2>/dev/null || echo "No docs mentioning EVM versions"

echo ""
echo "=== Look for any recent changes in README or similar ==="
cat README.md | head -50

echo ""
echo "=== Check if there's a CHANGELOG or similar ==="
find . -maxdepth 1 -type f \( -name "CHANGELOG*" -o -name "HISTORY*" -o -name "CHANGES*" \) 2>/dev/null | xargs cat 2>/dev/null || echo "No changelog found"

Repository: rainlanguage/rain.interpreter

Length of output: 2340


Clarify motivation and provide evidence that Cancun EVM upgrade has been tested.

Upgrading from Paris to Cancun EVM is a significant change affecting new opcodes, gas costs, and bytecode generation. The PR description lacks motivation for this change, and there's no evidence in the PR that the configuration has been validated with the existing test suite.

Before merging:

  1. Update the PR description explaining why the EVM version is being upgraded and any alignment needed with the submodule update to lib/rain.interpreter.interface
  2. Confirm that all tests pass with the Cancun configuration and document the results in the PR
  3. If this change affects deployment, verify contract bytecode and deployment behavior remain as expected
🤖 Prompt for AI Agents
In foundry.toml around line 9, the EVM version was changed to "cancun" without
justification or test evidence; update the PR by (1) adding a clear motivation
in the PR description explaining why Cancun is required and how it aligns with
the lib/rain.interpreter.interface submodule update, (2) running the full test
suite with foundry configured to use Cancun, documenting and attaching test
results (pass/fail, any flaky tests, CI logs) to the PR, and (3) verifying
contract bytecode and deployment by comparing compiled artifacts and a test
deploy (or dry-run) against the Paris baseline and noting any differences or
required migration steps in the PR description.


# Try to make sure the optimizer doesn't touch the output in a way that can break
# source maps for debugging.
Expand Down
2 changes: 1 addition & 1 deletion lib/rain.interpreter.interface
2 changes: 1 addition & 1 deletion lib/rain.lib.memkv
2 changes: 1 addition & 1 deletion lib/rain.metadata
2 changes: 1 addition & 1 deletion lib/rain.string
2 changes: 1 addition & 1 deletion lib/sol.lib.binmaskflag
4 changes: 2 additions & 2 deletions src/generated/Rainterpreter.pointers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ pragma solidity ^0.8.25;
// file needs the contract to exist so that it can be compiled.

/// @dev Hash of the known bytecode.
bytes32 constant BYTECODE_HASH = bytes32(0x148bacd9fea04b6fca1996ceeca380590f7df8ae88c1228307de8e14db98faa5);
bytes32 constant BYTECODE_HASH = bytes32(0xd58dd3ee27244854fdd5f74d50b75bee14b4fca4de91a5624574135a12d435dc);

/// @dev The function pointers known to the interpreter for dynamic dispatch.
/// By setting these as a constant they can be inlined into the interpreter
/// and loaded at eval time for very low gas (~100) due to the compiler
/// optimising it to a single `codecopy` to build the in memory bytes array.
bytes constant OPCODE_FUNCTION_POINTERS =
hex"0864089608ba0a390ae80afa0b0c0b250b490b7d0b8e0b9f0c410c600cf80d820df90f0810080cf810e711731208127312841295129512a612fc13d81442145b146f14b914d214eb150f1525153e155715a015c715da163c168a16d817261774178218361859186718f61927196b1990199e19ac19fd1a321a401a8e1abf1af01b3e1b6f1b871c161c431c661cf51dde";
hex"084c087e08a20a1a0ac70ad90aeb0b030b260b590b6a0b7b0c1c0c3b0cd00d570dca0ed20fcb0cd010a2112911bb1222123312441244125512aa138113e914011415145d1475148d14b114c614de14f6153e1564157615d71624167116be170b171817cb17ed17fa188818b918fc1920192d193a198a19be19cb1a181a491a7a1ac71af81b101b9e1bca1bec1c7a1d5e";
4 changes: 2 additions & 2 deletions src/generated/RainterpreterExpressionDeployer.pointers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ pragma solidity ^0.8.25;
// file needs the contract to exist so that it can be compiled.

/// @dev Hash of the known bytecode.
bytes32 constant BYTECODE_HASH = bytes32(0xddb67ea8aaa24f161feaaa0de916cd6d911a57af11bacdaeef24d5e08080161f);
bytes32 constant BYTECODE_HASH = bytes32(0x10b783747842a4ffe53f051096cee230c6af8f86f07d8597421cda77b7959bbe);

/// @dev The hash of the meta that describes the contract.
bytes32 constant DESCRIBED_BY_META_HASH = bytes32(0xb2500441a27ea683f814327be6e43c90f516b8f033203ad3e0ba2cde847fb0ba);

/// @dev The function pointers for the integrity check fns.
bytes constant INTEGRITY_FUNCTION_POINTERS =
hex"0dea0e680ecc102c10361036104010491064110a110a116611de11eb1036104011eb103610401036103610361040102c102c102c102c11f5121a12341036103611f51036103611eb10401036103611eb11eb102c123e123e123e123e123e1040123e103610401258102c1040104010401040103610401040123e102c102c123e102c102c125810361040125810401234";
hex"0d7f0dfb0e5e0fba0fc30fc30fcd0fd60ff01095109510f0116711740fc30fcd11740fc30fcd0fc30fc30fc30fcd0fba0fba0fba0fba117e11a211bb0fc30fc3117e0fc30fc311740fcd0fc30fc3117411740fba11c411c411c411c411c40fcd11c40fc30fcd11dd0fba0fcd0fcd0fcd0fcd0fc30fcd0fcd11c40fba0fba11c40fba0fba11dd0fc30fcd11dd0fcd11bb";
6 changes: 3 additions & 3 deletions src/generated/RainterpreterParser.pointers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pragma solidity ^0.8.25;
// file needs the contract to exist so that it can be compiled.

/// @dev Hash of the known bytecode.
bytes32 constant BYTECODE_HASH = bytes32(0xc3d889bb6ac3e2483e044761afe377bcc86ad4bdb6912612e38297a4ef34eed5);
bytes32 constant BYTECODE_HASH = bytes32(0x7e2614632ccb1896ce910e97fb0c4a90c6c4e61771aead0d21a0fa298fd44443);

/// @dev The parse meta that is used to lookup word definitions.
/// The structure of the parse meta is:
Expand Down Expand Up @@ -39,11 +39,11 @@ uint8 constant PARSE_META_BUILD_DEPTH = 2;
/// These positional indexes all map to the same indexes looked up in the parse
/// meta.
bytes constant OPERAND_HANDLER_FUNCTION_POINTERS =
hex"1989198919891a301b041b041b041a301a301989198919891b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b041b0419891b041b04";
hex"192b192b192b19ce1a9f1a9f1a9f19ce19ce192b192b192b1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f1a9f192b1a9f1a9f";

/// @dev Every two bytes is a function pointer for a literal parser.
/// Literal dispatches are determined by the first byte(s) of the literal
/// rather than a full word lookup, and are done with simple conditional
/// jumps as the possibilities are limited compared to the number of words we
/// have.
bytes constant LITERAL_PARSER_FUNCTION_POINTERS = hex"1547171f176217e4";
bytes constant LITERAL_PARSER_FUNCTION_POINTERS = hex"14f816cb170b1789";
12 changes: 6 additions & 6 deletions src/generated/RainterpreterReferenceExtern.pointers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pragma solidity ^0.8.25;
// file needs the contract to exist so that it can be compiled.

/// @dev Hash of the known bytecode.
bytes32 constant BYTECODE_HASH = bytes32(0x4e5e0c85082c3325eb262c3c8792301bc657f1ac4ae6bbb9bdbae1e5eac73618);
bytes32 constant BYTECODE_HASH = bytes32(0x32eda76cb06f05f52b9bc78dac37bfbb156af023b6d612265e829f0c3dd1fe84);

/// @dev The hash of the meta that describes the contract.
bytes32 constant DESCRIBED_BY_META_HASH = bytes32(0xadf71693c6ecf3fd560904bc46973d1b6e651440d15366673f9b3984749e7c16);
Expand Down Expand Up @@ -43,25 +43,25 @@ uint8 constant PARSE_META_BUILD_DEPTH = 1;
/// bytecode that dials back into this contract at eval time, and mapping
/// to things that happen entirely on the interpreter such as well known
/// constants and references to the context grid.
bytes constant SUB_PARSER_WORD_PARSERS = hex"070b072d073c074c075d";
bytes constant SUB_PARSER_WORD_PARSERS = hex"06ed070d071b07290738";

/// @dev Every two bytes is a function pointer for an operand handler.
/// These positional indexes all map to the same indexes looked up in the parse
/// meta.
bytes constant OPERAND_HANDLER_FUNCTION_POINTERS = hex"0cb90cfe0cb90cb90cb9";
bytes constant OPERAND_HANDLER_FUNCTION_POINTERS = hex"0c720cb40c720c720c72";

/// @dev Every two bytes is a function pointer for a literal parser.
/// Literal dispatches are determined by the first byte(s) of the literal
/// rather than a full word lookup, and are done with simple conditional
/// jumps as the possibilities are limited compared to the number of words we
/// have.
bytes constant LITERAL_PARSER_FUNCTION_POINTERS = hex"0c8a";
bytes constant LITERAL_PARSER_FUNCTION_POINTERS = hex"0c44";

/// @dev The function pointers for the integrity check fns.
bytes constant INTEGRITY_FUNCTION_POINTERS = hex"0b46";
bytes constant INTEGRITY_FUNCTION_POINTERS = hex"0b06";

/// @dev The function pointers known to the interpreter for dynamic dispatch.
/// By setting these as a constant they can be inlined into the interpreter
/// and loaded at eval time for very low gas (~100) due to the compiler
/// optimising it to a single `codecopy` to build the in memory bytes array.
bytes constant OPCODE_FUNCTION_POINTERS = hex"07ff";
bytes constant OPCODE_FUNCTION_POINTERS = hex"07d7";
2 changes: 1 addition & 1 deletion src/generated/RainterpreterStore.pointers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ pragma solidity ^0.8.25;
// file needs the contract to exist so that it can be compiled.

/// @dev Hash of the known bytecode.
bytes32 constant BYTECODE_HASH = bytes32(0x7329a063f432611fe994e093d4e06b1c2af50a66531606c6978406b60b7f0373);
bytes32 constant BYTECODE_HASH = bytes32(0x0504fb2004eb1cad882a8eb495be50b9f2beacdc99e0b0d6b7d3eb1e32854210);
20 changes: 10 additions & 10 deletions test/src/lib/parse/LibParseOperand.parseOperand.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ contract LibParseOperandParseOperandTest is Test {
// Casting an int256 to uint256 does not truncate, and is required to
// build a hex string.
//forge-lint: disable-next-line(unsafe-typecast)
string memory valueString = asHex ? uint256(value).toHexString() : value.toString();
string memory valueString = asHex ? uint256(value).toHexString() : value.toStringSigned();
string memory s = string.concat("<", maybeWhitespaceA, valueString, maybeWhitespaceB, ">", suffix);

bytes32[] memory expectedValues = new bytes32[](1);
Expand Down Expand Up @@ -117,9 +117,9 @@ contract LibParseOperandParseOperandTest is Test {
// Casting an int256 to uint256 does not truncate, and is required to
// build a hex string.
//forge-lint: disable-next-line(unsafe-typecast)
string memory valueAString = asHexA ? uint256(valueA).toHexString() : valueA.toString();
string memory valueAString = asHexA ? uint256(valueA).toHexString() : valueA.toStringSigned();
//forge-lint: disable-next-line(unsafe-typecast)
string memory valueBString = asHexB ? uint256(valueB).toHexString() : valueB.toString();
string memory valueBString = asHexB ? uint256(valueB).toHexString() : valueB.toStringSigned();

string memory s = string.concat(
"<", maybeWhitespaceA, valueAString, maybeWhitespaceB, valueBString, maybeWhitespaceC, ">", suffix
Expand Down Expand Up @@ -174,11 +174,11 @@ contract LibParseOperandParseOperandTest is Test {
// Casting an int256 to uint256 does not truncate, and is required to
// build a hex string.
//forge-lint: disable-next-line(unsafe-typecast)
string memory valueAString = asHexA ? uint256(valueA).toHexString() : valueA.toString();
string memory valueAString = asHexA ? uint256(valueA).toHexString() : valueA.toStringSigned();
//forge-lint: disable-next-line(unsafe-typecast)
string memory valueBString = asHexB ? uint256(valueB).toHexString() : valueB.toString();
string memory valueBString = asHexB ? uint256(valueB).toHexString() : valueB.toStringSigned();
//forge-lint: disable-next-line(unsafe-typecast)
string memory valueCString = asHexC ? uint256(valueC).toHexString() : valueC.toString();
string memory valueCString = asHexC ? uint256(valueC).toHexString() : valueC.toStringSigned();

s = string.concat(
string.concat(
Expand Down Expand Up @@ -236,10 +236,10 @@ contract LibParseOperandParseOperandTest is Test {
+ bytes(maybeWhitespace[2]).length + bytes(maybeWhitespace[3]).length + bytes(maybeWhitespace[4]).length;
}

string memory valueAString = asHex[0] ? uint256(values[0]).toHexString() : values[0].toString();
string memory valueBString = asHex[1] ? uint256(values[1]).toHexString() : values[1].toString();
string memory valueCString = asHex[2] ? uint256(values[2]).toHexString() : values[2].toString();
string memory valueDString = asHex[3] ? uint256(values[3]).toHexString() : values[3].toString();
string memory valueAString = asHex[0] ? uint256(values[0]).toHexString() : values[0].toStringSigned();
string memory valueBString = asHex[1] ? uint256(values[1]).toHexString() : values[1].toStringSigned();
string memory valueCString = asHex[2] ? uint256(values[2]).toHexString() : values[2].toStringSigned();
string memory valueDString = asHex[3] ? uint256(values[3]).toHexString() : values[3].toStringSigned();
Comment on lines +239 to +242

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Four-literal case matches prior patterns; optional helper extraction

The four uses of toStringSigned() are consistent with the other tests, and expectedLength correctly incorporates all four string lengths plus whitespace/suffix. If this pattern grows further, consider a small helper like formatLiteral(bool asHex, int256 v) to reduce duplication across these tests, but it’s not required for correctness.

🤖 Prompt for AI Agents
In test/src/lib/parse/LibParseOperand.parseOperand.t.sol around lines 239 to
242, the four repeated expressions that choose between toHexString() and
toStringSigned() can be refactored into a small helper to reduce duplication;
create a private helper function formatLiteral(bool asHex, int256 v) that
returns the appropriate string by selecting uint256(v).toHexString() when asHex
is true or v.toStringSigned() otherwise, then replace the four inline ternaries
with calls to that helper and update any expected length calculations to use the
helper results.


{
expectedLength += bytes(valueAString).length + bytes(valueBString).length + bytes(valueCString).length
Expand Down