diff --git a/script/InteropPoW.sol b/script/InteropPoW.sol index e59e40b..8af280a 100644 --- a/script/InteropPoW.sol +++ b/script/InteropPoW.sol @@ -13,7 +13,6 @@ contract InteropPoWScript is Script { vm.startBroadcast(); bytes memory results = w.compute(); - console.logBytes(results); vm.stopBroadcast(); } diff --git a/src/InteropPow.sol b/src/InteropPow.sol index 2fb2493..7fccd7f 100644 --- a/src/InteropPow.sol +++ b/src/InteropPow.sol @@ -4,30 +4,72 @@ pragma solidity ^0.8.13; import {IL2ToL2CrossDomainMessenger} from "./interfaces.sol"; interface IInteropPoW { - function run() external; + function run(uint256[] memory chainIds) external; function reportResults(bytes memory) external; event AllResults(bytes results); } -// contract InteropPoW is IInteropPoW {} +contract InteropPoW is IInteropPoW { + IL2ToL2CrossDomainMessenger xdm = IL2ToL2CrossDomainMessenger(0x4200000000000000000000000000000000000023); + address target; // TODO this should be the Worker contract, same address on all chains + bytes public allResults; + + function run(uint256[] memory chainIds) public { + for (uint8 i = 0; i < chainIds.length; i++) { + runOnChain(chainIds[i]); + } + } + + function runOnChain(uint256 chainId) public { + // prepare the x-domain message + bytes4 selector = bytes4(keccak256("run(uint256,address)")); + bytes memory data = abi.encodeWithSelector(selector, block.chainid, this); + + // send the x-domain message + xdm.sendMessage(chainId, target, data); + } + + function reportResults(bytes memory results) public { + // add results to global storage variable + for (uint256 i = 0; i < results.length; i++) { + allResults.push(results[i]); + } + + // emit everything we have so far, ideally there are no duplicates + // (the test or script running this should check) + emit AllResults(allResults); + } +} interface IWorker { - function run() external; + function run(uint256 returnDestination, address returnAddress) external; } contract Worker is IWorker { IL2ToL2CrossDomainMessenger xdm = IL2ToL2CrossDomainMessenger(0x4200000000000000000000000000000000000023); - uint256 destination; // TODO this should be the on the instigating chain - address target; // TODO this should be the InteropPoW contract - bytes32 constant difficulty = bytes32(uint256(2 ** 250 - 1)); + function run(uint256 returnDestination, address returnAddress) external { + // Do the computation + bytes memory results = compute(); + + // Prepare the X-domain message + bytes4 selector = bytes4(keccak256("sendMessage(uint256,address,bytes)")); + bytes memory data = abi.encodeWithSelector(selector, results); + + // Send the X-domain message + xdm.sendMessage(returnDestination, returnAddress, data); + } + function compute() public view returns (bytes memory) { bytes memory results; - uint8 seed = uint8(block.timestamp + uint256(blockhash(block.number - 1))); + + // compute the seed, this should be unique per chain + bytes31 seed = + bytes31(bytes32(keccak256(abi.encodePacked(block.chainid, block.timestamp, blockhash(block.number - 1))))); for (uint8 i = 0; i < 256 - 1; i++) { - bytes memory preimage = bytes.concat(bytes1(seed), bytes1(i)); + bytes memory preimage = bytes.concat(seed, bytes1(i)); // 32 bytes per solution bytes32 hash = keccak256(preimage); if (hash < difficulty) { results = bytes.concat(results, preimage); @@ -35,12 +77,4 @@ contract Worker is IWorker { } return results; } - - function run() external { - bytes memory results = compute(); - bytes4 selector = bytes4(keccak256("sendMessage(uint256,address,bytes)")); - bytes memory data = abi.encodeWithSelector(selector, results); - xdm.sendMessage(destination, target, data); - // TODO send results back to InteropPow contract - } } diff --git a/test/InteropPow.t.sol b/test/InteropPow.t.sol index 0e90f79..4640ed7 100644 --- a/test/InteropPow.t.sol +++ b/test/InteropPow.t.sol @@ -12,9 +12,10 @@ contract WorkerTest is Test { } function test_compute() public { - vm.warp(1641383230000); - bytes memory results = w.compute(); - console.log("found %s valid preimages", results.length); - console.logBytes(results); + for (uint8 i = 0; i < 256 - 1; i++) { + vm.warp(i); + bytes memory results = w.compute(); + console.log("found %s valid preimages", results.length / 32); + } } }