diff --git a/.gitignore b/.gitignore index df88794b6..e5352dfda 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ !/.yarn/releases !/.yarn/sdks !/.yarn/versions +/utils/e2e-tests/ts/node_modules diff --git a/utils/e2e-tests/ts/lib/abis/contractsFactory.ts b/utils/e2e-tests/ts/lib/abis/contractsFactory.ts new file mode 100644 index 000000000..7f82f846a --- /dev/null +++ b/utils/e2e-tests/ts/lib/abis/contractsFactory.ts @@ -0,0 +1,31 @@ +// pragma solidity ^0.8.13; +// +// contract ContractsFactory { +// function build() +// public +// returns (Item itemAddress) +// { +// return new Item(); +// } +// } +// +// contract Item {} + +export default { + "abi": [ + { + "type": "function", + "name": "build", + "inputs": [], + "outputs": [ + { + "name": "itemAddress", + "type": "address", + "internalType": "contract Item" + } + ], + "stateMutability": "nonpayable" + } + ], + "bytecode": "0x6080604052348015600e575f5ffd5b5061010f8061001c5f395ff3fe6080604052348015600e575f5ffd5b50600436106026575f3560e01c80638e1a55fc14602a575b5f5ffd5b6030604c565b6040516001600160a01b03909116815260200160405180910390f35b5f6040516057906075565b604051809103905ff080158015606f573d5f5f3e3d5ffd5b50905090565b6058806100828339019056fe6080604052348015600e575f5ffd5b50603e80601a5f395ff3fe60806040525f5ffdfea2646970667358221220792811ad984520d0fcc81e7965d60d949a45e844a276b72e02a9efd3a03f105864736f6c634300081c0033a26469706673582212207f6145ff575fd357fb707898e54cf8e8193fa1187fa2649da64a06e0b092a32864736f6c634300081c0033", +} as const; diff --git a/utils/e2e-tests/ts/lib/node.ts b/utils/e2e-tests/ts/lib/node.ts index 4b14bdc15..416d2b966 100644 --- a/utils/e2e-tests/ts/lib/node.ts +++ b/utils/e2e-tests/ts/lib/node.ts @@ -37,7 +37,7 @@ export const runNode = ( addCleanup: AddCleanup, ): RunNodeState => { const { args, stdio = "inherit" } = params; - const childProcess = spawn(PEER_PATH, args, { stdio }); + const childProcess = spawn(PEER_PATH, args, { stdio, env: { RUST_LOG: 'info,evm=debug' } }); console.log(`Spawned peer as pid ${childProcess.pid}`); const sendSig = (sig: number) => { diff --git a/utils/e2e-tests/ts/tests/eth/contractsFactory.ts b/utils/e2e-tests/ts/tests/eth/contractsFactory.ts new file mode 100644 index 000000000..77af344a4 --- /dev/null +++ b/utils/e2e-tests/ts/tests/eth/contractsFactory.ts @@ -0,0 +1,68 @@ +import { expect, describe, it } from "vitest"; +import { RunNodeState, runNode } from "../../lib/node"; +import * as eth from "../../lib/ethViem"; +import contractsFactory from "../../lib/abis/contractsFactory"; +import "../../lib/expect"; +import { beforeEachWithCleanup } from "../../lib/lifecycle"; + +describe("contracts factory", () => { + let node: RunNodeState; + let publicClient: eth.PublicClientWebSocket; + let devClients: eth.DevClientsWebSocket; + beforeEachWithCleanup(async (cleanup) => { + node = runNode({ args: ["--dev", "--tmp"] }, cleanup.push); + + await node.waitForBoot; + + publicClient = eth.publicClientFromNodeWebSocket(node, cleanup.push); + devClients = eth.devClientsFromNodeWebSocket(node, cleanup.push); + }, 60 * 1000); + + it("creates contracts at unique addresses", async () => { + const [alice, bob] = devClients; + + // Deploy contract and get address. + console.log(`Deploy`); + const deployContractTxHash = await alice.deployContract({ + abi: contractsFactory.abi, + bytecode: contractsFactory.bytecode, + }); + const deployContractTxReceipt = + await publicClient.waitForTransactionReceipt({ + hash: deployContractTxHash, + timeout: 18_000, + }); + + const factoryAddress = deployContractTxReceipt.contractAddress!; + + const itemAddress1 = await build(factoryAddress, publicClient, bob); + console.log(`Built 1: ${itemAddress1}`); + const itemAddress2 = await build(factoryAddress, publicClient, bob); + console.log(`Built 2: ${itemAddress2}`); + expect(itemAddress1).not.toEqual(itemAddress2); + }); +}); + +async function build(factoryAddress: `0x${string}`, publicClient: eth.PublicClientWebSocket, devClient: eth.DevClientsWebSocket[0]): `0x${string}` { + console.log(`Build`); + + const { request: buildingRequest, result: itemAddress } = await publicClient.simulateContract({ + address: factoryAddress, + abi: contractsFactory.abi, + functionName: "build", + account: devClient.account, + }); + const buildingTx = await devClient.writeContract(buildingRequest); + + // const buildingTx = await devClient.writeContract({ + // address: factoryAddress, + // abi: contractsFactory.abi, + // functionName: "build", + // }); + + await publicClient.waitForTransactionReceipt({ + hash: buildingTx, + timeout: 18_000, + }); + return itemAddress; +}