diff --git a/src/osp/OneStepProver0.sol b/src/osp/OneStepProver0.sol index 2d116915..421cec63 100644 --- a/src/osp/OneStepProver0.sol +++ b/src/osp/OneStepProver0.sol @@ -164,15 +164,25 @@ contract OneStepProver0 is IOneStepProver { mach.functionPc = 0; } - function executeCrossModuleDynamicCall( + function executeCrossModuleInternalCall( Machine memory mach, Module memory mod, Instruction calldata inst, - bytes calldata + bytes calldata proof ) internal pure { // Get the target from the stack - uint32 func = mach.valueStack.pop().assumeI32(); - uint32 module = mach.valueStack.pop().assumeI32(); + uint32 internalIndex = uint32(inst.argumentData); + uint32 moduleIndex = mach.valueStack.pop().assumeI32(); + Module memory calledMod; + + MerkleProof memory modProof; + uint256 offset = 0; + (calledMod, offset) = Deserialize.module(proof, offset); + (modProof, offset) = Deserialize.merkleProof(proof, offset); + require( + modProof.computeRootFromModule(moduleIndex, calledMod) == mach.modulesRoot, + "CROSS_MODULE_INTERNAL_MODULES_ROOT" + ); // Push the return pc to the stack mach.valueStack.push(createReturnValue(mach)); @@ -182,8 +192,8 @@ contract OneStepProver0 is IOneStepProver { mach.valueStack.push(ValueLib.newI32(mod.internalsOffset)); // Jump to the target - mach.moduleIdx = module; - mach.functionIdx = func; + mach.moduleIdx = moduleIndex; + mach.functionIdx = internalIndex + calledMod.internalsOffset; mach.functionPc = 0; } @@ -486,8 +496,8 @@ contract OneStepProver0 is IOneStepProver { impl = executeCrossModuleCall; } else if (opcode == Instructions.CROSS_MODULE_FORWARD) { impl = executeCrossModuleForward; - } else if (opcode == Instructions.CROSS_MODULE_DYNAMIC_CALL) { - impl = executeCrossModuleDynamicCall; + } else if (opcode == Instructions.CROSS_MODULE_INTERNAL_CALL) { + impl = executeCrossModuleInternalCall; } else if (opcode == Instructions.CALLER_MODULE_INTERNAL_CALL) { impl = executeCallerModuleInternalCall; } else if (opcode == Instructions.CALL_INDIRECT) { diff --git a/src/precompiles/ArbWasm.sol b/src/precompiles/ArbWasm.sol index 6ae4449e..b836a55a 100644 --- a/src/precompiles/ArbWasm.sol +++ b/src/precompiles/ArbWasm.sol @@ -26,6 +26,14 @@ interface ArbWasm { // @return version the program version (0 for EVM contracts) function programVersion(address program) external view returns (uint16 version); + // @notice gets the uncompressed size of the program at the given address in bytes + // @return size the size of the program in bytes rounded up to a multiple of 512 + function programSize(address program) external view returns (uint32 size); + + // @notice gets the memory footprint of the program at the given address in pages + // @return footprint the memory footprint of program in pages + function programMemoryFootprint(address program) external view returns (uint16 footprint); + // @notice gets the conversion rate between gas and ink // @return price the amount of ink 1 gas buys function inkPrice() external view returns (uint32 price); @@ -54,6 +62,8 @@ interface ArbWasm { // @return gas cost paid per half kb uncompressed. function callScalar() external view returns (uint16 gas); + event ProgramActivated(bytes32 indexed codehash, address program, uint16 version); + error ProgramNotActivated(); error ProgramOutOfDate(uint16 version); error ProgramUpToDate(); diff --git a/src/state/Instructions.sol b/src/state/Instructions.sol index 13447d63..2d04dc5c 100644 --- a/src/state/Instructions.sol +++ b/src/state/Instructions.sol @@ -135,7 +135,7 @@ library Instructions { uint16 internal constant CROSS_MODULE_CALL = 0x8009; uint16 internal constant CALLER_MODULE_INTERNAL_CALL = 0x800A; uint16 internal constant CROSS_MODULE_FORWARD = 0x800B; - uint16 internal constant CROSS_MODULE_DYNAMIC_CALL = 0x800C; + uint16 internal constant CROSS_MODULE_INTERNAL_CALL = 0x800C; uint16 internal constant GET_GLOBAL_STATE_BYTES32 = 0x8010; uint16 internal constant SET_GLOBAL_STATE_BYTES32 = 0x8011;