From 3798f589edd3bf10df964f1888382b694994afd2 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Sun, 26 May 2024 17:20:55 +0400 Subject: [PATCH 01/18] generated opcode function pointers --- foundry.toml | 1 + script/BuildPointers.sol | 52 ++++++++++++++++++++ src/concrete/RainterpreterNPE2.sol | 11 +---- src/generated/RainterpreterNPE2.pointers.sol | 18 +++++++ 4 files changed, 72 insertions(+), 10 deletions(-) create mode 100644 script/BuildPointers.sol create mode 100644 src/generated/RainterpreterNPE2.pointers.sol diff --git a/foundry.toml b/foundry.toml index a4a21857d..8a5d192cf 100644 --- a/foundry.toml +++ b/foundry.toml @@ -23,6 +23,7 @@ cbor_metadata = false fs_permissions = [ { access = "read-write", path = "./meta" }, + { access = "read-write", path = "src/generated" }, { access = "write", path = "./deployments/latest/RainterpreterParserNPE2" }, { access = "write", path = "./deployments/latest/RainterpreterStoreNPE2" }, { access = "write", path = "./deployments/latest/RainterpreterNPE2" }, diff --git a/script/BuildPointers.sol b/script/BuildPointers.sol new file mode 100644 index 000000000..a1e2efb71 --- /dev/null +++ b/script/BuildPointers.sol @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: CAL +pragma solidity =0.8.25; + +import {Script} from "forge-std/Script.sol"; +import {RainterpreterNPE2} from "src/concrete/RainterpreterNPE2.sol"; + +contract BuildPointers is Script { + function run() external { + RainterpreterNPE2 interpreter = new RainterpreterNPE2(); + bytes memory pointers = interpreter.functionPointers(); + + string memory path = "src/generated/RainterpreterNPE2.pointers.sol"; + string memory hexString = vm.toString(pointers); + assembly ("memory-safe") { + // Remove the leading 0x + let newHexString := add(hexString, 2) + mstore(newHexString, sub(mload(hexString), 2)) + hexString := newHexString + } + + bytes32 interpreterBytecodeHash; + assembly { + interpreterBytecodeHash := extcodehash(interpreter) + } + string memory interpreterBytecodeHashString = vm.toString(interpreterBytecodeHash); + + if (vm.exists(path)) { + vm.removeFile(path); + } + vm.writeFile(path, + string.concat( + "// THIS FILE IS AUTOGENERATED BY ./script/BuildPointers.sol\n\n", + "// This file is committed to the repository because there is a circular\n" + "// dependency between the interpreter and the pointers file. The interpreter\n" + "// needs the pointers file to exist so that it can compile, and the pointers\n" + "// file needs the interpreter to exist so that it can be compiled.\n\n", + "// SPDX-License-Identifier: CAL\n", + "pragma solidity =0.8.25;\n\n", + "/// @dev Hash of the known interpreter bytecode.\n", + "bytes32 constant INTERPRETER_BYTECODE_HASH = bytes32(", + interpreterBytecodeHashString, + ");\n\n", + "/// @dev The function pointers known to the interpreter for dynamic dispatch.\n", + "/// By setting these as a constant they can be inlined into the interpreter\n", + "/// and loaded at eval time for very low gas (~100) due to the compiler\n", + "/// optimising it to a single `codecopy` to build the in memory bytes array.\n", + "bytes constant OPCODE_FUNCTION_POINTERS = hex\"", + hexString, + "\";\n" + )); + } +} diff --git a/src/concrete/RainterpreterNPE2.sol b/src/concrete/RainterpreterNPE2.sol index 8b23dcad3..975051150 100644 --- a/src/concrete/RainterpreterNPE2.sol +++ b/src/concrete/RainterpreterNPE2.sol @@ -23,16 +23,7 @@ import { IInterpreterStoreV2 } from "rain.interpreter.interface/interface/IInterpreterV2.sol"; import {IInterpreterV3} from "rain.interpreter.interface/interface/unstable/IInterpreterV3.sol"; - -/// @dev Hash of the known interpreter bytecode. -bytes32 constant INTERPRETER_BYTECODE_HASH = bytes32(0x082edcc97843fd74ff6dc51867110b8633b0e419bac46f53765f5a833f36d024); - -/// @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"0e060e570e991065114c115e1170119311d512271238124912eb132813e6149613e6151a15bc1634166d16a616f5172e1793186718ba18ce1927193b1950196a19751989199e19d619fd1a7d1acb1b191b671b7f1b981be61bf41c021c1d1c321c4a1c631c711c7f1c8d1c9b1ce91d371d851dd31deb1deb1e021e301e301e471e761ecb1ed91ed91f7d2064"; +import {INTERPRETER_BYTECODE_HASH, OPCODE_FUNCTION_POINTERS} from "src/generated/RainterpreterNPE2.pointers.sol"; /// @title RainterpreterNPE2 /// @notice Implementation of a Rainlang interpreter that is compatible with diff --git a/src/generated/RainterpreterNPE2.pointers.sol b/src/generated/RainterpreterNPE2.pointers.sol new file mode 100644 index 000000000..bf6121b35 --- /dev/null +++ b/src/generated/RainterpreterNPE2.pointers.sol @@ -0,0 +1,18 @@ +// THIS FILE IS AUTOGENERATED BY ./script/BuildPointers.sol + +// This file is committed to the repository because there is a circular +// dependency between the interpreter and the pointers file. The interpreter +// needs the pointers file to exist so that it can compile, and the pointers +// file needs the interpreter to exist so that it can be compiled. + +// SPDX-License-Identifier: CAL +pragma solidity =0.8.25; + +/// @dev Hash of the known interpreter bytecode. +bytes32 constant INTERPRETER_BYTECODE_HASH = bytes32(0x802a1675e24b16dcec9dfe47f6a8f9658f5602a2c66a2f1630f42c9d05359653); + +/// @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"0e060e570e991065114c115e1170119311d512271238124912eb132813e6149613e6151a15bc1634166d16a616f5172e1793186718ba18ce1927193b1950196a19751989199e19d619fd1a7d1acb1b191b671b7f1b981be61bf41c021c1d1c321c4a1c631c711c7f1c8d1c9b1ce91d371d851dd31deb1deb1e021e301e301e471e761ecb1ed91ed91f7d2064"; From 7ae6bfdc2708488670f4801a75f97d6f1ec87d45 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Sun, 26 May 2024 17:22:54 +0400 Subject: [PATCH 02/18] update bytecode hash --- src/generated/RainterpreterNPE2.pointers.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generated/RainterpreterNPE2.pointers.sol b/src/generated/RainterpreterNPE2.pointers.sol index bf6121b35..f0ddddd16 100644 --- a/src/generated/RainterpreterNPE2.pointers.sol +++ b/src/generated/RainterpreterNPE2.pointers.sol @@ -9,7 +9,7 @@ pragma solidity =0.8.25; /// @dev Hash of the known interpreter bytecode. -bytes32 constant INTERPRETER_BYTECODE_HASH = bytes32(0x802a1675e24b16dcec9dfe47f6a8f9658f5602a2c66a2f1630f42c9d05359653); +bytes32 constant INTERPRETER_BYTECODE_HASH = bytes32(0x082edcc97843fd74ff6dc51867110b8633b0e419bac46f53765f5a833f36d024); /// @dev The function pointers known to the interpreter for dynamic dispatch. /// By setting these as a constant they can be inlined into the interpreter From 4c2bd88ad63ed8a4f893639ba3dadf6c0c124d28 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Sun, 26 May 2024 17:51:40 +0400 Subject: [PATCH 03/18] autogen store pointers --- script/BuildPointers.sol | 100 ++++++++++++++---- src/concrete/RainterpreterNPE2.sol | 2 +- src/concrete/RainterpreterStoreNPE2.sol | 11 +- src/generated/RainterpreterNPE2.pointers.sol | 5 +- .../RainterpreterStoreNPE2.pointers.sol | 12 +++ 5 files changed, 97 insertions(+), 33 deletions(-) create mode 100644 src/generated/RainterpreterStoreNPE2.pointers.sol diff --git a/script/BuildPointers.sol b/script/BuildPointers.sol index a1e2efb71..4b098a9d5 100644 --- a/script/BuildPointers.sol +++ b/script/BuildPointers.sol @@ -3,13 +3,60 @@ pragma solidity =0.8.25; import {Script} from "forge-std/Script.sol"; import {RainterpreterNPE2} from "src/concrete/RainterpreterNPE2.sol"; +import {RainterpreterStoreNPE2} from "src/concrete/RainterpreterStoreNPE2.sol"; contract BuildPointers is Script { - function run() external { + function filePrefix() internal pure returns (string memory) { + return string.concat( + "// THIS FILE IS AUTOGENERATED BY ./script/BuildPointers.sol\n\n", + "// This file is committed to the repository because there is a circular\n" + "// dependency between the contract and its pointers file. The contract\n" + "// needs the pointers file to exist so that it can compile, and the pointers\n" + "// file needs the contract to exist so that it can be compiled.\n\n", + "// SPDX-License-Identifier: CAL\n", + "pragma solidity =0.8.25;\n" + ); + } + + function pathForContract(string memory contractName) internal pure returns (string memory) { + return string.concat("src/generated/", contractName, ".pointers.sol"); + } + + function bytecodeHashConstantString(address instance) internal view returns (string memory) { + bytes32 bytecodeHash; + assembly { + bytecodeHash := extcodehash(instance) + } + return string.concat( + "\n", + "/// @dev Hash of the known bytecode.\n", + "bytes32 constant BYTECODE_HASH = bytes32(", + vm.toString(bytecodeHash), + ");\n" + ); + } + + function buildFileForContract(address instance, string memory contractName, string memory body) internal { + string memory path = pathForContract(contractName); + + if (vm.exists(path)) { + vm.removeFile(path); + } + vm.writeFile( + path, + string.concat( + filePrefix(), + bytecodeHashConstantString(instance), + body + ) + ); + } + + function buildRainterpreterNPE2Pointers() internal { RainterpreterNPE2 interpreter = new RainterpreterNPE2(); bytes memory pointers = interpreter.functionPointers(); - string memory path = "src/generated/RainterpreterNPE2.pointers.sol"; + string memory path = pathForContract("RainterpreterNPE2"); string memory hexString = vm.toString(pointers); assembly ("memory-safe") { // Remove the leading 0x @@ -27,26 +74,33 @@ contract BuildPointers is Script { if (vm.exists(path)) { vm.removeFile(path); } - vm.writeFile(path, - string.concat( - "// THIS FILE IS AUTOGENERATED BY ./script/BuildPointers.sol\n\n", - "// This file is committed to the repository because there is a circular\n" - "// dependency between the interpreter and the pointers file. The interpreter\n" - "// needs the pointers file to exist so that it can compile, and the pointers\n" - "// file needs the interpreter to exist so that it can be compiled.\n\n", - "// SPDX-License-Identifier: CAL\n", - "pragma solidity =0.8.25;\n\n", - "/// @dev Hash of the known interpreter bytecode.\n", - "bytes32 constant INTERPRETER_BYTECODE_HASH = bytes32(", - interpreterBytecodeHashString, - ");\n\n", - "/// @dev The function pointers known to the interpreter for dynamic dispatch.\n", - "/// By setting these as a constant they can be inlined into the interpreter\n", - "/// and loaded at eval time for very low gas (~100) due to the compiler\n", - "/// optimising it to a single `codecopy` to build the in memory bytes array.\n", - "bytes constant OPCODE_FUNCTION_POINTERS = hex\"", - hexString, - "\";\n" - )); + vm.writeFile( + path, + string.concat( + filePrefix(), + "/// @dev Hash of the known interpreter bytecode.\n", + "bytes32 constant INTERPRETER_BYTECODE_HASH = bytes32(", + interpreterBytecodeHashString, + ");\n\n", + "/// @dev The function pointers known to the interpreter for dynamic dispatch.\n", + "/// By setting these as a constant they can be inlined into the interpreter\n", + "/// and loaded at eval time for very low gas (~100) due to the compiler\n", + "/// optimising it to a single `codecopy` to build the in memory bytes array.\n", + "bytes constant OPCODE_FUNCTION_POINTERS = hex\"", + hexString, + "\";\n" + ) + ); + } + + function buildRainterpreterStoreNPE2Pointers() internal { + RainterpreterStoreNPE2 store = new RainterpreterStoreNPE2(); + + buildFileForContract(address(store), "RainterpreterStoreNPE2", ""); + } + + function run() external { + buildRainterpreterNPE2Pointers(); + buildRainterpreterStoreNPE2Pointers(); } } diff --git a/src/concrete/RainterpreterNPE2.sol b/src/concrete/RainterpreterNPE2.sol index 975051150..9369920a2 100644 --- a/src/concrete/RainterpreterNPE2.sol +++ b/src/concrete/RainterpreterNPE2.sol @@ -23,7 +23,7 @@ import { IInterpreterStoreV2 } from "rain.interpreter.interface/interface/IInterpreterV2.sol"; import {IInterpreterV3} from "rain.interpreter.interface/interface/unstable/IInterpreterV3.sol"; -import {INTERPRETER_BYTECODE_HASH, OPCODE_FUNCTION_POINTERS} from "src/generated/RainterpreterNPE2.pointers.sol"; +import {INTERPRETER_BYTECODE_HASH, OPCODE_FUNCTION_POINTERS} from "../generated/RainterpreterNPE2.pointers.sol"; /// @title RainterpreterNPE2 /// @notice Implementation of a Rainlang interpreter that is compatible with diff --git a/src/concrete/RainterpreterStoreNPE2.sol b/src/concrete/RainterpreterStoreNPE2.sol index 8675802ef..86e131ad3 100644 --- a/src/concrete/RainterpreterStoreNPE2.sol +++ b/src/concrete/RainterpreterStoreNPE2.sol @@ -1,17 +1,16 @@ // SPDX-License-Identifier: CAL pragma solidity =0.8.25; -import "openzeppelin-contracts/contracts/utils/introspection/ERC165.sol"; +import {ERC165} from "openzeppelin-contracts/contracts/utils/introspection/ERC165.sol"; -import "rain.interpreter.interface/interface/IInterpreterStoreV2.sol"; -import "rain.interpreter.interface/lib/ns/LibNamespace.sol"; +import {IInterpreterStoreV2} from "rain.interpreter.interface/interface/IInterpreterStoreV2.sol"; +import {LibNamespace, FullyQualifiedNamespace, StateNamespace} from "rain.interpreter.interface/lib/ns/LibNamespace.sol"; + +import {BYTECODE_HASH as STORE_BYTECODE_HASH} from "../generated/RainterpreterStoreNPE2.pointers.sol"; /// Thrown when a `set` call is made with an odd number of arguments. error OddSetLength(uint256 length); -/// @dev Hash of the known store bytecode. -bytes32 constant STORE_BYTECODE_HASH = bytes32(0x2a4559222e2f3600b2d393715de8af57620439684463f745059c653bbfe3727f); - /// @title RainterpreterStore /// @notice Simplest possible `IInterpreterStoreV2` that could work. /// Takes key/value pairings from the input array and stores each in an internal diff --git a/src/generated/RainterpreterNPE2.pointers.sol b/src/generated/RainterpreterNPE2.pointers.sol index f0ddddd16..c2e14db63 100644 --- a/src/generated/RainterpreterNPE2.pointers.sol +++ b/src/generated/RainterpreterNPE2.pointers.sol @@ -1,13 +1,12 @@ // THIS FILE IS AUTOGENERATED BY ./script/BuildPointers.sol // This file is committed to the repository because there is a circular -// dependency between the interpreter and the pointers file. The interpreter +// dependency between the contract and its pointers file. The contract // needs the pointers file to exist so that it can compile, and the pointers -// file needs the interpreter to exist so that it can be compiled. +// file needs the contract to exist so that it can be compiled. // SPDX-License-Identifier: CAL pragma solidity =0.8.25; - /// @dev Hash of the known interpreter bytecode. bytes32 constant INTERPRETER_BYTECODE_HASH = bytes32(0x082edcc97843fd74ff6dc51867110b8633b0e419bac46f53765f5a833f36d024); diff --git a/src/generated/RainterpreterStoreNPE2.pointers.sol b/src/generated/RainterpreterStoreNPE2.pointers.sol new file mode 100644 index 000000000..8d6c8c5d9 --- /dev/null +++ b/src/generated/RainterpreterStoreNPE2.pointers.sol @@ -0,0 +1,12 @@ +// THIS FILE IS AUTOGENERATED BY ./script/BuildPointers.sol + +// This file is committed to the repository because there is a circular +// dependency between the contract and its pointers file. The contract +// needs the pointers file to exist so that it can compile, and the pointers +// file needs the contract to exist so that it can be compiled. + +// SPDX-License-Identifier: CAL +pragma solidity =0.8.25; + +/// @dev Hash of the known bytecode. +bytes32 constant BYTECODE_HASH = bytes32(0x2a4559222e2f3600b2d393715de8af57620439684463f745059c653bbfe3727f); From 9bcdcbc9ce1284a4c297b481a1f7fc303410c251 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Sun, 26 May 2024 17:53:07 +0400 Subject: [PATCH 04/18] autogen store pointers --- script/BuildPointers.sol | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/script/BuildPointers.sol b/script/BuildPointers.sol index 4b098a9d5..497c5b265 100644 --- a/script/BuildPointers.sol +++ b/script/BuildPointers.sol @@ -56,7 +56,6 @@ contract BuildPointers is Script { RainterpreterNPE2 interpreter = new RainterpreterNPE2(); bytes memory pointers = interpreter.functionPointers(); - string memory path = pathForContract("RainterpreterNPE2"); string memory hexString = vm.toString(pointers); assembly ("memory-safe") { // Remove the leading 0x @@ -65,23 +64,11 @@ contract BuildPointers is Script { hexString := newHexString } - bytes32 interpreterBytecodeHash; - assembly { - interpreterBytecodeHash := extcodehash(interpreter) - } - string memory interpreterBytecodeHashString = vm.toString(interpreterBytecodeHash); - - if (vm.exists(path)) { - vm.removeFile(path); - } - vm.writeFile( - path, + buildFileForContract( + address(interpreter), + "RainterpreterNPE2", string.concat( - filePrefix(), - "/// @dev Hash of the known interpreter bytecode.\n", - "bytes32 constant INTERPRETER_BYTECODE_HASH = bytes32(", - interpreterBytecodeHashString, - ");\n\n", + "\n", "/// @dev The function pointers known to the interpreter for dynamic dispatch.\n", "/// By setting these as a constant they can be inlined into the interpreter\n", "/// and loaded at eval time for very low gas (~100) due to the compiler\n", From c928de28c5e2cc2a6d57eceb7cb7c8c97b2f5555 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Sun, 26 May 2024 17:58:58 +0400 Subject: [PATCH 05/18] refactor build pointers --- script/BuildPointers.sol | 50 ++++++++++++-------- src/concrete/RainterpreterNPE2.sol | 5 +- src/concrete/RainterpreterStoreNPE2.sol | 4 +- src/generated/RainterpreterNPE2.pointers.sol | 8 ++-- 4 files changed, 42 insertions(+), 25 deletions(-) diff --git a/script/BuildPointers.sol b/script/BuildPointers.sol index 497c5b265..07595d0a8 100644 --- a/script/BuildPointers.sol +++ b/script/BuildPointers.sol @@ -4,6 +4,7 @@ pragma solidity =0.8.25; import {Script} from "forge-std/Script.sol"; import {RainterpreterNPE2} from "src/concrete/RainterpreterNPE2.sol"; import {RainterpreterStoreNPE2} from "src/concrete/RainterpreterStoreNPE2.sol"; +import {IInterpreterV2} from "rain.interpreter.interface/interface/IInterpreterV2.sol"; contract BuildPointers is Script { function filePrefix() internal pure returns (string memory) { @@ -36,20 +37,40 @@ contract BuildPointers is Script { ); } + function interpreterFunctionPointersConstantString(IInterpreterV2 interpreter) + internal + view + returns (string memory) + { + bytes memory pointers = interpreter.functionPointers(); + + string memory hexString = vm.toString(pointers); + assembly ("memory-safe") { + // Remove the leading 0x + let newHexString := add(hexString, 2) + mstore(newHexString, sub(mload(hexString), 2)) + hexString := newHexString + } + + return string.concat( + "\n", + "/// @dev The function pointers known to the interpreter for dynamic dispatch.\n", + "/// By setting these as a constant they can be inlined into the interpreter\n", + "/// and loaded at eval time for very low gas (~100) due to the compiler\n", + "/// optimising it to a single `codecopy` to build the in memory bytes array.\n", + "bytes constant OPCODE_FUNCTION_POINTERS = hex\"", + hexString, + "\";\n" + ); + } + function buildFileForContract(address instance, string memory contractName, string memory body) internal { string memory path = pathForContract(contractName); if (vm.exists(path)) { vm.removeFile(path); } - vm.writeFile( - path, - string.concat( - filePrefix(), - bytecodeHashConstantString(instance), - body - ) - ); + vm.writeFile(path, string.concat(filePrefix(), bytecodeHashConstantString(instance), body)); } function buildRainterpreterNPE2Pointers() internal { @@ -65,18 +86,7 @@ contract BuildPointers is Script { } buildFileForContract( - address(interpreter), - "RainterpreterNPE2", - string.concat( - "\n", - "/// @dev The function pointers known to the interpreter for dynamic dispatch.\n", - "/// By setting these as a constant they can be inlined into the interpreter\n", - "/// and loaded at eval time for very low gas (~100) due to the compiler\n", - "/// optimising it to a single `codecopy` to build the in memory bytes array.\n", - "bytes constant OPCODE_FUNCTION_POINTERS = hex\"", - hexString, - "\";\n" - ) + address(interpreter), "RainterpreterNPE2", interpreterFunctionPointersConstantString(interpreter) ); } diff --git a/src/concrete/RainterpreterNPE2.sol b/src/concrete/RainterpreterNPE2.sol index 9369920a2..d8aaf9132 100644 --- a/src/concrete/RainterpreterNPE2.sol +++ b/src/concrete/RainterpreterNPE2.sol @@ -23,7 +23,10 @@ import { IInterpreterStoreV2 } from "rain.interpreter.interface/interface/IInterpreterV2.sol"; import {IInterpreterV3} from "rain.interpreter.interface/interface/unstable/IInterpreterV3.sol"; -import {INTERPRETER_BYTECODE_HASH, OPCODE_FUNCTION_POINTERS} from "../generated/RainterpreterNPE2.pointers.sol"; +import { + BYTECODE_HASH as INTERPRETER_BYTECODE_HASH, + OPCODE_FUNCTION_POINTERS +} from "../generated/RainterpreterNPE2.pointers.sol"; /// @title RainterpreterNPE2 /// @notice Implementation of a Rainlang interpreter that is compatible with diff --git a/src/concrete/RainterpreterStoreNPE2.sol b/src/concrete/RainterpreterStoreNPE2.sol index 86e131ad3..b8fa31a60 100644 --- a/src/concrete/RainterpreterStoreNPE2.sol +++ b/src/concrete/RainterpreterStoreNPE2.sol @@ -4,7 +4,9 @@ pragma solidity =0.8.25; import {ERC165} from "openzeppelin-contracts/contracts/utils/introspection/ERC165.sol"; import {IInterpreterStoreV2} from "rain.interpreter.interface/interface/IInterpreterStoreV2.sol"; -import {LibNamespace, FullyQualifiedNamespace, StateNamespace} from "rain.interpreter.interface/lib/ns/LibNamespace.sol"; +import { + LibNamespace, FullyQualifiedNamespace, StateNamespace +} from "rain.interpreter.interface/lib/ns/LibNamespace.sol"; import {BYTECODE_HASH as STORE_BYTECODE_HASH} from "../generated/RainterpreterStoreNPE2.pointers.sol"; diff --git a/src/generated/RainterpreterNPE2.pointers.sol b/src/generated/RainterpreterNPE2.pointers.sol index c2e14db63..303c49e95 100644 --- a/src/generated/RainterpreterNPE2.pointers.sol +++ b/src/generated/RainterpreterNPE2.pointers.sol @@ -7,11 +7,13 @@ // SPDX-License-Identifier: CAL pragma solidity =0.8.25; -/// @dev Hash of the known interpreter bytecode. -bytes32 constant INTERPRETER_BYTECODE_HASH = bytes32(0x082edcc97843fd74ff6dc51867110b8633b0e419bac46f53765f5a833f36d024); + +/// @dev Hash of the known bytecode. +bytes32 constant BYTECODE_HASH = bytes32(0x082edcc97843fd74ff6dc51867110b8633b0e419bac46f53765f5a833f36d024); /// @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"0e060e570e991065114c115e1170119311d512271238124912eb132813e6149613e6151a15bc1634166d16a616f5172e1793186718ba18ce1927193b1950196a19751989199e19d619fd1a7d1acb1b191b671b7f1b981be61bf41c021c1d1c321c4a1c631c711c7f1c8d1c9b1ce91d371d851dd31deb1deb1e021e301e301e471e761ecb1ed91ed91f7d2064"; +bytes constant OPCODE_FUNCTION_POINTERS = + hex"0e060e570e991065114c115e1170119311d512271238124912eb132813e6149613e6151a15bc1634166d16a616f5172e1793186718ba18ce1927193b1950196a19751989199e19d619fd1a7d1acb1b191b671b7f1b981be61bf41c021c1d1c321c4a1c631c711c7f1c8d1c9b1ce91d371d851dd31deb1deb1e021e301e301e471e761ecb1ed91ed91f7d2064"; From 55a050794d3afd6ae38b586fb5704a1d587315e3 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Sun, 26 May 2024 18:02:12 +0400 Subject: [PATCH 06/18] fmt --- script/BuildPointers.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/script/BuildPointers.sol b/script/BuildPointers.sol index 07595d0a8..ca421e8bc 100644 --- a/script/BuildPointers.sol +++ b/script/BuildPointers.sol @@ -58,7 +58,8 @@ contract BuildPointers is Script { "/// By setting these as a constant they can be inlined into the interpreter\n", "/// and loaded at eval time for very low gas (~100) due to the compiler\n", "/// optimising it to a single `codecopy` to build the in memory bytes array.\n", - "bytes constant OPCODE_FUNCTION_POINTERS = hex\"", + "bytes constant OPCODE_FUNCTION_POINTERS = \n", + " hex\"", hexString, "\";\n" ); From a9c4a79c28821ac3c2ecb3c2b02f20f793f0119b Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Sun, 26 May 2024 18:05:45 +0400 Subject: [PATCH 07/18] fmt --- script/BuildPointers.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/BuildPointers.sol b/script/BuildPointers.sol index ca421e8bc..5c37f77db 100644 --- a/script/BuildPointers.sol +++ b/script/BuildPointers.sol @@ -58,7 +58,7 @@ contract BuildPointers is Script { "/// By setting these as a constant they can be inlined into the interpreter\n", "/// and loaded at eval time for very low gas (~100) due to the compiler\n", "/// optimising it to a single `codecopy` to build the in memory bytes array.\n", - "bytes constant OPCODE_FUNCTION_POINTERS = \n", + "bytes constant OPCODE_FUNCTION_POINTERS =\n", " hex\"", hexString, "\";\n" From ba266baebdf83aa5ad318bed1b0e602a2a975abe Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Sun, 26 May 2024 18:24:39 +0400 Subject: [PATCH 08/18] build literal parser fn pointser --- script/BuildPointers.sol | 59 ++++++++++++------- src/concrete/RainterpreterParserNPE2.sol | 14 ++--- .../RainterpreterParserNPE2.pointers.sol | 18 ++++++ 3 files changed, 61 insertions(+), 30 deletions(-) create mode 100644 src/generated/RainterpreterParserNPE2.pointers.sol diff --git a/script/BuildPointers.sol b/script/BuildPointers.sol index 5c37f77db..294ce43f0 100644 --- a/script/BuildPointers.sol +++ b/script/BuildPointers.sol @@ -5,6 +5,7 @@ import {Script} from "forge-std/Script.sol"; import {RainterpreterNPE2} from "src/concrete/RainterpreterNPE2.sol"; import {RainterpreterStoreNPE2} from "src/concrete/RainterpreterStoreNPE2.sol"; import {IInterpreterV2} from "rain.interpreter.interface/interface/IInterpreterV2.sol"; +import {RainterpreterParserNPE2} from "src/concrete/RainterpreterParserNPE2.sol"; contract BuildPointers is Script { function filePrefix() internal pure returns (string memory) { @@ -23,6 +24,17 @@ contract BuildPointers is Script { return string.concat("src/generated/", contractName, ".pointers.sol"); } + function bytesToHex(bytes memory data) internal pure returns (string memory) { + string memory hexString = vm.toString(data); + assembly ("memory-safe") { + // Remove the leading 0x + let newHexString := add(hexString, 2) + mstore(newHexString, sub(mload(hexString), 2)) + hexString := newHexString + } + return hexString; + } + function bytecodeHashConstantString(address instance) internal view returns (string memory) { bytes32 bytecodeHash; assembly { @@ -42,16 +54,6 @@ contract BuildPointers is Script { view returns (string memory) { - bytes memory pointers = interpreter.functionPointers(); - - string memory hexString = vm.toString(pointers); - assembly ("memory-safe") { - // Remove the leading 0x - let newHexString := add(hexString, 2) - mstore(newHexString, sub(mload(hexString), 2)) - hexString := newHexString - } - return string.concat( "\n", "/// @dev The function pointers known to the interpreter for dynamic dispatch.\n", @@ -60,7 +62,24 @@ contract BuildPointers is Script { "/// optimising it to a single `codecopy` to build the in memory bytes array.\n", "bytes constant OPCODE_FUNCTION_POINTERS =\n", " hex\"", - hexString, + bytesToHex(interpreter.functionPointers()), + "\";\n" + ); + } + + function literalParserFunctionPointersConstantString(RainterpreterParserNPE2 instance) + internal + pure + returns (string memory) + { + return string.concat( + "\n", + "/// @dev Every two bytes is a function pointer for a literal parser.\n", + "/// Literal dispatches are determined by the first byte(s) of the literal\n", + "/// rather than a full word lookup, and are done with simple conditional\n", + "/// jumps as the possibilities are limited compared to the number of words we have.\n", + "bytes constant LITERAL_PARSER_FUNCTION_POINTERS = hex\"", + bytesToHex(instance.buildLiteralParserFunctionPointers()), "\";\n" ); } @@ -76,15 +95,6 @@ contract BuildPointers is Script { function buildRainterpreterNPE2Pointers() internal { RainterpreterNPE2 interpreter = new RainterpreterNPE2(); - bytes memory pointers = interpreter.functionPointers(); - - string memory hexString = vm.toString(pointers); - assembly ("memory-safe") { - // Remove the leading 0x - let newHexString := add(hexString, 2) - mstore(newHexString, sub(mload(hexString), 2)) - hexString := newHexString - } buildFileForContract( address(interpreter), "RainterpreterNPE2", interpreterFunctionPointersConstantString(interpreter) @@ -97,8 +107,17 @@ contract BuildPointers is Script { buildFileForContract(address(store), "RainterpreterStoreNPE2", ""); } + function buildRainterpreterParserNPE2Pointers() internal { + RainterpreterParserNPE2 parser = new RainterpreterParserNPE2(); + + buildFileForContract( + address(parser), "RainterpreterParserNPE2", literalParserFunctionPointersConstantString(parser) + ); + } + function run() external { buildRainterpreterNPE2Pointers(); buildRainterpreterStoreNPE2Pointers(); + buildRainterpreterParserNPE2Pointers(); } } diff --git a/src/concrete/RainterpreterParserNPE2.sol b/src/concrete/RainterpreterParserNPE2.sol index 688bc361e..52638023b 100644 --- a/src/concrete/RainterpreterParserNPE2.sol +++ b/src/concrete/RainterpreterParserNPE2.sol @@ -12,10 +12,10 @@ import {LibParseLiteral} from "../lib/parse/literal/LibParseLiteral.sol"; import {LibAllStandardOpsNP} from "../lib/op/LibAllStandardOpsNP.sol"; import {LibBytes, Pointer} from "rain.solmem/lib/LibBytes.sol"; import {LibParseInterstitial} from "../lib/parse/LibParseInterstitial.sol"; - -/// @dev The known hash of the parser bytecode. This is used by the deployer to -/// check that it is deploying a parser that is compatible with the interpreter. -bytes32 constant PARSER_BYTECODE_HASH = bytes32(0x458b319779ec46db91b9a23ad6cef12479a4e05fa05f5c0094fa3211b1c937cd); +import { + BYTECODE_HASH as PARSER_BYTECODE_HASH, + LITERAL_PARSER_FUNCTION_POINTERS +} from "../generated/RainterpreterParserNPE2.pointers.sol"; /// @dev Encodes the parser meta that is used to lookup word definitions. /// The structure of the parser meta is: @@ -44,12 +44,6 @@ uint8 constant PARSE_META_BUILD_DEPTH = 2; bytes constant OPERAND_HANDLER_FUNCTION_POINTERS = hex"18d818d818d8193d19b619b619b6193d193d18d818d818d819b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619fb19b61acd19fb19b61acd19b619b618d81b3619b619b6"; -/// @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"0f4e1216161d16f7"; - /// @title RainterpreterParserNPE2 /// @dev The parser implementation. contract RainterpreterParserNPE2 is IParserV1, IParserPragmaV1, ERC165 { diff --git a/src/generated/RainterpreterParserNPE2.pointers.sol b/src/generated/RainterpreterParserNPE2.pointers.sol new file mode 100644 index 000000000..63a23197d --- /dev/null +++ b/src/generated/RainterpreterParserNPE2.pointers.sol @@ -0,0 +1,18 @@ +// THIS FILE IS AUTOGENERATED BY ./script/BuildPointers.sol + +// This file is committed to the repository because there is a circular +// dependency between the contract and its pointers file. The contract +// needs the pointers file to exist so that it can compile, and the pointers +// file needs the contract to exist so that it can be compiled. + +// SPDX-License-Identifier: CAL +pragma solidity =0.8.25; + +/// @dev Hash of the known bytecode. +bytes32 constant BYTECODE_HASH = bytes32(0x458b319779ec46db91b9a23ad6cef12479a4e05fa05f5c0094fa3211b1c937cd); + +/// @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"0f4e1216161d16f7"; From 505bcbf7e1d2d91ea0ead8564b597d67a5075e2d Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Sun, 26 May 2024 18:33:51 +0400 Subject: [PATCH 09/18] operand handler function pointer --- script/BuildPointers.sol | 24 +++++++++++++++++-- src/concrete/RainterpreterParserNPE2.sol | 8 ++----- .../RainterpreterParserNPE2.pointers.sol | 8 ++++++- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/script/BuildPointers.sol b/script/BuildPointers.sol index 294ce43f0..f40f469f5 100644 --- a/script/BuildPointers.sol +++ b/script/BuildPointers.sol @@ -77,13 +77,30 @@ contract BuildPointers is Script { "/// @dev Every two bytes is a function pointer for a literal parser.\n", "/// Literal dispatches are determined by the first byte(s) of the literal\n", "/// rather than a full word lookup, and are done with simple conditional\n", - "/// jumps as the possibilities are limited compared to the number of words we have.\n", + "/// jumps as the possibilities are limited compared to the number of words we\n" + "/// have.\n", "bytes constant LITERAL_PARSER_FUNCTION_POINTERS = hex\"", bytesToHex(instance.buildLiteralParserFunctionPointers()), "\";\n" ); } + function operatorHandlerFunctionPointersConstantString(RainterpreterParserNPE2 instance) + internal + pure + returns (string memory) + { + return string.concat( + "\n", + "/// @dev Every two bytes is a function pointer for an operand handler.\n", + "/// These positional indexes all map to the same indexes looked up in the parse\n", + "/// meta.\n", + "bytes constant OPERAND_HANDLER_FUNCTION_POINTERS = hex\"", + bytesToHex(instance.buildOperandHandlerFunctionPointers()), + "\";\n" + ); + } + function buildFileForContract(address instance, string memory contractName, string memory body) internal { string memory path = pathForContract(contractName); @@ -111,7 +128,10 @@ contract BuildPointers is Script { RainterpreterParserNPE2 parser = new RainterpreterParserNPE2(); buildFileForContract( - address(parser), "RainterpreterParserNPE2", literalParserFunctionPointersConstantString(parser) + address(parser), "RainterpreterParserNPE2", string.concat( + operatorHandlerFunctionPointersConstantString(parser), + literalParserFunctionPointersConstantString(parser) + ) ); } diff --git a/src/concrete/RainterpreterParserNPE2.sol b/src/concrete/RainterpreterParserNPE2.sol index 52638023b..d46b91ae3 100644 --- a/src/concrete/RainterpreterParserNPE2.sol +++ b/src/concrete/RainterpreterParserNPE2.sol @@ -14,7 +14,8 @@ import {LibBytes, Pointer} from "rain.solmem/lib/LibBytes.sol"; import {LibParseInterstitial} from "../lib/parse/LibParseInterstitial.sol"; import { BYTECODE_HASH as PARSER_BYTECODE_HASH, - LITERAL_PARSER_FUNCTION_POINTERS + LITERAL_PARSER_FUNCTION_POINTERS, + OPERAND_HANDLER_FUNCTION_POINTERS } from "../generated/RainterpreterParserNPE2.pointers.sol"; /// @dev Encodes the parser meta that is used to lookup word definitions. @@ -39,11 +40,6 @@ bytes constant PARSE_META = /// @dev The build depth of the parser meta. uint8 constant PARSE_META_BUILD_DEPTH = 2; -/// @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"18d818d818d8193d19b619b619b6193d193d18d818d818d819b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619fb19b61acd19fb19b61acd19b619b618d81b3619b619b6"; - /// @title RainterpreterParserNPE2 /// @dev The parser implementation. contract RainterpreterParserNPE2 is IParserV1, IParserPragmaV1, ERC165 { diff --git a/src/generated/RainterpreterParserNPE2.pointers.sol b/src/generated/RainterpreterParserNPE2.pointers.sol index 63a23197d..f0135db63 100644 --- a/src/generated/RainterpreterParserNPE2.pointers.sol +++ b/src/generated/RainterpreterParserNPE2.pointers.sol @@ -11,8 +11,14 @@ pragma solidity =0.8.25; /// @dev Hash of the known bytecode. bytes32 constant BYTECODE_HASH = bytes32(0x458b319779ec46db91b9a23ad6cef12479a4e05fa05f5c0094fa3211b1c937cd); +/// @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"18d818d818d8193d19b619b619b6193d193d18d818d818d819b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619fb19b61acd19fb19b61acd19b619b618d81b3619b619b6"; + /// @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. +/// jumps as the possibilities are limited compared to the number of words we +/// have. bytes constant LITERAL_PARSER_FUNCTION_POINTERS = hex"0f4e1216161d16f7"; From 93f0343ec29ddb8d788f93e288ed3ee994ce963d Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Sun, 26 May 2024 18:46:11 +0400 Subject: [PATCH 10/18] build parse meta --- script/BuildPointers.sol | 41 +++++++++++++++++-- src/concrete/RainterpreterParserNPE2.sol | 26 ++---------- .../RainterpreterParserNPE2.pointers.sol | 22 ++++++++++ .../RainterpreterParserNPE2.pointers.t.sol | 5 ++- 4 files changed, 66 insertions(+), 28 deletions(-) diff --git a/script/BuildPointers.sol b/script/BuildPointers.sol index f40f469f5..9636b0b86 100644 --- a/script/BuildPointers.sol +++ b/script/BuildPointers.sol @@ -5,7 +5,9 @@ import {Script} from "forge-std/Script.sol"; import {RainterpreterNPE2} from "src/concrete/RainterpreterNPE2.sol"; import {RainterpreterStoreNPE2} from "src/concrete/RainterpreterStoreNPE2.sol"; import {IInterpreterV2} from "rain.interpreter.interface/interface/IInterpreterV2.sol"; -import {RainterpreterParserNPE2} from "src/concrete/RainterpreterParserNPE2.sol"; +import {RainterpreterParserNPE2, PARSE_META_BUILD_DEPTH} from "src/concrete/RainterpreterParserNPE2.sol"; +import {LibAllStandardOpsNP, AuthoringMetaV2} from "src/lib/op/LibAllStandardOpsNP.sol"; +import {LibParseMeta} from "src/lib/parse/LibParseMeta.sol"; contract BuildPointers is Script { function filePrefix() internal pure returns (string memory) { @@ -85,7 +87,7 @@ contract BuildPointers is Script { ); } - function operatorHandlerFunctionPointersConstantString(RainterpreterParserNPE2 instance) + function operandHandlerFunctionPointersConstantString(RainterpreterParserNPE2 instance) internal pure returns (string memory) @@ -101,6 +103,38 @@ contract BuildPointers is Script { ); } + function parseMetaConstantString(bytes memory authoringMetaBytes) internal pure returns (string memory) { + AuthoringMetaV2[] memory authoringMeta = abi.decode(authoringMetaBytes, (AuthoringMetaV2[])); + bytes memory parseMeta = LibParseMeta.buildParseMetaV2(authoringMeta, PARSE_META_BUILD_DEPTH); + return string.concat( + "\n", + "/// @dev Encodes the parser meta that is used to lookup word definitions.\n", + "/// The structure of the parser meta is:\n", + "/// - 1 byte: The depth of the bloom filters\n", + "/// - 1 byte: The hashing seed\n", + "/// - The bloom filters, each is 32 bytes long, one for each build depth.\n", + "/// - All the items for each word, each is 4 bytes long. Each item's first byte\n", + "/// is its opcode index, the remaining 3 bytes are the word fingerprint.\n", + "/// To do a lookup, the word is hashed with the seed, then the first byte of the\n", + "/// hash is compared against the bloom filter. If there is a hit then we count\n", + "/// the number of 1 bits in the bloom filter up to this item's 1 bit. We then\n", + "/// treat this a the index of the item in the items array. We then compare the\n", + "/// word fingerprint against the fingerprint of the item at this index. If the\n", + "/// fingerprints equal then we have a match, else we increment the seed and try\n", + "/// again with the next bloom filter, offsetting all the indexes by the total\n", + "/// bit count of the previous bloom filter. If we reach the end of the bloom\n", + "/// filters then we have a miss.\n", + "bytes constant PARSE_META =\n", + " hex\"", + bytesToHex(parseMeta), + "\";\n\n", + "/// @dev The build depth of the parser meta.\n", + "uint8 constant PARSE_META_BUILD_DEPTH = ", + vm.toString(PARSE_META_BUILD_DEPTH), + ";\n" + ); + } + function buildFileForContract(address instance, string memory contractName, string memory body) internal { string memory path = pathForContract(contractName); @@ -129,7 +163,8 @@ contract BuildPointers is Script { buildFileForContract( address(parser), "RainterpreterParserNPE2", string.concat( - operatorHandlerFunctionPointersConstantString(parser), + parseMetaConstantString(LibAllStandardOpsNP.authoringMetaV2()), + operandHandlerFunctionPointersConstantString(parser), literalParserFunctionPointersConstantString(parser) ) ); diff --git a/src/concrete/RainterpreterParserNPE2.sol b/src/concrete/RainterpreterParserNPE2.sol index d46b91ae3..0f9127804 100644 --- a/src/concrete/RainterpreterParserNPE2.sol +++ b/src/concrete/RainterpreterParserNPE2.sol @@ -15,31 +15,11 @@ import {LibParseInterstitial} from "../lib/parse/LibParseInterstitial.sol"; import { BYTECODE_HASH as PARSER_BYTECODE_HASH, LITERAL_PARSER_FUNCTION_POINTERS, - OPERAND_HANDLER_FUNCTION_POINTERS + OPERAND_HANDLER_FUNCTION_POINTERS, + PARSE_META, + PARSE_META_BUILD_DEPTH } from "../generated/RainterpreterParserNPE2.pointers.sol"; -/// @dev Encodes the parser meta that is used to lookup word definitions. -/// The structure of the parser meta is: -/// - 1 byte: The depth of the bloom filters -/// - 1 byte: The hashing seed -/// - The bloom filters, each is 32 bytes long, one for each build depth. -/// - All the items for each word, each is 4 bytes long. Each item's first byte -/// is its opcode index, the remaining 3 bytes are the word fingerprint. -/// To do a lookup, the word is hashed with the seed, then the first byte of the -/// hash is compared against the bloom filter. If there is a hit then we count -/// the number of 1 bits in the bloom filter up to this item's 1 bit. We then -/// treat this a the index of the item in the items array. We then compare the -/// word fingerprint against the fingerprint of the item at this index. If the -/// fingerprints equal then we have a match, else we increment the seed and try -/// again with the next bloom filter, offsetting all the indexes by the total -/// bit count of the previous bloom filter. If we reach the end of the bloom -/// filters then we have a miss. -bytes constant PARSE_META = - hex"027d02482901b41410193601380a408092011324604290a201223062960011040a8900000000000000000800000008000000100000000000000000000000000000000037af1e5831ee31ff1a4c426226d999cd14d454a62287204a17ca041510bfc04d05382451258fb9fe30e745fd28dbc3c529415aff38530a92368e9cbd2f4c3a173b402c5804ea67600a2aa235164d56371805a7653edd323d0cd5a68e1e3f22703f2237031f80073412d4a5b3119bd3ec068483ae402e554c35f6dc5d23f0c0a632fef45a2da6feff1c9677b92edb58d43c742e374178613501d4fa88030cae020885d59f2b766a3e158413022a67b453194070aa2040ab0f245a53d84392737c335bcbd00ff7e3283d5a200713686f5c39bd3f5f024641b909f14a300b1ec71b27a38323349552b91d792a60425d96b7457b8cf22153f8d14433bccc0d403ded0791b7eb002ddffc0e1abd702ce98c713ac04abd1b4507bb"; - -/// @dev The build depth of the parser meta. -uint8 constant PARSE_META_BUILD_DEPTH = 2; - /// @title RainterpreterParserNPE2 /// @dev The parser implementation. contract RainterpreterParserNPE2 is IParserV1, IParserPragmaV1, ERC165 { diff --git a/src/generated/RainterpreterParserNPE2.pointers.sol b/src/generated/RainterpreterParserNPE2.pointers.sol index f0135db63..f50b5d071 100644 --- a/src/generated/RainterpreterParserNPE2.pointers.sol +++ b/src/generated/RainterpreterParserNPE2.pointers.sol @@ -11,6 +11,28 @@ pragma solidity =0.8.25; /// @dev Hash of the known bytecode. bytes32 constant BYTECODE_HASH = bytes32(0x458b319779ec46db91b9a23ad6cef12479a4e05fa05f5c0094fa3211b1c937cd); +/// @dev Encodes the parser meta that is used to lookup word definitions. +/// The structure of the parser meta is: +/// - 1 byte: The depth of the bloom filters +/// - 1 byte: The hashing seed +/// - The bloom filters, each is 32 bytes long, one for each build depth. +/// - All the items for each word, each is 4 bytes long. Each item's first byte +/// is its opcode index, the remaining 3 bytes are the word fingerprint. +/// To do a lookup, the word is hashed with the seed, then the first byte of the +/// hash is compared against the bloom filter. If there is a hit then we count +/// the number of 1 bits in the bloom filter up to this item's 1 bit. We then +/// treat this a the index of the item in the items array. We then compare the +/// word fingerprint against the fingerprint of the item at this index. If the +/// fingerprints equal then we have a match, else we increment the seed and try +/// again with the next bloom filter, offsetting all the indexes by the total +/// bit count of the previous bloom filter. If we reach the end of the bloom +/// filters then we have a miss. +bytes constant PARSE_META = + hex"027d02482901b41410193601380a408092011324604290a201223062960011040a8900000000000000000800000008000000100000000000000000000000000000000037af1e5831ee31ff1a4c426226d999cd14d454a62287204a17ca041510bfc04d05382451258fb9fe30e745fd28dbc3c529415aff38530a92368e9cbd2f4c3a173b402c5804ea67600a2aa235164d56371805a7653edd323d0cd5a68e1e3f22703f2237031f80073412d4a5b3119bd3ec068483ae402e554c35f6dc5d23f0c0a632fef45a2da6feff1c9677b92edb58d43c742e374178613501d4fa88030cae020885d59f2b766a3e158413022a67b453194070aa2040ab0f245a53d84392737c335bcbd00ff7e3283d5a200713686f5c39bd3f5f024641b909f14a300b1ec71b27a38323349552b91d792a60425d96b7457b8cf22153f8d14433bccc0d403ded0791b7eb002ddffc0e1abd702ce98c713ac04abd1b4507bb"; + +/// @dev The build depth of the parser meta. +uint8 constant PARSE_META_BUILD_DEPTH = 2; + /// @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. diff --git a/test/src/concrete/RainterpreterParserNPE2.pointers.t.sol b/test/src/concrete/RainterpreterParserNPE2.pointers.t.sol index 5535b3a6a..267aec8a5 100644 --- a/test/src/concrete/RainterpreterParserNPE2.pointers.t.sol +++ b/test/src/concrete/RainterpreterParserNPE2.pointers.t.sol @@ -6,7 +6,8 @@ import { RainterpreterParserNPE2, OPERAND_HANDLER_FUNCTION_POINTERS, LITERAL_PARSER_FUNCTION_POINTERS, - PARSE_META + PARSE_META, + PARSE_META_BUILD_DEPTH } from "src/concrete/RainterpreterParserNPE2.sol"; import {LibAllStandardOpsNP, AuthoringMetaV2} from "src/lib/op/LibAllStandardOpsNP.sol"; import {LibParseMeta} from "src/lib/parse/LibParseMeta.sol"; @@ -29,7 +30,7 @@ contract RainterpreterParserNPE2PointersTest is Test { function testParserParseMeta() external { bytes memory authoringMetaBytes = LibAllStandardOpsNP.authoringMetaV2(); AuthoringMetaV2[] memory authoringMeta = abi.decode(authoringMetaBytes, (AuthoringMetaV2[])); - bytes memory expected = LibParseMeta.buildParseMetaV2(authoringMeta, 2); + bytes memory expected = LibParseMeta.buildParseMetaV2(authoringMeta, PARSE_META_BUILD_DEPTH); bytes memory actual = PARSE_META; assertEq(actual, expected); } From 35614921eed829d46341bebd17d1529efb7d0b1b Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Sun, 26 May 2024 18:46:22 +0400 Subject: [PATCH 11/18] fmt --- script/BuildPointers.sol | 7 ++++--- src/generated/RainterpreterParserNPE2.pointers.sol | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/script/BuildPointers.sol b/script/BuildPointers.sol index 9636b0b86..50f3bb758 100644 --- a/script/BuildPointers.sol +++ b/script/BuildPointers.sol @@ -79,8 +79,7 @@ contract BuildPointers is Script { "/// @dev Every two bytes is a function pointer for a literal parser.\n", "/// Literal dispatches are determined by the first byte(s) of the literal\n", "/// rather than a full word lookup, and are done with simple conditional\n", - "/// jumps as the possibilities are limited compared to the number of words we\n" - "/// have.\n", + "/// jumps as the possibilities are limited compared to the number of words we\n" "/// have.\n", "bytes constant LITERAL_PARSER_FUNCTION_POINTERS = hex\"", bytesToHex(instance.buildLiteralParserFunctionPointers()), "\";\n" @@ -162,7 +161,9 @@ contract BuildPointers is Script { RainterpreterParserNPE2 parser = new RainterpreterParserNPE2(); buildFileForContract( - address(parser), "RainterpreterParserNPE2", string.concat( + address(parser), + "RainterpreterParserNPE2", + string.concat( parseMetaConstantString(LibAllStandardOpsNP.authoringMetaV2()), operandHandlerFunctionPointersConstantString(parser), literalParserFunctionPointersConstantString(parser) diff --git a/src/generated/RainterpreterParserNPE2.pointers.sol b/src/generated/RainterpreterParserNPE2.pointers.sol index f50b5d071..3571c39d8 100644 --- a/src/generated/RainterpreterParserNPE2.pointers.sol +++ b/src/generated/RainterpreterParserNPE2.pointers.sol @@ -36,7 +36,8 @@ uint8 constant PARSE_META_BUILD_DEPTH = 2; /// @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"18d818d818d8193d19b619b619b6193d193d18d818d818d819b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619fb19b61acd19fb19b61acd19b619b618d81b3619b619b6"; +bytes constant OPERAND_HANDLER_FUNCTION_POINTERS = + hex"18d818d818d8193d19b619b619b6193d193d18d818d818d819b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619fb19b61acd19fb19b61acd19b619b618d81b3619b619b6"; /// @dev Every two bytes is a function pointer for a literal parser. /// Literal dispatches are determined by the first byte(s) of the literal From 74c3d28b7d829f6579bd028c4affb08193eafd6a Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Sun, 26 May 2024 19:10:11 +0400 Subject: [PATCH 12/18] build deployer pointers --- script/BuildPointers.sol | 50 +++++++++++++++++++ .../RainterpreterExpressionDeployerNPE2.sol | 8 +-- ...rpreterExpressionDeployerNPE2.pointers.sol | 19 +++++++ .../RainterpreterParserNPE2.pointers.sol | 3 +- .../ExpressionDeployerNPConstants.sol | 0 ...erExpressionDeployerNPE2.deployCheck.t.sol | 1 - ...essionDeployerNPE2.describedByMetaV1.t.sol | 2 +- ...rpreterExpressionDeployerNPE2.parse2.t.sol | 1 - 8 files changed, 72 insertions(+), 12 deletions(-) create mode 100644 src/generated/RainterpreterExpressionDeployerNPE2.pointers.sol rename {test => src}/lib/constants/ExpressionDeployerNPConstants.sol (100%) diff --git a/script/BuildPointers.sol b/script/BuildPointers.sol index 50f3bb758..a4b5f07e3 100644 --- a/script/BuildPointers.sol +++ b/script/BuildPointers.sol @@ -6,8 +6,13 @@ import {RainterpreterNPE2} from "src/concrete/RainterpreterNPE2.sol"; import {RainterpreterStoreNPE2} from "src/concrete/RainterpreterStoreNPE2.sol"; import {IInterpreterV2} from "rain.interpreter.interface/interface/IInterpreterV2.sol"; import {RainterpreterParserNPE2, PARSE_META_BUILD_DEPTH} from "src/concrete/RainterpreterParserNPE2.sol"; +import { + RainterpreterExpressionDeployerNPE2, + RainterpreterExpressionDeployerNPE2ConstructionConfigV2 +} from "src/concrete/RainterpreterExpressionDeployerNPE2.sol"; import {LibAllStandardOpsNP, AuthoringMetaV2} from "src/lib/op/LibAllStandardOpsNP.sol"; import {LibParseMeta} from "src/lib/parse/LibParseMeta.sol"; +import {EXPRESSION_DEPLOYER_NP_META_PATH} from "src/lib/constants/ExpressionDeployerNPConstants.sol"; contract BuildPointers is Script { function filePrefix() internal pure returns (string memory) { @@ -134,6 +139,31 @@ contract BuildPointers is Script { ); } + function integrityFunctionPointersConstantString(RainterpreterExpressionDeployerNPE2 deployer) + internal + view + returns (string memory) + { + return string.concat( + "\n", + "/// @dev The function pointers for the integrity check fns.\n", + "bytes constant INTEGRITY_FUNCTION_POINTERS =\n", + " hex\"", + bytesToHex(deployer.integrityFunctionPointers()), + "\";\n" + ); + } + + function describedByMetaHashConstantString(bytes memory describedByMeta) internal pure returns (string memory) { + return string.concat( + "\n", + "/// @dev The hash of the meta that describes the contract.\n", + "bytes32 constant DESCRIBED_BY_META_HASH = bytes32(", + vm.toString(keccak256(describedByMeta)), + ");\n" + ); + } + function buildFileForContract(address instance, string memory contractName, string memory body) internal { string memory path = pathForContract(contractName); @@ -171,9 +201,29 @@ contract BuildPointers is Script { ); } + function buildRainterpreterExpressionDeployerNPE2Pointers() internal { + RainterpreterNPE2 interpreter = new RainterpreterNPE2(); + RainterpreterStoreNPE2 store = new RainterpreterStoreNPE2(); + RainterpreterParserNPE2 parser = new RainterpreterParserNPE2(); + + RainterpreterExpressionDeployerNPE2 deployer = new RainterpreterExpressionDeployerNPE2( + RainterpreterExpressionDeployerNPE2ConstructionConfigV2( + address(interpreter), address(store), address(parser) + ) + ); + + buildFileForContract( + address(deployer), "RainterpreterExpressionDeployerNPE2", string.concat( + describedByMetaHashConstantString(vm.readFileBinary(EXPRESSION_DEPLOYER_NP_META_PATH)), + integrityFunctionPointersConstantString(deployer) + ) + ); + } + function run() external { buildRainterpreterNPE2Pointers(); buildRainterpreterStoreNPE2Pointers(); buildRainterpreterParserNPE2Pointers(); + buildRainterpreterExpressionDeployerNPE2Pointers(); } } diff --git a/src/concrete/RainterpreterExpressionDeployerNPE2.sol b/src/concrete/RainterpreterExpressionDeployerNPE2.sol index 6b5589c1e..0b2f09397 100644 --- a/src/concrete/RainterpreterExpressionDeployerNPE2.sol +++ b/src/concrete/RainterpreterExpressionDeployerNPE2.sol @@ -33,13 +33,7 @@ import {LibParse, LibParseMeta} from "../lib/parse/LibParse.sol"; import {RainterpreterNPE2, INTERPRETER_BYTECODE_HASH} from "./RainterpreterNPE2.sol"; import {PARSER_BYTECODE_HASH} from "./RainterpreterParserNPE2.sol"; import {STORE_BYTECODE_HASH} from "./RainterpreterStoreNPE2.sol"; - -/// @dev The function pointers for the integrity check fns. -bytes constant INTEGRITY_FUNCTION_POINTERS = - hex"0e780ef60f5b10d510df10df10e910f2110d11b311b3120f1289129610df10e910df10df10e910d510d510d510d512a012c512df10df12a010df10df129610e910df10df1296129612e912e912e912e910df10e912e910e910e910e910e910df10e910e910e910e910e912e912e912e912e910df10e910e910df10e910e910df10df10e912e912e910e912df"; - -/// @dev Hash of the metadata that describes the deployer (parsing). -bytes32 constant DESCRIBED_BY_META_HASH = bytes32(0x89148873ea148e1c312c3c6cffbc5fb012194570f04ed1177db6002901e7bf38); +import {INTEGRITY_FUNCTION_POINTERS, DESCRIBED_BY_META_HASH} from "../generated/RainterpreterExpressionDeployerNPE2.pointers.sol"; /// All config required to construct a `RainterpreterNPE2`. /// @param interpreter The `IInterpreterV2` to use for evaluation. MUST match diff --git a/src/generated/RainterpreterExpressionDeployerNPE2.pointers.sol b/src/generated/RainterpreterExpressionDeployerNPE2.pointers.sol new file mode 100644 index 000000000..584030f14 --- /dev/null +++ b/src/generated/RainterpreterExpressionDeployerNPE2.pointers.sol @@ -0,0 +1,19 @@ +// THIS FILE IS AUTOGENERATED BY ./script/BuildPointers.sol + +// This file is committed to the repository because there is a circular +// dependency between the contract and its pointers file. The contract +// needs the pointers file to exist so that it can compile, and the pointers +// file needs the contract to exist so that it can be compiled. + +// SPDX-License-Identifier: CAL +pragma solidity =0.8.25; + +/// @dev Hash of the known bytecode. +bytes32 constant BYTECODE_HASH = bytes32(0x1f3ab430cd5a8ad892a5974e85b001b59df9f2a9f9a2ccf562c518b4a6550b5a); + +/// @dev The hash of the meta that describes the contract. +bytes32 constant DESCRIBED_BY_META_HASH = bytes32(0x89148873ea148e1c312c3c6cffbc5fb012194570f04ed1177db6002901e7bf38); + +/// @dev The function pointers for the integrity check fns. +bytes constant INTEGRITY_FUNCTION_POINTERS = + hex"0e780ef60f5b10d510df10df10e910f2110d11b311b3120f1289129610df10e910df10df10e910d510d510d510d512a012c512df10df12a010df10df129610e910df10df1296129612e912e912e912e910df10e912e910e910e910e910e910df10e910e910e910e910e912e912e912e912e910df10e910e910df10e910e910df10df10e912e912e910e912df"; diff --git a/src/generated/RainterpreterParserNPE2.pointers.sol b/src/generated/RainterpreterParserNPE2.pointers.sol index 3571c39d8..f50b5d071 100644 --- a/src/generated/RainterpreterParserNPE2.pointers.sol +++ b/src/generated/RainterpreterParserNPE2.pointers.sol @@ -36,8 +36,7 @@ uint8 constant PARSE_META_BUILD_DEPTH = 2; /// @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"18d818d818d8193d19b619b619b6193d193d18d818d818d819b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619fb19b61acd19fb19b61acd19b619b618d81b3619b619b6"; +bytes constant OPERAND_HANDLER_FUNCTION_POINTERS = hex"18d818d818d8193d19b619b619b6193d193d18d818d818d819b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619fb19b61acd19fb19b61acd19b619b618d81b3619b619b6"; /// @dev Every two bytes is a function pointer for a literal parser. /// Literal dispatches are determined by the first byte(s) of the literal diff --git a/test/lib/constants/ExpressionDeployerNPConstants.sol b/src/lib/constants/ExpressionDeployerNPConstants.sol similarity index 100% rename from test/lib/constants/ExpressionDeployerNPConstants.sol rename to src/lib/constants/ExpressionDeployerNPConstants.sol diff --git a/test/src/concrete/RainterpreterExpressionDeployerNPE2.deployCheck.t.sol b/test/src/concrete/RainterpreterExpressionDeployerNPE2.deployCheck.t.sol index a83df7445..2bf74120f 100644 --- a/test/src/concrete/RainterpreterExpressionDeployerNPE2.deployCheck.t.sol +++ b/test/src/concrete/RainterpreterExpressionDeployerNPE2.deployCheck.t.sol @@ -3,7 +3,6 @@ pragma solidity =0.8.25; import {Test} from "forge-std/Test.sol"; import {INVALID_BYTECODE} from "test/lib/etch/LibEtch.sol"; -import {EXPRESSION_DEPLOYER_NP_META_PATH} from "test/lib/constants/ExpressionDeployerNPConstants.sol"; import {IERC1820Registry} from "openzeppelin-contracts/contracts/utils/introspection/IERC1820Registry.sol"; import {IERC1820_REGISTRY} from "rain.erc1820/lib/LibIERC1820.sol"; import {IInterpreterV2} from "rain.interpreter.interface/interface/IInterpreterV2.sol"; diff --git a/test/src/concrete/RainterpreterExpressionDeployerNPE2.describedByMetaV1.t.sol b/test/src/concrete/RainterpreterExpressionDeployerNPE2.describedByMetaV1.t.sol index cf78a6b02..f1cba3489 100644 --- a/test/src/concrete/RainterpreterExpressionDeployerNPE2.describedByMetaV1.t.sol +++ b/test/src/concrete/RainterpreterExpressionDeployerNPE2.describedByMetaV1.t.sol @@ -9,7 +9,7 @@ import { import {RainterpreterNPE2} from "src/concrete/RainterpreterNPE2.sol"; import {RainterpreterStoreNPE2} from "src/concrete/RainterpreterStoreNPE2.sol"; import {RainterpreterParserNPE2} from "src/concrete/RainterpreterParserNPE2.sol"; -import {EXPRESSION_DEPLOYER_NP_META_PATH} from "../../lib/constants/ExpressionDeployerNPConstants.sol"; +import {EXPRESSION_DEPLOYER_NP_META_PATH} from "src/lib/constants/ExpressionDeployerNPConstants.sol"; contract RainterpreterExpressionDeployerNPE2DescribedByMetaV1Test is Test { function testRainterpreterExpressionDeployerNPE2DescribedByMetaV1Happy() external { diff --git a/test/src/concrete/RainterpreterExpressionDeployerNPE2.parse2.t.sol b/test/src/concrete/RainterpreterExpressionDeployerNPE2.parse2.t.sol index 1ed0fe809..44a9102cb 100644 --- a/test/src/concrete/RainterpreterExpressionDeployerNPE2.parse2.t.sol +++ b/test/src/concrete/RainterpreterExpressionDeployerNPE2.parse2.t.sol @@ -2,7 +2,6 @@ pragma solidity =0.8.25; import {Test} from "forge-std/Test.sol"; -import {EXPRESSION_DEPLOYER_NP_META_PATH} from "test/lib/constants/ExpressionDeployerNPConstants.sol"; import { RainterpreterExpressionDeployerNPE2, RainterpreterExpressionDeployerNPE2ConstructionConfigV2 From 53f1fd744174883e06080f1a2dd09fa6e6119a57 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Sun, 26 May 2024 20:29:43 +0400 Subject: [PATCH 13/18] fmt --- script/BuildPointers.sol | 7 +++++-- src/concrete/RainterpreterExpressionDeployerNPE2.sol | 5 ++++- src/generated/RainterpreterParserNPE2.pointers.sol | 3 ++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/script/BuildPointers.sol b/script/BuildPointers.sol index a4b5f07e3..889142482 100644 --- a/script/BuildPointers.sol +++ b/script/BuildPointers.sol @@ -101,7 +101,8 @@ contract BuildPointers is Script { "/// @dev Every two bytes is a function pointer for an operand handler.\n", "/// These positional indexes all map to the same indexes looked up in the parse\n", "/// meta.\n", - "bytes constant OPERAND_HANDLER_FUNCTION_POINTERS = hex\"", + "bytes constant OPERAND_HANDLER_FUNCTION_POINTERS =\n", + " hex\"", bytesToHex(instance.buildOperandHandlerFunctionPointers()), "\";\n" ); @@ -213,7 +214,9 @@ contract BuildPointers is Script { ); buildFileForContract( - address(deployer), "RainterpreterExpressionDeployerNPE2", string.concat( + address(deployer), + "RainterpreterExpressionDeployerNPE2", + string.concat( describedByMetaHashConstantString(vm.readFileBinary(EXPRESSION_DEPLOYER_NP_META_PATH)), integrityFunctionPointersConstantString(deployer) ) diff --git a/src/concrete/RainterpreterExpressionDeployerNPE2.sol b/src/concrete/RainterpreterExpressionDeployerNPE2.sol index 0b2f09397..b0230ed0c 100644 --- a/src/concrete/RainterpreterExpressionDeployerNPE2.sol +++ b/src/concrete/RainterpreterExpressionDeployerNPE2.sol @@ -33,7 +33,10 @@ import {LibParse, LibParseMeta} from "../lib/parse/LibParse.sol"; import {RainterpreterNPE2, INTERPRETER_BYTECODE_HASH} from "./RainterpreterNPE2.sol"; import {PARSER_BYTECODE_HASH} from "./RainterpreterParserNPE2.sol"; import {STORE_BYTECODE_HASH} from "./RainterpreterStoreNPE2.sol"; -import {INTEGRITY_FUNCTION_POINTERS, DESCRIBED_BY_META_HASH} from "../generated/RainterpreterExpressionDeployerNPE2.pointers.sol"; +import { + INTEGRITY_FUNCTION_POINTERS, + DESCRIBED_BY_META_HASH +} from "../generated/RainterpreterExpressionDeployerNPE2.pointers.sol"; /// All config required to construct a `RainterpreterNPE2`. /// @param interpreter The `IInterpreterV2` to use for evaluation. MUST match diff --git a/src/generated/RainterpreterParserNPE2.pointers.sol b/src/generated/RainterpreterParserNPE2.pointers.sol index f50b5d071..3571c39d8 100644 --- a/src/generated/RainterpreterParserNPE2.pointers.sol +++ b/src/generated/RainterpreterParserNPE2.pointers.sol @@ -36,7 +36,8 @@ uint8 constant PARSE_META_BUILD_DEPTH = 2; /// @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"18d818d818d8193d19b619b619b6193d193d18d818d818d819b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619fb19b61acd19fb19b61acd19b619b618d81b3619b619b6"; +bytes constant OPERAND_HANDLER_FUNCTION_POINTERS = + hex"18d818d818d8193d19b619b619b6193d193d18d818d818d819b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619b619fb19b61acd19fb19b61acd19b619b618d81b3619b619b6"; /// @dev Every two bytes is a function pointer for a literal parser. /// Literal dispatches are determined by the first byte(s) of the literal From 649235b396fa58df83e04fa8be5d28e4e6e806b3 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Sun, 26 May 2024 20:33:50 +0400 Subject: [PATCH 14/18] check if git is clean on ci --- .github/workflows/git-clean.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/git-clean.yaml diff --git a/.github/workflows/git-clean.yaml b/.github/workflows/git-clean.yaml new file mode 100644 index 000000000..06db61120 --- /dev/null +++ b/.github/workflows/git-clean.yaml @@ -0,0 +1,19 @@ +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: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main + + - run: nix develop -c forge script ./script/BuildAuthoringMeta.sol + - run: nix develop -c forge script ./script/BuildPointers.sol + + - run: git diff --exit-code \ No newline at end of file From 4878f3f332413eabd0b49a22c8c686fdb97a16b1 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Mon, 27 May 2024 10:25:22 +0400 Subject: [PATCH 15/18] fix ci --- .github/workflows/git-clean.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/git-clean.yaml b/.github/workflows/git-clean.yaml index 06db61120..0a19df6ae 100644 --- a/.github/workflows/git-clean.yaml +++ b/.github/workflows/git-clean.yaml @@ -13,6 +13,7 @@ jobs: - uses: DeterminateSystems/nix-installer-action@main - uses: DeterminateSystems/magic-nix-cache-action@main + - run: mkdir -p meta - run: nix develop -c forge script ./script/BuildAuthoringMeta.sol - run: nix develop -c forge script ./script/BuildPointers.sol From f0c45c91adbd1ec6c58993a052ae656d1676bbb2 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Mon, 27 May 2024 10:38:10 +0400 Subject: [PATCH 16/18] fix ci --- .github/workflows/git-clean.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/git-clean.yaml b/.github/workflows/git-clean.yaml index 0a19df6ae..47161ea03 100644 --- a/.github/workflows/git-clean.yaml +++ b/.github/workflows/git-clean.yaml @@ -13,8 +13,8 @@ jobs: - uses: DeterminateSystems/nix-installer-action@main - uses: DeterminateSystems/magic-nix-cache-action@main - - run: mkdir -p meta - - run: nix develop -c forge script ./script/BuildAuthoringMeta.sol + - run: nix develop -c i9r-prelude + - run: nix develop -c forge script ./script/BuildPointers.sol - run: git diff --exit-code \ No newline at end of file From 000edb8125026f1df895dc9eb08fba8141fc1312 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Mon, 27 May 2024 10:43:35 +0400 Subject: [PATCH 17/18] demonstrate failing ci --- script/BuildPointers.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/BuildPointers.sol b/script/BuildPointers.sol index 889142482..7d98d3040 100644 --- a/script/BuildPointers.sol +++ b/script/BuildPointers.sol @@ -17,7 +17,7 @@ import {EXPRESSION_DEPLOYER_NP_META_PATH} from "src/lib/constants/ExpressionDepl contract BuildPointers is Script { function filePrefix() internal pure returns (string memory) { return string.concat( - "// THIS FILE IS AUTOGENERATED BY ./script/BuildPointers.sol\n\n", + "// zTHIS FILE IS AUTOGENERATED BY ./script/BuildPointers.sol\n\n", "// This file is committed to the repository because there is a circular\n" "// dependency between the contract and its pointers file. The contract\n" "// needs the pointers file to exist so that it can compile, and the pointers\n" From 54b94ab19ac3bb061339015ed42351952c078227 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Mon, 27 May 2024 10:43:45 +0400 Subject: [PATCH 18/18] fix ci --- script/BuildPointers.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/BuildPointers.sol b/script/BuildPointers.sol index 7d98d3040..889142482 100644 --- a/script/BuildPointers.sol +++ b/script/BuildPointers.sol @@ -17,7 +17,7 @@ import {EXPRESSION_DEPLOYER_NP_META_PATH} from "src/lib/constants/ExpressionDepl contract BuildPointers is Script { function filePrefix() internal pure returns (string memory) { return string.concat( - "// zTHIS FILE IS AUTOGENERATED BY ./script/BuildPointers.sol\n\n", + "// THIS FILE IS AUTOGENERATED BY ./script/BuildPointers.sol\n\n", "// This file is committed to the repository because there is a circular\n" "// dependency between the contract and its pointers file. The contract\n" "// needs the pointers file to exist so that it can compile, and the pointers\n"