From 7a8b687a0940d95d6ebd0d6812c9219832a01877 Mon Sep 17 00:00:00 2001 From: pjt <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Tue, 9 Dec 2025 14:00:12 +0100 Subject: [PATCH 01/13] feat!: remove voucher support (#511) --- CLI.md | 90 - cli_template.md | 2 - docs/-internal-/README.md | 1 - docs/-internal-/interfaces/VoucherInfo.md | 67 - docs/README.md | 1 - docs/classes/IExec.md | 8 - docs/classes/IExecConfig.md | 26 - docs/classes/IExecModule.md | 1 - docs/classes/IExecOrderModule.md | 35 +- docs/classes/IExecVoucherModule.md | 170 - docs/globals.md | 1 - docs/interfaces/IExecConfigOptions.md | 16 - generateEsModulesFromJson.cjs | 15 - package-lock.json | 99 - package.json | 8 - src/cli/cmd/iexec-app.js | 72 +- src/cli/cmd/iexec-order.js | 5 - src/cli/cmd/iexec-voucher.js | 131 - src/cli/cmd/iexec.js | 2 - src/cli/utils/cli-helper.js | 14 - src/cli/utils/fs.js | 2 - src/common/market/order.js | 290 +- src/common/utils/config.js | 18 - src/common/utils/voucher-utils.js | 39 - src/common/voucher/subgraph/voucherInfo.js | 66 - src/common/voucher/voucher.js | 223 - src/common/voucher/voucherHub.js | 58 - src/lib/IExec.d.ts | 5 - src/lib/IExec.js | 2 - src/lib/IExecConfig.d.ts | 18 - src/lib/IExecConfig.js | 20 - src/lib/IExecOrderModule.d.ts | 39 +- src/lib/IExecOrderModule.js | 26 +- src/lib/IExecVoucherModule.d.ts | 82 - src/lib/IExecVoucherModule.js | 48 - src/lib/index.d.ts | 1 - src/lib/index.js | 1 - test/cli/cli-iexec-app.test.js | 170 - test/cli/cli-iexec-order.test.js | 117 +- test/cli/cli-iexec-voucher.test.js | 211 - test/cli/cli-test-utils.js | 2 - test/docker-compose.yml | 20 - test/jest-setup.js | 2 +- test/lib/e2e/IExecConfig.test.js | 104 - test/lib/e2e/IExecOrderModule.test.js | 3985 +++++++---------- test/lib/e2e/IExecVoucherModule.test.js | 314 -- test/lib/e2e/IExecWalletModule.test.js | 3 - test/lib/e2e/IExecWorkerpoolModule.test.js | 2 +- test/lib/e2e/voucher.test.js | 41 - test/lib/unit/config.test.js | 24 - .../prepare-bellecour-fork-for-tests.js | 202 - test/test-config-utils.js | 2 - test/test-utils.js | 185 - typedoc_template.md | 1 - 54 files changed, 1707 insertions(+), 5380 deletions(-) delete mode 100644 docs/-internal-/interfaces/VoucherInfo.md delete mode 100644 docs/classes/IExecVoucherModule.md delete mode 100644 src/cli/cmd/iexec-voucher.js delete mode 100644 src/common/utils/voucher-utils.js delete mode 100644 src/common/voucher/subgraph/voucherInfo.js delete mode 100644 src/common/voucher/voucher.js delete mode 100644 src/common/voucher/voucherHub.js delete mode 100644 src/lib/IExecVoucherModule.d.ts delete mode 100644 src/lib/IExecVoucherModule.js delete mode 100644 test/cli/cli-iexec-voucher.test.js delete mode 100644 test/lib/e2e/IExecVoucherModule.test.js delete mode 100644 test/lib/e2e/voucher.test.js diff --git a/CLI.md b/CLI.md index 35ee321a..0ef05b7d 100644 --- a/CLI.md +++ b/CLI.md @@ -302,7 +302,6 @@ Commands: - [init](#iexec-init) - [iexec wallet](#iexec-wallet) - [iexec account](#iexec-account) -- [iexec voucher](#iexec-voucher) - [iexec app](#iexec-app) - [iexec dataset](#iexec-dataset) - [iexec workerpool](#iexec-workerpool) @@ -742,89 +741,6 @@ Options: | --gas-price \ | set custom gas price for transactions (default unit wei) | | --confirms \ | set custom block count to wait for transactions confirmation (default 1 block) | -### iexec voucher - -manage iExec voucher - -Usage: - -```sh -iexec voucher [options] -``` - -Commands: - -- [show](#iexec-voucher-show) -- [authorize](#iexec-voucher-authorize) -- [revoke](#iexec-voucher-revoke) - -#### iexec voucher show - -show voucher iExec details - -Usage: - -```sh -iexec voucher show [options] -``` - -Options: - -| option | description | -| --- | --- | -| --raw | use raw output | -| --quiet | stop prompting updates | -| --password \ | password used to encrypt the wallet (unsafe) | -| --wallet-file \ | specify the name of the wallet file to use | -| --wallet-address \ | specify the address of the wallet to use | -| --keystoredir \ | specify the wallet directory \<"global"\|"local"\|custom\> | -| --chain \ | chain name from "chain.json" | -| --user \ | custom user address | - -#### iexec voucher authorize - -authorize requester to use the voucher - -Usage: - -```sh -iexec voucher authorize [options] -``` - -Options: - -| option | description | -| --- | --- | -| --raw | use raw output | -| --quiet | stop prompting updates | -| --password \ | password used to encrypt the wallet (unsafe) | -| --wallet-file \ | specify the name of the wallet file to use | -| --wallet-address \ | specify the address of the wallet to use | -| --keystoredir \ | specify the wallet directory \<"global"\|"local"\|custom\> | -| --chain \ | chain name from "chain.json" | - -#### iexec voucher revoke - -revoke authorization to use the voucher - -Usage: - -```sh -iexec voucher revoke [options] -``` - -Options: - -| option | description | -| --- | --- | -| --raw | use raw output | -| --quiet | stop prompting updates | -| --password \ | password used to encrypt the wallet (unsafe) | -| --wallet-file \ | specify the name of the wallet file to use | -| --wallet-address \ | specify the address of the wallet to use | -| --keystoredir \ | specify the wallet directory \<"global"\|"local"\|custom\> | -| --chain \ | chain name from "chain.json" | - ### iexec app manage iExec apps @@ -1078,8 +994,6 @@ Options: | --beneficiary \ | specify the beneficiary of the request (default user address) | | --params \ | specify the params of the request
\* usage: --params '{"iexec\_args":"do stuff","iexec\_input\_files":\["https://example.com/file.zip"\]}' | | --skip-preflight-check | skip preflight check, this may result in task execution fail | -| --use-voucher | use the voucher to cover the costs of matching orders | -| --voucher-address \ | specify the voucher contract to use other than the owned voucher | #### iexec app request-execution @@ -1794,8 +1708,6 @@ Options: | --request \ | specify the requestorder from the marketplace to fill | | --params \ | specify the params of the request, existing request order will be ignored
\* usage: --params '{"iexec\_args":"do stuff","iexec\_input\_files":\["https://example.com/file.zip"\]}' | | --skip-preflight-check | skip preflight check, this may result in task execution fail | -| --use-voucher | use the voucher to cover the costs of matching orders | -| --voucher-address \ | specify the voucher contract to use other than the owned voucher | #### iexec order publish @@ -2700,9 +2612,7 @@ The `chain.json` file, located in every iExec project, describes the parameters - optional key `iexecGateway` set the url of the iexec marketplace gateway used by the SDK cli on each chain (overwrite default value). - optional key `ipfsGateway` set the url of the IPFS gateway used by the SDK cli on each chain (overwrite default value). - optional key `pocoSubgraph` set the url of the PoCo subgraph used by the SDK cli on each chain (overwrite default value). - - optional key `voucherSubgraph` set the url of the voucher subgraph used by the SDK cli on each chain (overwrite default value). - optional key `bridge` set the bridge used by the SDK cli when working with bridged networks (sidechain). `bridge.contract` set the address of the RLC bridge on the chain, `bridge.bridgedChainName` set the reference to the bridged network. - - optional key `voucherHub` set the address of the voucher hub contract used by the SDK cli on each chain (overwrite default value). - optional key `native` specify whether or not the chain native token is RLC (overwrite default value: chain value or `false`). - optional key `useGas` specify whether or not the chain requires to spend gas to send a transaction (overwrite default value: chain value or `true`). - optional key `providers` set the backends for public chains diff --git a/cli_template.md b/cli_template.md index fcedaea2..21eb5bad 100644 --- a/cli_template.md +++ b/cli_template.md @@ -401,9 +401,7 @@ The `chain.json` file, located in every iExec project, describes the parameters - optional key `iexecGateway` set the url of the iexec marketplace gateway used by the SDK cli on each chain (overwrite default value). - optional key `ipfsGateway` set the url of the IPFS gateway used by the SDK cli on each chain (overwrite default value). - optional key `pocoSubgraph` set the url of the PoCo subgraph used by the SDK cli on each chain (overwrite default value). - - optional key `voucherSubgraph` set the url of the voucher subgraph used by the SDK cli on each chain (overwrite default value). - optional key `bridge` set the bridge used by the SDK cli when working with bridged networks (sidechain). `bridge.contract` set the address of the RLC bridge on the chain, `bridge.bridgedChainName` set the reference to the bridged network. - - optional key `voucherHub` set the address of the voucher hub contract used by the SDK cli on each chain (overwrite default value). - optional key `native` specify whether or not the chain native token is RLC (overwrite default value: chain value or `false`). - optional key `useGas` specify whether or not the chain requires to spend gas to send a transaction (overwrite default value: chain value or `true`). - optional key `providers` set the backends for public chains diff --git a/docs/-internal-/README.md b/docs/-internal-/README.md index 924452f6..32745657 100644 --- a/docs/-internal-/README.md +++ b/docs/-internal-/README.md @@ -50,7 +50,6 @@ - [SignedRequestorder](interfaces/SignedRequestorder.md) - [SignedWorkerpoolorder](interfaces/SignedWorkerpoolorder.md) - [Task](interfaces/Task.md) -- [VoucherInfo](interfaces/VoucherInfo.md) - [Workerpool](interfaces/Workerpool.md) - [WorkerpoolDeploymentArgs](interfaces/WorkerpoolDeploymentArgs.md) - [WorkerpoolorderTemplate](interfaces/WorkerpoolorderTemplate.md) diff --git a/docs/-internal-/interfaces/VoucherInfo.md b/docs/-internal-/interfaces/VoucherInfo.md deleted file mode 100644 index 348da80b..00000000 --- a/docs/-internal-/interfaces/VoucherInfo.md +++ /dev/null @@ -1,67 +0,0 @@ -[**iexec**](../../README.md) - -*** - -[iexec](../../globals.md) / [\](../README.md) / VoucherInfo - -# Interface: VoucherInfo - -## Properties - -### address - -> **address**: `string` - -*** - -### allowanceAmount - -> **allowanceAmount**: [`BN`](../../interfaces/BN.md) - -*** - -### authorizedAccounts - -> **authorizedAccounts**: `string`[] - -*** - -### balance - -> **balance**: [`BN`](../../interfaces/BN.md) - -*** - -### expirationTimestamp - -> **expirationTimestamp**: [`BN`](../../interfaces/BN.md) - -*** - -### owner - -> **owner**: `string` - -*** - -### sponsoredApps - -> **sponsoredApps**: `string`[] - -*** - -### sponsoredDatasets - -> **sponsoredDatasets**: `string`[] - -*** - -### sponsoredWorkerpools - -> **sponsoredWorkerpools**: `string`[] - -*** - -### type - -> **type**: [`BN`](../../interfaces/BN.md) diff --git a/docs/README.md b/docs/README.md index 402eb8df..5d6a6620 100644 --- a/docs/README.md +++ b/docs/README.md @@ -84,7 +84,6 @@ Additionally the [IExec](./classes/IExec.md) module exposes all the following li - [IExecSecretsModule](./classes/IExecSecretsModule.md) exposes **secrets** methods - [IExecStorageModule](./classes/IExecStorageModule.md) exposes **storage** methods - [IExecTaskModule](./classes/IExecTaskModule.md) exposes **task** methods -- [IExecVoucherModule](./classes/IExecVoucherModule.md) exposes **voucher** methods - [IExecWalletModule](./classes/IExecWalletModule.md) exposes **wallet** methods - [IExecWorkerpoolModule](./classes/IExecWorkerpoolModule.md) exposes **workerpool** methods diff --git a/docs/classes/IExec.md b/docs/classes/IExec.md index 94ba6e6b..ae68594e 100644 --- a/docs/classes/IExec.md +++ b/docs/classes/IExec.md @@ -156,14 +156,6 @@ task module *** -### voucher - -> **voucher**: [`IExecVoucherModule`](IExecVoucherModule.md) - -voucher module - -*** - ### wallet > **wallet**: [`IExecWalletModule`](IExecWalletModule.md) diff --git a/docs/classes/IExecConfig.md b/docs/classes/IExecConfig.md index 16e6882b..f29692bb 100644 --- a/docs/classes/IExecConfig.md +++ b/docs/classes/IExecConfig.md @@ -223,29 +223,3 @@ resolve the current SMS URL #### Returns `Promise`\<`string`\> - -*** - -### resolveVoucherHubAddress() - -> **resolveVoucherHubAddress**(): `Promise`\<`string` \| `null`\> - -resolve the current VoucherHub contract address -returns `null` if not available - -#### Returns - -`Promise`\<`string` \| `null`\> - -*** - -### resolveVoucherSubgraphURL() - -> **resolveVoucherSubgraphURL**(): `Promise`\<`string` \| `null`\> - -resolve the current voucher subgraph URL -returns `null` if not available - -#### Returns - -`Promise`\<`string` \| `null`\> diff --git a/docs/classes/IExecModule.md b/docs/classes/IExecModule.md index fe5fc1ba..77cd138e 100644 --- a/docs/classes/IExecModule.md +++ b/docs/classes/IExecModule.md @@ -24,7 +24,6 @@ module base - [`IExecSecretsModule`](IExecSecretsModule.md) - [`IExecStorageModule`](IExecStorageModule.md) - [`IExecTaskModule`](IExecTaskModule.md) -- [`IExecVoucherModule`](IExecVoucherModule.md) - [`IExecWalletModule`](IExecWalletModule.md) - [`IExecWorkerpoolModule`](IExecWorkerpoolModule.md) diff --git a/docs/classes/IExecOrderModule.md b/docs/classes/IExecOrderModule.md index b39276c4..c59735fc 100644 --- a/docs/classes/IExecOrderModule.md +++ b/docs/classes/IExecOrderModule.md @@ -520,7 +520,7 @@ default `0` ### estimateMatchOrders() -> **estimateMatchOrders**(`orders`, `options?`): `Promise`\<\{ `sponsored`: [`BN`](../interfaces/BN.md); `total`: [`BN`](../interfaces/BN.md); `volume`: [`BN`](../interfaces/BN.md); \}\> +> **estimateMatchOrders**(`orders`): `Promise`\<\{ `sponsored`: [`BN`](../interfaces/BN.md); `total`: [`BN`](../interfaces/BN.md); `volume`: [`BN`](../interfaces/BN.md); \}\> estimates the cost of matching the provided orders @@ -532,10 +532,9 @@ const orders = { workerpoolorder, requestorder, }; -const result = await estimateMatchOrders(orders, {useVoucher: true}); +const result = await estimateMatchOrders(orders); console.log(`executable volume: ${result.volume} tasks`); console.log(`total cost for matching orders: ${result.total} nRLC`); -console.log(`sponsored cost covered by voucher: ${result.sponsored} nRLC`); ``` #### Parameters @@ -558,22 +557,6 @@ console.log(`sponsored cost covered by voucher: ${result.sponsored} nRLC`); [`ConsumableWorkerpoolorder`](../-internal-/interfaces/ConsumableWorkerpoolorder.md) -##### options? - -###### useVoucher? - -`boolean` - -use a voucher contract to sponsor the deal - -###### voucherAddress? - -`string` - -override the voucher contract to use, must be combined with `useVoucher: true` - -the user must be authorized by the voucher's owner to use it - #### Returns `Promise`\<\{ `sponsored`: [`BN`](../interfaces/BN.md); `total`: [`BN`](../interfaces/BN.md); `volume`: [`BN`](../interfaces/BN.md); \}\> @@ -721,20 +704,6 @@ console.log(`created deal ${dealid} in tx ${txHash}`); `boolean` -###### useVoucher? - -`boolean` - -use a voucher contract to sponsor the deal - -###### voucherAddress? - -`string` - -override the voucher contract to use, must be combined with `useVoucher: true` - -the user must be authorized by the voucher's owner to use it - #### Returns `Promise`\<\{ `dealid`: `string`; `txHash`: `string`; `volume`: [`BN`](../interfaces/BN.md); \}\> diff --git a/docs/classes/IExecVoucherModule.md b/docs/classes/IExecVoucherModule.md deleted file mode 100644 index 816c996a..00000000 --- a/docs/classes/IExecVoucherModule.md +++ /dev/null @@ -1,170 +0,0 @@ -[**iexec**](../README.md) - -*** - -[iexec](../globals.md) / IExecVoucherModule - -# Class: IExecVoucherModule - -module exposing voucher methods - -## Extends - -- [`IExecModule`](IExecModule.md) - -## Constructors - -### Constructor - -> **new IExecVoucherModule**(`configOrArgs`, `options?`): `IExecVoucherModule` - -Create an IExecModule instance - -#### Parameters - -##### configOrArgs - -[`IExecConfigArgs`](../interfaces/IExecConfigArgs.md) | [`IExecConfig`](IExecConfig.md) - -##### options? - -[`IExecConfigOptions`](../interfaces/IExecConfigOptions.md) - -#### Returns - -`IExecVoucherModule` - -#### Inherited from - -[`IExecModule`](IExecModule.md).[`constructor`](IExecModule.md#constructor) - -## Properties - -### config - -> **config**: [`IExecConfig`](IExecConfig.md) - -current IExecConfig - -#### Inherited from - -[`IExecModule`](IExecModule.md).[`config`](IExecModule.md#config) - -## Methods - -### authorizeRequester() - -> **authorizeRequester**(`requester`): `Promise`\<`string`\> - -**SIGNER REQUIRED** - -authorize a requester to use the voucher - -example: -```js -const txHash = await authorizeRequester(requesterAddress); -console.log('tx:', txHash); -``` - -#### Parameters - -##### requester - -`string` - -#### Returns - -`Promise`\<`string`\> - -*** - -### getVoucherAddress() - -> **getVoucherAddress**(`owner`): `Promise`\<`string` \| `null`\> - -returns the address of the voucher contract for the specified address if the address owns a voucher - -example: -```js -const voucherAddress = await getVoucherAddress(ownerAddress); -console.log('voucher contract address:', voucherAddress); -``` - -#### Parameters - -##### owner - -`string` - -#### Returns - -`Promise`\<`string` \| `null`\> - -*** - -### revokeRequesterAuthorization() - -> **revokeRequesterAuthorization**(`requester`): `Promise`\<`string`\> - -#### Parameters - -##### requester - -`string` - -#### Returns - -`Promise`\<`string`\> - -*** - -### showUserVoucher() - -> **showUserVoucher**(`owner`): `Promise`\<[`VoucherInfo`](../-internal-/interfaces/VoucherInfo.md)\> - -returns the user voucher information - -example: -```js -const userVoucher = await showUserVoucher(userAddress); -console.log('address:', userVoucher.address); -console.log('balance:', userVoucher.balance); -console.log('expiration:', userVoucher.expirationTimestamp); -console.log('sponsored apps:', userVoucher.sponsoredApps); -console.log('sponsored datasets:', userVoucher.sponsoredDatasets); -console.log('sponsored workerpools:', userVoucher.sponsoredWorkerpools); -console.log('allowance on user account:', userVoucher.allowanceAmount); -console.log('authorized accounts:', userVoucher.authorizedAccounts); -``` - -#### Parameters - -##### owner - -`string` - -#### Returns - -`Promise`\<[`VoucherInfo`](../-internal-/interfaces/VoucherInfo.md)\> - -*** - -### fromConfig() - -> `static` **fromConfig**(`config`): `IExecVoucherModule` - -Create an IExecVoucherModule instance using an IExecConfig instance - -#### Parameters - -##### config - -[`IExecConfig`](IExecConfig.md) - -#### Returns - -`IExecVoucherModule` - -#### Overrides - -[`IExecModule`](IExecModule.md).[`fromConfig`](IExecModule.md#fromconfig) diff --git a/docs/globals.md b/docs/globals.md index a281c50e..7cfc9cb1 100644 --- a/docs/globals.md +++ b/docs/globals.md @@ -33,7 +33,6 @@ - [IExecSecretsModule](classes/IExecSecretsModule.md) - [IExecStorageModule](classes/IExecStorageModule.md) - [IExecTaskModule](classes/IExecTaskModule.md) -- [IExecVoucherModule](classes/IExecVoucherModule.md) - [IExecWalletModule](classes/IExecWalletModule.md) - [IExecWorkerpoolModule](classes/IExecWorkerpoolModule.md) - [Observable](classes/Observable.md) diff --git a/docs/interfaces/IExecConfigOptions.md b/docs/interfaces/IExecConfigOptions.md index 5335dfcb..2b40c890 100644 --- a/docs/interfaces/IExecConfigOptions.md +++ b/docs/interfaces/IExecConfigOptions.md @@ -169,19 +169,3 @@ override the SMS URL to target a custom instance > `optional` **useGas**: `boolean` if false set the gasPrice to 0 (default true) - -*** - -### voucherHubAddress? - -> `optional` **voucherHubAddress**: `string` - -override the VoucherHub contract address to target a custom instance - -*** - -### voucherSubgraphURL? - -> `optional` **voucherSubgraphURL**: `string` - -override the voucher subgraph URL to target a custom instance diff --git a/generateEsModulesFromJson.cjs b/generateEsModulesFromJson.cjs index 2574294d..de3b0b70 100644 --- a/generateEsModulesFromJson.cjs +++ b/generateEsModulesFromJson.cjs @@ -63,21 +63,6 @@ const sources = [ '@iexec/poco/artifacts/contracts/registries/datasets/Dataset.sol/Dataset.json', { dir: '@iexec/poco', minifier: minifiers.abi }, ], - [ - '@iexec/voucher-contracts/artifacts/contracts/beacon/Voucher.sol/Voucher.json', - { dir: '@iexec/voucher-contracts', minifier: minifiers.abi }, - ], - [ - '@iexec/voucher-contracts/artifacts/contracts/VoucherHub.sol/VoucherHub.json', - { dir: '@iexec/voucher-contracts', minifier: minifiers.abi }, - ], - [ - '@iexec/voucher-contracts/deployments/bellecour/VoucherHubERC1967Proxy.json', - { - dir: '@iexec/voucher-contracts/deployments/bellecour', - minifier: minifiers.hardhatDeployment, - }, - ], [ '@ensdomains/ens-contracts/artifacts/contracts/registry/ENSRegistry.sol/ENSRegistry.json', { dir: '@ensdomains/registry', minifier: minifiers.abi }, diff --git a/package-lock.json b/package-lock.json index 451b8992..035da014 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,7 +39,6 @@ "@ensdomains/ens-contracts": "^1.2.5", "@eslint/js": "^9.23.0", "@iexec/poco": "^6.1.0", - "@iexec/voucher-contracts": "^1.0.1", "eslint": "^9.23.0", "eslint-config-prettier": "^10.1.1", "eslint-plugin-import": "^2.32.0", @@ -947,48 +946,6 @@ "integrity": "sha512-bUOmkSoPkjnUyMiKo6RYnb0VHBk5D9KKDAgNLzF41aqAM3TeE0yGdFF5dVRcV60pZdJLlyFT/jjXIZCWyyEzAQ==", "dev": true }, - "node_modules/@iexec/voucher-contracts": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@iexec/voucher-contracts/-/voucher-contracts-1.0.1.tgz", - "integrity": "sha512-nHku8/Rv8uxZYLdpe9hbk0zIr0tJRgEXjFMemb9CFXZ9ej8tXIff8NtmhkaXfxMnvfX4p/hygytd31ITelXHvA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@iexec/poco": "^5.5.0", - "@openzeppelin/contracts-upgradeable": "^5.0.2" - } - }, - "node_modules/@iexec/voucher-contracts/node_modules/@iexec/poco": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@iexec/poco/-/poco-5.5.0.tgz", - "integrity": "sha512-F2Jlhhc4CuTM2nghFQVjK+HGkasvX0OApyPGCB5VDm8XizfHPliw4rL9ABnrVcSl4XXc2FQaoWQfo9T6KpRNLQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@iexec/interface": "3.0.35-8", - "@iexec/solidity": "^0.1.1", - "@openzeppelin/contracts": "3.3.0", - "@openzeppelin/contracts-v5": "npm:@openzeppelin/contracts@^5.0.2", - "@uniswap/v2-periphery": "1.1.0-beta.0", - "rlc-faucet-contract": "1.0.10" - } - }, - "node_modules/@iexec/voucher-contracts/node_modules/@iexec/poco/node_modules/@openzeppelin/contracts": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.3.0.tgz", - "integrity": "sha512-AemZEsQYtUp1WRkcmZm1div5ORfTpLquLaziCIrSagjxyKdmObxuaY1yjQ5SHFMctR8rLwp706NXTbiIRJg7pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@iexec/voucher-contracts/node_modules/@openzeppelin/contracts-upgradeable": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.0.2.tgz", - "integrity": "sha512-0MmkHSHiW2NRFiT9/r5Lu4eJq5UJ4/tzlOgYXNAIj/ONkQTVnz22pLxDvp4C4uZ9he7ZFvGn3Driptn1/iU7tQ==", - "dev": true, - "peerDependencies": { - "@openzeppelin/contracts": "5.0.2" - } - }, "node_modules/@inquirer/ansi": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.2.tgz", @@ -2171,14 +2128,6 @@ "node": ">= 8" } }, - "node_modules/@openzeppelin/contracts": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.0.2.tgz", - "integrity": "sha512-ytPc6eLGcHHnapAZ9S+5qsdomhjo6QBHTDRRBFfTxXIpsicMhVPouPgmUPebZZZGX7vt9USA+Z+0M0dSVtSUEA==", - "dev": true, - "license": "MIT", - "peer": true - }, "node_modules/@openzeppelin/contracts-v5": { "name": "@openzeppelin/contracts", "version": "5.1.0", @@ -9676,47 +9625,6 @@ } } }, - "@iexec/voucher-contracts": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@iexec/voucher-contracts/-/voucher-contracts-1.0.1.tgz", - "integrity": "sha512-nHku8/Rv8uxZYLdpe9hbk0zIr0tJRgEXjFMemb9CFXZ9ej8tXIff8NtmhkaXfxMnvfX4p/hygytd31ITelXHvA==", - "dev": true, - "requires": { - "@iexec/poco": "^5.5.0", - "@openzeppelin/contracts-upgradeable": "^5.0.2" - }, - "dependencies": { - "@iexec/poco": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@iexec/poco/-/poco-5.5.0.tgz", - "integrity": "sha512-F2Jlhhc4CuTM2nghFQVjK+HGkasvX0OApyPGCB5VDm8XizfHPliw4rL9ABnrVcSl4XXc2FQaoWQfo9T6KpRNLQ==", - "dev": true, - "requires": { - "@iexec/interface": "3.0.35-8", - "@iexec/solidity": "^0.1.1", - "@openzeppelin/contracts": "3.3.0", - "@openzeppelin/contracts-v5": "npm:@openzeppelin/contracts@^5.0.2", - "@uniswap/v2-periphery": "1.1.0-beta.0", - "rlc-faucet-contract": "1.0.10" - }, - "dependencies": { - "@openzeppelin/contracts": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.3.0.tgz", - "integrity": "sha512-AemZEsQYtUp1WRkcmZm1div5ORfTpLquLaziCIrSagjxyKdmObxuaY1yjQ5SHFMctR8rLwp706NXTbiIRJg7pw==", - "dev": true - } - } - }, - "@openzeppelin/contracts-upgradeable": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.0.2.tgz", - "integrity": "sha512-0MmkHSHiW2NRFiT9/r5Lu4eJq5UJ4/tzlOgYXNAIj/ONkQTVnz22pLxDvp4C4uZ9he7ZFvGn3Driptn1/iU7tQ==", - "dev": true, - "requires": {} - } - } - }, "@inquirer/ansi": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.2.tgz", @@ -10561,13 +10469,6 @@ "fastq": "^1.6.0" } }, - "@openzeppelin/contracts": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.0.2.tgz", - "integrity": "sha512-ytPc6eLGcHHnapAZ9S+5qsdomhjo6QBHTDRRBFfTxXIpsicMhVPouPgmUPebZZZGX7vt9USA+Z+0M0dSVtSUEA==", - "dev": true, - "peer": true - }, "@openzeppelin/contracts-v5": { "version": "npm:@openzeppelin/contracts@5.1.0", "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.1.0.tgz", diff --git a/package.json b/package.json index 74a3797e..52f9c0a2 100644 --- a/package.json +++ b/package.json @@ -111,12 +111,6 @@ "browser": "./dist/esm/lib/IExecTaskModule.js", "default": "./dist/esm/lib/IExecTaskModule.js" }, - "./IExecVoucherModule": { - "types": "./dist/esm/lib/IExecVoucherModule.d.ts", - "import": "./dist/esm/lib/IExecVoucherModule.js", - "browser": "./dist/esm/lib/IExecVoucherModule.js", - "default": "./dist/esm/lib/IExecVoucherModule.js" - }, "./IExecWalletModule": { "types": "./dist/esm/lib/IExecWalletModule.d.ts", "import": "./dist/esm/lib/IExecWalletModule.js", @@ -182,7 +176,6 @@ "IExecSecretsModule", "IExecStorageModule", "IExecTaskModule", - "IExecVoucherModule", "IExecWalletModule", "IExecWorkerpoolModule", "errors", @@ -226,7 +219,6 @@ "@ensdomains/ens-contracts": "^1.2.5", "@eslint/js": "^9.23.0", "@iexec/poco": "^6.1.0", - "@iexec/voucher-contracts": "^1.0.1", "eslint": "^9.23.0", "eslint-config-prettier": "^10.1.1", "eslint-plugin-import": "^2.32.0", diff --git a/src/cli/cmd/iexec-app.js b/src/cli/cmd/iexec-app.js index 7b166735..71b675ce 100644 --- a/src/cli/cmd/iexec-app.js +++ b/src/cli/cmd/iexec-app.js @@ -589,8 +589,6 @@ run .option(...orderOption.beneficiary()) .option(...orderOption.params()) .option(...option.skipPreflightCheck()) - .option(...option.useVoucher()) - .option(...option.voucherAddress()) .description(desc.appRun()) .action(async (appAddress, opts) => { await checkUpdate(opts); @@ -1048,64 +1046,60 @@ run debug('requestorder', requestorder); - const { total: totalCost, sponsored } = await estimateMatchOrders({ + const { total: totalCost } = await estimateMatchOrders({ contracts: chain.contracts, - voucherHubAddress: chain.voucherHub, apporder, datasetorder, workerpoolorder, requestorder, - useVoucher: opts.useVoucher, - voucherAddress: opts.voucherAddress, }); spinner.stop(); if (!opts.force) { await prompt.custom( - `Do you want to spend ${formatRLC(totalCost)} nRLC ${ - sponsored > 0 ? `(${sponsored} nRLC sponsored by the voucher)` : '' - } to execute the following request: ${pretty({ - app: `${requestorder.app} (${formatRLC( - requestorder.appmaxprice, - )} RLC)`, - dataset: - requestorder.dataset !== NULL_ADDRESS - ? `${requestorder.dataset} (${formatRLC( - requestorder.datasetmaxprice, - )} RLC)` - : undefined, - workerpool: `${requestorder.workerpool} (${formatRLC( - requestorder.workerpoolmaxprice, - )} RLC)`, - params: - (requestorder.params && JSON.parse(requestorder.params)) || - undefined, - category: requestorder.category, - tag: - requestorder.tag !== NULL_BYTES32 ? requestorder.tag : undefined, - callback: - requestorder.callback !== NULL_ADDRESS - ? requestorder.callback - : undefined, - beneficiary: - requestorder.beneficiary !== requestorder.requester - ? requestorder.beneficiary - : undefined, - })}`, + `Do you want to spend ${formatRLC(totalCost)} nRLC to execute the following request: ${pretty( + { + app: `${requestorder.app} (${formatRLC( + requestorder.appmaxprice, + )} RLC)`, + dataset: + requestorder.dataset !== NULL_ADDRESS + ? `${requestorder.dataset} (${formatRLC( + requestorder.datasetmaxprice, + )} RLC)` + : undefined, + workerpool: `${requestorder.workerpool} (${formatRLC( + requestorder.workerpoolmaxprice, + )} RLC)`, + params: + (requestorder.params && JSON.parse(requestorder.params)) || + undefined, + category: requestorder.category, + tag: + requestorder.tag !== NULL_BYTES32 + ? requestorder.tag + : undefined, + callback: + requestorder.callback !== NULL_ADDRESS + ? requestorder.callback + : undefined, + beneficiary: + requestorder.beneficiary !== requestorder.requester + ? requestorder.beneficiary + : undefined, + }, + )}`, ); } spinner.start('Submitting deal'); const { dealid, volume, txHash } = await matchOrders({ contracts: chain.contracts, - voucherHubAddress: chain.voucherHub, apporder, datasetorder, workerpoolorder, requestorder, - useVoucher: opts.useVoucher, - voucherAddress: opts.voucherAddress, }); result.deals.push({ dealid, volume: volume.toString(), txHash }); diff --git a/src/cli/cmd/iexec-order.js b/src/cli/cmd/iexec-order.js index e41df8e6..4e9c58f8 100644 --- a/src/cli/cmd/iexec-order.js +++ b/src/cli/cmd/iexec-order.js @@ -418,8 +418,6 @@ fill .option(...option.fillRequestOrder()) .option(...option.fillRequestParams()) .option(...option.skipPreflightCheck()) - .option(...option.useVoucher()) - .option(...option.voucherAddress()) .description(desc.fill(objName)) .action(async (opts) => { await checkUpdate(opts); @@ -589,13 +587,10 @@ fill spinner.start(info.filling(objName)); const { dealid, volume, txHash } = await matchOrders({ contracts: chain.contracts, - voucherHubAddress: chain.voucherHub, apporder, datasetorder: useDataset ? datasetorder : undefined, workerpoolorder, requestorder, - useVoucher: opts.useVoucher, - voucherAddress: opts.voucherAddress, }); spinner.succeed( `${volume} task successfully purchased with dealid ${dealid}`, diff --git a/src/cli/cmd/iexec-voucher.js b/src/cli/cmd/iexec-voucher.js deleted file mode 100644 index 5c562649..00000000 --- a/src/cli/cmd/iexec-voucher.js +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env node - -import { program as cli } from 'commander'; -import { Keystore } from '../utils/keystore.js'; -import { connectKeystore, loadChain } from '../utils/chains.js'; -import { - finalizeCli, - addGlobalOptions, - addWalletLoadOptions, - computeWalletLoadOptions, - checkUpdate, - handleError, - option, - desc, - Spinner, - info, - pretty, - computeTxOptions, -} from '../utils/cli-helper.js'; -import { - authorizeRequester, - revokeRequesterAuthorization, - showUserVoucher, -} from '../../common/voucher/voucher.js'; - -const objName = 'voucher'; - -cli.name('iexec voucher').usage(' [options]'); - -const show = cli.command('show'); -addGlobalOptions(show); -addWalletLoadOptions(show); -show - .option(...option.chain()) - .option(...option.user()) - .description(desc.showObj('iExec', objName)) - .action(async (opts) => { - await checkUpdate(opts); - const spinner = Spinner(opts); - try { - const walletOptions = computeWalletLoadOptions(opts); - const keystore = Keystore({ ...walletOptions, isSigner: false }); - const [chain, [address]] = await Promise.all([ - loadChain(opts.chain, { spinner }), - keystore.accounts(), - ]); - const owner = opts.user || address; - spinner.start(info.checking('Voucher details')); - const voucherDetails = await showUserVoucher( - chain.contracts, - chain.voucherSubgraph, - chain.voucherHub, - owner, - ); - const prettyDetails = pretty({ - type: voucherDetails.type.toString(), - balance: voucherDetails.balance.toString(), - expirationTimestamp: voucherDetails.expirationTimestamp.toString(), - allowanceAmount: voucherDetails.allowanceAmount.toString(), - address: voucherDetails.address, - }); - spinner.succeed(`Voucher details: ${prettyDetails}`, { - raw: voucherDetails, - }); - } catch (error) { - handleError(error, cli, opts); - } - }); - -const authorize = cli.command('authorize '); -addGlobalOptions(authorize); -addWalletLoadOptions(authorize); -authorize - .option(...option.chain()) - .description(desc.authorize()) - .action(async (requester, opts) => { - await checkUpdate(opts); - const spinner = Spinner(opts); - try { - const walletOptions = computeWalletLoadOptions(opts); - const txOptions = await computeTxOptions(opts); - const keystore = Keystore(walletOptions); - const chain = await loadChain(opts.chain, { txOptions, spinner }); - await connectKeystore(chain, keystore, { txOptions }); - spinner.start(info.authorizing(requester)); - - const txHash = await authorizeRequester( - chain.contracts, - chain.voucherHub, - requester, - ); - spinner.succeed(info.authorized(requester), { - raw: { txHash }, - }); - } catch (error) { - handleError(error, cli, opts); - } - }); - -const revoke = cli.command('revoke '); -addGlobalOptions(revoke); -addWalletLoadOptions(revoke); -revoke - .option(...option.chain()) - .description(desc.revokeVoucherAuthorization()) - .action(async (requester, opts) => { - await checkUpdate(opts); - const spinner = Spinner(opts); - try { - const walletOptions = computeWalletLoadOptions(opts); - const txOptions = await computeTxOptions(opts); - const keystore = Keystore(walletOptions); - const chain = await loadChain(opts.chain, { txOptions, spinner }); - await connectKeystore(chain, keystore, { txOptions }); - spinner.start(info.revokingVoucherAuthorization()); - - const txHash = await revokeRequesterAuthorization( - chain.contracts, - chain.voucherHub, - requester, - ); - - spinner.succeed(info.revokedVoucherAuthorization(requester), { - raw: { txHash }, - }); - } catch (error) { - handleError(error, cli, opts); - } - }); - -finalizeCli(cli); diff --git a/src/cli/cmd/iexec.js b/src/cli/cmd/iexec.js index 41226536..5e1fb58b 100755 --- a/src/cli/cmd/iexec.js +++ b/src/cli/cmd/iexec.js @@ -85,8 +85,6 @@ cli.command('wallet', 'manage local ethereum wallet'); cli.command('account', 'manage iExec account'); -cli.command('voucher', 'manage iExec voucher'); - cli.command('app', 'manage iExec apps'); cli.command('dataset', 'manage iExec datasets'); diff --git a/src/cli/utils/cli-helper.js b/src/cli/utils/cli-helper.js index ffb056ee..8a98ad8c 100644 --- a/src/cli/utils/cli-helper.js +++ b/src/cli/utils/cli-helper.js @@ -79,18 +79,14 @@ export const info = { depositing: () => 'Making deposit...', approving: () => 'Making approve...', revoking: (spender) => `Revoking allowance for spender address ${spender}...`, - revokingVoucherAuthorization: () => `Revoking voucher authorization...`, checkingSwapRate: () => 'Checking swap rate...', claiming: (obj) => `Claiming ${obj}...`, deposited: (amount) => `Deposited ${amount} RLC to your iExec account`, withdrawing: () => 'Making withdraw...', - authorizing: (requester) => `Authorizing ${requester} to use the voucher...`, approved: (amount, spender, unit) => `Approved ${spender} to spend ${amount} ${unit} from your iExec account`, authorized: (requester) => `Requester ${requester} authorized successfully`, revoked: (spender) => `Revoked ${spender} to use your iExec account`, - revokedVoucherAuthorization: (requester) => - `Revoked ${requester} to use the voucher`, checkingAllowance: (spender, user) => `Checking allowance for ${spender} on user's account ${user}...`, allowance: (spender, user, amount) => @@ -132,8 +128,6 @@ export const desc = { claimObj: (objName) => `claim a ${objName} that is not COMPLETED`, deposit: () => 'deposit RLC onto your iExec account (default unit nRLC)', withdraw: () => 'withdraw RLC from your iExec account (default unit nRLC)', - authorize: () => 'authorize requester to use the voucher', - revokeVoucherAuthorization: () => 'revoke authorization to use the voucher', approve: () => 'approve spender to spend up to amount of RLC from your iExec account (default unit nRLC)', allowance: () => @@ -397,14 +391,6 @@ export const option = { '--requester-strict', 'fetch orders created strictly for the specified requester', ], - useVoucher: () => [ - '--use-voucher', - 'use the voucher to cover the costs of matching orders', - ], - voucherAddress: () => [ - '--voucher-address ', - 'specify the voucher contract to use other than the owned voucher', - ], }; export const optionCreator = { diff --git a/src/cli/utils/fs.js b/src/cli/utils/fs.js index 14528db1..a59f2659 100644 --- a/src/cli/utils/fs.js +++ b/src/cli/utils/fs.js @@ -28,14 +28,12 @@ const chainConfSchema = () => hub: string(), // todo address ensRegistry: string(), // TODO: DEPRECATED not used anymore ensPublicResolver: string(), // todo address - voucherHub: string(), // todo address sms: smsUrlOrMapSchema(), resultProxy: string(), ipfsGateway: string(), iexecGateway: string(), compass: string(), pocoSubgraph: string(), - voucherSubgraph: string(), native: boolean(), useGas: boolean().default(true), defaultTeeFramework: teeFrameworkSchema(), diff --git a/src/common/market/order.js b/src/common/market/order.js index ca8d92fd..f8e4b8c2 100644 --- a/src/common/market/order.js +++ b/src/common/market/order.js @@ -53,7 +53,6 @@ import { uint256Schema, nRlcAmountSchema, throwIfMissing, - booleanSchema, } from '../utils/validator.js'; import { wrapCall, @@ -61,13 +60,6 @@ import { wrapWait, wrapSignTypedData, } from '../utils/errorWrappers.js'; -import { getVoucherHubContract } from '../utils/voucher-utils.js'; -import { checkAllowance } from '../account/allowance.js'; -import { fetchVoucherContract } from '../voucher/voucher.js'; -import { - CHAIN_SPECIFIC_FEATURES, - checkImplementedOnChain, -} from '../utils/config.js'; const debug = Debug('iexec:market:order'); @@ -209,32 +201,6 @@ const getMatchOrdersTotalCost = ( bnAppPrice.add(bnDatasetPrice).add(bnWorkerpoolPrice), ); }; -const getMatchOrdersSponsoredCostWithVoucher = ( - appOrder, - datasetOrder, - workerpoolOrder, - matchableVolume, - balance, - isAppEligibleToMatchOrdersSponsoring, - isDatasetEligibleToMatchOrdersSponsoring, - isWorkerpoolEligibleToMatchOrdersSponsoring, -) => { - const sponsoredAppPrice = isAppEligibleToMatchOrdersSponsoring - ? appOrder.appprice - : 0; - const sponsoredDatasetPrice = isDatasetEligibleToMatchOrdersSponsoring - ? datasetOrder.datasetprice - : 0; - const sponsoredWorkerpoolPrice = isWorkerpoolEligibleToMatchOrdersSponsoring - ? workerpoolOrder.workerpoolprice - : 0; - const sponsoredAmount = new BN(matchableVolume).mul( - new BN(sponsoredAppPrice) - .add(new BN(sponsoredDatasetPrice)) - .add(new BN(sponsoredWorkerpoolPrice)), - ); - return BN.min(sponsoredAmount, new BN(balance)); -}; export const computeOrderHash = async ( contracts = throwIfMissing(), @@ -793,43 +759,27 @@ const getMatchableVolume = async ( export const estimateMatchOrders = async ({ contracts = throwIfMissing(), - voucherHubAddress, apporder, datasetorder = NULL_DATASETORDER, workerpoolorder, requestorder, - useVoucher = false, - voucherAddress, }) => { - const [ - vAppOrder, - vDatasetOrder, - vWorkerpoolOrder, - vRequestOrder, - vUseVoucher, - vVoucherAddress, - ] = await Promise.all([ - signedApporderSchema().required().label('apporder').validate(apporder), - signedDatasetorderSchema() - .required() - .label('datasetorder') - .validate(datasetorder), - signedWorkerpoolorderSchema() - .required() - .label('workerpoolorder') - .validate(workerpoolorder), - signedRequestorderSchema() - .required() - .label('requestorder') - .validate(requestorder), - booleanSchema().required().label('useVoucher').validate(useVoucher), - addressSchema({ ethProvider: contracts.provider }) - .label('voucherAddress') - .validate(voucherAddress), - ]); - if (vUseVoucher) { - checkImplementedOnChain(contracts.chainId, CHAIN_SPECIFIC_FEATURES.VOUCHER); - } + const [vAppOrder, vDatasetOrder, vWorkerpoolOrder, vRequestOrder] = + await Promise.all([ + signedApporderSchema().required().label('apporder').validate(apporder), + signedDatasetorderSchema() + .required() + .label('datasetorder') + .validate(datasetorder), + signedWorkerpoolorderSchema() + .required() + .label('workerpoolorder') + .validate(workerpoolorder), + signedRequestorderSchema() + .required() + .label('requestorder') + .validate(requestorder), + ]); const matchableVolume = await getMatchableVolume( contracts, vAppOrder, @@ -843,119 +793,37 @@ export const estimateMatchOrders = async ({ vDatasetOrder.datasetprice, vWorkerpoolOrder.workerpoolprice, ); - let sponsoredCost = new BN(0); - if (vUseVoucher) { - const voucherContract = await fetchVoucherContract( - contracts, - voucherHubAddress, - await getAddress(contracts), - { voucherAddress: vVoucherAddress }, - ); - if (!voucherContract) { - return { total: totalCost, sponsored: sponsoredCost }; - } - const voucherExpiration = await wrapCall(voucherContract.getExpiration()); - const now = Math.floor(Date.now() / 1000); - if (voucherExpiration <= now) { - return { total: totalCost, sponsored: sponsoredCost }; - } - const [balance, voucherTypeId] = await Promise.all([ - wrapCall(voucherContract.getBalance()), - wrapCall(voucherContract.getType()), - ]); - const voucherHubContract = getVoucherHubContract( - contracts, - voucherHubAddress, - ); - - const [ - isAppEligibleToMatchOrdersSponsoring, - isDatasetEligibleToMatchOrdersSponsoring, - isWorkerpoolEligibleToMatchOrdersSponsoring, - ] = await Promise.all([ - wrapCall( - voucherHubContract.isAssetEligibleToMatchOrdersSponsoring( - voucherTypeId, - apporder.app, - ), - ), - wrapCall( - voucherHubContract.isAssetEligibleToMatchOrdersSponsoring( - voucherTypeId, - datasetorder.dataset, - ), - ), - wrapCall( - voucherHubContract.isAssetEligibleToMatchOrdersSponsoring( - voucherTypeId, - workerpoolorder.workerpool, - ), - ), - ]); - - sponsoredCost = getMatchOrdersSponsoredCostWithVoucher( - vAppOrder, - vDatasetOrder, - vWorkerpoolOrder, - matchableVolume, - balance, - isAppEligibleToMatchOrdersSponsoring, - isDatasetEligibleToMatchOrdersSponsoring, - isWorkerpoolEligibleToMatchOrdersSponsoring, - ); - } - return { volume: matchableVolume, total: totalCost, - sponsored: sponsoredCost, }; }; export const matchOrders = async ({ contracts = throwIfMissing(), - voucherHubAddress, apporder, datasetorder = NULL_DATASETORDER, workerpoolorder, requestorder, - useVoucher = false, - voucherAddress, }) => { try { checkSigner(contracts); - const [ - vAppOrder, - vDatasetOrder, - vWorkerpoolOrder, - vRequestOrder, - vUseVoucher, - vVoucherAddress, - ] = await Promise.all([ - signedApporderSchema().required().label('apporder').validate(apporder), - signedDatasetorderSchema() - .required() - .label('datasetorder') - .validate(datasetorder), - signedWorkerpoolorderSchema() - .required() - .label('workerpoolorder') - .validate(workerpoolorder), - signedRequestorderSchema() - .required() - .label('requestorder') - .validate(requestorder), - booleanSchema().required().label('useVoucher').validate(useVoucher), - addressSchema({ ethProvider: contracts.provider }) - .label('voucherAddress') - .validate(voucherAddress), - ]); - if (vUseVoucher) { - checkImplementedOnChain( - contracts.chainId, - CHAIN_SPECIFIC_FEATURES.VOUCHER, - ); - } + const [vAppOrder, vDatasetOrder, vWorkerpoolOrder, vRequestOrder] = + await Promise.all([ + signedApporderSchema().required().label('apporder').validate(apporder), + signedDatasetorderSchema() + .required() + .label('datasetorder') + .validate(datasetorder), + signedWorkerpoolorderSchema() + .required() + .label('workerpoolorder') + .validate(workerpoolorder), + signedRequestorderSchema() + .required() + .label('requestorder') + .validate(requestorder), + ]); // check resulting tag await tagSchema() @@ -985,63 +853,20 @@ export const matchOrders = async ({ const appPrice = new BN(vAppOrder.appprice); const datasetPrice = new BN(vDatasetOrder.datasetprice); - // resolve voucher contract address if used - let voucherContract; - if (vUseVoucher) { - voucherContract = await fetchVoucherContract( - contracts, - voucherHubAddress, - await getAddress(contracts), - { voucherAddress: vVoucherAddress }, - ); - if (!voucherContract) { - throw new Error( - `No voucher available for the requester ${vRequestOrder.requester}`, - ); - } - } - // account stake check const checkRequesterSolvabilityAsync = async () => { const costPerTask = appPrice.add(datasetPrice).add(workerpoolPrice); const totalCost = costPerTask.mul(matchableVolume); const { stake } = await checkBalance(contracts, vRequestOrder.requester); - if (vUseVoucher) { - const { total, sponsored } = await estimateMatchOrders({ - contracts, - voucherHubAddress, - apporder: vAppOrder, - datasetorder: vDatasetOrder, - workerpoolorder: vWorkerpoolOrder, - requestorder: vRequestOrder, - useVoucher: vUseVoucher, - voucherAddress: vVoucherAddress, - }); - if (total.gt(sponsored)) { - const allowance = await checkAllowance( - contracts, - vRequestOrder.requester, - await voucherContract.getAddress(), - ); - const requiredAllowance = total.sub(sponsored); - if (allowance.lt(requiredAllowance)) { - const missingAmount = requiredAllowance.sub(allowance); - throw new Error( - `Orders can't be matched. Please approve an additional ${missingAmount} for voucher usage.`, - ); - } - } - } else { - if (stake.lt(costPerTask)) { - throw new Error( - `Cost per task (${costPerTask}) is greater than requester account stake (${stake}). Orders can't be matched. If you are the requester, you should deposit to top up your account`, - ); - } - if (stake.lt(totalCost)) { - throw new Error( - `Total cost for ${matchableVolume} tasks (${totalCost}) is greater than requester account stake (${stake}). Orders can't be matched. If you are the requester, you should deposit to top up your account or reduce your requestorder volume`, - ); - } + if (stake.lt(costPerTask)) { + throw new Error( + `Cost per task (${costPerTask}) is greater than requester account stake (${stake}). Orders can't be matched. If you are the requester, you should deposit to top up your account`, + ); + } + if (stake.lt(totalCost)) { + throw new Error( + `Total cost for ${matchableVolume} tasks (${totalCost}) is greater than requester account stake (${stake}). Orders can't be matched. If you are the requester, you should deposit to top up your account or reduce your requestorder volume`, + ); } }; @@ -1060,31 +885,16 @@ export const matchOrders = async ({ REQUEST_ORDER, vRequestOrder, ); - - let tx; const iexecContract = contracts.getIExecContract(); - if (vUseVoucher) { - tx = await wrapSend( - voucherContract - .connect(contracts.signer) - .matchOrders( - appOrderStruct, - datasetOrderStruct, - workerpoolOrderStruct, - requestOrderStruct, - ), - ); - } else { - tx = await wrapSend( - iexecContract.matchOrders( - appOrderStruct, - datasetOrderStruct, - workerpoolOrderStruct, - requestOrderStruct, - contracts.txOptions, - ), - ); - } + const tx = await wrapSend( + iexecContract.matchOrders( + appOrderStruct, + datasetOrderStruct, + workerpoolOrderStruct, + requestOrderStruct, + contracts.txOptions, + ), + ); const txReceipt = await wrapWait(tx.wait(contracts.confirms)); const events = parseTransactionLogs( txReceipt.logs, diff --git a/src/common/utils/config.js b/src/common/utils/config.js index 9667ccc1..3fb02c83 100644 --- a/src/common/utils/config.js +++ b/src/common/utils/config.js @@ -1,12 +1,10 @@ import { EnsPlugin, Network } from 'ethers'; -import { address as voucherHubBellecourAddress } from '../generated/@iexec/voucher-contracts/deployments/bellecour/VoucherHubERC1967Proxy.js'; import { TEE_FRAMEWORKS } from './constant.js'; import { ConfigurationError } from './errors.js'; export const CHAIN_SPECIFIC_FEATURES = { ENS: 'ENS', WORKERPOOL_API_URL_REGISTRATION: 'Workerpool API Registration', - VOUCHER: 'iExec Voucher', COMPASS: 'iExec Compass', XRLC_BRIDGE: 'iExec xRLC Bridge', BULK_PROCESSING: 'Bulk processing', @@ -30,9 +28,6 @@ const networkConfigs = [ iexecGateway: 'https://api.market.v8-bellecour.iex.ec', compass: undefined, // no compass using ENS pocoSubgraph: 'https://thegraph.iex.ec/subgraphs/name/bellecour/poco-v5', - voucherHub: voucherHubBellecourAddress, - voucherSubgraph: - 'https://thegraph.iex.ec/subgraphs/name/bellecour/iexec-voucher', bridge: { contract: '0x188A4376a1D818bF2434972Eb34eFd57102a19b7', bridgedChainId: '1', @@ -58,8 +53,6 @@ const networkConfigs = [ iexecGateway: undefined, // no protocol running compass: undefined, // no protocol running pocoSubgraph: undefined, // no protocol running - voucherHub: undefined, // no voucher - voucherSubgraph: undefined, // no voucher bridge: { contract: '0x4e55c9B8953AB1957ad0A59D413631A66798c6a2', bridgedChainId: '134', @@ -68,7 +61,6 @@ const networkConfigs = [ isExperimental: false, notImplemented: [ CHAIN_SPECIFIC_FEATURES.COMPASS, - CHAIN_SPECIFIC_FEATURES.VOUCHER, CHAIN_SPECIFIC_FEATURES.BULK_PROCESSING, ], }, @@ -90,8 +82,6 @@ const networkConfigs = [ compass: 'https://compass.arbitrum-sepolia-testnet.iex.ec', pocoSubgraph: 'https://thegraph.arbitrum-sepolia-testnet.iex.ec/api/subgraphs/id/2GCj8gzLCihsiEDq8cYvC5nUgK6VfwZ6hm3Wj8A3kcxz', - voucherHub: undefined, // no voucher - voucherSubgraph: undefined, // no voucher bridge: {}, // no bridge shouldRegisterNetwork: false, isExperimental: false, @@ -99,7 +89,6 @@ const networkConfigs = [ notImplemented: [ CHAIN_SPECIFIC_FEATURES.ENS, CHAIN_SPECIFIC_FEATURES.WORKERPOOL_API_URL_REGISTRATION, - CHAIN_SPECIFIC_FEATURES.VOUCHER, CHAIN_SPECIFIC_FEATURES.XRLC_BRIDGE, ], }, @@ -121,15 +110,12 @@ const networkConfigs = [ compass: 'https://compass.arbitrum-mainnet.iex.ec', pocoSubgraph: 'https://thegraph.arbitrum.iex.ec/api/subgraphs/id/B1comLe9SANBLrjdnoNTJSubbeC7cY7EoNu6zD82HeKy', - voucherHub: undefined, // no voucher - voucherSubgraph: undefined, // no voucher bridge: {}, // no bridge shouldRegisterNetwork: false, uploadBulkForThegraph: true, notImplemented: [ CHAIN_SPECIFIC_FEATURES.ENS, CHAIN_SPECIFIC_FEATURES.WORKERPOOL_API_URL_REGISTRATION, - CHAIN_SPECIFIC_FEATURES.VOUCHER, CHAIN_SPECIFIC_FEATURES.XRLC_BRIDGE, ], }, @@ -164,8 +150,6 @@ export const getChainDefaults = ( ipfsNode, compass, pocoSubgraph, - voucherHub, - voucherSubgraph, bridge, } = networkConfigs @@ -187,8 +171,6 @@ export const getChainDefaults = ( ipfsNode, compass, pocoSubgraph, - voucherHub, - voucherSubgraph, bridge, }; }; diff --git a/src/common/utils/voucher-utils.js b/src/common/utils/voucher-utils.js deleted file mode 100644 index b3756b8a..00000000 --- a/src/common/utils/voucher-utils.js +++ /dev/null @@ -1,39 +0,0 @@ -import { Contract } from 'ethers'; -import { GraphQLClient } from 'graphql-request'; -import { throwIfMissing } from './validator.js'; -import { ConfigurationError } from './errors.js'; -import { abi as voucherHubAbi } from '../generated/@iexec/voucher-contracts/VoucherHub.js'; -import { abi as voucherAbi } from '../generated/@iexec/voucher-contracts/Voucher.js'; - -export const getVoucherContract = ( - contracts = throwIfMissing(), - voucherAddress = throwIfMissing(), -) => new Contract(voucherAddress, voucherAbi, contracts.provider); - -export const getVoucherHubContract = ( - contracts = throwIfMissing(), - voucherHubAddress, -) => { - if (!voucherHubAddress) { - throw new ConfigurationError( - `voucherHubAddress option not set and no default value for your chain ${contracts.chainId}`, - ); - } - return new Contract(voucherHubAddress, voucherHubAbi, contracts.provider); -}; - -export const getVoucherSubgraphClient = ( - contracts = throwIfMissing(), - voucherSubgraphUrl, -) => { - if (!voucherSubgraphUrl) { - throw new ConfigurationError( - `voucherSubgraphURL option not set and no default value for your chain ${contracts.chainId}`, - ); - } - try { - return new GraphQLClient(voucherSubgraphUrl); - } catch (error) { - throw new Error(`Failed to create GraphQLClient: ${error.message}`); - } -}; diff --git a/src/common/voucher/subgraph/voucherInfo.js b/src/common/voucher/subgraph/voucherInfo.js deleted file mode 100644 index 1ba1100c..00000000 --- a/src/common/voucher/subgraph/voucherInfo.js +++ /dev/null @@ -1,66 +0,0 @@ -import Debug from 'debug'; -import { gql } from 'graphql-request'; -import { throwIfMissing } from '../../utils/validator.js'; -import { checksummedAddress } from '../../utils/utils.js'; - -const debug = Debug('iexec:voucher:info'); - -export const getVoucherInfo = async ( - graphQLClient = throwIfMissing(), - voucherId, -) => { - const lowercaseVoucherId = voucherId.toLowerCase(); - - const query = gql` - query getVoucherInfo($id: ID!) { - voucher(id: $id) { - voucherType { - eligibleAssets { - type: __typename - id - } - } - authorizedAccounts { - id - } - } - } - `; - - try { - const response = await graphQLClient.request(query, { - id: lowercaseVoucherId, - }); - const voucherInfo = response.voucher; - - const mapIds = (items) => - items?.map((item) => checksummedAddress(item.id.toLowerCase())) || []; - - const sponsoredApps = mapIds( - voucherInfo?.voucherType?.eligibleAssets.filter( - ({ type }) => type === 'App', - ), - ); - const sponsoredDatasets = mapIds( - voucherInfo?.voucherType?.eligibleAssets.filter( - ({ type }) => type === 'Dataset', - ), - ); - const sponsoredWorkerpools = mapIds( - voucherInfo?.voucherType?.eligibleAssets.filter( - ({ type }) => type === 'Workerpool', - ), - ); - const authorizedAccounts = mapIds(voucherInfo?.authorizedAccounts); - - return { - sponsoredApps, - sponsoredDatasets, - sponsoredWorkerpools, - authorizedAccounts, - }; - } catch (error) { - debug('getVoucherInfo()', error); - throw error; - } -}; diff --git a/src/common/voucher/voucher.js b/src/common/voucher/voucher.js deleted file mode 100644 index 991d8c47..00000000 --- a/src/common/voucher/voucher.js +++ /dev/null @@ -1,223 +0,0 @@ -import Debug from 'debug'; -import { addressSchema, throwIfMissing } from '../utils/validator.js'; -import { fetchVoucherAddress, isVoucherAddress } from './voucherHub.js'; -import { checkAllowance } from '../account/allowance.js'; -import { bigIntToBn, checkSigner } from '../utils/utils.js'; -import { getAddress } from '../wallet/address.js'; -import { wrapCall, wrapSend } from '../utils/errorWrappers.js'; -import { getVoucherInfo } from './subgraph/voucherInfo.js'; -import { - getVoucherContract, - getVoucherSubgraphClient, -} from '../utils/voucher-utils.js'; -import { - CHAIN_SPECIFIC_FEATURES, - checkImplementedOnChain, -} from '../utils/config.js'; - -const debug = Debug('iexec:voucher:voucher'); - -export const fetchVoucherContract = async ( - contracts = throwIfMissing(), - voucherHubAddress, - userAddress, - { voucherAddress } = {}, -) => { - try { - const [vUserAddress, vVoucherAddress] = await Promise.all([ - addressSchema({ - ethProvider: contracts.provider, - }) - .required() - .label('userAddress') - .validate(userAddress), - addressSchema({ - ethProvider: contracts.provider, - }) - .label('voucherAddress') - .validate(voucherAddress), - ]); - - let voucherContract; - if (vVoucherAddress) { - const isVoucher = await isVoucherAddress( - contracts, - voucherHubAddress, - vVoucherAddress, - ); - if (!isVoucher) { - throw new Error('Invalid voucher contract address'); - } - voucherContract = getVoucherContract(contracts, vVoucherAddress); - const [userAuthorized, userIsOwner] = await Promise.all([ - wrapCall(voucherContract.isAccountAuthorized(vUserAddress)), - wrapCall(voucherContract.owner()).then( - (owner) => owner.toLowerCase() === vUserAddress.toLowerCase(), - ), - ]); - if (!userAuthorized && !userIsOwner) { - throw new Error('User is not authorized to use the voucher'); - } - } else { - const ownedVoucherAddress = await fetchVoucherAddress( - contracts, - voucherHubAddress, - userAddress, - ); - if (ownedVoucherAddress) { - voucherContract = getVoucherContract(contracts, ownedVoucherAddress); - } - } - return voucherContract; - } catch (error) { - debug('fetchVoucherContract()', error); - throw error; - } -}; - -export const showUserVoucher = async ( - contracts = throwIfMissing(), - voucherSubgraphURL, - voucherHubAddress, - owner = throwIfMissing(), -) => { - try { - checkImplementedOnChain(contracts.chainId, CHAIN_SPECIFIC_FEATURES.VOUCHER); - const vOwner = await addressSchema({ - ethProvider: contracts.provider, - }) - .required() - .label('owner') - .validate(owner); - const graphQLClient = getVoucherSubgraphClient( - contracts, - voucherSubgraphURL, - ); - const voucherAddress = await fetchVoucherAddress( - contracts, - voucherHubAddress, - vOwner, - ); - if (!voucherAddress) { - throw new Error(`No Voucher found for address ${vOwner}`); - } - const voucherContract = await fetchVoucherContract( - contracts, - voucherHubAddress, - vOwner, - ); - const fetchType = voucherContract.getType(); - const fetchBalance = voucherContract.getBalance(); - const fetchExpirationTimestamp = voucherContract.getExpiration(); - const fetchAllowanceAmount = checkAllowance( - contracts, - vOwner, - voucherAddress, - ); - const fetchVoucherInfo = getVoucherInfo(graphQLClient, voucherAddress); - const [type, balance, expirationTimestamp, allowanceAmount, voucherInfo] = - await Promise.all([ - fetchType, - fetchBalance, - fetchExpirationTimestamp, - fetchAllowanceAmount, - fetchVoucherInfo, - ]); - return { - owner, - address: voucherAddress, - type: bigIntToBn(type), - balance: bigIntToBn(balance), - allowanceAmount: bigIntToBn(allowanceAmount), - expirationTimestamp: bigIntToBn(expirationTimestamp), - ...voucherInfo, - }; - } catch (error) { - debug('showUserVoucher()', error); - throw error; - } -}; - -export const authorizeRequester = async ( - contracts = throwIfMissing(), - voucherHubAddress, - requester, -) => { - try { - checkImplementedOnChain(contracts.chainId, CHAIN_SPECIFIC_FEATURES.VOUCHER); - checkSigner(contracts); - const userAddress = await getAddress(contracts); - const vRequester = await addressSchema({ - ethProvider: contracts.provider, - }) - .required() - .label('requester') - .validate(requester); - const voucherContract = await fetchVoucherContract( - contracts, - voucherHubAddress, - userAddress, - ); - if (!voucherContract) { - throw new Error(`No Voucher found for address ${userAddress}`); - } - const isAuthorized = await wrapCall( - voucherContract.isAccountAuthorized(vRequester), - ); - if (isAuthorized) { - throw new Error(`${vRequester} is already authorized`); - } - const tx = await wrapSend( - voucherContract - .connect(contracts.signer) - .authorizeAccount(vRequester, contracts.txOptions), - ); - await tx.wait(); - return tx.hash; - } catch (error) { - debug('authorizeRequester()', error); - throw error; - } -}; - -export const revokeRequesterAuthorization = async ( - contracts = throwIfMissing(), - voucherHubAddress, - requester, -) => { - try { - checkImplementedOnChain(contracts.chainId, CHAIN_SPECIFIC_FEATURES.VOUCHER); - checkSigner(contracts); - const userAddress = await getAddress(contracts); - const vRequester = await addressSchema({ - ethProvider: contracts.provider, - }) - .required() - .label('requester') - .validate(requester); - const voucherContract = await fetchVoucherContract( - contracts, - voucherHubAddress, - userAddress, - ); - if (!voucherContract) { - throw new Error(`No Voucher found for address ${userAddress}`); - } - const isAuthorized = await wrapCall( - voucherContract.isAccountAuthorized(vRequester), - ); - if (!isAuthorized) { - throw new Error(`${vRequester} is not authorized`); - } - const tx = await wrapSend( - voucherContract - .connect(contracts.signer) - .unauthorizeAccount(vRequester, contracts.txOptions), - ); - await tx.wait(); - return tx.hash; - } catch (error) { - debug('revokeRequesterAuthorization()', error); - throw error; - } -}; diff --git a/src/common/voucher/voucherHub.js b/src/common/voucher/voucherHub.js deleted file mode 100644 index 55d11e01..00000000 --- a/src/common/voucher/voucherHub.js +++ /dev/null @@ -1,58 +0,0 @@ -import Debug from 'debug'; - -import { addressSchema, throwIfMissing } from '../utils/validator.js'; -import { wrapCall } from '../utils/errorWrappers.js'; -import { NULL_ADDRESS } from '../utils/constant.js'; -import { getVoucherHubContract } from '../utils/voucher-utils.js'; -import { - CHAIN_SPECIFIC_FEATURES, - checkImplementedOnChain, -} from '../utils/config.js'; - -const debug = Debug('iexec:voucher:voucherHub'); - -export const fetchVoucherAddress = async ( - contracts = throwIfMissing(), - voucherHubAddress, - owner, -) => { - try { - checkImplementedOnChain(contracts.chainId, CHAIN_SPECIFIC_FEATURES.VOUCHER); - const vOwner = await addressSchema({ ethProvider: contracts.provider }) - .required() - .label('owner') - .validate(owner); - const voucherHubContract = getVoucherHubContract( - contracts, - voucherHubAddress, - ); - const address = await wrapCall(voucherHubContract.getVoucher(vOwner)); - return address !== NULL_ADDRESS ? address : null; - } catch (error) { - debug('fetchVoucherAddress()', error); - throw error; - } -}; - -export const isVoucherAddress = async ( - contracts = throwIfMissing(), - voucherHubAddress, - voucherAddress, -) => { - try { - const vVoucherAddress = await addressSchema({ - ethProvider: contracts.provider, - }) - .required() - .label('voucherAddress') - .validate(voucherAddress); - const voucherHubContract = getVoucherHubContract( - contracts, - voucherHubAddress, - ); - return wrapCall(voucherHubContract.isVoucher(vVoucherAddress)); - } catch (error) { - debug('checkVoucherAddress()', error); - throw error; - } -}; diff --git a/src/lib/IExec.d.ts b/src/lib/IExec.d.ts index 0cb68117..0f22f70a 100644 --- a/src/lib/IExec.d.ts +++ b/src/lib/IExec.d.ts @@ -16,7 +16,6 @@ import IExecResultModule from './IExecResultModule.js'; import IExecSecretsModule from './IExecSecretsModule.js'; import IExecStorageModule from './IExecStorageModule.js'; import IExecTaskModule from './IExecTaskModule.js'; -import IExecVoucherModule from './IExecVoucherModule.js'; import IExecWalletModule from './IExecWalletModule.js'; import IExecWorkerpoolModule from './IExecWorkerpoolModule.js'; @@ -76,10 +75,6 @@ export default class IExec extends IExecModule { * task module */ task: IExecTaskModule; - /** - * voucher module - */ - voucher: IExecVoucherModule; /** * wallet module */ diff --git a/src/lib/IExec.js b/src/lib/IExec.js index 5df313df..eb26abb0 100644 --- a/src/lib/IExec.js +++ b/src/lib/IExec.js @@ -14,7 +14,6 @@ import IExecStorageModule from './IExecStorageModule.js'; import IExecTaskModule from './IExecTaskModule.js'; import IExecWalletModule from './IExecWalletModule.js'; import IExecWorkerpoolModule from './IExecWorkerpoolModule.js'; -import IExecVoucherModule from './IExecVoucherModule.js'; export default class IExec extends IExecModule { constructor(...args) { @@ -34,7 +33,6 @@ export default class IExec extends IExecModule { this.secrets = IExecSecretsModule.fromConfig(this.config); this.storage = IExecStorageModule.fromConfig(this.config); this.ens = IExecENSModule.fromConfig(this.config); - this.voucher = IExecVoucherModule.fromConfig(this.config); this.network = IExecNetworkModule.fromConfig(this.config); } } diff --git a/src/lib/IExecConfig.d.ts b/src/lib/IExecConfig.d.ts index 8f04674a..c6f84e41 100644 --- a/src/lib/IExecConfig.d.ts +++ b/src/lib/IExecConfig.d.ts @@ -53,10 +53,6 @@ export interface IExecConfigOptions { * override the ENS public resolver contract address to target a custom instance */ ensPublicResolverAddress?: string; - /** - * override the VoucherHub contract address to target a custom instance - */ - voucherHubAddress?: string; /** * override the bridge contract address to target a custom instance */ @@ -116,10 +112,6 @@ export interface IExecConfigOptions { * override the PoCo subgraph URL to target a custom instance */ pocoSubgraphURL?: string; - /** - * override the voucher subgraph URL to target a custom instance - */ - voucherSubgraphURL?: string; /** * number of block to wait for transactions confirmation (default 1) */ @@ -213,11 +205,6 @@ export default class IExecConfig { * resolve the current PoCo subgraph URL */ resolvePocoSubgraphURL(): Promise; - /** - * resolve the current voucher subgraph URL - * returns `null` if not available - */ - resolveVoucherSubgraphURL(): Promise; /** * resolve the current bridge contract address */ @@ -230,9 +217,4 @@ export default class IExecConfig { * resolve the current ENS public resolver contract address */ resolveEnsPublicResolverAddress(): Promise; - /** - * resolve the current VoucherHub contract address - * returns `null` if not available - */ - resolveVoucherHubAddress(): Promise; } diff --git a/src/lib/IExecConfig.js b/src/lib/IExecConfig.js index 1e2e3001..0346ec16 100644 --- a/src/lib/IExecConfig.js +++ b/src/lib/IExecConfig.js @@ -19,7 +19,6 @@ export default class IExecConfig { { hubAddress, ensPublicResolverAddress, - voucherHubAddress, isNative, useGas = true, confirms, @@ -32,7 +31,6 @@ export default class IExecConfig { iexecGatewayURL, compassURL, pocoSubgraphURL, - voucherSubgraphURL, defaultTeeFramework, providerOptions, allowExperimentalNetworks = false, @@ -345,15 +343,6 @@ export default class IExecConfig { ); }; - this.resolveVoucherSubgraphURL = async () => { - const chainConfDefaults = await chainConfDefaultsPromise; - const value = voucherSubgraphURL || chainConfDefaults.voucherSubgraph; - if (value !== undefined) { - return value; - } - return null; - }; - this.resolveBridgeAddress = async () => { const { chainId } = await networkPromise; const chainConfDefaults = await chainConfDefaultsPromise; @@ -385,14 +374,5 @@ export default class IExecConfig { `ensPublicResolverAddress option not set and no default value for your chain ${chainId}`, ); }; - - this.resolveVoucherHubAddress = async () => { - const chainConfDefaults = await chainConfDefaultsPromise; - const value = voucherHubAddress || chainConfDefaults.voucherHub; - if (value !== undefined) { - return value; - } - return null; - }; } } diff --git a/src/lib/IExecOrderModule.d.ts b/src/lib/IExecOrderModule.d.ts index 5c1cda9c..accd83a1 100644 --- a/src/lib/IExecOrderModule.d.ts +++ b/src/lib/IExecOrderModule.d.ts @@ -1034,16 +1034,6 @@ export default class IExecOrderModule extends IExecModule { }, options?: { preflightCheck?: boolean; - /** - * use a voucher contract to sponsor the deal - */ - useVoucher?: boolean; - /** - * override the voucher contract to use, must be combined with `useVoucher: true` - * - * the user must be authorized by the voucher's owner to use it - */ - voucherAddress?: Addressish; }, ): Promise<{ dealid: Dealid; volume: BN; txHash: TxHash }>; /** @@ -1057,32 +1047,17 @@ export default class IExecOrderModule extends IExecModule { * workerpoolorder, * requestorder, * }; - * const result = await estimateMatchOrders(orders, {useVoucher: true}); + * const result = await estimateMatchOrders(orders); * console.log(`executable volume: ${result.volume} tasks`); * console.log(`total cost for matching orders: ${result.total} nRLC`); - * console.log(`sponsored cost covered by voucher: ${result.sponsored} nRLC`); * ``` */ - estimateMatchOrders( - orders: { - apporder: ConsumableApporder; - datasetorder?: ConsumableDatasetorder; - workerpoolorder: ConsumableWorkerpoolorder; - requestorder: ConsumableRequestorder; - }, - options?: { - /** - * use a voucher contract to sponsor the deal - */ - useVoucher?: boolean; - /** - * override the voucher contract to use, must be combined with `useVoucher: true` - * - * the user must be authorized by the voucher's owner to use it - */ - voucherAddress?: Addressish; - }, - ): Promise<{ volume: BN; total: BN; sponsored: BN }>; + estimateMatchOrders(orders: { + apporder: ConsumableApporder; + datasetorder?: ConsumableDatasetorder; + workerpoolorder: ConsumableWorkerpoolorder; + requestorder: ConsumableRequestorder; + }): Promise<{ volume: BN; total: BN; sponsored: BN }>; /** * Prepare a bulk from datasetorders to process multiple datasets with a single requestorder * diff --git a/src/lib/IExecOrderModule.js b/src/lib/IExecOrderModule.js index 3302e531..a8ef40de 100644 --- a/src/lib/IExecOrderModule.js +++ b/src/lib/IExecOrderModule.js @@ -310,13 +310,9 @@ export default class IExecOrderModule extends IExecModule { workerpoolorder, requestorder, }, - { preflightCheck = true, useVoucher = false, voucherAddress } = {}, + { preflightCheck = true } = {}, ) => { const contracts = await this.config.resolveContractsClient(); - let voucherHubAddress; - if (useVoucher) { - voucherHubAddress = await this.config.resolveVoucherHubAddress(); - } if (preflightCheck === true) { const resolvedTag = sumTags([ ( @@ -335,7 +331,6 @@ export default class IExecOrderModule extends IExecModule { ]); return matchOrders({ contracts, - voucherHubAddress, apporder: await checkAppRequirements( { contracts, @@ -363,36 +358,29 @@ export default class IExecOrderModule extends IExecModule { }, requestorder, ).then(() => requestorder), - useVoucher, - voucherAddress, }); } return matchOrders({ contracts, - voucherHubAddress, apporder, datasetorder, workerpoolorder, requestorder, - useVoucher, - voucherAddress, }); }; - this.estimateMatchOrders = async ( - { apporder, datasetorder, workerpoolorder, requestorder }, - { useVoucher = false, voucherAddress } = {}, - ) => { + this.estimateMatchOrders = async ({ + apporder, + datasetorder, + workerpoolorder, + requestorder, + }) => { const contracts = await this.config.resolveContractsClient(); - const voucherHubAddress = await this.config.resolveVoucherHubAddress(); return estimateMatchOrders({ contracts, - voucherHubAddress, apporder, datasetorder, workerpoolorder, requestorder, - useVoucher, - voucherAddress, }); }; this.prepareDatasetBulk = async ( diff --git a/src/lib/IExecVoucherModule.d.ts b/src/lib/IExecVoucherModule.d.ts deleted file mode 100644 index c7635eae..00000000 --- a/src/lib/IExecVoucherModule.d.ts +++ /dev/null @@ -1,82 +0,0 @@ -export type * from '../common/types.js'; - -import IExecConfig from './IExecConfig.js'; -import IExecModule from './IExecModule.js'; -import { Address, Addressish, BN, TxHash } from '../common/types.js'; - -interface VoucherInfo { - owner: Address; - address: Address; - type: BN; - balance: BN; - expirationTimestamp: BN; - sponsoredApps: Address[]; - sponsoredDatasets: Address[]; - sponsoredWorkerpools: Address[]; - allowanceAmount: BN; - authorizedAccounts: Address[]; -} - -/** - * module exposing voucher methods - */ -export default class IExecVoucherModule extends IExecModule { - /** - * returns the address of the voucher contract for the specified address if the address owns a voucher - * - * example: - * ```js - * const voucherAddress = await getVoucherAddress(ownerAddress); - * console.log('voucher contract address:', voucherAddress); - * ``` - */ - getVoucherAddress(owner: Addressish): Promise
; - - /** - * **SIGNER REQUIRED** - * - * authorize a requester to use the voucher - * - * example: - * ```js - * const txHash = await authorizeRequester(requesterAddress); - * console.log('tx:', txHash); - * ``` - */ - authorizeRequester(requester: Addressish): Promise; - - /** - * returns the user voucher information - * - * example: - * ```js - * const userVoucher = await showUserVoucher(userAddress); - * console.log('address:', userVoucher.address); - * console.log('balance:', userVoucher.balance); - * console.log('expiration:', userVoucher.expirationTimestamp); - * console.log('sponsored apps:', userVoucher.sponsoredApps); - * console.log('sponsored datasets:', userVoucher.sponsoredDatasets); - * console.log('sponsored workerpools:', userVoucher.sponsoredWorkerpools); - * console.log('allowance on user account:', userVoucher.allowanceAmount); - * console.log('authorized accounts:', userVoucher.authorizedAccounts); - * ``` - */ - showUserVoucher(owner: Addressish): Promise; - - /* **SIGNER REQUIRED** - * - * revoke the authorization previously granted to a requester to use the voucher - * - * example: - * ```js - * const txHash = await revokeRequesterAuthorization(requesterAddress); - * console.log('tx:', txHash); - * ``` - */ - revokeRequesterAuthorization(requester: Addressish): Promise; - - /** - * Create an IExecVoucherModule instance using an IExecConfig instance - */ - static fromConfig(config: IExecConfig): IExecVoucherModule; -} diff --git a/src/lib/IExecVoucherModule.js b/src/lib/IExecVoucherModule.js deleted file mode 100644 index 6ba21ed4..00000000 --- a/src/lib/IExecVoucherModule.js +++ /dev/null @@ -1,48 +0,0 @@ -import IExecModule from './IExecModule.js'; -import { fetchVoucherAddress } from '../common/voucher/voucherHub.js'; -import { - authorizeRequester, - revokeRequesterAuthorization, - showUserVoucher, -} from '../common/voucher/voucher.js'; - -export default class IExecVoucherModule extends IExecModule { - constructor(...args) { - super(...args); - - this.getVoucherAddress = async (owner) => { - const contracts = await this.config.resolveContractsClient(); - const voucherHubAddress = await this.config.resolveVoucherHubAddress(); - return fetchVoucherAddress(contracts, voucherHubAddress, owner); - }; - - this.showUserVoucher = async (owner) => { - const contracts = await this.config.resolveContractsClient(); - const voucherHubAddress = await this.config.resolveVoucherHubAddress(); - const voucherSubgraphURL = await this.config.resolveVoucherSubgraphURL(); - - return showUserVoucher( - contracts, - voucherSubgraphURL, - voucherHubAddress, - owner, - ); - }; - - this.authorizeRequester = async (requester) => { - const contracts = await this.config.resolveContractsClient(); - const voucherHubAddress = await this.config.resolveVoucherHubAddress(); - return authorizeRequester(contracts, voucherHubAddress, requester); - }; - - this.revokeRequesterAuthorization = async (requester) => { - const contracts = await this.config.resolveContractsClient(); - const voucherHubAddress = await this.config.resolveVoucherHubAddress(); - return revokeRequesterAuthorization( - contracts, - voucherHubAddress, - requester, - ); - }; - } -} diff --git a/src/lib/index.d.ts b/src/lib/index.d.ts index 1788b01e..0ec81cb9 100644 --- a/src/lib/index.d.ts +++ b/src/lib/index.d.ts @@ -17,7 +17,6 @@ export { default as IExecResultModule } from './IExecResultModule.js'; export { default as IExecSecretsModule } from './IExecSecretsModule.js'; export { default as IExecStorageModule } from './IExecStorageModule.js'; export { default as IExecTaskModule } from './IExecTaskModule.js'; -export { default as IExecVoucherModule } from './IExecVoucherModule.js'; export { default as IExecWalletModule } from './IExecWalletModule.js'; export { default as IExecWorkerpoolModule } from './IExecWorkerpoolModule.js'; diff --git a/src/lib/index.js b/src/lib/index.js index 4ccfe63b..cc825193 100644 --- a/src/lib/index.js +++ b/src/lib/index.js @@ -17,7 +17,6 @@ export { default as IExecResultModule } from './IExecResultModule.js'; export { default as IExecSecretsModule } from './IExecSecretsModule.js'; export { default as IExecStorageModule } from './IExecStorageModule.js'; export { default as IExecTaskModule } from './IExecTaskModule.js'; -export { default as IExecVoucherModule } from './IExecVoucherModule.js'; export { default as IExecWalletModule } from './IExecWalletModule.js'; export { default as IExecWorkerpoolModule } from './IExecWorkerpoolModule.js'; diff --git a/test/cli/cli-iexec-app.test.js b/test/cli/cli-iexec-app.test.js index 491c738d..21fe473e 100644 --- a/test/cli/cli-iexec-app.test.js +++ b/test/cli/cli-iexec-app.test.js @@ -5,17 +5,12 @@ import { NULL_ADDRESS, NULL_BYTES32, TEST_CHAINS, - addVoucherEligibleAsset, adminCreateCategory, - createAndPublishWorkerpoolOrder, - createVoucher, - createVoucherType, execAsync, getRandomAddress, getRandomWallet, } from '../test-utils.js'; import { - editRequestorder, globalSetup, globalTeardown, iexecPath, @@ -26,7 +21,6 @@ import { setWallet, } from './cli-test-utils.js'; import '../jest-setup.js'; -import { getTestConfig } from '../test-config-utils.js'; const testChain = TEST_CHAINS['bellecour-fork']; @@ -410,170 +404,6 @@ describe('iexec app', () => { expect(res.failedTasks[0].statusName).toBe('TIMEOUT'); expect(res.failedTasks[0].taskTimedOut).toBe(true); }); - - describe('iexec app run --use-voucher', () => { - beforeAll(async () => { - await runIExecCliRaw( - `${iexecPath} dataset publish ${userDataset} --price 2 nRLC --volume 100 --app-restrict ${userApp} --force`, - ); - - await execAsync(`${iexecPath} order init --request`); - await editRequestorder({ - app: userApp, - dataset: userDataset, - workerpool: testChain.prodWorkerpool, - appmaxprice: '1000', - workerpoolmaxprice: '1000', - datasetmaxprice: '1000', - category: 0, - volume: '1', - }); - await execAsync( - `${iexecPath} order sign --request --skip-preflight-check --raw`, - ); - }); - - test('fail without voucher', async () => { - const raw = await execAsync( - `${iexecPath} app run --workerpool ${userWokerpool} --dataset ${userDataset} --use-voucher --skip-preflight-check --force --raw`, - ).catch((e) => e.message); - const res = JSON.parse(raw); - expect(res.ok).toBe(false); - expect(res.error.message).toBe( - `No voucher available for the requester ${userWallet.address}`, - ); - }); - - test('should create a deal and match orders with voucher', async () => { - const voucherType = await createVoucherType(testChain)({}); - await createVoucher(testChain)({ - owner: userWallet.address, - voucherType, - value: 1000 + 2, // workerpoolprice + datasetprice nRLC - }); - await addVoucherEligibleAsset(testChain)( - testChain.prodWorkerpool, - voucherType, - ); - await addVoucherEligibleAsset(testChain)(userDataset, voucherType); - - const raw = await execAsync( - `${iexecPath} app run --workerpool ${testChain.prodWorkerpool} --dataset ${userDataset} --use-voucher --skip-preflight-check --force --raw`, - ).catch((e) => e.message); - const res = JSON.parse(raw); - expect(res.ok).toBe(true); - expect(res.deals).toBeDefined(); - expect(res.deals.length).toBe(1); - expect(res.deals[0].volume).toBe('1'); - expect(res.deals[0].dealid).toBeDefined(); - expect(res.deals[0].txHash).toBeDefined(); - - const rawDeal = await execAsync( - `${iexecPath} deal show ${res.deals[0].dealid} --raw`, - ); - const ensRaw = await execAsync( - `${iexecPath} ens resolve ${testChain.prodWorkerpool} --raw`, - ); - const workerpool = JSON.parse(ensRaw); - - const resDeal = JSON.parse(rawDeal); - - expect(resDeal.ok).toBe(true); - expect(resDeal.deal).toBeDefined(); - expect(resDeal.deal.app.pointer).toBe(userApp); - expect(resDeal.deal.app.price).toBe('0'); - expect(resDeal.deal.dataset.pointer).toBe(userDataset); - expect(resDeal.deal.dataset.price).toBe('0'); - expect(resDeal.deal.workerpool.pointer).toBe(workerpool.address); - expect(resDeal.deal.category).toBe('0'); - expect(resDeal.deal.callback).toBe(NULL_ADDRESS); - expect(resDeal.deal.requester).toBe(userWallet.address); - expect(resDeal.deal.beneficiary).toBe(userWallet.address); - expect(resDeal.deal.params).toBe( - `{"iexec_result_storage_provider":"ipfs"}`, - ); - expect(resDeal.deal.botFirst).toBe('0'); - expect(resDeal.deal.botSize).toBe('1'); - expect(resDeal.deal.trust).toBe('1'); - expect(Object.keys(resDeal.deal.tasks).length).toBe(1); - expect(resDeal.deal.tasks['0']).toBeDefined(); - }); - describe('--voucher-address', () => { - test('should create a deal and match orders with selected voucher', async () => { - const { iexec: iexecVoucherOwner, wallet: voucherOwnerWallet } = - getTestConfig(testChain)(); - const voucherType = await createVoucherType(testChain)({}); - await addVoucherEligibleAsset(testChain)( - testChain.prodWorkerpool, - voucherType, - ); - await addVoucherEligibleAsset(testChain)(userDataset, voucherType); - const voucherAddress = await createVoucher(testChain)({ - owner: voucherOwnerWallet.address, - voucherType, - value: 1000, - }); - await iexecVoucherOwner.voucher.authorizeRequester( - userWallet.address, - ); - // create dedicated order - await createAndPublishWorkerpoolOrder(testChain)({ - workerpool: testChain.prodWorkerpool, - workerpoolOwnerWallet: testChain.prodWorkerpoolOwnerWallet, - price: 1, - volume: 1, - requesterrestrict: userWallet.address, - }); - - const raw = await execAsync( - `${iexecPath} app run --workerpool ${testChain.prodWorkerpool} --dataset ${userDataset} --use-voucher --voucher-address ${voucherAddress} --skip-preflight-check --force --raw`, - ).catch((e) => e.message); - const res = JSON.parse(raw); - - expect(res.ok).toBe(true); - expect(res.deals).toBeDefined(); - expect(res.deals.length).toBe(1); - expect(res.deals[0].volume).toBe('1'); - expect(res.deals[0].dealid).toBeDefined(); - expect(res.deals[0].txHash).toBeDefined(); - - const rawDeal = await execAsync( - `${iexecPath} deal show ${res.deals[0].dealid} --raw`, - ); - const ensRaw = await execAsync( - `${iexecPath} ens resolve ${testChain.prodWorkerpool} --raw`, - ); - const workerpool = JSON.parse(ensRaw); - - const resDeal = JSON.parse(rawDeal); - - expect(resDeal.ok).toBe(true); - expect(resDeal.deal).toBeDefined(); - expect(resDeal.deal.app.pointer).toBe(userApp); - expect(resDeal.deal.app.price).toBe('0'); - expect(resDeal.deal.dataset.pointer).toBe(userDataset); - expect(resDeal.deal.dataset.price).toBe('0'); - expect(resDeal.deal.workerpool.pointer).toBe(workerpool.address); - expect(resDeal.deal.category).toBe('0'); - expect(resDeal.deal.callback).toBe(NULL_ADDRESS); - expect(resDeal.deal.requester).toBe(userWallet.address); - expect(resDeal.deal.beneficiary).toBe(userWallet.address); - expect(resDeal.deal.params).toBe( - `{"iexec_result_storage_provider":"ipfs"}`, - ); - expect(resDeal.deal.botFirst).toBe('0'); - expect(resDeal.deal.botSize).toBe('1'); - expect(resDeal.deal.trust).toBe('1'); - expect(Object.keys(resDeal.deal.tasks).length).toBe(1); - expect(resDeal.deal.tasks['0']).toBeDefined(); - - const tx = await testChain.provider.getTransaction( - res.deals[0].txHash, - ); - expect(tx.to).toBe(voucherAddress); - }); - }); - }); }); describe('push-secret / check-secret', () => { diff --git a/test/cli/cli-iexec-order.test.js b/test/cli/cli-iexec-order.test.js index d62bbf5d..0ad1ab58 100644 --- a/test/cli/cli-iexec-order.test.js +++ b/test/cli/cli-iexec-order.test.js @@ -1,13 +1,7 @@ // @jest/global comes with jest // eslint-disable-next-line import/no-extraneous-dependencies -import { describe, test, expect, beforeEach } from '@jest/globals'; -import { - TEST_CHAINS, - addVoucherEligibleAsset, - createVoucher, - createVoucherType, - execAsync, -} from '../test-utils.js'; +import { describe, test, expect } from '@jest/globals'; +import { TEST_CHAINS, execAsync } from '../test-utils.js'; import { editApporder, editDatasetorder, @@ -16,12 +10,10 @@ import { globalSetup, globalTeardown, iexecPath, - runIExecCliRaw, setChain, setRandomWallet, } from './cli-test-utils.js'; import '../jest-setup.js'; -import { getTestConfig } from '../test-config-utils.js'; const testChain = TEST_CHAINS['bellecour-fork']; @@ -334,109 +326,4 @@ describe('iexec order', () => { expect(tx.gasPrice.toString()).toBe('0'); }); }); - - describe('iexec order fill --use-voucher', () => { - let workerpoolOrderHash; - let datasetOrderHash; - let apporderHash; - let voucherType; - - beforeAll(async () => { - const publishApporder = await runIExecCliRaw( - `${iexecPath} app publish ${userApp} --price 0.000000001 RLC --volume 100 --force`, - ); - apporderHash = publishApporder.orderHash; - const publishDatasetorder = await runIExecCliRaw( - `${iexecPath} dataset publish ${userDataset} --price 0.000000002 RLC --volume 100 --app-restrict ${userApp} --force`, - ); - datasetOrderHash = publishDatasetorder.orderHash; - - const publishWorkerpoolorder = await runIExecCliRaw( - `${iexecPath} workerpool publish ${userWorkerpool} --price 0.000000003 RLC --volume 100 --category 0 --force`, - ); - workerpoolOrderHash = publishWorkerpoolorder.orderHash; - - await execAsync(`${iexecPath} order init --request`); - await editRequestorder({ - app: userApp, - dataset: userDataset, - workerpool: userWorkerpool, - appmaxprice: '1000', - workerpoolmaxprice: '1000', - datasetmaxprice: '1000', - category: 0, - volume: '1', - }); - - voucherType = await createVoucherType(testChain)({}); - await addVoucherEligibleAsset(testChain)(userWorkerpool, voucherType); - await addVoucherEligibleAsset(testChain)(userDataset, voucherType); - await addVoucherEligibleAsset(testChain)(userApp, voucherType); - }); - - beforeEach(async () => { - await execAsync( - `${iexecPath} order sign --request --skip-preflight-check --raw`, - ); - }); - - test('fail without voucher', async () => { - const raw = await execAsync( - `${iexecPath} order fill --use-voucher --app ${apporderHash} --workerpool ${workerpoolOrderHash} --dataset ${datasetOrderHash} --skip-preflight-check --raw`, - ).catch((e) => e.message); - const res = JSON.parse(raw); - expect(res.ok).toBe(false); - expect(res.error.message).toBe( - `No voucher available for the requester ${userWallet.address}`, - ); - }); - - test('should match orders with voucher', async () => { - const voucherAddress = await createVoucher(testChain)({ - owner: userWallet.address, - voucherType, - value: 6, // nRLC - }); - const raw = await execAsync( - `${iexecPath} order fill --use-voucher --app ${apporderHash} --workerpool ${workerpoolOrderHash} --dataset ${datasetOrderHash} --skip-preflight-check --raw`, - ); - const res = JSON.parse(raw); - expect(res.ok).toBe(true); - expect(res.volume).toBe('1'); - expect(res.dealid).toBeDefined(); - expect(res.txHash).toBeDefined(); - await testChain.provider.getTransaction(res.txHash).then((tx) => { - expect(tx.gasPrice.toString()).toBe('0'); - }); - const tx = await testChain.provider.getTransaction(res.txHash); - expect(tx.to).toBe(voucherAddress); - }); - - describe('--voucher-address', () => { - test('should match orders with specified voucher', async () => { - const { iexec: iexecVoucherOwner, wallet: voucherOwnerWallet } = - getTestConfig(testChain)(); - const voucherAddress = await createVoucher(testChain)({ - owner: voucherOwnerWallet.address, - voucherType, - value: 6, // nRLC - }); - await iexecVoucherOwner.voucher.authorizeRequester(userWallet.address); - - const raw = await execAsync( - `${iexecPath} order fill --use-voucher --voucher-address ${voucherAddress} --app ${apporderHash} --workerpool ${workerpoolOrderHash} --dataset ${datasetOrderHash} --skip-preflight-check --raw`, - ); - const res = JSON.parse(raw); - expect(res.ok).toBe(true); - expect(res.volume).toBe('1'); - expect(res.dealid).toBeDefined(); - expect(res.txHash).toBeDefined(); - await testChain.provider.getTransaction(res.txHash).then((tx) => { - expect(tx.gasPrice.toString()).toBe('0'); - }); - const tx = await testChain.provider.getTransaction(res.txHash); - expect(tx.to).toBe(voucherAddress); - }); - }); - }); }); diff --git a/test/cli/cli-iexec-voucher.test.js b/test/cli/cli-iexec-voucher.test.js deleted file mode 100644 index 7808bb52..00000000 --- a/test/cli/cli-iexec-voucher.test.js +++ /dev/null @@ -1,211 +0,0 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies -import { describe, test, expect } from '@jest/globals'; -import { - TEST_CHAINS, - addVoucherEligibleAsset, - createVoucher, - createVoucherType, - execAsync, - getRandomAddress, -} from '../test-utils.js'; -import { - globalSetup, - globalTeardown, - iexecPath, - runIExecCliRaw, - setAppUniqueName, - setChain, - setDatasetUniqueName, - setRandomWallet, - setWallet, - setWorkerpoolUniqueDescription, -} from './cli-test-utils.js'; -import '../jest-setup.js'; - -const testChain = TEST_CHAINS['bellecour-fork']; - -describe('iexec voucher', () => { - let userWallet; - let voucherType; - let voucherValue; - let deployedAppAddress; - let deployedDatasetAddress; - let deployedWorkerpoolAddress; - let requesterAddress; - beforeAll(async () => { - await globalSetup('cli-iexec-voucher'); - await execAsync(`${iexecPath} init --skip-wallet --force`); - await setChain(testChain)(); - userWallet = await setRandomWallet(); - - voucherType = await createVoucherType(testChain)({}); - voucherValue = 1000; - await createVoucher(testChain)({ - owner: userWallet.address, - voucherType, - value: voucherValue, - }); - requesterAddress = await getRandomAddress(); - }); - - afterAll(async () => { - await globalTeardown(); - }); - - describe('show', () => { - test('returns voucher details when user has one without sponsored assets', async () => { - const raw = await execAsync(`${iexecPath} voucher show --raw`); - const res = JSON.parse(raw); - expect(res.ok).toBe(true); - expect(res.address).toBeDefined(); - expect(parseInt(res.balance, 16)).toBe(Number(voucherValue)); - expect(parseInt(res.type, 16)).toBe(Number(voucherType)); - expect(res.owner).toBe(userWallet.address); - expect(res.expirationTimestamp).toBeDefined(); - expect(res.allowanceAmount).toBeDefined(); - expect(res.sponsoredApps).toEqual([]); - expect(res.sponsoredDatasets).toEqual([]); - expect(res.sponsoredWorkerpools).toEqual([]); - expect(res.authorizedAccounts).toEqual([]); - }); - - test('returns voucher details when user has one with sponsored assets', async () => { - // deploy and add eligible assets (app, dataset, workerpool) - await execAsync(`${iexecPath} app init`); - await setAppUniqueName(); - const deployedApp = await runIExecCliRaw(`${iexecPath} app deploy`); - deployedAppAddress = deployedApp.address; - await addVoucherEligibleAsset(testChain)(deployedAppAddress, voucherType); - - await execAsync(`${iexecPath} dataset init`); - await setDatasetUniqueName(); - const deployedDataset = await runIExecCliRaw( - `${iexecPath} dataset deploy`, - ); - deployedDatasetAddress = deployedDataset.address; - await addVoucherEligibleAsset(testChain)( - deployedDatasetAddress, - voucherType, - ); - - await execAsync(`${iexecPath} workerpool init`); - await setWorkerpoolUniqueDescription(); - const deployedWorkerpool = await runIExecCliRaw( - `${iexecPath} workerpool deploy`, - ); - deployedWorkerpoolAddress = deployedWorkerpool.address; - await addVoucherEligibleAsset(testChain)( - deployedWorkerpoolAddress, - voucherType, - ); - - const randomRequesterAddress = await getRandomAddress(); - - await execAsync( - `${iexecPath} voucher authorize ${randomRequesterAddress} --raw`, - ); - - const raw = await execAsync(`${iexecPath} voucher show --raw`); - const res = JSON.parse(raw); - expect(res.ok).toBe(true); - expect(res.address).toBeDefined(); - expect(parseInt(res.balance, 16)).toBe(Number(voucherValue)); - expect(parseInt(res.type, 16)).toBe(Number(voucherType)); - expect(res.owner).toBe(userWallet.address); - expect(res.expirationTimestamp).toBeDefined(); - expect(res.allowanceAmount).toBeDefined(); - expect(res.sponsoredApps).toEqual([deployedAppAddress]); - expect(res.sponsoredDatasets).toEqual([deployedDatasetAddress]); - expect(res.authorizedAccounts).toEqual([randomRequesterAddress]); - }); - - test('returns error when no voucher is found for the user', async () => { - // use a new random wallet that doesn't have a voucher - const newWallet = await setRandomWallet(); - const raw = await execAsync(`${iexecPath} voucher show --raw`).catch( - (e) => e.message, - ); - const res = JSON.parse(raw); - expect(res.ok).toBe(false); - expect(res.error.message).toBe( - `No Voucher found for address ${newWallet.address}`, - ); - setWallet(userWallet.privateKey); - }); - }); - - describe('authorize', () => { - test('authorize the requester to use the voucher', async () => { - const raw = await execAsync( - `${iexecPath} voucher authorize ${requesterAddress} --raw`, - ); - const res = JSON.parse(raw); - expect(res.ok).toBe(true); - expect(res.txHash).toBeDefined(); - }); - - test('throw when requester is already authorized', async () => { - const raw = await execAsync( - `${iexecPath} voucher authorize ${requesterAddress} --raw`, - ).catch((e) => e.message); - const res = JSON.parse(raw); - expect(res.ok).toBe(false); - expect(res.error.message).toBe( - `${requesterAddress} is already authorized`, - ); - }); - - test('throw when the user has no voucher', async () => { - // use a new random wallet that doesn't have a voucher - const newWallet = await setRandomWallet(); - const raw = await execAsync( - `${iexecPath} voucher authorize ${requesterAddress} --raw`, - ).catch((e) => e.message); - const res = JSON.parse(raw); - expect(res.ok).toBe(false); - expect(res.error.message).toBe( - `No Voucher found for address ${newWallet.address}`, - ); - setWallet(userWallet.privateKey); - }); - }); - - describe('revoke', () => { - test('revoke the requester authorization to use the voucher', async () => { - const raw = await execAsync( - `${iexecPath} voucher revoke ${requesterAddress} --raw`, - ); - const res = JSON.parse(raw); - expect(res.ok).toBe(true); - expect(res.txHash).toBeDefined(); - }); - - test('throw when requester was not previously authorized', async () => { - const newRequesterAddress = await getRandomAddress(); - - const raw = await execAsync( - `${iexecPath} voucher revoke ${newRequesterAddress} --raw`, - ).catch((e) => e.message); - const res = JSON.parse(raw); - expect(res.ok).toBe(false); - expect(res.error.message).toBe( - `${newRequesterAddress} is not authorized`, - ); - }); - - test('throw when the user has no voucher', async () => { - // use a new random wallet that doesn't have a voucher - const newWallet = await setRandomWallet(); - const raw = await execAsync( - `${iexecPath} voucher revoke ${requesterAddress} --raw`, - ).catch((e) => e.message); - const res = JSON.parse(raw); - expect(res.ok).toBe(false); - expect(res.error.message).toBe( - `No Voucher found for address ${newWallet.address}`, - ); - setWallet(userWallet.privateKey); - }); - }); -}); diff --git a/test/cli/cli-test-utils.js b/test/cli/cli-test-utils.js index 81ae1bd7..d36faa52 100644 --- a/test/cli/cli-test-utils.js +++ b/test/cli/cli-test-utils.js @@ -73,8 +73,6 @@ export const setChain = iexecGateway: chain.iexecGatewayURL, resultProxy: chain.resultProxyURL, ensPublicResolver: chain.ensPublicResolverAddress, - voucherSubgraph: chain.voucherSubgraphURL, - voucherHub: chain.voucherHubAddress, useGas: chain.useGas, native: chain.isNative, ...chainOptions, diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 519413a5..5d91fb33 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -30,24 +30,6 @@ services: retries: 3 start_period: 30s - voucher-subgraph-deployer: - restart: 'no' - # https://github.com/iExecBlockchainComputing/iexec-voucher-subgraph - image: iexechub/voucher-subgraph-deployer:1.0.0 - environment: - RPC_URL: http://bellecour-fork:8545 - GRAPHNODE_URL: http://graphnode:8020 - IPFS_URL: http://ipfs:5001 - VOUCHER_HUB_ADDRESS: '0x3137B6DF4f36D338b82260eDBB2E7bab034AFEda' - VOUCHER_HUB_START_BLOCK: $BELLECOUR_FORK_BLOCK - depends_on: - bellecour-fork: - condition: service_healthy - graphnode: - condition: service_healthy - ipfs: - condition: service_healthy - graphnode-postgres: image: postgres:12 restart: unless-stopped @@ -327,5 +309,3 @@ services: condition: service_started custom-token-chain-compass: condition: service_healthy - voucher-subgraph-deployer: - condition: service_completed_successfully diff --git a/test/jest-setup.js b/test/jest-setup.js index 24621751..6ed9dd09 100644 --- a/test/jest-setup.js +++ b/test/jest-setup.js @@ -40,7 +40,7 @@ expect.extend({ try { getAddress(received); pass = true; - } catch (e) { + } catch { /* noop */ } return { diff --git a/test/lib/e2e/IExecConfig.test.js b/test/lib/e2e/IExecConfig.test.js index e93ad29a..23029164 100644 --- a/test/lib/e2e/IExecConfig.test.js +++ b/test/lib/e2e/IExecConfig.test.js @@ -1217,57 +1217,6 @@ describe('[IExecConfig]', () => { }); }); - describe('resolveVoucherSubgraphURL()', () => { - test('success', async () => { - const config = new IExecConfig({ - ethProvider: 'bellecour', - }); - const promise = config.resolveVoucherSubgraphURL(); - const url = await promise; - expect(typeof url).toBe('string'); - expect(url.length > 0).toBe(true); - }); - test('success when configured on custom chain', async () => { - const config = new IExecConfig( - { - ethProvider: unknownTestChain.rpcURL, - }, - { voucherSubgraphURL: 'https://custom-subgraph.iex.ec/subgraph/name' }, - ); - const promise = config.resolveVoucherSubgraphURL(); - await expect(promise).resolves.toBe( - 'https://custom-subgraph.iex.ec/subgraph/name', - ); - }); - test('success voucherSubgraphURL override', async () => { - const config = new IExecConfig( - { - ethProvider: 'bellecour', - }, - { voucherSubgraphURL: 'https://custom-subgraph.iex.ec/subgraph/name' }, - ); - const promise = config.resolveVoucherSubgraphURL(); - await expect(promise).resolves.toBe( - 'https://custom-subgraph.iex.ec/subgraph/name', - ); - }); - test('returns null when not configured on custom chain', async () => { - const config = new IExecConfig({ - ethProvider: unknownTestChain.rpcURL, - }); - const res = await config.resolveVoucherSubgraphURL(); - expect(res).toBe(null); - }); - test('throw on network error', async () => { - const config = new IExecConfig({ - ethProvider: 'http://localhost:8888', - }); - const promise = config.resolveVoucherSubgraphURL(); - await expect(promise).rejects.toThrow('Failed to detect network:'); - await expect(promise).rejects.toThrow(Error); - }); - }); - describe('resolveBridgeAddress()', () => { test('success', async () => { const config = new IExecConfig({ @@ -1441,57 +1390,4 @@ describe('[IExecConfig]', () => { await expect(promise).rejects.toThrow(Error); }); }); - - describe('resolveVoucherHubAddress()', () => { - test('success', async () => { - const config = new IExecConfig({ - ethProvider: 'bellecour', - }); - const promise = config.resolveVoucherHubAddress(); - const address = await promise; - expect(typeof address).toBe('string'); - expect(address.length).toBe(42); - }); - test('success voucherHubAddress override', async () => { - const voucherHubAddressOverride = getRandomAddress(); - const config = new IExecConfig( - { - ethProvider: 'bellecour', - }, - { - voucherHubAddress: voucherHubAddressOverride, - }, - ); - const promise = config.resolveVoucherHubAddress(); - await expect(promise).resolves.toBe(voucherHubAddressOverride); - }); - test('success with voucherHubAddress on custom chain', async () => { - const voucherHubAddressOverride = getRandomAddress(); - const config = new IExecConfig( - { - ethProvider: unknownTestChain.rpcURL, - }, - { - voucherHubAddress: voucherHubAddressOverride, - }, - ); - const promise = config.resolveVoucherHubAddress(); - await expect(promise).resolves.toBe(voucherHubAddressOverride); - }); - test('returns null on unknown chain', async () => { - const config = new IExecConfig({ - ethProvider: unknownTestChain.rpcURL, - }); - const res = await config.resolveVoucherHubAddress(); - expect(res).toBe(null); - }); - test('throw on network error', async () => { - const config = new IExecConfig({ - ethProvider: 'http://localhost:8888', - }); - const promise = config.resolveVoucherHubAddress(); - await expect(promise).rejects.toThrow('Failed to detect network:'); - await expect(promise).rejects.toThrow(Error); - }); - }); }); diff --git a/test/lib/e2e/IExecOrderModule.test.js b/test/lib/e2e/IExecOrderModule.test.js index 2791e369..6b294a1f 100644 --- a/test/lib/e2e/IExecOrderModule.test.js +++ b/test/lib/e2e/IExecOrderModule.test.js @@ -21,9 +21,6 @@ import { getRandomAddress, setNRlcBalance, NULL_ADDRESS, - createVoucher, - createVoucherType, - addVoucherEligibleAsset, SERVICE_UNREACHABLE_URL, SERVICE_HTTP_500_URL, setBalance, @@ -32,7 +29,7 @@ import '../../jest-setup.js'; import { errors } from '../../../src/lib/index.js'; import { DATASET_INFINITE_VOLUME } from '../../../src/lib/utils.js'; -const { MarketCallError, ConfigurationError } = errors; +const { MarketCallError } = errors; const iexecTestChain = TEST_CHAINS['bellecour-fork']; @@ -399,637 +396,634 @@ describe('order', () => { ); }); }); -}); -describe('signDatasetorder()', () => { - test('signs the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { address } = await deployRandomDataset(iexec); - const order = await iexec.order.createDatasetorder({ - dataset: address, - }); + describe('signDatasetorder()', () => { + test('signs the order', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const { address } = await deployRandomDataset(iexec); + const order = await iexec.order.createDatasetorder({ + dataset: address, + }); - const res = await iexec.order.signDatasetorder(order, { - preflightCheck: false, - }); - expect(res.salt).toBeTxHash(); - expect(res.sign).toMatch(signRegex); - expect(res).toEqual({ - ...order, - ...{ sign: res.sign, salt: res.salt }, + const res = await iexec.order.signDatasetorder(order, { + preflightCheck: false, + }); + expect(res.salt).toBeTxHash(); + expect(res.sign).toMatch(signRegex); + expect(res).toEqual({ + ...order, + ...{ sign: res.sign, salt: res.salt }, + }); }); - }); - test('preflightCheck dataset secret', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { address } = await deployRandomDataset(iexec); - const order = await iexec.order.createDatasetorder({ - dataset: address, - }); - await expect( - iexec.order.signDatasetorder({ ...order, tag: ['tee'] }), - ).rejects.toThrow( - new Error( - `Dataset encryption key is not set for dataset ${address} in the SMS. Dataset decryption will fail.`, - ), - ); - await expect( - iexec.order.signDatasetorder({ ...order, tag: ['tee', 'scone'] }), - ).rejects.toThrow( - new Error( - `Dataset encryption key is not set for dataset ${address} in the SMS. Dataset decryption will fail.`, - ), - ); - await expect( - iexec.order.signDatasetorder({ ...order, tag: ['tee', 'tdx'] }), - ).rejects.toThrow( - new Error( - `Dataset encryption key is not set for dataset ${address} in the SMS. Dataset decryption will fail.`, - ), - ); - await iexec.dataset.pushDatasetSecret( - address, - iexec.dataset.generateEncryptionKey(), - ); - await iexec.dataset.pushDatasetSecret( - address, - iexec.dataset.generateEncryptionKey(), - { teeFramework: TEE_FRAMEWORKS.TDX }, - ); - await expect( - iexec.order.signDatasetorder({ ...order, tag: ['tee'] }), - ).resolves.toBeDefined(); - await expect( - iexec.order.signDatasetorder({ ...order, tag: ['tee', 'tdx'] }), - ).resolves.toBeDefined(); - await expect( - iexec.order.signDatasetorder({ ...order, tag: ['tee', 'scone'] }), - ).resolves.toBeDefined(); - await expect( - iexec.order.signDatasetorder({ ...order, tag: ['tee', 'gramine'] }), - ).rejects.toThrow( - new Error( - `Dataset encryption key is not set for dataset ${address} in the SMS. Dataset decryption will fail.`, - ), - ); - }); + test('preflightCheck dataset secret', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const { address } = await deployRandomDataset(iexec); + const order = await iexec.order.createDatasetorder({ + dataset: address, + }); + await expect( + iexec.order.signDatasetorder({ ...order, tag: ['tee'] }), + ).rejects.toThrow( + new Error( + `Dataset encryption key is not set for dataset ${address} in the SMS. Dataset decryption will fail.`, + ), + ); + await expect( + iexec.order.signDatasetorder({ ...order, tag: ['tee', 'scone'] }), + ).rejects.toThrow( + new Error( + `Dataset encryption key is not set for dataset ${address} in the SMS. Dataset decryption will fail.`, + ), + ); - test('preflightCheck fails with invalid tag', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const order = await iexec.order.createDatasetorder({ - dataset: getRandomAddress(), - }); - await expect( - iexec.order.signDatasetorder({ ...order, tag: ['scone'] }), - ).rejects.toThrow(Error("'scone' tag must be used with 'tee' tag")); - await expect( - iexec.order.signDatasetorder({ ...order, tag: ['gramine'] }), - ).rejects.toThrow(Error("'gramine' tag must be used with 'tee' tag")); - await expect( - iexec.order.signDatasetorder({ - ...order, - tag: ['tee', 'scone', 'gramine'], - }), - ).rejects.toThrow( - new Error("tee framework tags are exclusive ('scone'|'gramine'|'tdx')"), - ); - }); -}); + // default SMS push (scone) + await iexec.dataset.pushDatasetSecret( + address, + iexec.dataset.generateEncryptionKey(), + ); + await iexec.dataset.pushDatasetSecret( + address, + iexec.dataset.generateEncryptionKey(), + { teeFramework: TEE_FRAMEWORKS.TDX }, + ); -describe('signWorkerpoolorder()', () => { - test('signs the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { address } = await deployRandomWorkerpool(iexec); - const order = await iexec.order.createWorkerpoolorder({ - workerpool: address, - category: 5, + await expect( + iexec.order.signDatasetorder({ ...order, tag: ['tee'] }), + ).resolves.toBeDefined(); + await expect( + iexec.order.signDatasetorder({ ...order, tag: ['tee', 'scone'] }), + ).resolves.toBeDefined(); + await expect( + iexec.order.signDatasetorder({ ...order, tag: ['tee', 'tdx'] }), + ).resolves.toBeDefined(); + await expect( + iexec.order.signDatasetorder({ ...order, tag: ['tee', 'gramine'] }), + ).rejects.toThrow( + new Error( + `Dataset encryption key is not set for dataset ${address} in the SMS. Dataset decryption will fail.`, + ), + ); }); - const res = await iexec.order.signWorkerpoolorder(order); - expect(res.salt).toBeTxHash(); - expect(res.sign).toMatch(signRegex); - expect(res).toEqual({ - ...order, - ...{ sign: res.sign, salt: res.salt }, + test('preflightCheck fails with invalid tag', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const order = await iexec.order.createDatasetorder({ + dataset: getRandomAddress(), + }); + await expect( + iexec.order.signDatasetorder({ ...order, tag: ['scone'] }), + ).rejects.toThrow(Error("'scone' tag must be used with 'tee' tag")); + await expect( + iexec.order.signDatasetorder({ ...order, tag: ['gramine'] }), + ).rejects.toThrow(Error("'gramine' tag must be used with 'tee' tag")); + await expect( + iexec.order.signDatasetorder({ + ...order, + tag: ['tee', 'scone', 'gramine'], + }), + ).rejects.toThrow( + new Error("tee framework tags are exclusive ('scone'|'gramine'|'tdx')"), + ); }); }); -}); -describe('signRequestorder()', () => { - test('signs the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const order = await iexec.order.createRequestorder({ - app: getRandomAddress(), - category: 5, - }); + describe('signWorkerpoolorder()', () => { + test('signs the order', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const { address } = await deployRandomWorkerpool(iexec); + const order = await iexec.order.createWorkerpoolorder({ + workerpool: address, + category: 5, + }); - const res = await iexec.order.signRequestorder(order, { - preflightCheck: false, - }); - expect(res.salt).toBeTxHash(); - expect(res.sign).toMatch(signRegex); - expect(res).toEqual({ - ...order, - ...{ params: JSON.stringify(order.params) }, - ...{ sign: res.sign, salt: res.salt }, + const res = await iexec.order.signWorkerpoolorder(order); + expect(res.salt).toBeTxHash(); + expect(res.sign).toMatch(signRegex); + expect(res).toEqual({ + ...order, + ...{ sign: res.sign, salt: res.salt }, + }); }); }); - test('preflightCheck fails with invalid tag', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const order = await iexec.order.createRequestorder({ - app: getRandomAddress(), - category: 5, - }); - await expect( - iexec.order.signRequestorder({ ...order, tag: ['scone'] }), - ).rejects.toThrow(Error("'scone' tag must be used with 'tee' tag")); - await expect( - iexec.order.signRequestorder({ ...order, tag: ['gramine'] }), - ).rejects.toThrow(Error("'gramine' tag must be used with 'tee' tag")); - await expect( - iexec.order.signRequestorder({ - ...order, - tag: ['tee', 'scone', 'gramine'], - }), - ).rejects.toThrow( - new Error("tee framework tags are exclusive ('scone'|'gramine'|'tdx')"), - ); - }); + describe('signRequestorder()', () => { + test('signs the order', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const order = await iexec.order.createRequestorder({ + app: getRandomAddress(), + category: 5, + }); - test('preflightCheck dropbox storage token exists', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const order = await iexec.order.createRequestorder({ - app: getRandomAddress(), - category: 5, - tag: ['tee', 'scone'], - params: { - iexec_result_storage_provider: 'dropbox', - }, + const res = await iexec.order.signRequestorder(order, { + preflightCheck: false, + }); + expect(res.salt).toBeTxHash(); + expect(res.sign).toMatch(signRegex); + expect(res).toEqual({ + ...order, + ...{ params: JSON.stringify(order.params) }, + ...{ sign: res.sign, salt: res.salt }, + }); }); - await expect(iexec.order.signRequestorder(order)).rejects.toThrow( - new Error( - 'Requester storage token is not set for selected provider "dropbox". Result archive upload will fail.', - ), - ); - - await iexec.storage.pushStorageToken('oops', { provider: 'dropbox' }); - const res = await iexec.order.signRequestorder(order); - expect(res.salt).toBeTxHash(); - expect(res.sign).toMatch(signRegex); - expect(res).toEqual({ - ...order, - ...{ params: JSON.stringify(order.params) }, - ...{ sign: res.sign, salt: res.salt }, + test('preflightCheck fails with invalid tag', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const order = await iexec.order.createRequestorder({ + app: getRandomAddress(), + category: 5, + }); + await expect( + iexec.order.signRequestorder({ ...order, tag: ['scone'] }), + ).rejects.toThrow(Error("'scone' tag must be used with 'tee' tag")); + await expect( + iexec.order.signRequestorder({ ...order, tag: ['gramine'] }), + ).rejects.toThrow(Error("'gramine' tag must be used with 'tee' tag")); + await expect( + iexec.order.signRequestorder({ + ...order, + tag: ['tee', 'scone', 'gramine'], + }), + ).rejects.toThrow( + new Error("tee framework tags are exclusive ('scone'|'gramine'|'tdx')"), + ); }); - }); - test('preflightCheck result encryption exists', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const order = await iexec.order.createRequestorder({ - app: getRandomAddress(), - category: 5, - params: { iexec_result_encryption: true }, - }); - await iexec.storage - .defaultStorageLogin() - .then(iexec.storage.pushStorageToken); - await expect(iexec.order.signRequestorder(order)).rejects.toThrow( - new Error( - 'Beneficiary result encryption key is not set in the SMS. Result encryption will fail.', - ), - ); - await iexec.result.pushResultEncryptionKey('oops'); - const res = await iexec.order.signRequestorder(order); - expect(res.salt).toBeTxHash(); - expect(res.sign).toMatch(signRegex); - expect(res).toEqual({ - ...order, - ...{ params: JSON.stringify(order.params) }, - ...{ sign: res.sign, salt: res.salt }, - }); - }); + test('preflightCheck dropbox storage token exists', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const order = await iexec.order.createRequestorder({ + app: getRandomAddress(), + category: 5, + tag: ['tee', 'scone'], + params: { + iexec_result_storage_provider: 'dropbox', + }, + }); - test('preflightCheck checks dataset encryption key exists for tee datasets', async () => { - const { iexec: iexecDatasetProvider } = getTestConfig(iexecTestChain)(); - const { iexec: iexecDatasetConsumer } = getTestConfig(iexecTestChain)(); + await expect(iexec.order.signRequestorder(order)).rejects.toThrow( + new Error( + 'Requester storage token is not set for selected provider "dropbox". Result archive upload will fail.', + ), + ); - await iexecDatasetConsumer.storage - .defaultStorageLogin() - .then(iexecDatasetConsumer.storage.pushStorageToken); - const { address: dataset } = - await deployRandomDataset(iexecDatasetProvider); + await iexec.storage.pushStorageToken('oops', { provider: 'dropbox' }); + const res = await iexec.order.signRequestorder(order); + expect(res.salt).toBeTxHash(); + expect(res.sign).toMatch(signRegex); + expect(res).toEqual({ + ...order, + ...{ params: JSON.stringify(order.params) }, + ...{ sign: res.sign, salt: res.salt }, + }); + }); - // non tee pass - await expect( - iexecDatasetConsumer.order - .createRequestorder({ - app: getRandomAddress(), - category: 5, - dataset, - }) - .then(iexecDatasetConsumer.order.signRequestorder), - ).resolves.toBeDefined(); + test('preflightCheck result encryption exists', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const order = await iexec.order.createRequestorder({ + app: getRandomAddress(), + category: 5, + params: { iexec_result_encryption: true }, + }); + await iexec.storage + .defaultStorageLogin() + .then(iexec.storage.pushStorageToken); + await expect(iexec.order.signRequestorder(order)).rejects.toThrow( + new Error( + 'Beneficiary result encryption key is not set in the SMS. Result encryption will fail.', + ), + ); + await iexec.result.pushResultEncryptionKey('oops'); + const res = await iexec.order.signRequestorder(order); + expect(res.salt).toBeTxHash(); + expect(res.sign).toMatch(signRegex); + expect(res).toEqual({ + ...order, + ...{ params: JSON.stringify(order.params) }, + ...{ sign: res.sign, salt: res.salt }, + }); + }); - // tee fail without secret - await expect( - iexecDatasetConsumer.order - .createRequestorder({ - app: getRandomAddress(), - category: 5, - dataset, - tag: ['tee', 'scone'], - }) - .then(iexecDatasetConsumer.order.signRequestorder), - ).rejects.toThrow( - new Error( - `Dataset encryption key is not set for dataset ${dataset} in the SMS. Dataset decryption will fail.`, - ), - ); - - // tee pass with secret - await iexecDatasetProvider.dataset.pushDatasetSecret( - dataset, - iexecDatasetProvider.dataset.generateEncryptionKey(), - ); - await expect( - iexecDatasetConsumer.order - .createRequestorder({ - app: getRandomAddress(), - category: 5, - dataset, - tag: ['tee', 'scone'], - }) - .then(iexecDatasetConsumer.order.signRequestorder), - ).resolves.toBeDefined(); - }); + test('preflightCheck checks dataset encryption key exists for tee datasets', async () => { + const { iexec: iexecDatasetProvider } = getTestConfig(iexecTestChain)(); + const { iexec: iexecDatasetConsumer } = getTestConfig(iexecTestChain)(); - test('preflightCheck requester secrets exist', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - await iexec.storage - .defaultStorageLogin() - .then(iexec.storage.pushStorageToken); + await iexecDatasetConsumer.storage + .defaultStorageLogin() + .then(iexecDatasetConsumer.storage.pushStorageToken); + const { address: dataset } = + await deployRandomDataset(iexecDatasetProvider); - // non requester secret pass - await expect( - iexec.order - .createRequestorder({ - app: getRandomAddress(), - category: 5, - tag: ['tee', 'scone'], - }) - .then(iexec.order.signRequestorder), - ).resolves.toBeDefined(); + // non tee pass + await expect( + iexecDatasetConsumer.order + .createRequestorder({ + app: getRandomAddress(), + category: 5, + dataset, + }) + .then(iexecDatasetConsumer.order.signRequestorder), + ).resolves.toBeDefined(); - // unset secret fail - await iexec.secrets.pushRequesterSecret('foo', 'secret'); - await expect( - iexec.order - .createRequestorder({ - app: getRandomAddress(), - category: 5, - tag: ['tee', 'scone'], - params: { - iexec_secrets: { - 1: 'foo', - 2: 'bar', - }, - }, - }) - .then(iexec.order.signRequestorder), - ).rejects.toThrow( - new Error( - `Requester secret "bar" is not set for requester ${wallet.address} in the SMS. Requester secret provisioning will fail.`, - ), - ); - // set secrets pass - await iexec.secrets.pushRequesterSecret('bar', 'secret'); - await expect( - iexec.order - .createRequestorder({ - app: getRandomAddress(), - category: 5, - tag: ['tee', 'scone'], - params: { - iexec_secrets: { - 1: 'foo', - 2: 'bar', - }, - }, - }) - .then(iexec.order.signRequestorder), - ).resolves.toBeDefined(); - }); -}); + // tee fail without secret + await expect( + iexecDatasetConsumer.order + .createRequestorder({ + app: getRandomAddress(), + category: 5, + dataset, + tag: ['tee', 'scone'], + }) + .then(iexecDatasetConsumer.order.signRequestorder), + ).rejects.toThrow( + new Error( + `Dataset encryption key is not set for dataset ${dataset} in the SMS. Dataset decryption will fail.`, + ), + ); -describe('hashApporder()', () => { - test('gives the order hash', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); - const order = { - app: '0x76fE91568d50C5fF9411223df5A0c50Ec5fa326A', - appprice: 0, - volume: 1000000, - tag: '0x0000000000000000000000000000000000000000000000000000000000000005', - datasetrestrict: '0x0000000000000000000000000000000000000000', - workerpoolrestrict: '0x0000000000000000000000000000000000000000', - requesterrestrict: '0x0000000000000000000000000000000000000000', - salt: '0xcadb4f169d98b940ae506dfc8ee7832e1ff36854aab92f89b7408257693207b3', - sign: '0x5b84b81dd0450897568fa1afdb7969f92259c2f9003a1bed0da96e00c9891957233ad6a0e16101b4ab7b2bf4d4aa117b58bae5fa2bad46522ec62e16ff3c36fe1b', - }; - const res = await iexec.order.hashApporder(order); - expect(res).toBe( - '0x210576e452027bc2430a32f6fae97bec8bd1f7bb7a96f59202d6947ec7d6de8f', - ); - }); -}); + // tee pass with secret + await iexecDatasetProvider.dataset.pushDatasetSecret( + dataset, + iexecDatasetProvider.dataset.generateEncryptionKey(), + ); + await expect( + iexecDatasetConsumer.order + .createRequestorder({ + app: getRandomAddress(), + category: 5, + dataset, + tag: ['tee', 'scone'], + }) + .then(iexecDatasetConsumer.order.signRequestorder), + ).resolves.toBeDefined(); + }); -describe('hashDatasetorder()', () => { - test('gives the order hash', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); - const order = { - dataset: '0x2Ad5773db1a705DB568fAd403cd247fee4808Fb8', - datasetprice: 0, - volume: 1, - tag: '0x0000000000000000000000000000000000000000000000000000000000000000', - apprestrict: '0x0000000000000000000000000000000000000000', - workerpoolrestrict: '0x0000000000000000000000000000000000000000', - requesterrestrict: '0x0000000000000000000000000000000000000000', - salt: '0x48380ababf82c79128c1e3ebcba70ce94c6a3ff0ba4125358d1e0c0f871e29e7', - sign: '0x4ce323a70464eb3b35aa90fcd1582e4733a57b16b0d6fb13ffa3189c2e970ffb399779d0c9d4a2d4b0a65adfc2037a7916a9a004148edcdf3dd1a9e12b3c1b0c1b', - }; - const res = await iexec.order.hashDatasetorder(order); - expect(res).toBe( - '0x5831e4e2911c431236a3df6d82698fcb849da8c781d7c4e9eb75ed551e4d35d4', - ); - }); -}); + test('preflightCheck requester secrets exist', async () => { + const { iexec, wallet } = getTestConfig(iexecTestChain)(); + await iexec.storage + .defaultStorageLogin() + .then(iexec.storage.pushStorageToken); -describe('hashWorkerpoolorder()', () => { - test('gives the order hash', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); - const order = { - workerpool: '0x9DEB16F7861123CE34AE755F48D30697eD066793', - workerpoolprice: 0, - volume: 4, - tag: '0x0000000000000000000000000000000000000000000000000000000000000000', - category: 3, - trust: 1, - apprestrict: '0x0000000000000000000000000000000000000000', - datasetrestrict: '0x0000000000000000000000000000000000000000', - requesterrestrict: '0x0000000000000000000000000000000000000000', - salt: '0x0c8d51b480466c65b459e828ed8549cf4b15ba1abda0ef5d454964c23f3edf62', - sign: '0xd8941d9974d6b6468a6dac46e88eb80a1575aedd5921d78e002483bf4faa72e319e4c128f9a7f927857c6039988ba456de8ec337078eb538b13488d2374c379e1c', - }; - const res = await iexec.order.hashWorkerpoolorder(order); - expect(res).toBe( - '0x7b23e26344284e809d7809395467d611ba148ef83b2ff3854e03430311f3f8fa', - ); - }); -}); + // non requester secret pass + await expect( + iexec.order + .createRequestorder({ + app: getRandomAddress(), + category: 5, + tag: ['tee', 'scone'], + }) + .then(iexec.order.signRequestorder), + ).resolves.toBeDefined(); -describe('hashRequestorder()', () => { - test('gives the order hash', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); - const order = { - app: '0x33c791fE02eDDBfF3D3d37176737Eb3F488E150F', - dataset: '0x69d4a400CFf9838985cD2950aafF28289afc6ad3', - workerpool: '0x0000000000000000000000000000000000000000', - params: - '{"iexec_result_storage_provider":"ipfs","iexec_result_storage_proxy":"https://result.v8-bellecour.iex.ec","iexec_result_encryption":false,"iexec_args":"\\"0x4e64fb5fa96eb73ef37dacd416eb2bade0ea8f9e7efebe42abe9a062a9caede836ee4da1ec1a72264e1287e74fba7fdc76edce05729c4b2ecf6fb8970f13f8321b 22\\""}', - appmaxprice: 0, - datasetmaxprice: 0, - workerpoolmaxprice: 0, - volume: 1, - tag: '0x0000000000000000000000000000000000000000000000000000000000000000', - category: 0, - trust: 0, - requester: '0x4CF114732732c072D49a783e80C6Fe9fe8BA420a', - beneficiary: '0x4CF114732732c072D49a783e80C6Fe9fe8BA420a', - callback: '0x0000000000000000000000000000000000000000', - salt: '0xef743ff11d68960e724362944b6cd22b59b88402a17f8a1ffabf8fb9be2f4008', - sign: '0xdcd90a96f4c5cd05a0f907220e173a038e01e2a647bd9c8e04714be5dd4f986b0478cb69cf46b3cb3eb05ee74d2b91868bee4d96a89bc79ac8d8cccc96810bf21c', - }; - const res = await iexec.order.hashRequestorder(order); - expect(res).toBeTxHash(); - expect(res).toBe( - '0x8096dd3852b29d6e86b03505ded47fbc96b0bacc9be097f11de3a747ee0e4283', - ); + // unset secret fail + await iexec.secrets.pushRequesterSecret('foo', 'secret'); + await expect( + iexec.order + .createRequestorder({ + app: getRandomAddress(), + category: 5, + tag: ['tee', 'scone'], + params: { + iexec_secrets: { + 1: 'foo', + 2: 'bar', + }, + }, + }) + .then(iexec.order.signRequestorder), + ).rejects.toThrow( + new Error( + `Requester secret "bar" is not set for requester ${wallet.address} in the SMS. Requester secret provisioning will fail.`, + ), + ); + // set secrets pass + await iexec.secrets.pushRequesterSecret('bar', 'secret'); + await expect( + iexec.order + .createRequestorder({ + app: getRandomAddress(), + category: 5, + tag: ['tee', 'scone'], + params: { + iexec_secrets: { + 1: 'foo', + 2: 'bar', + }, + }, + }) + .then(iexec.order.signRequestorder), + ).resolves.toBeDefined(); + }); }); -}); -describe('cancelApporder()', () => { - test('revokes the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const order = await deployAndGetApporder(iexec); - const res = await iexec.order.cancelApporder(order); - expect(res.order).toEqual(order); - expect(res.txHash).toBeTxHash(); - await expect(iexec.order.cancelApporder(order)).rejects.toThrow( - new Error('apporder already canceled'), - ); + describe('hashApporder()', () => { + test('gives the order hash', async () => { + const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const order = { + app: '0x76fE91568d50C5fF9411223df5A0c50Ec5fa326A', + appprice: 0, + volume: 1000000, + tag: '0x0000000000000000000000000000000000000000000000000000000000000005', + datasetrestrict: '0x0000000000000000000000000000000000000000', + workerpoolrestrict: '0x0000000000000000000000000000000000000000', + requesterrestrict: '0x0000000000000000000000000000000000000000', + salt: '0xcadb4f169d98b940ae506dfc8ee7832e1ff36854aab92f89b7408257693207b3', + sign: '0x5b84b81dd0450897568fa1afdb7969f92259c2f9003a1bed0da96e00c9891957233ad6a0e16101b4ab7b2bf4d4aa117b58bae5fa2bad46522ec62e16ff3c36fe1b', + }; + const res = await iexec.order.hashApporder(order); + expect(res).toBe( + '0x210576e452027bc2430a32f6fae97bec8bd1f7bb7a96f59202d6947ec7d6de8f', + ); + }); }); -}); -describe('cancelDatasetorder()', () => { - test('revokes the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const order = await deployAndGetDatasetorder(iexec); - const res = await iexec.order.cancelDatasetorder(order); - expect(res.order).toEqual(order); - expect(res.txHash).toBeTxHash(); - await expect(iexec.order.cancelDatasetorder(order)).rejects.toThrow( - new Error('datasetorder already canceled'), - ); + describe('hashDatasetorder()', () => { + test('gives the order hash', async () => { + const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const order = { + dataset: '0x2Ad5773db1a705DB568fAd403cd247fee4808Fb8', + datasetprice: 0, + volume: 1, + tag: '0x0000000000000000000000000000000000000000000000000000000000000000', + apprestrict: '0x0000000000000000000000000000000000000000', + workerpoolrestrict: '0x0000000000000000000000000000000000000000', + requesterrestrict: '0x0000000000000000000000000000000000000000', + salt: '0x48380ababf82c79128c1e3ebcba70ce94c6a3ff0ba4125358d1e0c0f871e29e7', + sign: '0x4ce323a70464eb3b35aa90fcd1582e4733a57b16b0d6fb13ffa3189c2e970ffb399779d0c9d4a2d4b0a65adfc2037a7916a9a004148edcdf3dd1a9e12b3c1b0c1b', + }; + const res = await iexec.order.hashDatasetorder(order); + expect(res).toBe( + '0x5831e4e2911c431236a3df6d82698fcb849da8c781d7c4e9eb75ed551e4d35d4', + ); + }); }); -}); -describe('cancelWorkerpoolorder()', () => { - test('revokes the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const order = await deployAndGetWorkerpoolorder(iexec); - const res = await iexec.order.cancelWorkerpoolorder(order); - expect(res.order).toEqual(order); - expect(res.txHash).toBeTxHash(); - await expect(iexec.order.cancelWorkerpoolorder(order)).rejects.toThrow( - new Error('workerpoolorder already canceled'), - ); + describe('hashWorkerpoolorder()', () => { + test('gives the order hash', async () => { + const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const order = { + workerpool: '0x9DEB16F7861123CE34AE755F48D30697eD066793', + workerpoolprice: 0, + volume: 4, + tag: '0x0000000000000000000000000000000000000000000000000000000000000000', + category: 3, + trust: 1, + apprestrict: '0x0000000000000000000000000000000000000000', + datasetrestrict: '0x0000000000000000000000000000000000000000', + requesterrestrict: '0x0000000000000000000000000000000000000000', + salt: '0x0c8d51b480466c65b459e828ed8549cf4b15ba1abda0ef5d454964c23f3edf62', + sign: '0xd8941d9974d6b6468a6dac46e88eb80a1575aedd5921d78e002483bf4faa72e319e4c128f9a7f927857c6039988ba456de8ec337078eb538b13488d2374c379e1c', + }; + const res = await iexec.order.hashWorkerpoolorder(order); + expect(res).toBe( + '0x7b23e26344284e809d7809395467d611ba148ef83b2ff3854e03430311f3f8fa', + ); + }); }); -}); -describe('cancelRequestorder()', () => { - test('revokes the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const order = await iexec.order - .createRequestorder({ - app: getRandomAddress(), + describe('hashRequestorder()', () => { + test('gives the order hash', async () => { + const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const order = { + app: '0x33c791fE02eDDBfF3D3d37176737Eb3F488E150F', + dataset: '0x69d4a400CFf9838985cD2950aafF28289afc6ad3', + workerpool: '0x0000000000000000000000000000000000000000', + params: + '{"iexec_result_storage_provider":"ipfs","iexec_result_storage_proxy":"https://result.v8-bellecour.iex.ec","iexec_result_encryption":false,"iexec_args":"\\"0x4e64fb5fa96eb73ef37dacd416eb2bade0ea8f9e7efebe42abe9a062a9caede836ee4da1ec1a72264e1287e74fba7fdc76edce05729c4b2ecf6fb8970f13f8321b 22\\""}', appmaxprice: 0, + datasetmaxprice: 0, workerpoolmaxprice: 0, - requester: await iexec.wallet.getAddress(), volume: 1, - category: 1, - }) - .then((o) => iexec.order.signRequestorder(o, { preflightCheck: false })); - const res = await iexec.order.cancelRequestorder(order); - expect(res.order).toEqual(order); - expect(res.txHash).toBeTxHash(); - await expect(iexec.order.cancelRequestorder(order)).rejects.toThrow( - new Error('requestorder already canceled'), - ); - }); -}); - -describe('publish...order()', () => { - test("throw a MarketCallError when the Market API can't be reached", async () => { - const { iexec } = getTestConfig(iexecTestChain)({ - options: { - iexecGatewayURL: SERVICE_UNREACHABLE_URL, - }, + tag: '0x0000000000000000000000000000000000000000000000000000000000000000', + category: 0, + trust: 0, + requester: '0x4CF114732732c072D49a783e80C6Fe9fe8BA420a', + beneficiary: '0x4CF114732732c072D49a783e80C6Fe9fe8BA420a', + callback: '0x0000000000000000000000000000000000000000', + salt: '0xef743ff11d68960e724362944b6cd22b59b88402a17f8a1ffabf8fb9be2f4008', + sign: '0xdcd90a96f4c5cd05a0f907220e173a038e01e2a647bd9c8e04714be5dd4f986b0478cb69cf46b3cb3eb05ee74d2b91868bee4d96a89bc79ac8d8cccc96810bf21c', + }; + const res = await iexec.order.hashRequestorder(order); + expect(res).toBeTxHash(); + expect(res).toBe( + '0x8096dd3852b29d6e86b03505ded47fbc96b0bacc9be097f11de3a747ee0e4283', + ); }); - const requestorder = await iexec.order - .createRequestorder({ app: getRandomAddress(), category: 0 }) - .then(iexec.order.signRequestorder); - await expectAsyncCustomError( - iexec.order.publishRequestorder(requestorder), - { - constructor: MarketCallError, - message: `Market API error: Connection to ${SERVICE_UNREACHABLE_URL} failed with a network error`, - }, - ); }); - test('throw a MarketCallError when the Market API encounters an error', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ - options: { - iexecGatewayURL: SERVICE_HTTP_500_URL, - }, + describe('cancelApporder()', () => { + test('revokes the order', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const order = await deployAndGetApporder(iexec); + const res = await iexec.order.cancelApporder(order); + expect(res.order).toEqual(order); + expect(res.txHash).toBeTxHash(); + await expect(iexec.order.cancelApporder(order)).rejects.toThrow( + new Error('apporder already canceled'), + ); }); - const requestorder = await iexec.order - .createRequestorder({ app: getRandomAddress(), category: 0 }) - .then(iexec.order.signRequestorder); - await expectAsyncCustomError( - iexec.order.publishRequestorder(requestorder), - { - constructor: MarketCallError, - message: `Market API error: Server at ${SERVICE_HTTP_500_URL} encountered an internal error`, - }, - ); }); - describe('publishApporder()', () => { - test('publishes the order', async () => { + describe('cancelDatasetorder()', () => { + test('revokes the order', async () => { const { iexec } = getTestConfig(iexecTestChain)(); - const apporder = await deployAndGetApporder(iexec); - const orderHash = await iexec.order.publishApporder(apporder); - expect(orderHash).toBeTxHash(); - }); - }); - - describe('publishDatasetorder()', () => { - test('publishes the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const datasetorder = await deployAndGetDatasetorder(iexec); - const orderHash = await iexec.order.publishDatasetorder(datasetorder); - expect(orderHash).toBeTxHash(); - }); - - test('preflightChecks dataset secret exists for tee tag', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const datasetorder = await deployAndGetDatasetorder(iexec, { - tag: ['tee'], - }); - const datasetAddress = datasetorder.dataset; - await expect( - iexec.order.publishDatasetorder(datasetorder), - ).rejects.toThrow( - new Error( - `Dataset encryption key is not set for dataset ${datasetAddress} in the SMS. Dataset decryption will fail.`, - ), - ); - - const orderHashSkipPreflight = await iexec.order.publishDatasetorder( - await iexec.order.signDatasetorder(datasetorder, { - preflightCheck: false, - }), - { preflightCheck: false }, - ); - expect(orderHashSkipPreflight).toBeTxHash(); - - await iexec.dataset.pushDatasetSecret(datasetAddress, 'foo'); - - const orderHashPreflight = await iexec.order.publishDatasetorder( - await iexec.order.signDatasetorder(datasetorder, { - preflightCheck: false, - }), + const order = await deployAndGetDatasetorder(iexec); + const res = await iexec.order.cancelDatasetorder(order); + expect(res.order).toEqual(order); + expect(res.txHash).toBeTxHash(); + await expect(iexec.order.cancelDatasetorder(order)).rejects.toThrow( + new Error('datasetorder already canceled'), ); - expect(orderHashPreflight).toBeTxHash(); }); }); - describe('publishWorkerpoolorder()', () => { - test('publishes the order', async () => { + describe('cancelWorkerpoolorder()', () => { + test('revokes the order', async () => { const { iexec } = getTestConfig(iexecTestChain)(); - const workerpoolorder = await deployAndGetWorkerpoolorder(iexec); - const orderHash = - await iexec.order.publishWorkerpoolorder(workerpoolorder); - expect(orderHash).toBeTxHash(); + const order = await deployAndGetWorkerpoolorder(iexec); + const res = await iexec.order.cancelWorkerpoolorder(order); + expect(res.order).toEqual(order); + expect(res.txHash).toBeTxHash(); + await expect(iexec.order.cancelWorkerpoolorder(order)).rejects.toThrow( + new Error('workerpoolorder already canceled'), + ); }); }); - describe('publishRequestorder()', () => { - test('publishes the order (skip preflightCheck)', async () => { + describe('cancelRequestorder()', () => { + test('revokes the order', async () => { const { iexec } = getTestConfig(iexecTestChain)(); - const apporder = await deployAndGetApporder(iexec); - await iexec.order.publishApporder(apporder); - const requestorder = await iexec.order + const order = await iexec.order .createRequestorder({ - requester: await iexec.wallet.getAddress(), - app: apporder.app, - appmaxprice: apporder.appprice, - dataset: NULL_ADDRESS, - datasetmaxprice: 0, - workerpool: NULL_ADDRESS, + app: getRandomAddress(), + appmaxprice: 0, workerpoolmaxprice: 0, - category: 1, - trust: 0, + requester: await iexec.wallet.getAddress(), volume: 1, + category: 1, }) .then((o) => iexec.order.signRequestorder(o, { preflightCheck: false }), ); - const orderHash = await iexec.order.publishRequestorder(requestorder, { - preflightCheck: false, + const res = await iexec.order.cancelRequestorder(order); + expect(res.order).toEqual(order); + expect(res.txHash).toBeTxHash(); + await expect(iexec.order.cancelRequestorder(order)).rejects.toThrow( + new Error('requestorder already canceled'), + ); + }); + }); + + describe('publish...order()', () => { + test("throw a MarketCallError when the Market API can't be reached", async () => { + const { iexec } = getTestConfig(iexecTestChain)({ + options: { + iexecGatewayURL: SERVICE_UNREACHABLE_URL, + }, }); - expect(orderHash).toBeTxHash(); + const requestorder = await iexec.order + .createRequestorder({ app: getRandomAddress(), category: 0 }) + .then(iexec.order.signRequestorder); + await expectAsyncCustomError( + iexec.order.publishRequestorder(requestorder), + { + constructor: MarketCallError, + message: `Market API error: Connection to ${SERVICE_UNREACHABLE_URL} failed with a network error`, + }, + ); }); - test('preflightCheck result encryption key', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { iexec: iexecAppDev } = getTestConfig(iexecTestChain)(); - const apporder = await deployAndGetApporder(iexecAppDev, { - teeFramework: TEE_FRAMEWORKS.SCONE, - tag: ['tee', 'scone'], + test('throw a MarketCallError when the Market API encounters an error', async () => { + const { iexec } = getTestConfig(iexecTestChain)({ + options: { + iexecGatewayURL: SERVICE_HTTP_500_URL, + }, }); - await iexecAppDev.order.publishApporder(apporder); const requestorder = await iexec.order - .createRequestorder({ - app: apporder.app, - appmaxprice: apporder.appprice, - category: 1, - params: { iexec_result_encryption: true }, - }) - .then((o) => - iexec.order.signRequestorder(o, { preflightCheck: false }), - ); - await expect( + .createRequestorder({ app: getRandomAddress(), category: 0 }) + .then(iexec.order.signRequestorder); + await expectAsyncCustomError( iexec.order.publishRequestorder(requestorder), - ).rejects.toThrow( - new Error( - 'Beneficiary result encryption key is not set in the SMS. Result encryption will fail.', - ), + { + constructor: MarketCallError, + message: `Market API error: Server at ${SERVICE_HTTP_500_URL} encountered an internal error`, + }, ); - await iexec.result.pushResultEncryptionKey( - `-----BEGIN PUBLIC KEY----- + }); + + describe('publishApporder()', () => { + test('publishes the order', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const apporder = await deployAndGetApporder(iexec); + const orderHash = await iexec.order.publishApporder(apporder); + expect(orderHash).toBeTxHash(); + }); + }); + + describe('publishDatasetorder()', () => { + test('publishes the order', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const datasetorder = await deployAndGetDatasetorder(iexec); + const orderHash = await iexec.order.publishDatasetorder(datasetorder); + expect(orderHash).toBeTxHash(); + }); + + test('preflightChecks dataset secret exists for tee tag', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const datasetorder = await deployAndGetDatasetorder(iexec, { + tag: ['tee'], + }); + const datasetAddress = datasetorder.dataset; + await expect( + iexec.order.publishDatasetorder(datasetorder), + ).rejects.toThrow( + new Error( + `Dataset encryption key is not set for dataset ${datasetAddress} in the SMS. Dataset decryption will fail.`, + ), + ); + + const orderHashSkipPreflight = await iexec.order.publishDatasetorder( + await iexec.order.signDatasetorder(datasetorder, { + preflightCheck: false, + }), + { preflightCheck: false }, + ); + expect(orderHashSkipPreflight).toBeTxHash(); + + await iexec.dataset.pushDatasetSecret(datasetAddress, 'foo'); + + const orderHashPreflight = await iexec.order.publishDatasetorder( + await iexec.order.signDatasetorder(datasetorder, { + preflightCheck: false, + }), + ); + expect(orderHashPreflight).toBeTxHash(); + }); + }); + + describe('publishWorkerpoolorder()', () => { + test('publishes the order', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const workerpoolorder = await deployAndGetWorkerpoolorder(iexec); + const orderHash = + await iexec.order.publishWorkerpoolorder(workerpoolorder); + expect(orderHash).toBeTxHash(); + }); + }); + + describe('publishRequestorder()', () => { + test('publishes the order (skip preflightCheck)', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const apporder = await deployAndGetApporder(iexec); + await iexec.order.publishApporder(apporder); + const requestorder = await iexec.order + .createRequestorder({ + requester: await iexec.wallet.getAddress(), + app: apporder.app, + appmaxprice: apporder.appprice, + dataset: NULL_ADDRESS, + datasetmaxprice: 0, + workerpool: NULL_ADDRESS, + workerpoolmaxprice: 0, + category: 1, + trust: 0, + volume: 1, + }) + .then((o) => + iexec.order.signRequestorder(o, { preflightCheck: false }), + ); + const orderHash = await iexec.order.publishRequestorder(requestorder, { + preflightCheck: false, + }); + expect(orderHash).toBeTxHash(); + }); + + test('preflightCheck result encryption key', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec: iexecAppDev } = getTestConfig(iexecTestChain)(); + const apporder = await deployAndGetApporder(iexecAppDev, { + teeFramework: TEE_FRAMEWORKS.SCONE, + tag: ['tee', 'scone'], + }); + await iexecAppDev.order.publishApporder(apporder); + const requestorder = await iexec.order + .createRequestorder({ + app: apporder.app, + appmaxprice: apporder.appprice, + category: 1, + params: { iexec_result_encryption: true }, + }) + .then((o) => + iexec.order.signRequestorder(o, { preflightCheck: false }), + ); + await expect( + iexec.order.publishRequestorder(requestorder), + ).rejects.toThrow( + new Error( + 'Beneficiary result encryption key is not set in the SMS. Result encryption will fail.', + ), + ); + await iexec.result.pushResultEncryptionKey( + `-----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA29Y2NYC08oFJ8GxPR3dK kI+Au+6keWHZ8CXs9f54WrXlNusNqqhOH7h4fQKaNHhptqSutmo6xYwmen4eUqe6 72NnmTeBpexvlHj16uDqgVoySVMaYMSwexRr+n7BQ2NWYntYc3r0ZjBACK7NMyrb @@ -1043,549 +1037,443 @@ describe('publish...order()', () => { oSEDTczO+ZMeoYGNQwiFpetTB7E4zNfxofllEvMax3/VOFurRbwDlMavD0LPeRM6 MUkxe2lT4YFowUo6JCUFlPcCAwEAAQ== -----END PUBLIC KEY-----`, - ); - const orderHash = await iexec.order.publishRequestorder(requestorder); - expect(orderHash).toBeTxHash(); - }); - - test('preflightCheck dropbox token', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { iexec: iexecAppDev } = getTestConfig(iexecTestChain)(); - const apporder = await deployAndGetApporder(iexecAppDev, { - teeFramework: TEE_FRAMEWORKS.SCONE, - tag: ['tee', 'scone'], + ); + const orderHash = await iexec.order.publishRequestorder(requestorder); + expect(orderHash).toBeTxHash(); }); - await iexecAppDev.order.publishApporder(apporder); - const requestorder = await iexec.order - .createRequestorder({ - app: apporder.app, - appmaxprice: apporder.appprice, - category: 1, - params: { iexec_result_storage_provider: 'dropbox' }, + + test('preflightCheck dropbox token', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec: iexecAppDev } = getTestConfig(iexecTestChain)(); + const apporder = await deployAndGetApporder(iexecAppDev, { + teeFramework: TEE_FRAMEWORKS.SCONE, tag: ['tee', 'scone'], - }) - .then((o) => - iexec.order.signRequestorder(o, { preflightCheck: false }), + }); + await iexecAppDev.order.publishApporder(apporder); + const requestorder = await iexec.order + .createRequestorder({ + app: apporder.app, + appmaxprice: apporder.appprice, + category: 1, + params: { iexec_result_storage_provider: 'dropbox' }, + tag: ['tee', 'scone'], + }) + .then((o) => + iexec.order.signRequestorder(o, { preflightCheck: false }), + ); + await expect( + iexec.order.publishRequestorder(requestorder), + ).rejects.toThrow( + new Error( + 'Requester storage token is not set for selected provider "dropbox". Result archive upload will fail.', + ), ); - await expect( - iexec.order.publishRequestorder(requestorder), - ).rejects.toThrow( - new Error( - 'Requester storage token is not set for selected provider "dropbox". Result archive upload will fail.', - ), - ); - await iexec.storage.pushStorageToken(`foo`, { provider: 'dropbox' }); - const orderHash = await iexec.order.publishRequestorder(requestorder); - expect(orderHash).toBeTxHash(); - }); - }); -}); - -describe('unpublish...order()', () => { - test("throw a MarketCallError when the Market API can't be reached", async () => { - const { iexec } = getTestConfig(iexecTestChain)({ - options: { - iexecGatewayURL: SERVICE_UNREACHABLE_URL, - }, - }); - await expectAsyncCustomError(iexec.order.unpublishAllRequestorders(), { - constructor: MarketCallError, - message: `Market API error: Connection to ${SERVICE_UNREACHABLE_URL} failed with a network error`, + await iexec.storage.pushStorageToken(`foo`, { provider: 'dropbox' }); + const orderHash = await iexec.order.publishRequestorder(requestorder); + expect(orderHash).toBeTxHash(); + }); }); }); - test('throw a MarketCallError when the Market API encounters an error', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ - options: { - iexecGatewayURL: SERVICE_HTTP_500_URL, - }, - }); - await expectAsyncCustomError(iexec.order.unpublishAllRequestorders(), { - constructor: MarketCallError, - message: `Market API error: Server at ${SERVICE_HTTP_500_URL} encountered an internal error`, + describe('unpublish...order()', () => { + test("throw a MarketCallError when the Market API can't be reached", async () => { + const { iexec } = getTestConfig(iexecTestChain)({ + options: { + iexecGatewayURL: SERVICE_UNREACHABLE_URL, + }, + }); + await expectAsyncCustomError(iexec.order.unpublishAllRequestorders(), { + constructor: MarketCallError, + message: `Market API error: Connection to ${SERVICE_UNREACHABLE_URL} failed with a network error`, + }); }); - }); - describe('unpublishApporder()', () => { - test('unpublish the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const apporder = await deployAndGetApporder(iexec); - const orderHash = await iexec.order.publishApporder(apporder); - const unpublishRes = await iexec.order.unpublishApporder(orderHash); - expect(unpublishRes).toBe(orderHash); - await expect(iexec.order.unpublishApporder(orderHash)).rejects.toThrow( - new Error( - `API error: apporder with orderHash ${orderHash} is not published`, - ), - ); + test('throw a MarketCallError when the Market API encounters an error', async () => { + const { iexec } = getTestConfig(iexecTestChain)({ + options: { + iexecGatewayURL: SERVICE_HTTP_500_URL, + }, + }); + await expectAsyncCustomError(iexec.order.unpublishAllRequestorders(), { + constructor: MarketCallError, + message: `Market API error: Server at ${SERVICE_HTTP_500_URL} encountered an internal error`, + }); }); - }); - describe('unpublishDatasetorder()', () => { - test('unpublish the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const datasetorder = await deployAndGetDatasetorder(iexec); - const orderHash = await iexec.order.publishDatasetorder(datasetorder, { - preflightCheck: false, + describe('unpublishApporder()', () => { + test('unpublish the order', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const apporder = await deployAndGetApporder(iexec); + const orderHash = await iexec.order.publishApporder(apporder); + const unpublishRes = await iexec.order.unpublishApporder(orderHash); + expect(unpublishRes).toBe(orderHash); + await expect(iexec.order.unpublishApporder(orderHash)).rejects.toThrow( + new Error( + `API error: apporder with orderHash ${orderHash} is not published`, + ), + ); }); - const unpublishRes = await iexec.order.unpublishDatasetorder(orderHash); - expect(unpublishRes).toBe(orderHash); - await expect( - iexec.order.unpublishDatasetorder(orderHash), - ).rejects.toThrow( - new Error( - `API error: datasetorder with orderHash ${orderHash} is not published`, - ), - ); }); - }); - describe('unpublishWorkerpoolorder()', () => { - test('unpublish the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const workerpoolorder = await deployAndGetWorkerpoolorder(iexec); - const orderHash = - await iexec.order.publishWorkerpoolorder(workerpoolorder); - const unpublishRes = - await iexec.order.unpublishWorkerpoolorder(orderHash); - expect(unpublishRes).toBe(orderHash); - await expect( - iexec.order.unpublishWorkerpoolorder(orderHash), - ).rejects.toThrow( - new Error( - `API error: workerpoolorder with orderHash ${orderHash} is not published`, - ), - ); + describe('unpublishDatasetorder()', () => { + test('unpublish the order', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const datasetorder = await deployAndGetDatasetorder(iexec); + const orderHash = await iexec.order.publishDatasetorder(datasetorder, { + preflightCheck: false, + }); + const unpublishRes = await iexec.order.unpublishDatasetorder(orderHash); + expect(unpublishRes).toBe(orderHash); + await expect( + iexec.order.unpublishDatasetorder(orderHash), + ).rejects.toThrow( + new Error( + `API error: datasetorder with orderHash ${orderHash} is not published`, + ), + ); + }); }); - }); - describe('unpublishRequestorder()', () => { - test('unpublish the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const apporder = await deployAndGetApporder(iexec); - await iexec.order.publishApporder(apporder); - const requestorder = await iexec.order - .createRequestorder({ - requester: await iexec.wallet.getAddress(), - app: apporder.app, - appmaxprice: apporder.appprice, - dataset: NULL_ADDRESS, - datasetmaxprice: 0, - workerpool: NULL_ADDRESS, - workerpoolmaxprice: 0, - category: 1, - trust: 0, - volume: 1, - }) - .then((o) => - iexec.order.signRequestorder(o, { preflightCheck: false }), + describe('unpublishWorkerpoolorder()', () => { + test('unpublish the order', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const workerpoolorder = await deployAndGetWorkerpoolorder(iexec); + const orderHash = + await iexec.order.publishWorkerpoolorder(workerpoolorder); + const unpublishRes = + await iexec.order.unpublishWorkerpoolorder(orderHash); + expect(unpublishRes).toBe(orderHash); + await expect( + iexec.order.unpublishWorkerpoolorder(orderHash), + ).rejects.toThrow( + new Error( + `API error: workerpoolorder with orderHash ${orderHash} is not published`, + ), ); - const orderHash = await iexec.order.publishRequestorder(requestorder, { - preflightCheck: false, }); - const unpublishRes = await iexec.order.unpublishRequestorder(orderHash); - expect(unpublishRes).toBe(orderHash); - await expect( - iexec.order.unpublishRequestorder(orderHash), - ).rejects.toThrow( - new Error( - `API error: requestorder with orderHash ${orderHash} is not published`, - ), - ); }); - }); - describe('unpublishLastApporder()', () => { - test('unpublish the order', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - const apporder = await deployAndGetApporder(iexec); - const orderHash = await iexec.order.publishApporder(apporder); - const lastApporder = await iexec.order.signApporder(apporder); - const lastOrderHash = await iexec.order.publishApporder(lastApporder); - const unpublishLastRes = await iexec.order.unpublishLastApporder( - apporder.app, - ); - expect(unpublishLastRes).toBe(lastOrderHash); - const unpublishLast2Res = await iexec.order.unpublishLastApporder( - apporder.app, - ); - expect(unpublishLast2Res).toBe(orderHash); - await expect( - iexec.order.unpublishLastApporder(apporder.app), - ).rejects.toThrow( - new Error( - `API error: no open apporder published by signer ${wallet.address} for app ${apporder.app}`, - ), - ); + describe('unpublishRequestorder()', () => { + test('unpublish the order', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const apporder = await deployAndGetApporder(iexec); + await iexec.order.publishApporder(apporder); + const requestorder = await iexec.order + .createRequestorder({ + requester: await iexec.wallet.getAddress(), + app: apporder.app, + appmaxprice: apporder.appprice, + dataset: NULL_ADDRESS, + datasetmaxprice: 0, + workerpool: NULL_ADDRESS, + workerpoolmaxprice: 0, + category: 1, + trust: 0, + volume: 1, + }) + .then((o) => + iexec.order.signRequestorder(o, { preflightCheck: false }), + ); + const orderHash = await iexec.order.publishRequestorder(requestorder, { + preflightCheck: false, + }); + const unpublishRes = await iexec.order.unpublishRequestorder(orderHash); + expect(unpublishRes).toBe(orderHash); + await expect( + iexec.order.unpublishRequestorder(orderHash), + ).rejects.toThrow( + new Error( + `API error: requestorder with orderHash ${orderHash} is not published`, + ), + ); + }); }); - }); - describe('unpublishLastDatasetorder()', () => { - test('unpublish the order', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - const datasetorder = await deployAndGetDatasetorder(iexec); - const orderHash = await iexec.order.publishDatasetorder(datasetorder, { - preflightCheck: false, + describe('unpublishLastApporder()', () => { + test('unpublish the order', async () => { + const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const apporder = await deployAndGetApporder(iexec); + const orderHash = await iexec.order.publishApporder(apporder); + const lastApporder = await iexec.order.signApporder(apporder); + const lastOrderHash = await iexec.order.publishApporder(lastApporder); + const unpublishLastRes = await iexec.order.unpublishLastApporder( + apporder.app, + ); + expect(unpublishLastRes).toBe(lastOrderHash); + const unpublishLast2Res = await iexec.order.unpublishLastApporder( + apporder.app, + ); + expect(unpublishLast2Res).toBe(orderHash); + await expect( + iexec.order.unpublishLastApporder(apporder.app), + ).rejects.toThrow( + new Error( + `API error: no open apporder published by signer ${wallet.address} for app ${apporder.app}`, + ), + ); }); - const lastDatasetorder = await iexec.order.signDatasetorder( - datasetorder, - { - preflightCheck: false, - }, - ); - const lastOrderHash = await iexec.order.publishDatasetorder( - lastDatasetorder, - { preflightCheck: false }, - ); - const unpublishLastRes = await iexec.order.unpublishLastDatasetorder( - datasetorder.dataset, - ); - expect(unpublishLastRes).toBe(lastOrderHash); - const unpublishLast2Res = await iexec.order.unpublishLastDatasetorder( - datasetorder.dataset, - ); - expect(unpublishLast2Res).toBe(orderHash); - await expect( - iexec.order.unpublishLastDatasetorder(datasetorder.dataset), - ).rejects.toThrow( - new Error( - `API error: no open datasetorder published by signer ${wallet.address} for dataset ${datasetorder.dataset}`, - ), - ); }); - }); - describe('unpublishLastWorkerpoolorder()', () => { - test('unpublish the order', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - const workerpoolorder = await deployAndGetWorkerpoolorder(iexec); - const orderHash = - await iexec.order.publishWorkerpoolorder(workerpoolorder); - const lastWorkerpoolorder = - await iexec.order.signWorkerpoolorder(workerpoolorder); - const lastOrderHash = - await iexec.order.publishWorkerpoolorder(lastWorkerpoolorder); - const unpublishLastRes = await iexec.order.unpublishLastWorkerpoolorder( - workerpoolorder.workerpool, - ); - expect(unpublishLastRes).toBe(lastOrderHash); - const unpublishLast2Res = await iexec.order.unpublishLastWorkerpoolorder( - workerpoolorder.workerpool, - ); - expect(unpublishLast2Res).toBe(orderHash); - await expect( - iexec.order.unpublishLastWorkerpoolorder(workerpoolorder.workerpool), - ).rejects.toThrow( - new Error( - `API error: no open workerpoolorder published by signer ${wallet.address} for workerpool ${workerpoolorder.workerpool}`, - ), - ); + describe('unpublishLastDatasetorder()', () => { + test('unpublish the order', async () => { + const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const datasetorder = await deployAndGetDatasetorder(iexec); + const orderHash = await iexec.order.publishDatasetorder(datasetorder, { + preflightCheck: false, + }); + const lastDatasetorder = await iexec.order.signDatasetorder( + datasetorder, + { + preflightCheck: false, + }, + ); + const lastOrderHash = await iexec.order.publishDatasetorder( + lastDatasetorder, + { preflightCheck: false }, + ); + const unpublishLastRes = await iexec.order.unpublishLastDatasetorder( + datasetorder.dataset, + ); + expect(unpublishLastRes).toBe(lastOrderHash); + const unpublishLast2Res = await iexec.order.unpublishLastDatasetorder( + datasetorder.dataset, + ); + expect(unpublishLast2Res).toBe(orderHash); + await expect( + iexec.order.unpublishLastDatasetorder(datasetorder.dataset), + ).rejects.toThrow( + new Error( + `API error: no open datasetorder published by signer ${wallet.address} for dataset ${datasetorder.dataset}`, + ), + ); + }); }); - }); - describe('unpublishLastRequestorder()', () => { - test('unpublish the order', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - const apporder = await deployAndGetApporder(iexec); - await iexec.order.publishApporder(apporder); - const requestorder = await iexec.order - .createRequestorder({ - requester: await iexec.wallet.getAddress(), - app: apporder.app, - appmaxprice: apporder.appprice, - dataset: NULL_ADDRESS, - datasetmaxprice: 0, - workerpool: NULL_ADDRESS, - workerpoolmaxprice: 0, - category: 1, - trust: 0, - volume: 1, - }) - .then((o) => - iexec.order.signRequestorder(o, { preflightCheck: false }), + describe('unpublishLastWorkerpoolorder()', () => { + test('unpublish the order', async () => { + const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const workerpoolorder = await deployAndGetWorkerpoolorder(iexec); + const orderHash = + await iexec.order.publishWorkerpoolorder(workerpoolorder); + const lastWorkerpoolorder = + await iexec.order.signWorkerpoolorder(workerpoolorder); + const lastOrderHash = + await iexec.order.publishWorkerpoolorder(lastWorkerpoolorder); + const unpublishLastRes = await iexec.order.unpublishLastWorkerpoolorder( + workerpoolorder.workerpool, + ); + expect(unpublishLastRes).toBe(lastOrderHash); + const unpublishLast2Res = + await iexec.order.unpublishLastWorkerpoolorder( + workerpoolorder.workerpool, + ); + expect(unpublishLast2Res).toBe(orderHash); + await expect( + iexec.order.unpublishLastWorkerpoolorder(workerpoolorder.workerpool), + ).rejects.toThrow( + new Error( + `API error: no open workerpoolorder published by signer ${wallet.address} for workerpool ${workerpoolorder.workerpool}`, + ), ); - const orderHash = await iexec.order.publishRequestorder(requestorder, { - preflightCheck: false, }); - const lastRequestorder = await iexec.order.signRequestorder( - requestorder, - { + }); + + describe('unpublishLastRequestorder()', () => { + test('unpublish the order', async () => { + const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const apporder = await deployAndGetApporder(iexec); + await iexec.order.publishApporder(apporder); + const requestorder = await iexec.order + .createRequestorder({ + requester: await iexec.wallet.getAddress(), + app: apporder.app, + appmaxprice: apporder.appprice, + dataset: NULL_ADDRESS, + datasetmaxprice: 0, + workerpool: NULL_ADDRESS, + workerpoolmaxprice: 0, + category: 1, + trust: 0, + volume: 1, + }) + .then((o) => + iexec.order.signRequestorder(o, { preflightCheck: false }), + ); + const orderHash = await iexec.order.publishRequestorder(requestorder, { preflightCheck: false, - }, - ); - const lastOrderHash = await iexec.order.publishRequestorder( - lastRequestorder, - { preflightCheck: false }, - ); - const unpublishLastRes = await iexec.order.unpublishLastRequestorder( - requestorder.requester, - ); - expect(unpublishLastRes).toBe(lastOrderHash); - const unpublishLast2Res = await iexec.order.unpublishLastRequestorder( - requestorder.requester, - ); - expect(unpublishLast2Res).toBe(orderHash); - await expect( - iexec.order.unpublishLastRequestorder(requestorder.requester), - ).rejects.toThrow( - new Error( - `API error: no open requestorder published by signer ${wallet.address} for requester ${requestorder.requester}`, - ), - ); - }); - }); - - describe('unpublishAllApporders()', () => { - test('unpublish all orders', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - const apporder = await deployAndGetApporder(iexec); - const orderHash = await iexec.order.publishApporder(apporder); - const lastApporder = await iexec.order.signApporder(apporder); - const lastOrderHash = await iexec.order.publishApporder(lastApporder); - const unpublishAllRes = await iexec.order.unpublishAllApporders( - apporder.app, - ); - expect(unpublishAllRes).toEqual( - expect.arrayContaining([orderHash, lastOrderHash]), - ); - expect(unpublishAllRes.length).toBe(2); - await expect( - iexec.order.unpublishAllApporders(apporder.app), - ).rejects.toThrow( - new Error( - `API error: no open apporder published by signer ${wallet.address} for app ${apporder.app}`, - ), - ); - }); - }); - - describe('unpublishAllDatasetorders()', () => { - test('unpublish all orders', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - const datasetorder = await deployAndGetDatasetorder(iexec); - const orderHash = await iexec.order.publishDatasetorder(datasetorder, { - preflightCheck: false, + }); + const lastRequestorder = await iexec.order.signRequestorder( + requestorder, + { + preflightCheck: false, + }, + ); + const lastOrderHash = await iexec.order.publishRequestorder( + lastRequestorder, + { preflightCheck: false }, + ); + const unpublishLastRes = await iexec.order.unpublishLastRequestorder( + requestorder.requester, + ); + expect(unpublishLastRes).toBe(lastOrderHash); + const unpublishLast2Res = await iexec.order.unpublishLastRequestorder( + requestorder.requester, + ); + expect(unpublishLast2Res).toBe(orderHash); + await expect( + iexec.order.unpublishLastRequestorder(requestorder.requester), + ).rejects.toThrow( + new Error( + `API error: no open requestorder published by signer ${wallet.address} for requester ${requestorder.requester}`, + ), + ); }); - const lastDatasetorder = await iexec.order.signDatasetorder( - datasetorder, - { - preflightCheck: false, - }, - ); - const lastOrderHash = await iexec.order.publishDatasetorder( - lastDatasetorder, - { preflightCheck: false }, - ); - const unpublishAllRes = await iexec.order.unpublishAllDatasetorders( - datasetorder.dataset, - ); - expect(unpublishAllRes).toEqual( - expect.arrayContaining([orderHash, lastOrderHash]), - ); - expect(unpublishAllRes.length).toBe(2); - await expect( - iexec.order.unpublishAllDatasetorders(datasetorder.dataset), - ).rejects.toThrow( - new Error( - `API error: no open datasetorder published by signer ${wallet.address} for dataset ${datasetorder.dataset}`, - ), - ); - }); - }); - - describe('unpublishAllWorkerpoolorders()', () => { - test('unpublish all orders', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - const workerpoolorder = await deployAndGetWorkerpoolorder(iexec); - const orderHash = - await iexec.order.publishWorkerpoolorder(workerpoolorder); - const lastWorkerpoolorder = - await iexec.order.signWorkerpoolorder(workerpoolorder); - const lastOrderHash = - await iexec.order.publishWorkerpoolorder(lastWorkerpoolorder); - const unpublishAllRes = await iexec.order.unpublishAllWorkerpoolorders( - workerpoolorder.workerpool, - ); - expect(unpublishAllRes).toEqual( - expect.arrayContaining([orderHash, lastOrderHash]), - ); - expect(unpublishAllRes.length).toBe(2); - await expect( - iexec.order.unpublishAllWorkerpoolorders(workerpoolorder.workerpool), - ).rejects.toThrow( - new Error( - `API error: no open workerpoolorder published by signer ${wallet.address} for workerpool ${workerpoolorder.workerpool}`, - ), - ); }); - }); - describe('unpublishAllRequestorders()', () => { - test('unpublish all orders', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - const apporder = await deployAndGetApporder(iexec); - await iexec.order.publishApporder(apporder); - const requestorder = await iexec.order - .createRequestorder({ - requester: await iexec.wallet.getAddress(), - app: apporder.app, - appmaxprice: apporder.appprice, - dataset: NULL_ADDRESS, - datasetmaxprice: 0, - workerpool: NULL_ADDRESS, - workerpoolmaxprice: 0, - category: 1, - trust: 0, - volume: 1, - }) - .then((o) => - iexec.order.signRequestorder(o, { preflightCheck: false }), + describe('unpublishAllApporders()', () => { + test('unpublish all orders', async () => { + const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const apporder = await deployAndGetApporder(iexec); + const orderHash = await iexec.order.publishApporder(apporder); + const lastApporder = await iexec.order.signApporder(apporder); + const lastOrderHash = await iexec.order.publishApporder(lastApporder); + const unpublishAllRes = await iexec.order.unpublishAllApporders( + apporder.app, + ); + expect(unpublishAllRes).toEqual( + expect.arrayContaining([orderHash, lastOrderHash]), + ); + expect(unpublishAllRes.length).toBe(2); + await expect( + iexec.order.unpublishAllApporders(apporder.app), + ).rejects.toThrow( + new Error( + `API error: no open apporder published by signer ${wallet.address} for app ${apporder.app}`, + ), ); - const orderHash = await iexec.order.publishRequestorder(requestorder, { - preflightCheck: false, }); - const lastRequestorder = await iexec.order.signRequestorder( - requestorder, - { - preflightCheck: false, - }, - ); - const lastOrderHash = await iexec.order.publishRequestorder( - lastRequestorder, - { preflightCheck: false }, - ); - const unpublishAllRes = await iexec.order.unpublishAllRequestorders( - requestorder.requester, - ); - expect(unpublishAllRes).toEqual( - expect.arrayContaining([orderHash, lastOrderHash]), - ); - expect(unpublishAllRes.length).toBe(2); - await expect( - iexec.order.unpublishAllRequestorders(requestorder.requester), - ).rejects.toThrow( - new Error( - `API error: no open requestorder published by signer ${wallet.address} for requester ${requestorder.requester}`, - ), - ); }); - }); -}); -describe('estimateMatchOrders()', () => { - test('estimates the total cost and volume', async () => { - const noVoucherTestChain = TEST_CHAINS['custom-token-chain']; - const options = { - resultProxyURL: 'https://result-proxy.iex.ec', - smsURL: 'https://sms.iex.ec', - }; - const { iexec: iexecRequester } = getTestConfig(noVoucherTestChain)({ - options, - }); - const { iexec: iexecResourcesProvider, wallet: providerWallet } = - getTestConfig(noVoucherTestChain)({ - options, + describe('unpublishAllDatasetorders()', () => { + test('unpublish all orders', async () => { + const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const datasetorder = await deployAndGetDatasetorder(iexec); + const orderHash = await iexec.order.publishDatasetorder(datasetorder, { + preflightCheck: false, + }); + const lastDatasetorder = await iexec.order.signDatasetorder( + datasetorder, + { + preflightCheck: false, + }, + ); + const lastOrderHash = await iexec.order.publishDatasetorder( + lastDatasetorder, + { preflightCheck: false }, + ); + const unpublishAllRes = await iexec.order.unpublishAllDatasetorders( + datasetorder.dataset, + ); + expect(unpublishAllRes).toEqual( + expect.arrayContaining([orderHash, lastOrderHash]), + ); + expect(unpublishAllRes.length).toBe(2); + await expect( + iexec.order.unpublishAllDatasetorders(datasetorder.dataset), + ).rejects.toThrow( + new Error( + `API error: no open datasetorder published by signer ${wallet.address} for dataset ${datasetorder.dataset}`, + ), + ); }); - - await setBalance(noVoucherTestChain)(providerWallet.address, ONE_ETH); - - const apporder = await deployAndGetApporder(iexecResourcesProvider, { - volume: 10, - appprice: 5, - }); - const datasetorder = await deployAndGetDatasetorder( - iexecResourcesProvider, - { - volume: 7, - datasetprice: 1, - }, - ); - const workerpoolorder = await deployAndGetWorkerpoolorder( - iexecResourcesProvider, - { volume: 5, workerpoolprice: 1 }, - ); - const requestorder = await getMatchableRequestorder(iexecRequester, { - apporder, - datasetorder, - workerpoolorder, - }); - - const res = await iexecRequester.order.estimateMatchOrders({ - apporder, - datasetorder, - workerpoolorder, - requestorder, }); - expect(res.sponsored).toBeInstanceOf(BN); - expect(res.sponsored).toEqual(new BN(0)); - expect(res.total).toBeInstanceOf(BN); - expect(res.total).toEqual(new BN(35)); - expect(res.volume).toBeInstanceOf(BN); - expect(res.volume).toEqual(new BN(5)); - }); - - describe('with useVoucher', () => { - let iexecProvider; - let apporderTemplate; - let datasetorderTemplate; - let workerpoolorderTemplate; - let voucherTypeId; - let matchableVolume; - let expectedTotal; - beforeAll(async () => { - const providerConfig = getTestConfig(iexecTestChain)(); - iexecProvider = providerConfig.iexec; - apporderTemplate = await deployAndGetApporder(iexecProvider, { - volume: 10, - appprice: 5, - }); - datasetorderTemplate = await deployAndGetDatasetorder(iexecProvider, { - volume: 7, - datasetprice: 1, + describe('unpublishAllWorkerpoolorders()', () => { + test('unpublish all orders', async () => { + const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const workerpoolorder = await deployAndGetWorkerpoolorder(iexec); + const orderHash = + await iexec.order.publishWorkerpoolorder(workerpoolorder); + const lastWorkerpoolorder = + await iexec.order.signWorkerpoolorder(workerpoolorder); + const lastOrderHash = + await iexec.order.publishWorkerpoolorder(lastWorkerpoolorder); + const unpublishAllRes = await iexec.order.unpublishAllWorkerpoolorders( + workerpoolorder.workerpool, + ); + expect(unpublishAllRes).toEqual( + expect.arrayContaining([orderHash, lastOrderHash]), + ); + expect(unpublishAllRes.length).toBe(2); + await expect( + iexec.order.unpublishAllWorkerpoolorders(workerpoolorder.workerpool), + ).rejects.toThrow( + new Error( + `API error: no open workerpoolorder published by signer ${wallet.address} for workerpool ${workerpoolorder.workerpool}`, + ), + ); }); - workerpoolorderTemplate = await deployAndGetWorkerpoolorder( - iexecProvider, - { volume: 5, workerpoolprice: 1 }, - ); - - matchableVolume = new BN(5); // min volume among orders - expectedTotal = new BN(5 + 1 + 1).mul(matchableVolume); // volume * orders unit prices + }); - voucherTypeId = await createVoucherType(iexecTestChain)({ - description: 'test voucher type', - duration: 60 * 60, + describe('unpublishAllRequestorders()', () => { + test('unpublish all orders', async () => { + const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const apporder = await deployAndGetApporder(iexec); + await iexec.order.publishApporder(apporder); + const requestorder = await iexec.order + .createRequestorder({ + requester: await iexec.wallet.getAddress(), + app: apporder.app, + appmaxprice: apporder.appprice, + dataset: NULL_ADDRESS, + datasetmaxprice: 0, + workerpool: NULL_ADDRESS, + workerpoolmaxprice: 0, + category: 1, + trust: 0, + volume: 1, + }) + .then((o) => + iexec.order.signRequestorder(o, { preflightCheck: false }), + ); + const orderHash = await iexec.order.publishRequestorder(requestorder, { + preflightCheck: false, + }); + const lastRequestorder = await iexec.order.signRequestorder( + requestorder, + { + preflightCheck: false, + }, + ); + const lastOrderHash = await iexec.order.publishRequestorder( + lastRequestorder, + { preflightCheck: false }, + ); + const unpublishAllRes = await iexec.order.unpublishAllRequestorders( + requestorder.requester, + ); + expect(unpublishAllRes).toEqual( + expect.arrayContaining([orderHash, lastOrderHash]), + ); + expect(unpublishAllRes.length).toBe(2); + await expect( + iexec.order.unpublishAllRequestorders(requestorder.requester), + ).rejects.toThrow( + new Error( + `API error: no open requestorder published by signer ${wallet.address} for requester ${requestorder.requester}`, + ), + ); }); - - await addVoucherEligibleAsset(iexecTestChain)( - apporderTemplate.app, - voucherTypeId, - ); - await addVoucherEligibleAsset(iexecTestChain)( - datasetorderTemplate.dataset, - voucherTypeId, - ); - await addVoucherEligibleAsset(iexecTestChain)( - workerpoolorderTemplate.workerpool, - voucherTypeId, - ); }); + }); - test('requires voucherHubAddress to be configured when useVoucher is true', async () => { - const noVoucherTestChain = TEST_CHAINS['custom-token-chain']; - const options = { - resultProxyURL: 'https://result-proxy.iex.ec', - smsURL: 'https://sms.iex.ec', - }; - const { iexec: iexecRequester } = getTestConfig(noVoucherTestChain)({ - options, - }); + describe('estimateMatchOrders()', () => { + test('estimates the total cost and volume', async () => { + const { iexec: iexecRequester } = getTestConfig(iexecTestChain)(); const { iexec: iexecResourcesProvider, wallet: providerWallet } = - getTestConfig(noVoucherTestChain)({ - options, - }); + getTestConfig(iexecTestChain)(); - await setBalance(noVoucherTestChain)(providerWallet.address, ONE_ETH); + await setBalance(iexecTestChain)(providerWallet.address, ONE_ETH); const apporder = await deployAndGetApporder(iexecResourcesProvider, { volume: 10, @@ -1608,152 +1496,43 @@ describe('estimateMatchOrders()', () => { workerpoolorder, }); - await expect( - iexecRequester.order.estimateMatchOrders( - { - apporder, - datasetorder, - workerpoolorder, - requestorder, - }, - { useVoucher: true }, - ), - ).rejects.toThrow( - new ConfigurationError( - `voucherHubAddress option not set and no default value for your chain ${noVoucherTestChain.chainId}`, - ), - ); - // estimate match orders without useVoucher should pass - const res = await iexecRequester.order.estimateMatchOrders( - { - apporder, - datasetorder, - workerpoolorder, - requestorder, - }, - { useVoucher: false }, - ); - expect(res.sponsored).toBeInstanceOf(BN); - expect(res.sponsored).toEqual(new BN(0)); - expect(res.total).toBeInstanceOf(BN); - expect(res.total).toEqual(new BN(35)); - expect(res.volume).toBeInstanceOf(BN); - expect(res.volume).toEqual(new BN(5)); - }); - - test('should have sponsored amount as 0 when useVoucher is false', async () => { - const { iexec: iexecRequester, wallet: requesterWallet } = - getTestConfig(iexecTestChain)(); - - const requestorderTemplate = await getMatchableRequestorder( - iexecRequester, - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, - }, - ); - - await createVoucher(iexecTestChain)({ - owner: await requesterWallet.getAddress(), - voucherType: voucherTypeId, - value: 100, - }); - const res = await iexecRequester.order.estimateMatchOrders({ - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, - requestorder: requestorderTemplate, + apporder, + datasetorder, + workerpoolorder, + requestorder, }); - - expect(res.sponsored).toBeInstanceOf(BN); - expect(res.sponsored).toEqual(new BN(0)); expect(res.total).toBeInstanceOf(BN); - expect(res.total).toEqual(expectedTotal); + expect(res.total).toEqual(new BN(35)); expect(res.volume).toBeInstanceOf(BN); - expect(res.volume).toEqual(matchableVolume); + expect(res.volume).toEqual(new BN(5)); }); + }); - test('should return total cost and sponsored amount when using voucher', async () => { - const { iexec: iexecRequester, wallet: requesterWallet } = + describe('matchOrders()', () => { + test('order.matchOrders() all tests (split TODO)', async () => { + const { iexec: iexecBroker } = getTestConfig(iexecTestChain)(); + const { iexec: iexecPoolManager, wallet: poolManagerWallet } = getTestConfig(iexecTestChain)(); - - const requestorderTemplate = await getMatchableRequestorder( - iexecRequester, - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, - }, - ); - - await createVoucher(iexecTestChain)({ - owner: await requesterWallet.getAddress(), - voucherType: voucherTypeId, - value: 1000, - }); - - const res = await iexecRequester.order.estimateMatchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, - requestorder: requestorderTemplate, - }, - { useVoucher: true }, - ); - expect(res.sponsored).toBeInstanceOf(BN); - expect(res.sponsored).toEqual(expectedTotal); - expect(res.total).toBeInstanceOf(BN); - expect(res.total).toEqual(expectedTotal); - expect(res.volume).toBeInstanceOf(BN); - expect(res.volume).toEqual(matchableVolume); - }); - - test('should return sponsored amount equal to voucher balance when voucher value is less than total cost', async () => { const { iexec: iexecRequester, wallet: requesterWallet } = getTestConfig(iexecTestChain)(); + const { iexec: iexecAppProvider } = getTestConfig(iexecTestChain)(); + const { iexec: iexecDatasetProvider } = getTestConfig(iexecTestChain)(); - const requestorderTemplate = await getMatchableRequestorder( - iexecRequester, - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, - }, - ); - - await createVoucher(iexecTestChain)({ - owner: await requesterWallet.getAddress(), - voucherType: voucherTypeId, - value: 10, - }); - const voucherInfo = await iexecRequester.voucher.showUserVoucher( + await setNRlcBalance(iexecTestChain)( requesterWallet.address, + 10n * ONE_RLC, ); - - const res = await iexecRequester.order.estimateMatchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, - requestorder: requestorderTemplate, - }, - { useVoucher: true }, + await setNRlcBalance(iexecTestChain)( + poolManagerWallet.address, + 10n * ONE_RLC, ); - expect(res.sponsored).toBeInstanceOf(BN); - expect(res.sponsored).toEqual(new BN(voucherInfo.balance)); - expect(res.total).toBeInstanceOf(BN); - expect(res.total).toEqual(expectedTotal); - expect(res.volume).toBeInstanceOf(BN); - expect(res.volume).toEqual(matchableVolume); - }); - - test('should have sponsored amount as 0 when voucher expired', async () => { - const { iexec: iexecRequester, wallet: requesterWallet } = - getTestConfig(iexecTestChain)(); + const apporderTemplate = await deployAndGetApporder(iexecAppProvider); + const datasetorderTemplate = + await deployAndGetDatasetorder(iexecDatasetProvider); + const workerpoolorderTemplate = + await deployAndGetWorkerpoolorder(iexecPoolManager); const requestorderTemplate = await getMatchableRequestorder( iexecRequester, { @@ -1762,1098 +1541,591 @@ describe('estimateMatchOrders()', () => { workerpoolorder: workerpoolorderTemplate, }, ); - const voucherType = await createVoucherType(iexecTestChain)({ - description: 'test voucher type', - duration: 1, - }); - await createVoucher(iexecTestChain)({ - owner: await requesterWallet.getAddress(), - voucherType, - value: 100, - }); - - const res = await iexecRequester.order.estimateMatchOrders({ - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, - requestorder: requestorderTemplate, - }); - expect(res.sponsored).toBeInstanceOf(BN); - expect(res.sponsored).toEqual(new BN(0)); - expect(res.total).toBeInstanceOf(BN); - expect(res.total).toEqual(expectedTotal); - expect(res.volume).toBeInstanceOf(BN); - expect(res.volume).toEqual(matchableVolume); - }); - - describe('with custom voucherAddress option', () => { - let voucherAddress; - let authorizedRequesterWallet; - beforeAll(async () => { - const { iexec: iexecVoucherOwner, wallet: voucherOwnerWallet } = - getTestConfig(iexecTestChain)(); - ({ wallet: authorizedRequesterWallet } = - getTestConfig(iexecTestChain)()); - - voucherAddress = await createVoucher(iexecTestChain)({ - owner: await voucherOwnerWallet.getAddress(), - voucherType: voucherTypeId, - value: 1000, - }); - await iexecVoucherOwner.voucher.authorizeRequester( - authorizedRequesterWallet.address, - ); - }); - - test('should use specified voucherAddress', async () => { - const { iexec: iexecRequester } = getTestConfig(iexecTestChain)({ - privateKey: authorizedRequesterWallet.privateKey, - }); - const requestorder = await getMatchableRequestorder(iexecRequester, { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, - }); - - const res = await iexecRequester.order.estimateMatchOrders( + // resource not deployed + const fakeAddress = getRandomAddress(); + const apporderNotDeployed = { ...apporderTemplate, app: fakeAddress }; + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderNotDeployed, + datasetorder: datasetorderTemplate, + workerpoolorder: workerpoolorderTemplate, + requestorder: requestorderTemplate, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow(Error(`No app deployed at address ${fakeAddress}`)); + const datasetorderNotDeployed = { + ...datasetorderTemplate, + dataset: fakeAddress, + }; + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderTemplate, + datasetorder: datasetorderNotDeployed, + workerpoolorder: workerpoolorderTemplate, + requestorder: requestorderTemplate, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow(Error(`No dataset deployed at address ${fakeAddress}`)); + const workerpoolorderNotDeployed = { + ...workerpoolorderTemplate, + workerpool: fakeAddress, + }; + await expect( + iexecBroker.order.matchOrders( { apporder: apporderTemplate, datasetorder: datasetorderTemplate, + workerpoolorder: workerpoolorderNotDeployed, + requestorder: requestorderTemplate, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow( + new Error(`No workerpool deployed at address ${fakeAddress}`), + ); + // invalid sign + const apporderInvalidSign = { + ...apporderTemplate, + sign: '0xa1d59ea4f4ed84ed1c2fcbdb217f22d64180d95ccaed3268bdfef796ff7f5fa50c2d4c83bf7465afbd9ca292c433495eb573d1f8bcca585cb107b047c899dcb81c', + }; + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderInvalidSign, + datasetorder: datasetorderTemplate, workerpoolorder: workerpoolorderTemplate, - requestorder, + requestorder: requestorderTemplate, }, - { useVoucher: true, voucherAddress }, - ); - expect(res.sponsored).toBeInstanceOf(BN); - expect(res.sponsored).toEqual(expectedTotal); - expect(res.total).toBeInstanceOf(BN); - expect(res.total).toEqual(expectedTotal); - expect(res.volume).toBeInstanceOf(BN); - expect(res.volume).toEqual(matchableVolume); - }); - - test('should throw if specified voucherAddress is not a voucher', async () => { - const { iexec: iexecRequester } = getTestConfig(iexecTestChain)({ - privateKey: authorizedRequesterWallet.privateKey, - }); + { preflightCheck: false }, + ), + ).rejects.toThrow(Error('apporder invalid sign')); + const datasetorderInvalidSign = { + ...datasetorderTemplate, + sign: '0xa1d59ea4f4ed84ed1c2fcbdb217f22d64180d95ccaed3268bdfef796ff7f5fa50c2d4c83bf7465afbd9ca292c433495eb573d1f8bcca585cb107b047c899dcb81c', + }; + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderTemplate, + datasetorder: datasetorderInvalidSign, + workerpoolorder: workerpoolorderTemplate, + requestorder: requestorderTemplate, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow(Error('datasetorder invalid sign')); + const workerpoolorderInvalidSign = { + ...workerpoolorderTemplate, + sign: '0xa1d59ea4f4ed84ed1c2fcbdb217f22d64180d95ccaed3268bdfef796ff7f5fa50c2d4c83bf7465afbd9ca292c433495eb573d1f8bcca585cb107b047c899dcb81c', + }; + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderTemplate, + datasetorder: datasetorderTemplate, + workerpoolorder: workerpoolorderInvalidSign, + requestorder: requestorderTemplate, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow(Error('workerpoolorder invalid sign')); + const requestorderInvalidSign = { + ...requestorderTemplate, + sign: '0xa1d59ea4f4ed84ed1c2fcbdb217f22d64180d95ccaed3268bdfef796ff7f5fa50c2d4c83bf7465afbd9ca292c433495eb573d1f8bcca585cb107b047c899dcb81c', + }; + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderTemplate, + datasetorder: datasetorderTemplate, + workerpoolorder: workerpoolorderTemplate, + requestorder: requestorderInvalidSign, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow(Error('requestorder invalid sign')); - const requestorder = await getMatchableRequestorder(iexecRequester, { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, + // address mismatch + const apporderAddressMismatch = + await deployAndGetApporder(iexecAppProvider); + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderAddressMismatch, + datasetorder: datasetorderTemplate, + workerpoolorder: workerpoolorderTemplate, + requestorder: requestorderTemplate, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow( + new Error( + `app address mismatch between requestorder (${requestorderTemplate.app}) and apporder (${apporderAddressMismatch.app})`, + ), + ); + const datasetorderAddressMismatch = + await deployAndGetDatasetorder(iexecDatasetProvider); + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderTemplate, + datasetorder: datasetorderAddressMismatch, + workerpoolorder: workerpoolorderTemplate, + requestorder: requestorderTemplate, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow( + new Error( + `dataset address mismatch between requestorder (${requestorderTemplate.dataset}) and datasetorder (${datasetorderAddressMismatch.dataset})`, + ), + ); + const workerpoolorderAddressMismatch = + await deployAndGetWorkerpoolorder(iexecPoolManager); + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderTemplate, + datasetorder: datasetorderTemplate, + workerpoolorder: workerpoolorderAddressMismatch, + requestorder: requestorderTemplate, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow( + new Error( + `workerpool address mismatch between requestorder (${requestorderTemplate.workerpool}) and workerpoolorder (${workerpoolorderAddressMismatch.workerpool})`, + ), + ); + // category check + const workerpoolorderCategoryMismatch = + await iexecPoolManager.order.signWorkerpoolorder({ + ...workerpoolorderTemplate, + category: 2, }); - - await expect( - iexecRequester.order.estimateMatchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, - requestorder, - }, - { useVoucher: true, voucherAddress: getRandomAddress() }, - ), - ).rejects.toThrow('Invalid voucher contract address'); - }); - - test('should throw if user is not allowed to use specified voucherAddress', async () => { - const { iexec: iexecRequester } = getTestConfig(iexecTestChain)(); - - const requestorder = await getMatchableRequestorder(iexecRequester, { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderTemplate, + datasetorder: datasetorderTemplate, + workerpoolorder: workerpoolorderCategoryMismatch, + requestorder: requestorderTemplate, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow( + new Error( + `category mismatch between requestorder (${requestorderTemplate.category}) and workerpoolorder (${workerpoolorderCategoryMismatch.category})`, + ), + ); + // trust check + const workerpoolorderTrustZero = + await iexecPoolManager.order.signWorkerpoolorder({ + ...workerpoolorderTemplate, + trust: 0, }); + const requestorderTrustTooHigh = + await iexecRequester.order.signRequestorder( + { + ...requestorderTemplate, + trust: 2, + }, + { preflightCheck: false }, + ); + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderTemplate, + datasetorder: datasetorderTemplate, + workerpoolorder: workerpoolorderTrustZero, + requestorder: requestorderTrustTooHigh, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow( + new Error( + `workerpoolorder trust is too low (expected ${requestorderTrustTooHigh.trust}, got ${workerpoolorderTrustZero.trust})`, + ), + ); - await expect( - iexecRequester.order.estimateMatchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, - requestorder, - }, - { useVoucher: true, voucherAddress }, - ), - ).rejects.toThrow('User is not authorized to use the voucher'); - }); - }); - }); -}); - -describe('matchOrders()', () => { - test('order.matchOrders() all tests (split TODO)', async () => { - const { iexec: iexecBroker } = getTestConfig(iexecTestChain)(); - const { iexec: iexecPoolManager, wallet: poolManagerWallet } = - getTestConfig(iexecTestChain)(); - const { iexec: iexecRequester, wallet: requesterWallet } = - getTestConfig(iexecTestChain)(); - const { iexec: iexecAppProvider } = getTestConfig(iexecTestChain)(); - const { iexec: iexecDatasetProvider } = getTestConfig(iexecTestChain)(); - - await setNRlcBalance(iexecTestChain)( - requesterWallet.address, - 10n * ONE_RLC, - ); - await setNRlcBalance(iexecTestChain)( - poolManagerWallet.address, - 10n * ONE_RLC, - ); - - const apporderTemplate = await deployAndGetApporder(iexecAppProvider); - const datasetorderTemplate = - await deployAndGetDatasetorder(iexecDatasetProvider); - const workerpoolorderTemplate = - await deployAndGetWorkerpoolorder(iexecPoolManager); - const requestorderTemplate = await getMatchableRequestorder( - iexecRequester, - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, - }, - ); - - // resource not deployed - const fakeAddress = getRandomAddress(); - const apporderNotDeployed = { ...apporderTemplate, app: fakeAddress }; - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderNotDeployed, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, - requestorder: requestorderTemplate, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow(Error(`No app deployed at address ${fakeAddress}`)); - const datasetorderNotDeployed = { - ...datasetorderTemplate, - dataset: fakeAddress, - }; - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderNotDeployed, - workerpoolorder: workerpoolorderTemplate, - requestorder: requestorderTemplate, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow(Error(`No dataset deployed at address ${fakeAddress}`)); - const workerpoolorderNotDeployed = { - ...workerpoolorderTemplate, - workerpool: fakeAddress, - }; - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderNotDeployed, - requestorder: requestorderTemplate, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow( - new Error(`No workerpool deployed at address ${fakeAddress}`), - ); - // invalid sign - const apporderInvalidSign = { - ...apporderTemplate, - sign: '0xa1d59ea4f4ed84ed1c2fcbdb217f22d64180d95ccaed3268bdfef796ff7f5fa50c2d4c83bf7465afbd9ca292c433495eb573d1f8bcca585cb107b047c899dcb81c', - }; - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderInvalidSign, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, - requestorder: requestorderTemplate, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow(Error('apporder invalid sign')); - const datasetorderInvalidSign = { - ...datasetorderTemplate, - sign: '0xa1d59ea4f4ed84ed1c2fcbdb217f22d64180d95ccaed3268bdfef796ff7f5fa50c2d4c83bf7465afbd9ca292c433495eb573d1f8bcca585cb107b047c899dcb81c', - }; - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderInvalidSign, - workerpoolorder: workerpoolorderTemplate, - requestorder: requestorderTemplate, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow(Error('datasetorder invalid sign')); - const workerpoolorderInvalidSign = { - ...workerpoolorderTemplate, - sign: '0xa1d59ea4f4ed84ed1c2fcbdb217f22d64180d95ccaed3268bdfef796ff7f5fa50c2d4c83bf7465afbd9ca292c433495eb573d1f8bcca585cb107b047c899dcb81c', - }; - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderInvalidSign, - requestorder: requestorderTemplate, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow(Error('workerpoolorder invalid sign')); - const requestorderInvalidSign = { - ...requestorderTemplate, - sign: '0xa1d59ea4f4ed84ed1c2fcbdb217f22d64180d95ccaed3268bdfef796ff7f5fa50c2d4c83bf7465afbd9ca292c433495eb573d1f8bcca585cb107b047c899dcb81c', - }; - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, - requestorder: requestorderInvalidSign, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow(Error('requestorder invalid sign')); - - // address mismatch - const apporderAddressMismatch = - await deployAndGetApporder(iexecAppProvider); - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderAddressMismatch, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, - requestorder: requestorderTemplate, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow( - new Error( - `app address mismatch between requestorder (${requestorderTemplate.app}) and apporder (${apporderAddressMismatch.app})`, - ), - ); - const datasetorderAddressMismatch = - await deployAndGetDatasetorder(iexecDatasetProvider); - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderAddressMismatch, - workerpoolorder: workerpoolorderTemplate, - requestorder: requestorderTemplate, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow( - new Error( - `dataset address mismatch between requestorder (${requestorderTemplate.dataset}) and datasetorder (${datasetorderAddressMismatch.dataset})`, - ), - ); - const workerpoolorderAddressMismatch = - await deployAndGetWorkerpoolorder(iexecPoolManager); - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderAddressMismatch, - requestorder: requestorderTemplate, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow( - new Error( - `workerpool address mismatch between requestorder (${requestorderTemplate.workerpool}) and workerpoolorder (${workerpoolorderAddressMismatch.workerpool})`, - ), - ); - // category check - const workerpoolorderCategoryMismatch = - await iexecPoolManager.order.signWorkerpoolorder({ - ...workerpoolorderTemplate, - category: 2, - }); - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderCategoryMismatch, - requestorder: requestorderTemplate, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow( - new Error( - `category mismatch between requestorder (${requestorderTemplate.category}) and workerpoolorder (${workerpoolorderCategoryMismatch.category})`, - ), - ); - // trust check - const workerpoolorderTrustZero = - await iexecPoolManager.order.signWorkerpoolorder({ - ...workerpoolorderTemplate, - trust: 0, - }); - const requestorderTrustTooHigh = - await iexecRequester.order.signRequestorder( + // workerpool tag check + const requestorderTagTeeGpu = await iexecRequester.order.signRequestorder( { ...requestorderTemplate, - trust: 2, + tag: ['tee', 'scone', 'gpu'], }, { preflightCheck: false }, ); - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTrustZero, - requestorder: requestorderTrustTooHigh, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow( - new Error( - `workerpoolorder trust is too low (expected ${requestorderTrustTooHigh.trust}, got ${workerpoolorderTrustZero.trust})`, - ), - ); - - // workerpool tag check - const requestorderTagTeeGpu = await iexecRequester.order.signRequestorder( - { - ...requestorderTemplate, - tag: ['tee', 'scone', 'gpu'], - }, - { preflightCheck: false }, - ); - const workerpoolorderTagGpu = - await iexecPoolManager.order.signWorkerpoolorder({ - ...workerpoolorderTemplate, - tag: ['gpu'], - }); - const workerpoolorderTagTee = - await iexecPoolManager.order.signWorkerpoolorder({ - ...workerpoolorderTemplate, - tag: ['tee', 'scone'], - }); - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTagGpu, - requestorder: requestorderTagTeeGpu, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow(Error('Missing tags [tee,scone] in workerpoolorder')); - const apporderTagGpu = await iexecAppProvider.order.signApporder({ - ...apporderTemplate, - tag: ['gpu'], - }); - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderTagGpu, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTagTee, - requestorder: requestorderTemplate, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow(Error('Missing tags [gpu] in workerpoolorder')); - const datasetorderTagTeeGpu = - await iexecDatasetProvider.order.signDatasetorder( - { - ...datasetorderTemplate, + const workerpoolorderTagGpu = + await iexecPoolManager.order.signWorkerpoolorder({ + ...workerpoolorderTemplate, tag: ['gpu'], - }, - { preflightCheck: false }, - ); - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderTagTeeGpu, - workerpoolorder: workerpoolorderTagTee, - requestorder: requestorderTemplate, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow(Error('Missing tags [gpu] in workerpoolorder')); - // app tag check - const requestorderTagTee = await iexecRequester.order.signRequestorder( - { - ...requestorderTemplate, - tag: ['tee', 'scone'], - }, - { preflightCheck: false }, - ); - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTagTee, - requestorder: requestorderTagTee, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow(Error('Missing tag [tee] in apporder')); - // price check - const apporderTooExpensive = await iexecAppProvider.order.signApporder({ - ...apporderTemplate, - appprice: 1, - }); - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderTooExpensive, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, - requestorder: requestorderTemplate, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow( - new Error( - `appmaxprice too low (expected ${apporderTooExpensive.appprice}, got ${requestorderTemplate.appmaxprice})`, - ), - ); - - const datasetorderTooExpensive = - await iexecDatasetProvider.order.signDatasetorder( - { - ...datasetorderTemplate, - datasetprice: 1, - }, - { preflightCheck: false }, - ); - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderTooExpensive, - workerpoolorder: workerpoolorderTemplate, - requestorder: requestorderTemplate, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow( - new Error( - `datasetmaxprice too low (expected ${datasetorderTooExpensive.datasetprice}, got ${requestorderTemplate.datasetmaxprice})`, - ), - ); - - const workerpoolorderTooExpensive = - await iexecPoolManager.order.signWorkerpoolorder({ - ...workerpoolorderTemplate, - workerpoolprice: 1, - }); - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTooExpensive, - requestorder: requestorderTemplate, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow( - new Error( - `workerpoolmaxprice too low (expected ${workerpoolorderTooExpensive.workerpoolprice}, got ${requestorderTemplate.workerpoolmaxprice})`, - ), - ); - // volumes checks - const apporderCanceled = await iexecAppProvider.order - .signApporder(apporderTemplate, { preflightCheck: false }) - .then(async (order) => { - await iexecAppProvider.order.cancelApporder(order); - return order; - }); - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderCanceled, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, - requestorder: requestorderTemplate, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow(Error('apporder is fully consumed')); - - const datasetorderCanceled = await iexecDatasetProvider.order - .signDatasetorder(datasetorderTemplate, { preflightCheck: false }) - .then(async (order) => { - await iexecDatasetProvider.order.cancelDatasetorder(order); - return order; - }); - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderCanceled, - workerpoolorder: workerpoolorderTemplate, - requestorder: requestorderTemplate, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow(Error('datasetorder is fully consumed')); - - const workerpoolorderCanceled = await iexecPoolManager.order - .signWorkerpoolorder(workerpoolorderTemplate) - .then(async (order) => { - await iexecPoolManager.order.cancelWorkerpoolorder(order); - return order; - }); - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderCanceled, - requestorder: requestorderTemplate, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow(Error('workerpoolorder is fully consumed')); - const requestorderCanceled = await iexecRequester.order - .signRequestorder(requestorderTemplate, { preflightCheck: false }) - .then(async (order) => { - await iexecRequester.order.cancelRequestorder(order); - return order; - }); - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, - requestorder: requestorderCanceled, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow(Error('requestorder is fully consumed')); - - // requester account stake check - const balance = await iexecRequester.account.checkBalance( - await iexecRequester.wallet.getAddress(), - ); - await iexecRequester.account.withdraw(balance.stake).catch(() => {}); - await iexecRequester.account.deposit(5); - - const apporder3nRlc = await iexecAppProvider.order.signApporder( - { + }); + const workerpoolorderTagTee = + await iexecPoolManager.order.signWorkerpoolorder({ + ...workerpoolorderTemplate, + tag: ['tee', 'scone'], + }); + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderTemplate, + datasetorder: datasetorderTemplate, + workerpoolorder: workerpoolorderTagGpu, + requestorder: requestorderTagTeeGpu, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow(Error('Missing tags [tee,scone] in workerpoolorder')); + const apporderTagGpu = await iexecAppProvider.order.signApporder({ ...apporderTemplate, - appprice: 3, - }, - { preflightCheck: false }, - ); - const datasetorder2nRlc = await iexecDatasetProvider.order.signDatasetorder( - { - ...datasetorderTemplate, - datasetprice: 2, - }, - { preflightCheck: false }, - ); - const workerpoolorder1nRlc = - await iexecPoolManager.order.signWorkerpoolorder({ - ...workerpoolorderTemplate, - workerpoolprice: 1, + tag: ['gpu'], }); - const requestorder300nRlc = await iexecRequester.order.signRequestorder( - { - ...requestorderTemplate, - appmaxprice: 100, - datasetmaxprice: 100, - workerpoolmaxprice: 100, - }, - { preflightCheck: false }, - ); - await expect( - iexecBroker.order.matchOrders( + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderTagGpu, + datasetorder: datasetorderTemplate, + workerpoolorder: workerpoolorderTagTee, + requestorder: requestorderTemplate, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow(Error('Missing tags [gpu] in workerpoolorder')); + const datasetorderTagTeeGpu = + await iexecDatasetProvider.order.signDatasetorder( + { + ...datasetorderTemplate, + tag: ['gpu'], + }, + { preflightCheck: false }, + ); + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderTemplate, + datasetorder: datasetorderTagTeeGpu, + workerpoolorder: workerpoolorderTagTee, + requestorder: requestorderTemplate, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow(Error('Missing tags [gpu] in workerpoolorder')); + // app tag check + const requestorderTagTee = await iexecRequester.order.signRequestorder( { - apporder: apporder3nRlc, - datasetorder: datasetorder2nRlc, - workerpoolorder: workerpoolorder1nRlc, - requestorder: requestorder300nRlc, + ...requestorderTemplate, + tag: ['tee', 'scone'], }, { preflightCheck: false }, - ), - ).rejects.toThrow( - new Error( - "Cost per task (6) is greater than requester account stake (5). Orders can't be matched. If you are the requester, you should deposit to top up your account", - ), - ); - - const apporder0nRlc = await iexecAppProvider.order.signApporder( - { + ); + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderTemplate, + datasetorder: datasetorderTemplate, + workerpoolorder: workerpoolorderTagTee, + requestorder: requestorderTagTee, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow(Error('Missing tag [tee] in apporder')); + // price check + const apporderTooExpensive = await iexecAppProvider.order.signApporder({ ...apporderTemplate, - appprice: 0, - volume: 1000, - }, - { preflightCheck: false }, - ); - const datasetorder0nRlc = await iexecDatasetProvider.order.signDatasetorder( - { - ...datasetorderTemplate, - datasetprice: 0, - volume: 1000, - }, - { preflightCheck: false }, - ); - const workerpoolorder2nRlc = - await iexecPoolManager.order.signWorkerpoolorder({ - ...workerpoolorderTemplate, - workerpoolprice: 2, - volume: 1000, + appprice: 1, }); - const requestorder6nRlc = await iexecRequester.order.signRequestorder( - { - ...requestorderTemplate, - workerpoolmaxprice: 2, - volume: 3, - }, - { preflightCheck: false }, - ); - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporder0nRlc, - datasetorder: datasetorder0nRlc, - workerpoolorder: workerpoolorder2nRlc, - requestorder: requestorder6nRlc, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow( - new Error( - "Total cost for 3 tasks (6) is greater than requester account stake (5). Orders can't be matched. If you are the requester, you should deposit to top up your account or reduce your requestorder volume", - ), - ); - // workerpool owner stake check - const workerpoolorder7nRlc = - await iexecPoolManager.order.signWorkerpoolorder({ - ...workerpoolorderTemplate, - workerpoolprice: 7, - }); - await iexecRequester.account.deposit(10); - const poolManagerBalance = await iexecPoolManager.account.checkBalance( - await iexecPoolManager.wallet.getAddress(), - ); - await iexecPoolManager.account - .withdraw(poolManagerBalance.stake) - .catch(() => {}); - - await iexecPoolManager.account.deposit(1); - await expect( - iexecBroker.order.matchOrders( - { - apporder: apporder3nRlc, - datasetorder: datasetorder2nRlc, - workerpoolorder: workerpoolorder7nRlc, - requestorder: requestorder300nRlc, - }, - { preflightCheck: false }, - ), - ).rejects.toThrow( - new Error( - "workerpool required stake (2) is greater than workerpool owner's account stake (1). Orders can't be matched. If you are the workerpool owner, you should deposit to top up your account", - ), - ); - // standard case - const res = await iexecBroker.order.matchOrders( - { - apporder: apporderTemplate, - datasetorder: datasetorderTemplate, - workerpoolorder: workerpoolorderTemplate, - requestorder: requestorderTemplate, - }, - { preflightCheck: false }, - ); - expect(res.txHash).toBeTxHash(); - expect(res.volume).toBeInstanceOf(BN); - expect(res.volume.eq(new BN(1))).toBe(true); - expect(res.dealid).toBeTxHash(); - }); - - test('preflightChecks', async () => { - const { iexec: iexecRequester } = getTestConfig(iexecTestChain)(); - const { iexec: iexecResourcesProvider } = getTestConfig(iexecTestChain)(); - - const apporder = await deployAndGetApporder(iexecResourcesProvider); - const datasetorder = await deployAndGetDatasetorder(iexecResourcesProvider); - const workerpoolorder = await deployAndGetWorkerpoolorder( - iexecResourcesProvider, - ); - const requestorder = await getMatchableRequestorder(iexecRequester, { - apporder, - datasetorder, - workerpoolorder, - }); - - const teeApporder = await deployAndGetApporder(iexecResourcesProvider, { - teeFramework: TEE_FRAMEWORKS.SCONE, - tag: ['tee', 'scone'], - }); - const teeDatasetorder = await deployAndGetDatasetorder( - iexecResourcesProvider, - { tag: ['tee'] }, - ); - const teeWorkerpoolorder = await deployAndGetWorkerpoolorder( - iexecResourcesProvider, - { - tag: ['tee', 'scone'], - }, - ); - const res = await iexecRequester.order.matchOrders({ - apporder, - datasetorder, - workerpoolorder, - requestorder, - }); - expect(res.txHash).toBeTxHash(); - expect(res.volume).toBeInstanceOf(BN); - expect(res.volume.eq(new BN(1))).toBe(true); - expect(res.dealid).toBeTxHash(); - - // trigger app check - await expect( - iexecRequester.order.matchOrders({ - apporder, - datasetorder, - workerpoolorder: teeWorkerpoolorder, - requestorder: await getMatchableRequestorder(iexecRequester, { - apporder, - datasetorder, - workerpoolorder: teeWorkerpoolorder, - }).then((o) => - iexecRequester.order.signRequestorder( - { ...o, tag: ['tee', 'scone'] }, - { preflightCheck: false }, - ), + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderTooExpensive, + datasetorder: datasetorderTemplate, + workerpoolorder: workerpoolorderTemplate, + requestorder: requestorderTemplate, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow( + new Error( + `appmaxprice too low (expected ${apporderTooExpensive.appprice}, got ${requestorderTemplate.appmaxprice})`, ), - }), - ).rejects.toThrow(Error('Tag mismatch the TEE framework specified by app')); - - // trigger dataset check - await expect( - iexecRequester.order.matchOrders({ - apporder: teeApporder, - datasetorder: teeDatasetorder, - workerpoolorder: teeWorkerpoolorder, - requestorder: await getMatchableRequestorder(iexecRequester, { - apporder: teeApporder, - datasetorder: teeDatasetorder, - workerpoolorder: teeWorkerpoolorder, - }), - }), - ).rejects.toThrow('Dataset encryption key is not set for dataset '); - }); - - test('datasetorder tee framework burned tags are ignored', async () => { - const { iexec: iexecRequester } = getTestConfig(iexecTestChain)(); - const { iexec: iexecResourcesProvider } = getTestConfig(iexecTestChain)(); - - const apporder = await deployAndGetApporder(iexecResourcesProvider, { - teeFramework: TEE_FRAMEWORKS.SCONE, - tag: ['tee', 'scone'], - }); - const datasetorder = await deployAndGetDatasetorder( - iexecResourcesProvider, - { - tag: ['tee', 'gramine'], - }, - ); - await iexecResourcesProvider.dataset.pushDatasetSecret( - datasetorder.dataset, - 'foo', - ); - const workerpoolorder = await deployAndGetWorkerpoolorder( - iexecResourcesProvider, - { - tag: ['tee', 'scone'], - }, - ); - const requestorder = await getMatchableRequestorder(iexecRequester, { - apporder, - datasetorder, - workerpoolorder, - }); - // on bellecour burned tags are not implemented, so the match reverts on-chain but passes preflight checks - await expect( - iexecRequester.order.matchOrders({ - apporder, - datasetorder, - workerpoolorder, - requestorder, - }), - ).rejects.toThrow('execution reverted: revert: iExecV5-matchOrders-0x06'); - }); - - test('TDX tag with app without mrenclave passes checkAppRequirements (preflight)', async () => { - const { iexec: iexecRequester } = getTestConfig(iexecTestChain)(); - const { iexec: iexecResourcesProvider } = getTestConfig(iexecTestChain)(); - - const apporder = await deployAndGetApporder(iexecResourcesProvider, { - teeFramework: undefined, - tag: ['tee', 'tdx'], - }); - const datasetorder = await deployAndGetDatasetorder( - iexecResourcesProvider, - {}, - ); - await iexecResourcesProvider.dataset.pushDatasetSecret( - datasetorder.dataset, - 'foo', - { teeFramework: TEE_FRAMEWORKS.TDX }, - ); - const workerpoolorder = await deployAndGetWorkerpoolorder( - iexecResourcesProvider, - { tag: ['tee', 'tdx'] }, - ); - const requestorder = await getMatchableRequestorder(iexecRequester, { - apporder, - datasetorder, - workerpoolorder, - }); - await iexecRequester.order - .matchOrders( - { - apporder, - datasetorder, - workerpoolorder, - requestorder, - }, - { preflightCheck: true }, - ) - .then((res) => { - expect(res.txHash).toBeTxHash(); - expect(res.volume).toBeInstanceOf(BN); - expect(res.volume.eq(new BN(1))).toBe(true); - expect(res.dealid).toBeTxHash(); - }); - }); - - describe('useVoucher option', () => { - let iexecProvider; - let apporderTemplate; - let datasetorderTemplate; - let workerpoolorderTemplate; - let voucherTypeId; - - beforeAll(async () => { - const providerConfig = getTestConfig(iexecTestChain)(); - iexecProvider = providerConfig.iexec; - apporderTemplate = await deployAndGetApporder(iexecProvider, { - volume: 10, - appprice: 5, - }); - datasetorderTemplate = await deployAndGetDatasetorder(iexecProvider, { - volume: 7, - datasetprice: 1, - }); - workerpoolorderTemplate = await deployAndGetWorkerpoolorder( - iexecProvider, - { volume: 5, workerpoolprice: 1 }, - ); - - voucherTypeId = await createVoucherType(iexecTestChain)({ - description: 'test voucher type', - duration: 60 * 60, - }); - - await addVoucherEligibleAsset(iexecTestChain)( - apporderTemplate.app, - voucherTypeId, - ); - await addVoucherEligibleAsset(iexecTestChain)( - datasetorderTemplate.dataset, - voucherTypeId, - ); - await addVoucherEligibleAsset(iexecTestChain)( - workerpoolorderTemplate.workerpool, - voucherTypeId, ); - }); - test('should throw error if no voucher available for the requester', async () => { - const { iexec: iexecRequester, wallet: requesterWallet } = - getTestConfig(iexecTestChain)(); - - const apporder = await iexecProvider.order.signApporder(apporderTemplate); - const datasetorder = - await iexecProvider.order.signDatasetorder(datasetorderTemplate); - const workerpoolorder = await iexecProvider.order.signWorkerpoolorder( - workerpoolorderTemplate, + const datasetorderTooExpensive = + await iexecDatasetProvider.order.signDatasetorder( + { + ...datasetorderTemplate, + datasetprice: 1, + }, + { preflightCheck: false }, + ); + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderTemplate, + datasetorder: datasetorderTooExpensive, + workerpoolorder: workerpoolorderTemplate, + requestorder: requestorderTemplate, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow( + new Error( + `datasetmaxprice too low (expected ${datasetorderTooExpensive.datasetprice}, got ${requestorderTemplate.datasetmaxprice})`, + ), ); - const requestorder = await getMatchableRequestorder(iexecRequester, { - apporder, - datasetorder, - workerpoolorder, - }); + const workerpoolorderTooExpensive = + await iexecPoolManager.order.signWorkerpoolorder({ + ...workerpoolorderTemplate, + workerpoolprice: 1, + }); await expect( - iexecRequester.order.matchOrders( + iexecBroker.order.matchOrders( { - apporder, - datasetorder, - workerpoolorder, - requestorder, + apporder: apporderTemplate, + datasetorder: datasetorderTemplate, + workerpoolorder: workerpoolorderTooExpensive, + requestorder: requestorderTemplate, }, - { useVoucher: true }, + { preflightCheck: false }, ), ).rejects.toThrow( new Error( - `No voucher available for the requester ${requesterWallet.address}`, + `workerpoolmaxprice too low (expected ${workerpoolorderTooExpensive.workerpoolprice}, got ${requestorderTemplate.workerpoolmaxprice})`, ), ); - }); + // volumes checks + const apporderCanceled = await iexecAppProvider.order + .signApporder(apporderTemplate, { preflightCheck: false }) + .then(async (order) => { + await iexecAppProvider.order.cancelApporder(order); + return order; + }); + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderCanceled, + datasetorder: datasetorderTemplate, + workerpoolorder: workerpoolorderTemplate, + requestorder: requestorderTemplate, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow(Error('apporder is fully consumed')); - test('requires voucherHubAddress to be configured when useVoucher is true', async () => { - const noVoucherTestChain = TEST_CHAINS['custom-token-chain']; - const options = { - resultProxyURL: 'https://result-proxy.iex.ec', - smsURL: 'https://sms.iex.ec', - }; - const { iexec: iexecRequester, wallet: requesterWallet } = getTestConfig( - noVoucherTestChain, - )({ - options, - }); - const { iexec: iexecResourceProvider, wallet: resourceProviderWallet } = - getTestConfig(noVoucherTestChain)({ - options, + const datasetorderCanceled = await iexecDatasetProvider.order + .signDatasetorder(datasetorderTemplate, { preflightCheck: false }) + .then(async (order) => { + await iexecDatasetProvider.order.cancelDatasetorder(order); + return order; + }); + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderTemplate, + datasetorder: datasetorderCanceled, + workerpoolorder: workerpoolorderTemplate, + requestorder: requestorderTemplate, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow(Error('datasetorder is fully consumed')); + + const workerpoolorderCanceled = await iexecPoolManager.order + .signWorkerpoolorder(workerpoolorderTemplate) + .then(async (order) => { + await iexecPoolManager.order.cancelWorkerpoolorder(order); + return order; + }); + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderTemplate, + datasetorder: datasetorderTemplate, + workerpoolorder: workerpoolorderCanceled, + requestorder: requestorderTemplate, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow(Error('workerpoolorder is fully consumed')); + const requestorderCanceled = await iexecRequester.order + .signRequestorder(requestorderTemplate, { preflightCheck: false }) + .then(async (order) => { + await iexecRequester.order.cancelRequestorder(order); + return order; }); + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporderTemplate, + datasetorder: datasetorderTemplate, + workerpoolorder: workerpoolorderTemplate, + requestorder: requestorderCanceled, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow(Error('requestorder is fully consumed')); - await setBalance(noVoucherTestChain)(requesterWallet.address, ONE_ETH); - await setBalance(noVoucherTestChain)( - resourceProviderWallet.address, - ONE_ETH, + // requester account stake check + const balance = await iexecRequester.account.checkBalance( + await iexecRequester.wallet.getAddress(), ); + await iexecRequester.account.withdraw(balance.stake).catch(() => {}); + await iexecRequester.account.deposit(5); - const apporder = await deployAndGetApporder(iexecResourceProvider, { - volume: 10, - appprice: 5, - }); - const datasetorder = await deployAndGetDatasetorder( - iexecResourceProvider, + const apporder3nRlc = await iexecAppProvider.order.signApporder( { - volume: 7, - datasetprice: 1, + ...apporderTemplate, + appprice: 3, }, + { preflightCheck: false }, ); - const workerpoolorder = await deployAndGetWorkerpoolorder( - iexecResourceProvider, - { volume: 5, workerpoolprice: 1 }, + const datasetorder2nRlc = + await iexecDatasetProvider.order.signDatasetorder( + { + ...datasetorderTemplate, + datasetprice: 2, + }, + { preflightCheck: false }, + ); + const workerpoolorder1nRlc = + await iexecPoolManager.order.signWorkerpoolorder({ + ...workerpoolorderTemplate, + workerpoolprice: 1, + }); + const requestorder300nRlc = await iexecRequester.order.signRequestorder( + { + ...requestorderTemplate, + appmaxprice: 100, + datasetmaxprice: 100, + workerpoolmaxprice: 100, + }, + { preflightCheck: false }, ); - const requestorder = await getMatchableRequestorder(iexecRequester, { - apporder, - datasetorder, - workerpoolorder, - }); - - await setNRlcBalance(noVoucherTestChain)(requesterWallet.address, 100); - await iexecRequester.account.deposit(100); await expect( - iexecRequester.order.matchOrders( + iexecBroker.order.matchOrders( { - apporder, - datasetorder, - workerpoolorder, - requestorder, + apporder: apporder3nRlc, + datasetorder: datasetorder2nRlc, + workerpoolorder: workerpoolorder1nRlc, + requestorder: requestorder300nRlc, }, - { useVoucher: true }, + { preflightCheck: false }, ), ).rejects.toThrow( - new ConfigurationError( - `voucherHubAddress option not set and no default value for your chain ${noVoucherTestChain.chainId}`, + new Error( + "Cost per task (6) is greater than requester account stake (5). Orders can't be matched. If you are the requester, you should deposit to top up your account", ), ); - // match orders without useVoucher should pass - const res = await iexecRequester.order.matchOrders( + + const apporder0nRlc = await iexecAppProvider.order.signApporder( { - apporder, - datasetorder, - workerpoolorder, - requestorder, + ...apporderTemplate, + appprice: 0, + volume: 1000, }, - { useVoucher: false }, + { preflightCheck: false }, ); - expect(res.txHash).toBeTxHash(); - expect(res.volume).toBeInstanceOf(BN); - expect(res.volume.eq(new BN(5))).toBe(true); - expect(res.dealid).toBeTxHash(); - }); - - test('should throw error for insufficient voucher allowance', async () => { - const { iexec: iexecRequester, wallet: requesterWallet } = - getTestConfig(iexecTestChain)(); - const apporder = await iexecProvider.order.signApporder(apporderTemplate); - const datasetorder = - await iexecProvider.order.signDatasetorder(datasetorderTemplate); - const workerpoolorder = await iexecProvider.order.signWorkerpoolorder( - workerpoolorderTemplate, + const datasetorder0nRlc = + await iexecDatasetProvider.order.signDatasetorder( + { + ...datasetorderTemplate, + datasetprice: 0, + volume: 1000, + }, + { preflightCheck: false }, + ); + const workerpoolorder2nRlc = + await iexecPoolManager.order.signWorkerpoolorder({ + ...workerpoolorderTemplate, + workerpoolprice: 2, + volume: 1000, + }); + const requestorder6nRlc = await iexecRequester.order.signRequestorder( + { + ...requestorderTemplate, + workerpoolmaxprice: 2, + volume: 3, + }, + { preflightCheck: false }, ); - const requestorder = await getMatchableRequestorder(iexecRequester, { - apporder, - datasetorder, - workerpoolorder, - }); - const voucherAddress = await createVoucher(iexecTestChain)({ - owner: await requesterWallet.getAddress(), - voucherType: voucherTypeId, - value: 10, - }); - const allowance = await iexecRequester.account.checkAllowance( - requestorder.requester, - voucherAddress, + await expect( + iexecBroker.order.matchOrders( + { + apporder: apporder0nRlc, + datasetorder: datasetorder0nRlc, + workerpoolorder: workerpoolorder2nRlc, + requestorder: requestorder6nRlc, + }, + { preflightCheck: false }, + ), + ).rejects.toThrow( + new Error( + "Total cost for 3 tasks (6) is greater than requester account stake (5). Orders can't be matched. If you are the requester, you should deposit to top up your account or reduce your requestorder volume", + ), ); - const { total, sponsored } = - await iexecRequester.order.estimateMatchOrders( - { apporder, datasetorder, workerpoolorder, requestorder }, - { useVoucher: true }, - ); - - const requiredAmount = total.sub(sponsored); - const missingAmount = requiredAmount.sub(allowance); + // workerpool owner stake check + const workerpoolorder7nRlc = + await iexecPoolManager.order.signWorkerpoolorder({ + ...workerpoolorderTemplate, + workerpoolprice: 7, + }); + await iexecRequester.account.deposit(10); + const poolManagerBalance = await iexecPoolManager.account.checkBalance( + await iexecPoolManager.wallet.getAddress(), + ); + await iexecPoolManager.account + .withdraw(poolManagerBalance.stake) + .catch(() => {}); + await iexecPoolManager.account.deposit(1); await expect( - iexecRequester.order.matchOrders( + iexecBroker.order.matchOrders( { - apporder, - datasetorder, - workerpoolorder, - requestorder, + apporder: apporder3nRlc, + datasetorder: datasetorder2nRlc, + workerpoolorder: workerpoolorder7nRlc, + requestorder: requestorder300nRlc, }, - { useVoucher: true }, + { preflightCheck: false }, ), ).rejects.toThrow( new Error( - `Orders can't be matched. Please approve an additional ${missingAmount} for voucher usage.`, + "workerpool required stake (2) is greater than workerpool owner's account stake (1). Orders can't be matched. If you are the workerpool owner, you should deposit to top up your account", ), ); + // standard case + const res = await iexecBroker.order.matchOrders( + { + apporder: apporderTemplate, + datasetorder: datasetorderTemplate, + workerpoolorder: workerpoolorderTemplate, + requestorder: requestorderTemplate, + }, + { preflightCheck: false }, + ); + expect(res.txHash).toBeTxHash(); + expect(res.volume).toBeInstanceOf(BN); + expect(res.volume.eq(new BN(1))).toBe(true); + expect(res.dealid).toBeTxHash(); }); - test('should match orders with voucher when user deposits to cover the missing amount', async () => { - const { iexec: iexecRequester, wallet: requesterWallet } = - getTestConfig(iexecTestChain)(); + test('preflightChecks', async () => { + const { iexec: iexecRequester } = getTestConfig(iexecTestChain)(); + const { iexec: iexecResourcesProvider } = getTestConfig(iexecTestChain)(); - const apporder = await iexecProvider.order.signApporder(apporderTemplate); - const datasetorder = - await iexecProvider.order.signDatasetorder(datasetorderTemplate); - const workerpoolorder = await iexecProvider.order.signWorkerpoolorder( - workerpoolorderTemplate, + const apporder = await deployAndGetApporder(iexecResourcesProvider); + const datasetorder = await deployAndGetDatasetorder( + iexecResourcesProvider, + ); + const workerpoolorder = await deployAndGetWorkerpoolorder( + iexecResourcesProvider, ); const requestorder = await getMatchableRequestorder(iexecRequester, { apporder, @@ -2861,198 +2133,149 @@ describe('matchOrders()', () => { workerpoolorder, }); - const voucherAddress = await createVoucher(iexecTestChain)({ - owner: await requesterWallet.getAddress(), - voucherType: voucherTypeId, - value: 10, + const teeApporder = await deployAndGetApporder(iexecResourcesProvider, { + teeFramework: TEE_FRAMEWORKS.SCONE, + tag: ['tee', 'scone'], }); - await setNRlcBalance(iexecTestChain)(requesterWallet.address, 30); - await iexecRequester.account.deposit(30); - await iexecRequester.account.approve(25, voucherAddress); - const res = await iexecRequester.order.matchOrders( + const teeDatasetorder = await deployAndGetDatasetorder( + iexecResourcesProvider, + { tag: ['tee'] }, + ); + const teeWorkerpoolorder = await deployAndGetWorkerpoolorder( + iexecResourcesProvider, { - apporder, - datasetorder, - workerpoolorder, - requestorder, + tag: ['tee', 'scone'], }, - { useVoucher: true }, ); + const res = await iexecRequester.order.matchOrders({ + apporder, + datasetorder, + workerpoolorder, + requestorder, + }); expect(res.txHash).toBeTxHash(); expect(res.volume).toBeInstanceOf(BN); - expect(res.volume.eq(new BN(5))).toBe(true); + expect(res.volume.eq(new BN(1))).toBe(true); expect(res.dealid).toBeTxHash(); - const tx = await iexecTestChain.provider.getTransaction(res.txHash); - expect(tx.to).toBe(voucherAddress); - }); - - describe('with custom voucherAddress option', () => { - test('should use specified voucherAddress', async () => { - const { iexec: iexecRequester, wallet: requesterWallet } = - getTestConfig(iexecTestChain)(); - const { iexec: iexecVoucherOwner, wallet: voucherOwnerWallet } = - getTestConfig(iexecTestChain)(); - - const apporder = - await iexecProvider.order.signApporder(apporderTemplate); - const datasetorder = - await iexecProvider.order.signDatasetorder(datasetorderTemplate); - const workerpoolorder = await iexecProvider.order.signWorkerpoolorder( - workerpoolorderTemplate, - ); - const requestorder = await getMatchableRequestorder(iexecRequester, { + // trigger app check + await expect( + iexecRequester.order.matchOrders({ apporder, datasetorder, - workerpoolorder, - }); - - const voucherAddress = await createVoucher(iexecTestChain)({ - owner: await voucherOwnerWallet.getAddress(), - voucherType: voucherTypeId, - value: 1000000000, - }); - await iexecVoucherOwner.voucher.authorizeRequester( - requesterWallet.address, - ); - - const res = await iexecRequester.order.matchOrders( - { + workerpoolorder: teeWorkerpoolorder, + requestorder: await getMatchableRequestorder(iexecRequester, { apporder, datasetorder, - workerpoolorder, - requestorder, - }, - { useVoucher: true, voucherAddress }, - ); - expect(res.txHash).toBeTxHash(); - expect(res.volume).toBeInstanceOf(BN); - expect(res.volume.eq(new BN(5))).toBe(true); - expect(res.dealid).toBeTxHash(); - const tx = await iexecTestChain.provider.getTransaction(res.txHash); - expect(tx.to).toBe(voucherAddress); - }); - - test('requester can pay for non-sponsored assets', async () => { - const { iexec: iexecRequester, wallet: requesterWallet } = - getTestConfig(iexecTestChain)(); - await setNRlcBalance(iexecTestChain)(requesterWallet.address, 1000); - await iexecRequester.account.deposit(1000); + workerpoolorder: teeWorkerpoolorder, + }).then((o) => + iexecRequester.order.signRequestorder( + { ...o, tag: ['tee', 'scone'] }, + { preflightCheck: false }, + ), + ), + }), + ).rejects.toThrow( + Error('Tag mismatch the TEE framework specified by app'), + ); - const { iexec: iexecVoucherOwner, wallet: voucherOwnerWallet } = - getTestConfig(iexecTestChain)(); + // trigger dataset check + await expect( + iexecRequester.order.matchOrders({ + apporder: teeApporder, + datasetorder: teeDatasetorder, + workerpoolorder: teeWorkerpoolorder, + requestorder: await getMatchableRequestorder(iexecRequester, { + apporder: teeApporder, + datasetorder: teeDatasetorder, + workerpoolorder: teeWorkerpoolorder, + }), + }), + ).rejects.toThrow('Dataset encryption key is not set for dataset '); + }); - const { iexec: iexecDatasetProvider } = getTestConfig(iexecTestChain)(); + test('datasetorder tee framework burned tags are ignored', async () => { + const { iexec: iexecRequester } = getTestConfig(iexecTestChain)(); + const { iexec: iexecResourcesProvider } = getTestConfig(iexecTestChain)(); - const apporder = - await iexecProvider.order.signApporder(apporderTemplate); - const workerpoolorder = await iexecProvider.order.signWorkerpoolorder( - workerpoolorderTemplate, - ); - // non-sponsored asset - const datasetorder = await deployAndGetDatasetorder( - iexecDatasetProvider, - { datasetprice: 200 }, - ); - const requestorder = await getMatchableRequestorder(iexecRequester, { + const apporder = await deployAndGetApporder(iexecResourcesProvider, { + teeFramework: TEE_FRAMEWORKS.SCONE, + tag: ['tee', 'scone'], + }); + const datasetorder = await deployAndGetDatasetorder( + iexecResourcesProvider, + { + tag: ['tee', 'gramine'], + }, + ); + await iexecResourcesProvider.dataset.pushDatasetSecret( + datasetorder.dataset, + 'foo', + ); + const workerpoolorder = await deployAndGetWorkerpoolorder( + iexecResourcesProvider, + { + tag: ['tee', 'scone'], + }, + ); + const requestorder = await getMatchableRequestorder(iexecRequester, { + apporder, + datasetorder, + workerpoolorder, + }); + // on bellecour burned tags are not implemented, so the match reverts on-chain but passes preflight checks + await expect( + iexecRequester.order.matchOrders({ apporder, datasetorder, workerpoolorder, - }); + requestorder, + }), + ).rejects.toThrow('execution reverted: revert: iExecV5-matchOrders-0x06'); + }); - const voucherAddress = await createVoucher(iexecTestChain)({ - owner: await voucherOwnerWallet.getAddress(), - voucherType: voucherTypeId, - value: 1000000000, - }); - await iexecVoucherOwner.voucher.authorizeRequester( - requesterWallet.address, - ); - await iexecRequester.account.approve(500, voucherAddress); - const res = await iexecRequester.order.matchOrders( + test('TDX tag with app without mrenclave passes checkAppRequirements (preflight)', async () => { + const { iexec: iexecRequester } = getTestConfig(iexecTestChain)(); + const { iexec: iexecResourcesProvider } = getTestConfig(iexecTestChain)(); + + const apporder = await deployAndGetApporder(iexecResourcesProvider, { + teeFramework: undefined, + tag: ['tee', 'tdx'], + }); + const datasetorder = await deployAndGetDatasetorder( + iexecResourcesProvider, + {}, + ); + await iexecResourcesProvider.dataset.pushDatasetSecret( + datasetorder.dataset, + 'foo', + { teeFramework: TEE_FRAMEWORKS.TDX }, + ); + const workerpoolorder = await deployAndGetWorkerpoolorder( + iexecResourcesProvider, + { tag: ['tee', 'tdx'] }, + ); + const requestorder = await getMatchableRequestorder(iexecRequester, { + apporder, + datasetorder, + workerpoolorder, + }); + await iexecRequester.order + .matchOrders( { apporder, datasetorder, workerpoolorder, requestorder, }, - { useVoucher: true, voucherAddress }, - ); - expect(res.txHash).toBeTxHash(); - expect(res.dealid).toBeTxHash(); - const tx = await iexecTestChain.provider.getTransaction(res.txHash); - expect(tx.to).toBe(voucherAddress); - const finalAccountBalance = await iexecRequester.account.checkBalance( - requesterWallet.address, - ); - expect(finalAccountBalance.stake.eq(new BN(800))).toBe(true); - }); - - test('should throw if specified voucherAddress is not a voucher', async () => { - const { iexec: iexecRequester } = getTestConfig(iexecTestChain)(); - - const apporder = - await iexecProvider.order.signApporder(apporderTemplate); - const datasetorder = - await iexecProvider.order.signDatasetorder(datasetorderTemplate); - const workerpoolorder = await iexecProvider.order.signWorkerpoolorder( - workerpoolorderTemplate, - ); - const requestorder = await getMatchableRequestorder(iexecRequester, { - apporder, - datasetorder, - workerpoolorder, - }); - - await expect( - iexecRequester.order.matchOrders( - { - apporder, - datasetorder, - workerpoolorder, - requestorder, - }, - { useVoucher: true, voucherAddress: getRandomAddress() }, - ), - ).rejects.toThrow(Error('Invalid voucher contract address')); - }); - - test('should throw if user is not allowed to use specified voucherAddress', async () => { - const { iexec: iexecRequester } = getTestConfig(iexecTestChain)(); - - const { wallet: voucherOwnerWallet } = getTestConfig(iexecTestChain)(); - - const apporder = - await iexecProvider.order.signApporder(apporderTemplate); - const datasetorder = - await iexecProvider.order.signDatasetorder(datasetorderTemplate); - const workerpoolorder = await iexecProvider.order.signWorkerpoolorder( - workerpoolorderTemplate, - ); - const requestorder = await getMatchableRequestorder(iexecRequester, { - apporder, - datasetorder, - workerpoolorder, - }); - - const voucherAddress = await createVoucher(iexecTestChain)({ - owner: await voucherOwnerWallet.getAddress(), - voucherType: voucherTypeId, - value: 100000000, + { preflightCheck: true }, + ) + .then((res) => { + expect(res.txHash).toBeTxHash(); + expect(res.volume).toBeInstanceOf(BN); + expect(res.volume.eq(new BN(1))).toBe(true); + expect(res.dealid).toBeTxHash(); }); - - await expect( - iexecRequester.order.matchOrders( - { - apporder, - datasetorder, - workerpoolorder, - requestorder, - }, - { useVoucher: true, voucherAddress }, - ), - ).rejects.toThrow(Error('User is not authorized to use the voucher')); - }); }); }); }); diff --git a/test/lib/e2e/IExecVoucherModule.test.js b/test/lib/e2e/IExecVoucherModule.test.js deleted file mode 100644 index 5cf73f3c..00000000 --- a/test/lib/e2e/IExecVoucherModule.test.js +++ /dev/null @@ -1,314 +0,0 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies -import { beforeAll, describe, test, expect } from '@jest/globals'; -import { BN } from 'bn.js'; -import { - deployRandomApp, - deployRandomDataset, - deployRandomWorkerpool, - getTestConfig, -} from '../lib-test-utils.js'; -import { - TEST_CHAINS, - addVoucherEligibleAsset, - createVoucher, - createVoucherType, - getRandomAddress, - getRandomWallet, - sleep, -} from '../../test-utils.js'; -import '../../jest-setup.js'; - -const iexecTestChain = TEST_CHAINS['bellecour-fork']; -const unknownTestChain = TEST_CHAINS['custom-token-chain']; - -describe('voucher', () => { - describe('getVoucherAddress()', () => { - test('requires voucherHubAddress to be configured', async () => { - const owner = getRandomAddress(); - const { iexec } = getTestConfig(unknownTestChain)({ readOnly: true }); - await expect(iexec.voucher.getVoucherAddress(owner)).rejects.toThrow( - new Error( - `voucherHubAddress option not set and no default value for your chain ${unknownTestChain.chainId}`, - ), - ); - }); - - test('returns null if user has no voucher', async () => { - const owner = getRandomAddress(); - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); - const res = await iexec.voucher.getVoucherAddress(owner); - expect(res).toBe(null); - }); - - test('returns voucher address when user has one', async () => { - const owner = getRandomAddress(); - const voucherType = await createVoucherType(iexecTestChain)({}); - const voucherAddress = await createVoucher(iexecTestChain)({ - owner, - voucherType, - value: 1000, - }); - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); - const res = await iexec.voucher.getVoucherAddress(owner); - expect(res).toBe(voucherAddress); - }); - }); - - describe('showUserVoucher()', () => { - test('requires voucherHubAddress to be configured', async () => { - const owner = getRandomAddress(); - const { iexec } = getTestConfig(unknownTestChain)({ - readOnly: true, - options: { voucherSubgraphURL: 'http://voucher-subgraph.iex.ec' }, - }); - await expect(iexec.voucher.showUserVoucher(owner)).rejects.toThrow( - new Error( - `voucherHubAddress option not set and no default value for your chain ${unknownTestChain.chainId}`, - ), - ); - }); - - test('requires voucherSubgraphURL to be configured', async () => { - const owner = getRandomAddress(); - const { iexec } = getTestConfig(unknownTestChain)({ - readOnly: true, - options: { voucherHubAddress: getRandomAddress() }, - }); - await expect(iexec.voucher.showUserVoucher(owner)).rejects.toThrow( - new Error( - `voucherSubgraphURL option not set and no default value for your chain ${unknownTestChain.chainId}`, - ), - ); - }); - - test('throw error if user has no voucher', async () => { - const owner = getRandomAddress(); - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); - - await expect(iexec.voucher.showUserVoucher(owner)).rejects.toThrowError( - `No Voucher found for address ${owner}`, - ); - }); - - test('throw error if owner address is not provided', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); - await expect(iexec.voucher.showUserVoucher()).rejects.toThrowError( - 'Missing parameter', - ); - }); - - test('throw error if user address is not a valid ethereum address', async () => { - const owner = 'invalid_address'; - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); - await expect(iexec.voucher.showUserVoucher(owner)).rejects.toThrowError( - `${owner} is not a valid ethereum address`, - ); - }); - - test('returns voucher details when user has one', async () => { - // initial setup - const voucherOwnerWallet = getRandomWallet(); - const { iexec } = getTestConfig(iexecTestChain)({ - privateKey: voucherOwnerWallet.privateKey, - }); - const voucherType = await createVoucherType(iexecTestChain)({}); - // add sponsored assets - const { address: appAddress } = await deployRandomApp(iexec); - const { address: appAddress1 } = await deployRandomApp(iexec); - const { address: datasetAddress } = await deployRandomDataset(iexec); - const { address: datasetAddress1 } = await deployRandomDataset(iexec); - const { address: workerpoolAddress } = - await deployRandomWorkerpool(iexec); - const { address: workerpoolAddress1 } = - await deployRandomWorkerpool(iexec); - - await addVoucherEligibleAsset(iexecTestChain)(appAddress, voucherType); - await addVoucherEligibleAsset(iexecTestChain)(appAddress1, voucherType); - await addVoucherEligibleAsset(iexecTestChain)( - datasetAddress, - voucherType, - ); - await addVoucherEligibleAsset(iexecTestChain)( - datasetAddress1, - voucherType, - ); - await addVoucherEligibleAsset(iexecTestChain)( - workerpoolAddress, - voucherType, - ); - await addVoucherEligibleAsset(iexecTestChain)( - workerpoolAddress1, - voucherType, - ); - - // create voucher - const voucherValue = 1000; - const voucherAddress = await createVoucher(iexecTestChain)({ - owner: voucherOwnerWallet.address, - voucherType, - value: voucherValue, - }); - - // authorize an account for the voucher - const accountAddress = getRandomAddress(); - await iexec.voucher.authorizeRequester(accountAddress); - const accountAddress1 = getRandomAddress(); - await iexec.voucher.authorizeRequester(accountAddress1); - - await sleep(10000); // wait for subgraph indexation - - // call the function and check the results - const userVoucher = await iexec.voucher.showUserVoucher( - voucherOwnerWallet.address, - ); - - expect(userVoucher.type).toBeInstanceOf(BN); - expect(userVoucher.expirationTimestamp).toBeInstanceOf(BN); - expect(userVoucher.balance).toBeInstanceOf(BN); - expect(userVoucher.allowanceAmount).toBeInstanceOf(BN); - expect(userVoucher.owner).toBe(voucherOwnerWallet.address); - expect(userVoucher.address).toBe(voucherAddress); - expect([...userVoucher.sponsoredApps].sort()).toEqual( - [appAddress, appAddress1].sort(), - ); - expect([...userVoucher.sponsoredDatasets].sort()).toEqual( - [datasetAddress, datasetAddress1].sort(), - ); - expect([...userVoucher.sponsoredWorkerpools].sort()).toEqual( - [workerpoolAddress, workerpoolAddress1].sort(), - ); - expect([...userVoucher.authorizedAccounts].sort()).toEqual( - [accountAddress, accountAddress1].sort(), - ); - }); - }); - - describe('authorizeRequester()', () => { - let voucherType; - beforeAll(async () => { - voucherType = await createVoucherType(iexecTestChain)({}); - }); - - test('requires voucherHubAddress to be configured', async () => { - const { iexec } = getTestConfig(unknownTestChain)(); - await expect( - iexec.voucher.authorizeRequester(getRandomAddress()), - ).rejects.toThrow( - new Error( - `voucherHubAddress option not set and no default value for your chain ${unknownTestChain.chainId}`, - ), - ); - }); - - test('requires a signer', async () => { - const requester = getRandomAddress(); - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); - await expect(iexec.voucher.authorizeRequester(requester)).rejects.toThrow( - new Error( - 'The current provider is not a signer, impossible to sign messages or transactions', - ), - ); - }); - - test('requires the user owns a voucher', async () => { - const requester = getRandomAddress(); - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - await expect(iexec.voucher.authorizeRequester(requester)).rejects.toThrow( - new Error(`No Voucher found for address ${wallet.address}`), - ); - }); - - test('authorizes the requester to use the voucher', async () => { - const requester = getRandomAddress(); - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - await createVoucher(iexecTestChain)({ - owner: wallet.address, - voucherType, - value: 1000, - }); - const res = await iexec.voucher.authorizeRequester(requester); - expect(res).toBeTxHash(); - }); - - test('throw when the requester is already authorized', async () => { - const requester = getRandomAddress(); - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - await createVoucher(iexecTestChain)({ - owner: wallet.address, - voucherType, - value: 1000, - }); - await iexec.voucher.authorizeRequester(requester); - await expect(iexec.voucher.authorizeRequester(requester)).rejects.toThrow( - new Error(`${requester} is already authorized`), - ); - }); - }); - - describe('revokeRequesterAuthorization()', () => { - let voucherType; - beforeAll(async () => { - voucherType = await createVoucherType(iexecTestChain)({}); - }); - - test('requires voucherHubAddress to be configured', async () => { - const { iexec } = getTestConfig(unknownTestChain)(); - await expect( - iexec.voucher.revokeRequesterAuthorization(getRandomAddress()), - ).rejects.toThrow( - new Error( - `voucherHubAddress option not set and no default value for your chain ${unknownTestChain.chainId}`, - ), - ); - }); - - test('requires a signer', async () => { - const requester = getRandomAddress(); - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); - await expect( - iexec.voucher.revokeRequesterAuthorization(requester), - ).rejects.toThrow( - new Error( - 'The current provider is not a signer, impossible to sign messages or transactions', - ), - ); - }); - - test('requires the user owns a voucher', async () => { - const requester = getRandomAddress(); - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - await expect( - iexec.voucher.revokeRequesterAuthorization(requester), - ).rejects.toThrow( - new Error(`No Voucher found for address ${wallet.address}`), - ); - }); - - test('throw when the requester is not previously authorized', async () => { - const requester = getRandomAddress(); - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - await createVoucher(iexecTestChain)({ - owner: wallet.address, - voucherType, - value: 1000, - }); - await expect( - iexec.voucher.revokeRequesterAuthorization(requester), - ).rejects.toThrow(Error(`${requester} is not authorized`)); - }); - - test('revokes the requester authorization to use the voucher', async () => { - const requester = getRandomAddress(); - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - await createVoucher(iexecTestChain)({ - owner: wallet.address, - voucherType, - value: 1000, - }); - await iexec.voucher.authorizeRequester(requester); - const res = await iexec.voucher.revokeRequesterAuthorization(requester); - expect(res).toBeTxHash(); - }); - }); -}); diff --git a/test/lib/e2e/IExecWalletModule.test.js b/test/lib/e2e/IExecWalletModule.test.js index 5691a39a..627dd766 100644 --- a/test/lib/e2e/IExecWalletModule.test.js +++ b/test/lib/e2e/IExecWalletModule.test.js @@ -4,9 +4,6 @@ import { describe, test, expect } from '@jest/globals'; import { BN } from 'bn.js'; import { ONE_ETH, ONE_RLC, getTestConfig } from '../lib-test-utils.js'; import { - ALCHEMY_API_KEY, - ETHERSCAN_API_KEY, - INFURA_PROJECT_ID, DEFAULT_PROVIDER_OPTIONS, TEST_CHAINS, getRandomAddress, diff --git a/test/lib/e2e/IExecWorkerpoolModule.test.js b/test/lib/e2e/IExecWorkerpoolModule.test.js index 760f4e33..eb6e2b7e 100644 --- a/test/lib/e2e/IExecWorkerpoolModule.test.js +++ b/test/lib/e2e/IExecWorkerpoolModule.test.js @@ -11,7 +11,7 @@ import { getRandomAddress, } from '../../test-utils.js'; import '../../jest-setup.js'; -import { errors, IExec } from '../../../src/lib/index.js'; +import { errors } from '../../../src/lib/index.js'; const iexecTestChain = TEST_CHAINS['bellecour-fork']; diff --git a/test/lib/e2e/voucher.test.js b/test/lib/e2e/voucher.test.js deleted file mode 100644 index ec187157..00000000 --- a/test/lib/e2e/voucher.test.js +++ /dev/null @@ -1,41 +0,0 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies -import { describe, test, expect } from '@jest/globals'; -import { - TEST_CHAINS, - createVoucher, - createVoucherType, - getRandomAddress, -} from '../../test-utils.js'; -import '../../jest-setup.js'; -import { getTestConfig } from '../lib-test-utils.js'; - -const iexecTestChain = TEST_CHAINS['bellecour-fork']; - -describe('voucher test utils', () => { - test('createVoucherType should create a voucherType and return the id', async () => { - const voucherTypeId = await createVoucherType(iexecTestChain)({ - description: 'test voucher type', - duration: 42, - }); - expect(typeof voucherTypeId).toBe('bigint'); - }); - test('createVoucher should create a voucher and publish workerpool orders', async () => { - const owner = getRandomAddress(); - const voucherTypeId = await createVoucherType(iexecTestChain)(); - await createVoucher(iexecTestChain)({ - owner, - voucherType: voucherTypeId, - value: 48, - }); - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); - const debugWorkerpoolOrderbook = - await iexec.orderbook.fetchWorkerpoolOrderbook({ - workerpool: 'debug-v8-bellecour.main.pools.iexec.eth', - minTag: ['tee', 'scone'], - requester: owner, - isRequesterStrict: true, - }); - expect(debugWorkerpoolOrderbook.count).toBeGreaterThan(0); - }); -}); diff --git a/test/lib/unit/config.test.js b/test/lib/unit/config.test.js index 9d23f3f3..90fff87f 100644 --- a/test/lib/unit/config.test.js +++ b/test/lib/unit/config.test.js @@ -41,9 +41,6 @@ describe('getChainDefaults', () => { scone: 'https://sms.iex.ec', }, compass: undefined, - voucherHub: '0x3137B6DF4f36D338b82260eDBB2E7bab034AFEda', - voucherSubgraph: - 'https://thegraph.iex.ec/subgraphs/name/bellecour/iexec-voucher', }); }); test('unknown id returns empty object', () => { @@ -108,27 +105,6 @@ describe('checkImplementedOnChain', () => { ); }); }); - describe(`feature ${CHAIN_SPECIFIC_FEATURES.VOUCHER}`, () => { - const feature = CHAIN_SPECIFIC_FEATURES.VOUCHER; - test('is implemented on bellecour', () => { - expect(() => checkImplementedOnChain(134, feature)).not.toThrow(); - }); - test('is not implemented on mainnet', () => { - expect(() => checkImplementedOnChain(1, feature)).toThrow( - `${feature} is not available on network mainnet`, - ); - }); - test('is not implemented on arbitrum-mainnet', () => { - expect(() => checkImplementedOnChain(42161, feature)).toThrow( - `${feature} is not available on network arbitrum-mainnet`, - ); - }); - test('is not implemented on arbitrum-sepolia-testnet', () => { - expect(() => checkImplementedOnChain(421614, feature)).toThrow( - `${feature} is not available on network arbitrum-sepolia-testnet`, - ); - }); - }); describe(`feature ${CHAIN_SPECIFIC_FEATURES.COMPASS}`, () => { const feature = CHAIN_SPECIFIC_FEATURES.COMPASS; test('is not implemented on bellecour', () => { diff --git a/test/scripts/prepare-bellecour-fork-for-tests.js b/test/scripts/prepare-bellecour-fork-for-tests.js index c66aa9b4..c37c6769 100755 --- a/test/scripts/prepare-bellecour-fork-for-tests.js +++ b/test/scripts/prepare-bellecour-fork-for-tests.js @@ -3,22 +3,12 @@ import { JsonRpcProvider, JsonRpcSigner, formatEther, - keccak256, toBeHex, } from 'ethers'; const IEXEC_HUB_ADDRESS = '0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f'; -const VOUCHER_HUB_ADDRESS = '0x3137B6DF4f36D338b82260eDBB2E7bab034AFEda'; const TARGET_POCO_ADMIN_WALLET = '0x7bd4783FDCAD405A28052a0d1f11236A741da593'; const TARGET_FAUCET_WALLET = '0xdFa2585C16cAf9c853086F36d2A37e9b8d1eab87'; -const TARGET_VOUCHER_MANAGER_WALLET = - '0x44cA21A3c4efE9B1A0268e2e9B2547E7d9C8f19C'; -const DEBUG_WORKERPOOL_OWNER_WALLET = - '0x02D0e61355e963210d0DE382e6BA09781181bB94'; -const PROD_WORKERPOOL_OWNER_WALLET = - '0x1Ff6AfF580e8Ca738F76485E0914C2aCaDa7B462'; -const DEBUG_WORKERPOOL = '0xdb214a4a444d176e22030be1ed89da1b029320f2'; // 'debug-v8-bellecour.main.pools.iexec.eth'; -const PROD_WORKERPOOL = '0x0e7bc972c99187c191a17f3cae4a2711a4188c3f'; // 'prod-v8-bellecour.main.pools.iexec.eth'; const rpcURL = 'http://localhost:8545'; @@ -113,190 +103,6 @@ const getIExecHubOwnership = async (targetOwner) => { ); }; -const getVoucherManagementRoles = async (targetManager) => { - const voucherHubContract = new Contract( - VOUCHER_HUB_ADDRESS, - [ - { - inputs: [], - name: 'defaultAdmin', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'grantRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'hasRole', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - ], - provider, - ); - - const defaultAdmin = await voucherHubContract.defaultAdmin(); - - console.log('VoucherHub defaultAdmin:', defaultAdmin); - - await impersonate(defaultAdmin); - - const MINTER_ROLE = keccak256(Buffer.from('MINTER_ROLE')); - - const MANAGER_ROLE = keccak256(Buffer.from('MANAGER_ROLE')); - - await voucherHubContract - .connect(new JsonRpcSigner(provider, defaultAdmin)) - .grantRole(MINTER_ROLE, targetManager, { gasPrice: 0 }) - .then((tx) => tx.wait()); - - await voucherHubContract - .connect(new JsonRpcSigner(provider, defaultAdmin)) - .grantRole(MANAGER_ROLE, targetManager, { - gasPrice: 0, - }) - .then((tx) => tx.wait()); - - await stopImpersonate(defaultAdmin); - - console.log( - `${targetManager} has role MINTER_ROLE: ${await voucherHubContract.hasRole( - MINTER_ROLE, - targetManager, - )}`, - ); - - console.log( - `${targetManager} has role MANAGER_ROLE: ${await voucherHubContract.hasRole( - MANAGER_ROLE, - targetManager, - )}`, - ); -}; - -const getWorkerpoolOwnership = async (resourceAddress, targetOwner) => { - const RESOURCE_ABI = [ - { - inputs: [], - name: 'owner', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'registry', - outputs: [ - { - internalType: 'contract IRegistry', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - ]; - const RESOURCE_REGISTRY_ABI = [ - { - inputs: [ - { - internalType: 'address', - name: 'from', - type: 'address', - }, - { - internalType: 'address', - name: 'to', - type: 'address', - }, - { - internalType: 'uint256', - name: 'tokenId', - type: 'uint256', - }, - ], - name: 'safeTransferFrom', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - ]; - - const resourceContract = new Contract( - resourceAddress, - RESOURCE_ABI, - provider, - ); - - const resourceOwner = await resourceContract.owner(); - const resourceRegistryAddress = await resourceContract.registry(); - const resourceRegistryContract = new Contract( - resourceRegistryAddress, - RESOURCE_REGISTRY_ABI, - provider, - ); - - await impersonate(resourceOwner); - await resourceRegistryContract - .connect(new JsonRpcSigner(provider, resourceOwner)) - .safeTransferFrom(resourceOwner, targetOwner, resourceAddress, { - gasPrice: 0, - }) - .then((tx) => tx.wait()); - await stopImpersonate(resourceOwner); - - const newOwner = await resourceContract.owner(); - console.log(`Workerpool ${resourceAddress} is now owned by ${newOwner}`); -}; - const main = async () => { console.log(`preparing bellecour-fork at ${rpcURL}`); @@ -306,14 +112,6 @@ const main = async () => { // prepare faucet wallet await setBalance(TARGET_FAUCET_WALLET, 1000000n * 10n ** 18n); - - // prepare Voucher - await setBalance(TARGET_VOUCHER_MANAGER_WALLET, 1000000n * 10n ** 18n); - await getVoucherManagementRoles(TARGET_VOUCHER_MANAGER_WALLET); - - // prepare workerpools - await getWorkerpoolOwnership(DEBUG_WORKERPOOL, DEBUG_WORKERPOOL_OWNER_WALLET); - await getWorkerpoolOwnership(PROD_WORKERPOOL, PROD_WORKERPOOL_OWNER_WALLET); }; main(); diff --git a/test/test-config-utils.js b/test/test-config-utils.js index 14fa7441..29280ffa 100644 --- a/test/test-config-utils.js +++ b/test/test-config-utils.js @@ -13,12 +13,10 @@ export const getTestConfigOptions = options.ensPublicResolverAddress ?? chain.ensPublicResolverAddress, ensRegistryAddress: options.ensRegistryAddress ?? chain.ensRegistryAddress, hubAddress: options.hubAddress ?? chain.hubAddress, - voucherHubAddress: options.voucherHubAddress ?? chain.voucherHubAddress, iexecGatewayURL: options.iexecGatewayURL ?? chain.iexecGatewayURL, ipfsNodeURL: options.ipfsNodeURL ?? chain.ipfsNodeURL, ipfsGatewayURL: options.ipfsGatewayURL ?? chain.ipfsGatewayURL, pocoSubgraphURL: options.pocoSubgraphURL ?? chain.pocoSubgraphURL, - voucherSubgraphURL: options.voucherSubgraphURL ?? chain.voucherSubgraphURL, isNative: options.isNative ?? chain.isNative, providerOptions: options.providerOptions ?? chain.providerOptions, resultProxyURL: options.resultProxyURL ?? chain.resultProxyURL, diff --git a/test/test-utils.js b/test/test-utils.js index 620eb069..76306bd7 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -10,9 +10,6 @@ import { } from 'ethers'; import { IExec } from '../src/lib/index.js'; import { getSignerFromPrivateKey } from '../src/lib/utils.js'; -import { getEventFromLogs } from '../src/common/utils/utils.js'; -import { getTestConfig } from './test-config-utils.js'; -import { abi as voucherHubAbi } from '../src/common/generated/@iexec/voucher-contracts/VoucherHub.js'; export { TEE_FRAMEWORKS, @@ -120,25 +117,11 @@ export const TEST_CHAINS = { faucetWallet: new Wallet( '0xde43b282c2931fc41ca9e1486fedc2c45227a3b9b4115c89d37f6333c8816d89', ), - voucherManagerWallet: new Wallet( - '0x2c906d4022cace2b3ee6c8b596564c26c4dcadddf1e949b769bcb0ad75c40c33', - ), - voucherSubgraphURL: - 'http://localhost:8000/subgraphs/name/bellecour/iexec-voucher', - debugWorkerpool: 'debug-v8-bellecour.main.pools.iexec.eth', - debugWorkerpoolOwnerWallet: new Wallet( - '0x800e01919eadf36f110f733decb1cc0f82e7941a748e89d7a3f76157f6654bb3', - ), - prodWorkerpool: 'prod-v8-bellecour.main.pools.iexec.eth', - prodWorkerpoolOwnerWallet: new Wallet( - '0x6a12f56d7686e85ab0f46eb3c19cb0c75bfabf8fb04e595654fc93ad652fa7bc', - ), provider: new JsonRpcProvider('http://localhost:8545', undefined, { pollingInterval: 100, }), defaults: { hubAddress: '0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f', - voucherHubAddress: '0x3137B6DF4f36D338b82260eDBB2E7bab034AFEda', ensRegistryAddress: '0x5f5B93fca68c9C79318d1F3868A354EE67D8c006', ensPublicResolverAddress: '0x1347d8a1840A810B990d0B774A6b7Bb8A1bd62BB', isNative: true, @@ -412,171 +395,3 @@ export const adminCreateCategory = } return res; }; - -export const createVoucherType = - (chain) => - async ({ description = 'test', duration = 1000 } = {}) => { - const voucherHubAddress = - chain.voucherHubAddress || chain.defaults.voucherHubAddress; - - const voucherHubContract = new Contract( - voucherHubAddress, - voucherHubAbi, - chain.provider, - ); - const signer = chain.voucherManagerWallet.connect(chain.provider); - - const retryableCreateVoucherType = async (tryCount = 1) => { - let id; - try { - const createVoucherTypeTxHash = await voucherHubContract - .connect(signer) - .createVoucherType(description, duration); - const txReceipt = await createVoucherTypeTxHash.wait(); - id = getEventFromLogs('VoucherTypeCreated', txReceipt.logs, { - strict: true, - }).args.id; - } catch (error) { - console.warn( - `Error creating voucher type (try count ${tryCount}):`, - error, - ); - if (tryCount < 5) { - await sleep(3000 * tryCount); - id = await retryableCreateVoucherType(tryCount + 1); - } else { - throw new Error( - `Failed to create voucher after ${tryCount} attempts`, - ); - } - } - return id; - }; - return retryableCreateVoucherType(); // return voucherType id (bigint) - }; - -// TODO: update createWorkerpoolorder() parameters when it is specified -export const createAndPublishWorkerpoolOrder = - (chain) => - async ({ - workerpool, - workerpoolOwnerWallet, - requesterrestrict, - volume = 1000, - price = 1000, - }) => { - const { iexec } = getTestConfig(chain)({ - privateKey: workerpoolOwnerWallet.privateKey, - }); - - await setStakedNRlcBalance(chain)( - workerpoolOwnerWallet.address, - volume * price, - ); - - const workerpoolorder = await iexec.order.createWorkerpoolorder({ - workerpool, - category: 0, - requesterrestrict, - volume, - workerpoolprice: price, - tag: ['tee', 'scone'], - }); - - await iexec.order - .signWorkerpoolorder(workerpoolorder) - .then((o) => iexec.order.publishWorkerpoolorder(o)); - }; - -export const createVoucher = - (chain) => - async ({ owner, voucherType, value }) => { - const voucherHubAddress = - chain.voucherHubAddress || chain.defaults.voucherHubAddress; - // deposit voucher value on VoucherHub with a random wallet - await setStakedNRlcBalance(chain)(voucherHubAddress, value); - - const voucherHubContract = new Contract( - voucherHubAddress, - voucherHubAbi, - chain.provider, - ); - - const signer = chain.voucherManagerWallet.connect(chain.provider); - - const retryableCreateVoucher = async (tryCount = 1) => { - try { - const createVoucherTx = await voucherHubContract - .connect(signer) - .createVoucher(owner, voucherType, value); - await createVoucherTx.wait(); - } catch (error) { - console.warn(`Error creating voucher (try count ${tryCount}):`, error); - if (tryCount < 5) { - await sleep(3000 * tryCount); - await retryableCreateVoucher(tryCount + 1); - } else { - throw new Error( - `Failed to create voucher after ${tryCount} attempts`, - ); - } - } - }; - await retryableCreateVoucher(); - - try { - await createAndPublishWorkerpoolOrder(chain)({ - workerpool: chain.debugWorkerpool, - workerpoolOwnerWallet: chain.debugWorkerpoolOwnerWallet, - requesterrestrict: owner, - }); - await createAndPublishWorkerpoolOrder(chain)({ - workerpool: chain.prodWorkerpool, - workerpoolOwnerWallet: chain.prodWorkerpoolOwnerWallet, - requesterrestrict: owner, - }); - } catch (error) { - console.error('Error publishing workerpoolorder:', error); - throw error; - } - - try { - return await voucherHubContract.getVoucher(owner); - } catch (error) { - console.error('Error getting voucher:', error); - throw error; - } - }; - -export const addVoucherEligibleAsset = - (chain) => async (assetAddress, voucherTypeId) => { - const voucherHubAddress = - chain.voucherHubAddress || chain.defaults.voucherHubAddress; - - const voucherHubContract = new Contract(voucherHubAddress, voucherHubAbi); - - const signer = chain.voucherManagerWallet.connect(chain.provider); - - const retryableAddEligibleAsset = async (tryCount = 1) => { - try { - const tx = await voucherHubContract - .connect(signer) - .addEligibleAsset(voucherTypeId, assetAddress); - await tx.wait(); - } catch (error) { - console.warn( - `Error adding eligible asset to voucher (try count ${tryCount}):`, - error, - ); - if (tryCount < 5) { - await sleep(3000 * tryCount); - await retryableAddEligibleAsset(tryCount + 1); - } else { - throw new Error( - `Failed to add eligible asset to voucher after ${tryCount} attempts`, - ); - } - } - }; - await retryableAddEligibleAsset(); - }; diff --git a/typedoc_template.md b/typedoc_template.md index d40d7a39..acb6c834 100644 --- a/typedoc_template.md +++ b/typedoc_template.md @@ -80,7 +80,6 @@ Additionally the [IExec](./classes/IExec.md) module exposes all the following li - [IExecSecretsModule](./classes/IExecSecretsModule.md) exposes **secrets** methods - [IExecStorageModule](./classes/IExecStorageModule.md) exposes **storage** methods - [IExecTaskModule](./classes/IExecTaskModule.md) exposes **task** methods -- [IExecVoucherModule](./classes/IExecVoucherModule.md) exposes **voucher** methods - [IExecWalletModule](./classes/IExecWalletModule.md) exposes **wallet** methods - [IExecWorkerpoolModule](./classes/IExecWorkerpoolModule.md) exposes **workerpool** methods From 4ff755e1cba6ac57b71455475ec7dca59ebeba82 Mon Sep 17 00:00:00 2001 From: pjt <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Tue, 16 Dec 2025 08:33:54 +0100 Subject: [PATCH 02/13] feat!: remove multi SMS and gramine support (#517) --- CLI.md | 13 +- cli_template.md | 2 +- docs/-internal-/README.md | 1 - .../interfaces/AppDeploymentArgs.md | 2 +- .../-internal-/interfaces/GramineMREnclave.md | 31 - docs/classes/IExecAppModule.md | 16 +- docs/classes/IExecConfig.md | 10 +- docs/classes/IExecDatasetModule.md | 16 +- docs/classes/IExecResultModule.md | 12 +- docs/classes/IExecSecretsModule.md | 16 +- docs/classes/IExecStorageModule.md | 8 - docs/interfaces/IExecConfigOptions.md | 10 +- docs/type-aliases/Tag.md | 1 - docs/type-aliases/TeeFramework.md | 2 +- src/cli/cmd/iexec-app.js | 69 +- src/cli/cmd/iexec-dataset.js | 29 +- src/cli/cmd/iexec-ens.js | 4 +- src/cli/cmd/iexec-order.js | 54 +- src/cli/cmd/iexec-orderbook.js | 10 +- src/cli/cmd/iexec-requester.js | 13 +- src/cli/cmd/iexec-result.js | 13 +- src/cli/cmd/iexec-storage.js | 18 +- src/cli/cmd/iexec-wallet.js | 6 +- src/cli/cmd/iexec-workerpool.js | 8 +- src/cli/utils/cli-helper.js | 29 +- src/cli/utils/fs.js | 6 +- src/cli/utils/templates.js | 15 - src/common/execution/order-helper.js | 21 +- src/common/protocol/registries.js | 23 +- src/common/types.d.ts | 3 +- src/common/utils/config.js | 16 +- src/common/utils/constant.js | 1 - src/common/utils/utils.js | 2 +- src/common/utils/validator.js | 38 +- src/lib/IExecAppModule.d.ts | 29 +- src/lib/IExecAppModule.js | 29 +- src/lib/IExecConfig.d.ts | 10 +- src/lib/IExecConfig.js | 79 +- src/lib/IExecDatasetModule.d.ts | 11 +- src/lib/IExecDatasetModule.js | 15 +- src/lib/IExecOrderModule.js | 35 +- src/lib/IExecResultModule.d.ts | 4 +- src/lib/IExecResultModule.js | 11 +- src/lib/IExecSecretsModule.d.ts | 8 +- src/lib/IExecSecretsModule.js | 16 +- src/lib/IExecStorageModule.d.ts | 4 +- src/lib/IExecStorageModule.js | 11 +- test/cli/cli-common.test.js | 2 - test/cli/cli-iexec-account.test.js | 2 - test/cli/cli-iexec-app.test.js | 40 +- test/cli/cli-iexec-category.test.js | 2 - test/cli/cli-iexec-dataset.test.js | 72 - test/cli/cli-iexec-deal.test.js | 2 - test/cli/cli-iexec-ens.test.js | 2 - test/cli/cli-iexec-info.test.js | 2 - test/cli/cli-iexec-init.test.js | 2 - test/cli/cli-iexec-order.test.js | 4 +- test/cli/cli-iexec-requester.test.js | 42 +- test/cli/cli-iexec-result.test.js | 38 +- test/cli/cli-iexec-storage.test.js | 15 - test/cli/cli-iexec-task.test.js | 2 - test/cli/cli-iexec-wallet.test.js | 16 +- test/cli/cli-iexec-workerpool.test.js | 2 - test/cli/cli-test-utils.js | 2 +- test/cli/cli-tx-options.test.js | 2 - test/docker-compose.yml | 46 - test/jest-setup.js | 2 - test/lib/e2e/IExecAccountModule.test.js | 2 - test/lib/e2e/IExecAppModule.test.js | 143 +- test/lib/e2e/IExecConfig.test.js | 118 +- test/lib/e2e/IExecDatasetModule.test.js | 86 +- test/lib/e2e/IExecDealModule.test.js | 2 - test/lib/e2e/IExecEnsModule.test.js | 2 - test/lib/e2e/IExecHubModule.test.js | 2 - test/lib/e2e/IExecOrderModule.test.js | 1390 ++++++++--------- test/lib/e2e/IExecOrderbookModule.test.js | 2 - test/lib/e2e/IExecResultModule.test.js | 35 +- test/lib/e2e/IExecSecretsModule.test.js | 18 - test/lib/e2e/IExecStorageModule.test.js | 18 - test/lib/e2e/IExecTaskModule.test.js | 2 - test/lib/e2e/IExecWalletModule.test.js | 2 - test/lib/e2e/IExecWorkerpoolModule.test.js | 2 - test/lib/e2e/utils.test.js | 4 +- test/lib/e2e/workflow.test.js | 2 - test/lib/lib-test-utils.js | 10 +- test/lib/unit/config.test.js | 6 +- test/lib/unit/errorWrappers.test.js | 2 - test/lib/unit/validator.test.js | 121 +- test/test-config-utils.js | 4 +- test/test-utils.js | 14 +- 90 files changed, 922 insertions(+), 2142 deletions(-) delete mode 100644 docs/-internal-/interfaces/GramineMREnclave.md diff --git a/CLI.md b/CLI.md index 0ef05b7d..4ead4dbe 100644 --- a/CLI.md +++ b/CLI.md @@ -785,7 +785,6 @@ Options: | --wallet-file \ | specify the name of the wallet file to use | | --wallet-address \ | specify the address of the wallet to use | | --keystoredir \ | specify the wallet directory \<"global"\|"local"\|custom\> | -| --tee | use the Trusted Execution Environment template | | --tee-framework \ | specify the TEE framework to use | #### iexec app deploy @@ -875,7 +874,6 @@ Options: | --raw | use raw output | | --quiet | stop prompting updates | | --chain \ | chain name from "chain.json" | -| --tee-framework \ | specify the TEE framework to use | #### iexec app push-secret @@ -899,7 +897,6 @@ Options: | --keystoredir \ | specify the wallet directory \<"global"\|"local"\|custom\> | | --chain \ | chain name from "chain.json" | | --secret-value \ | secret value (unsafe) | -| --tee-framework \ | specify the TEE framework to use | #### iexec app publish @@ -1224,7 +1221,6 @@ Options: | --keystoredir \ | specify the wallet directory \<"global"\|"local"\|custom\> | | --chain \ | chain name from "chain.json" | | --secret-path \ | push the secret from a file | -| --tee-framework \ | specify the TEE framework to use | #### iexec dataset check-secret @@ -1243,7 +1239,6 @@ Options: | --raw | use raw output | | --quiet | stop prompting updates | | --chain \ | chain name from "chain.json" | -| --tee-framework \ | specify the TEE framework to use | #### iexec dataset publish @@ -1579,7 +1574,6 @@ Options: | --keystoredir \ | specify the wallet directory \<"global"\|"local"\|custom\> | | --chain \ | chain name from "chain.json" | | --secret-value \ | secret value (unsafe) | -| --tee-framework \ | specify the TEE framework to use | #### iexec requester check-secret @@ -1602,7 +1596,6 @@ Options: | --wallet-address \ | specify the address of the wallet to use | | --keystoredir \ | specify the wallet directory \<"global"\|"local"\|custom\> | | --chain \ | chain name from "chain.json" | -| --tee-framework \ | specify the TEE framework to use | ### iexec order @@ -2138,7 +2131,6 @@ Options: | --chain \ | chain name from "chain.json" | | --force-update | update if already exists | | --token \ | storage provider authorization token (unsafe) | -| --tee-framework \ | specify the TEE framework to use | #### iexec storage check @@ -2162,7 +2154,6 @@ Options: | --keystoredir \ | specify the wallet directory \<"global"\|"local"\|custom\> | | --chain \ | chain name from "chain.json" | | --user \ | custom user address | -| --tee-framework \ | specify the TEE framework to use | ### iexec result @@ -2255,7 +2246,6 @@ Options: | --chain \ | chain name from "chain.json" | | --force-update | update if already exists | | --secret-path \ | push the secret from a file | -| --tee-framework \ | specify the TEE framework to use | #### iexec result check-encryption-key @@ -2280,7 +2270,6 @@ Options: | --wallet-address \ | specify the address of the wallet to use | | --keystoredir \ | specify the wallet directory \<"global"\|"local"\|custom\> | | --chain \ | chain name from "chain.json" | -| --tee-framework \ | specify the TEE framework to use | ### iexec ens @@ -2607,7 +2596,7 @@ The `chain.json` file, located in every iExec project, describes the parameters - `chains` set the available chains - optional key `host` set the url of the ethereum node used by the SDK cli on each chain (overwrite default value). - optional key `hub` set the address of the hub used by the SDK cli on each chain (overwrite default value). - - optional key `sms` set the url of the Secret Management Service used by the SDK cli on each chain (overwrite default value), this key accepts a string or a mapping TEE framework - SMS url. + - optional key `sms` set the url of the Secret Management Service used by the SDK cli on each chain (overwrite default value). - optional key `resultProxy` set the url of the Result Proxy used by the SDK cli on each chain (overwrite default value). - optional key `iexecGateway` set the url of the iexec marketplace gateway used by the SDK cli on each chain (overwrite default value). - optional key `ipfsGateway` set the url of the IPFS gateway used by the SDK cli on each chain (overwrite default value). diff --git a/cli_template.md b/cli_template.md index 21eb5bad..8b8ad8c5 100644 --- a/cli_template.md +++ b/cli_template.md @@ -396,7 +396,7 @@ The `chain.json` file, located in every iExec project, describes the parameters - `chains` set the available chains - optional key `host` set the url of the ethereum node used by the SDK cli on each chain (overwrite default value). - optional key `hub` set the address of the hub used by the SDK cli on each chain (overwrite default value). - - optional key `sms` set the url of the Secret Management Service used by the SDK cli on each chain (overwrite default value), this key accepts a string or a mapping TEE framework - SMS url. + - optional key `sms` set the url of the Secret Management Service used by the SDK cli on each chain (overwrite default value). - optional key `resultProxy` set the url of the Result Proxy used by the SDK cli on each chain (overwrite default value). - optional key `iexecGateway` set the url of the iexec marketplace gateway used by the SDK cli on each chain (overwrite default value). - optional key `ipfsGateway` set the url of the IPFS gateway used by the SDK cli on each chain (overwrite default value). diff --git a/docs/-internal-/README.md b/docs/-internal-/README.md index 32745657..ff3f467c 100644 --- a/docs/-internal-/README.md +++ b/docs/-internal-/README.md @@ -27,7 +27,6 @@ - [Dataset](interfaces/Dataset.md) - [DatasetDeploymentArgs](interfaces/DatasetDeploymentArgs.md) - [DatasetorderTemplate](interfaces/DatasetorderTemplate.md) -- [GramineMREnclave](interfaces/GramineMREnclave.md) - [HashableApporder](interfaces/HashableApporder.md) - [HashableDatasetorder](interfaces/HashableDatasetorder.md) - [HashableRequestorder](interfaces/HashableRequestorder.md) diff --git a/docs/-internal-/interfaces/AppDeploymentArgs.md b/docs/-internal-/interfaces/AppDeploymentArgs.md index 5f66a17a..e0c721d1 100644 --- a/docs/-internal-/interfaces/AppDeploymentArgs.md +++ b/docs/-internal-/interfaces/AppDeploymentArgs.md @@ -18,7 +18,7 @@ app image digest ### mrenclave? -> `optional` **mrenclave**: [`SconeMREnclave`](SconeMREnclave.md) \| [`GramineMREnclave`](GramineMREnclave.md) +> `optional` **mrenclave**: [`SconeMREnclave`](SconeMREnclave.md) optional for TEE apps only, specify the TEE protocol to use diff --git a/docs/-internal-/interfaces/GramineMREnclave.md b/docs/-internal-/interfaces/GramineMREnclave.md deleted file mode 100644 index efed3554..00000000 --- a/docs/-internal-/interfaces/GramineMREnclave.md +++ /dev/null @@ -1,31 +0,0 @@ -[**iexec**](../../README.md) - -*** - -[iexec](../../globals.md) / [\](../README.md) / GramineMREnclave - -# Interface: GramineMREnclave - -## Properties - -### fingerprint - -> **fingerprint**: `string` - -app tee fingerprint - -*** - -### framework - -> **framework**: `string` - -TEE framework name 'GRAMINE' - -*** - -### version - -> **version**: `string` - -framework's protocol version diff --git a/docs/classes/IExecAppModule.md b/docs/classes/IExecAppModule.md index 594ecc24..f8d39a8e 100644 --- a/docs/classes/IExecAppModule.md +++ b/docs/classes/IExecAppModule.md @@ -54,7 +54,7 @@ current IExecConfig ### checkAppSecretExists() -> **checkAppSecretExists**(`appAddress`, `options?`): `Promise`\<`boolean`\> +> **checkAppSecretExists**(`appAddress`): `Promise`\<`boolean`\> check if a secret exists for the app in the Secret Management Service @@ -72,12 +72,6 @@ _NB_: `string` -##### options? - -###### teeFramework? - -[`TeeFramework`](../type-aliases/TeeFramework.md) - #### Returns `Promise`\<`boolean`\> @@ -196,7 +190,7 @@ console.log('address', address); ### pushAppSecret() -> **pushAppSecret**(`appAddress`, `secretValue`, `options?`): `Promise`\<`boolean`\> +> **pushAppSecret**(`appAddress`, `secretValue`): `Promise`\<`boolean`\> **SIGNER REQUIRED, ONLY APP OWNER** @@ -223,12 +217,6 @@ console.log('pushed App secret:', isPushed); `String` -##### options? - -###### teeFramework? - -[`TeeFramework`](../type-aliases/TeeFramework.md) - #### Returns `Promise`\<`boolean`\> diff --git a/docs/classes/IExecConfig.md b/docs/classes/IExecConfig.md index f29692bb..f176a89a 100644 --- a/docs/classes/IExecConfig.md +++ b/docs/classes/IExecConfig.md @@ -208,18 +208,10 @@ resolve the current result proxy URL ### resolveSmsURL() -> **resolveSmsURL**(`options?`): `Promise`\<`string`\> +> **resolveSmsURL**(): `Promise`\<`string`\> resolve the current SMS URL -#### Parameters - -##### options? - -###### teeFramework? - -[`TeeFramework`](../type-aliases/TeeFramework.md) - #### Returns `Promise`\<`string`\> diff --git a/docs/classes/IExecDatasetModule.md b/docs/classes/IExecDatasetModule.md index 04869091..ed88fbbc 100644 --- a/docs/classes/IExecDatasetModule.md +++ b/docs/classes/IExecDatasetModule.md @@ -54,7 +54,7 @@ current IExecConfig ### checkDatasetSecretExists() -> **checkDatasetSecretExists**(`datasetAddress`, `options?`): `Promise`\<`boolean`\> +> **checkDatasetSecretExists**(`datasetAddress`): `Promise`\<`boolean`\> check if a the dataset secret exists in the Secret Management Service @@ -70,12 +70,6 @@ console.log('secret exists:', isSecretSet); `string` -##### options? - -###### teeFramework? - -[`TeeFramework`](../type-aliases/TeeFramework.md) - #### Returns `Promise`\<`boolean`\> @@ -288,7 +282,7 @@ console.log('address', address); ### pushDatasetSecret() -> **pushDatasetSecret**(`datasetAddress`, `encryptionKey`, `options?`): `Promise`\<`boolean`\> +> **pushDatasetSecret**(`datasetAddress`, `encryptionKey`): `Promise`\<`boolean`\> **SIGNER REQUIRED, ONLY DATASET OWNER** @@ -312,12 +306,6 @@ console.log('secret pushed:', pushed); `string` -##### options? - -###### teeFramework? - -[`TeeFramework`](../type-aliases/TeeFramework.md) - #### Returns `Promise`\<`boolean`\> diff --git a/docs/classes/IExecResultModule.md b/docs/classes/IExecResultModule.md index cce22092..a6440332 100644 --- a/docs/classes/IExecResultModule.md +++ b/docs/classes/IExecResultModule.md @@ -54,7 +54,7 @@ current IExecConfig ### checkResultEncryptionKeyExists() -> **checkResultEncryptionKeyExists**(`beneficiaryAddress`, `options`): `Promise`\<`boolean`\> +> **checkResultEncryptionKeyExists**(`beneficiaryAddress`): `Promise`\<`boolean`\> check if a beneficiary result encryption key exists in the Secret Management Service @@ -70,12 +70,6 @@ console.log('encryption key available:', isEncryptionKeyAvailable); `string` -##### options - -###### teeFramework? - -[`TeeFramework`](../type-aliases/TeeFramework.md) - #### Returns `Promise`\<`boolean`\> @@ -142,10 +136,6 @@ console.log('encryption key pushed:', isPushed); `boolean` -###### teeFramework? - -[`TeeFramework`](../type-aliases/TeeFramework.md) - #### Returns `Promise`\<\{ `isPushed`: `boolean`; `isUpdated`: `boolean`; \}\> diff --git a/docs/classes/IExecSecretsModule.md b/docs/classes/IExecSecretsModule.md index 9a9768ce..e855583a 100644 --- a/docs/classes/IExecSecretsModule.md +++ b/docs/classes/IExecSecretsModule.md @@ -54,7 +54,7 @@ current IExecConfig ### checkRequesterSecretExists() -> **checkRequesterSecretExists**(`requesterAddress`, `secretName`, `options?`): `Promise`\<`boolean`\> +> **checkRequesterSecretExists**(`requesterAddress`, `secretName`): `Promise`\<`boolean`\> check if a named secret exists for the requester in the Secret Management Service @@ -74,12 +74,6 @@ console.log('secret "my-password" set:', isSecretSet); `String` -##### options? - -###### teeFramework? - -[`TeeFramework`](../type-aliases/TeeFramework.md) - #### Returns `Promise`\<`boolean`\> @@ -88,7 +82,7 @@ console.log('secret "my-password" set:', isSecretSet); ### pushRequesterSecret() -> **pushRequesterSecret**(`secretName`, `secretValue`, `options?`): `Promise`\<\{ `isPushed`: `boolean`; \}\> +> **pushRequesterSecret**(`secretName`, `secretValue`): `Promise`\<\{ `isPushed`: `boolean`; \}\> **SIGNER REQUIRED, ONLY REQUESTER** @@ -114,12 +108,6 @@ console.log('pushed secret "my-password":', isPushed); `String` -##### options? - -###### teeFramework? - -[`TeeFramework`](../type-aliases/TeeFramework.md) - #### Returns `Promise`\<\{ `isPushed`: `boolean`; \}\> diff --git a/docs/classes/IExecStorageModule.md b/docs/classes/IExecStorageModule.md index 5c9db81d..85be9713 100644 --- a/docs/classes/IExecStorageModule.md +++ b/docs/classes/IExecStorageModule.md @@ -78,10 +78,6 @@ console.log('IPFS storage initialized:', isIpfsStorageInitialized); `string` -###### teeFramework? - -[`TeeFramework`](../type-aliases/TeeFramework.md) - #### Returns `Promise`\<`boolean`\> @@ -150,10 +146,6 @@ console.log('dropbox storage initialized:', isPushed); `string` -###### teeFramework? - -[`TeeFramework`](../type-aliases/TeeFramework.md) - #### Returns `Promise`\<\{ `isPushed`: `boolean`; `isUpdated`: `boolean`; \}\> diff --git a/docs/interfaces/IExecConfigOptions.md b/docs/interfaces/IExecConfigOptions.md index 2b40c890..7858915c 100644 --- a/docs/interfaces/IExecConfigOptions.md +++ b/docs/interfaces/IExecConfigOptions.md @@ -76,14 +76,6 @@ number of block to wait for transactions confirmation (default 1) *** -### defaultTeeFramework? - -> `optional` **defaultTeeFramework**: [`TeeFramework`](../type-aliases/TeeFramework.md) - -override the TEE framework to use when as default - -*** - ### ensPublicResolverAddress? > `optional` **ensPublicResolverAddress**: `string` @@ -158,7 +150,7 @@ override the result proxy URL to target a custom instance ### smsURL? -> `optional` **smsURL**: `string` \| `Record`\<[`TeeFramework`](../type-aliases/TeeFramework.md), `string`\> +> `optional` **smsURL**: `string` override the SMS URL to target a custom instance diff --git a/docs/type-aliases/Tag.md b/docs/type-aliases/Tag.md index 6dba9596..fa00791a 100644 --- a/docs/type-aliases/Tag.md +++ b/docs/type-aliases/Tag.md @@ -14,5 +14,4 @@ example: ```js const gpuTag = ['gpu']; const sconeTeeTag = ['tee', 'scone']; -const gramineTeeTag = ['tee', 'gramine']; ``` diff --git a/docs/type-aliases/TeeFramework.md b/docs/type-aliases/TeeFramework.md index fed490e6..ede60c35 100644 --- a/docs/type-aliases/TeeFramework.md +++ b/docs/type-aliases/TeeFramework.md @@ -6,6 +6,6 @@ # Type Alias: TeeFramework -> **TeeFramework** = `"scone"` \| `"gramine"` \| `"tdx"` +> **TeeFramework** = `"scone"` \| `"tdx"` Trusted Execution Environment name diff --git a/src/cli/cmd/iexec-app.js b/src/cli/cmd/iexec-app.js index 71b675ce..af3fa04b 100644 --- a/src/cli/cmd/iexec-app.js +++ b/src/cli/cmd/iexec-app.js @@ -20,7 +20,7 @@ import { apporderSchema, requestorderSchema, } from '../../common/utils/validator.js'; -import { app, sconeTeeApp, gramineTeeApp } from '../utils/templates.js'; +import { app, sconeTeeApp } from '../utils/templates.js'; import { deployApp, showApp, @@ -32,7 +32,6 @@ import { checkDeployedApp, checkDeployedDataset, checkDeployedWorkerpool, - resolveTeeFrameworkFromApp, transferApp, } from '../../common/protocol/registries.js'; import { showCategory } from '../../common/protocol/category.js'; @@ -86,7 +85,6 @@ import { import { checkRequestRequirements, checkDatasetRequirements, - resolveTeeFrameworkFromTag, checkAppRequirements, } from '../../common/execution/order-helper.js'; import { @@ -106,9 +104,7 @@ import { info, isEthAddress, renderTasksStatus, - getPropertyFormChain, - getDefaultTeeFrameworkFromChain, - getSmsUrlFromChain, + getPropertyFromChain, optionCreator, } from '../utils/cli-helper.js'; import { @@ -140,7 +136,6 @@ const init = cli.command('init'); addGlobalOptions(init); addWalletLoadOptions(init); init - .option(...option.initTee()) .addOption(optionCreator.teeFramework()) .description(desc.initObj(objName)) .action(async (opts) => { @@ -151,19 +146,13 @@ init const keystore = Keystore({ ...walletOptions, isSigner: false }); const [address] = await keystore.accounts(); - const teeFramework = - (await teeFrameworkSchema().validate(opts.teeFramework)) || - (opts.tee && - getDefaultTeeFrameworkFromChain( - await loadChain(opts.chain, { spinner }), - )); + const teeFramework = await teeFrameworkSchema().validate( + opts.teeFramework, + ); let teeTemplate = {}; if (teeFramework === TEE_FRAMEWORKS.SCONE) { teeTemplate = sconeTeeApp; } - if (teeFramework === TEE_FRAMEWORKS.GRAMINE) { - teeTemplate = gramineTeeApp; - } if (teeFramework === TEE_FRAMEWORKS.TDX) { teeTemplate = app; } @@ -327,7 +316,6 @@ const checkSecret = cli.command('check-secret [appAddress]'); addGlobalOptions(checkSecret); checkSecret .option(...option.chain()) - .addOption(optionCreator.teeFramework()) .description(desc.checkSecret()) .action(async (objAddress, opts) => { await checkUpdate(opts); @@ -345,12 +333,7 @@ checkSecret ); } spinner.info(`Checking secret for address ${resourceAddress}`); - let teeFramework = await teeFrameworkSchema().validate(opts.teeFramework); - if (!teeFramework) { - const { app } = await showApp(chain.contracts, resourceAddress); - teeFramework = await resolveTeeFrameworkFromApp(app); - } - const sms = getSmsUrlFromChain(chain, { teeFramework }); + const sms = getPropertyFromChain(chain, 'sms'); const secretIsSet = await checkAppSecretExists( chain.contracts, sms, @@ -376,7 +359,6 @@ addWalletLoadOptions(pushSecret); pushSecret .option(...option.chain()) .option(...option.secretValue()) - .addOption(optionCreator.teeFramework()) .description('push the app secret to the secret management service') .action(async (objAddress, opts) => { await checkUpdate(opts); @@ -398,12 +380,7 @@ pushSecret ); } spinner.info(`App ${resourceAddress}`); - let teeFramework = await teeFrameworkSchema().validate(opts.teeFramework); - if (!teeFramework) { - const { app } = await showApp(chain.contracts, resourceAddress); - teeFramework = await resolveTeeFrameworkFromApp(app); - } - const sms = getSmsUrlFromChain(chain, { teeFramework }); + const sms = getPropertyFromChain(chain, 'sms'); const secretValue = opts.secretValue || (await prompt.password(`Paste your secret`, { @@ -489,7 +466,7 @@ publish const signedOrder = await signApporder(chain.contracts, orderToSign); const orderHash = await publishApporder( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), signedOrder, ); spinner.succeed( @@ -543,12 +520,12 @@ unpublish const unpublished = all ? await unpublishAllApporders( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), address, ) : await unpublishLastApporder( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), address, ); spinner.succeed( @@ -765,24 +742,24 @@ run }).then((o) => signApporder(chain.contracts, o)); } spinner.info('Fetching apporder from iExec Marketplace'); - const minTags = []; + const appMinTags = []; if (checkActiveBitInTag(tag, TAG_MAP.tee)) { - minTags.push('tee'); + appMinTags.push('tee'); } Object.values(TEE_FRAMEWORKS).forEach((teeFrameworkTag) => { if (checkActiveBitInTag(tag, TAG_MAP[teeFrameworkTag])) { - minTags.push(teeFrameworkTag); + appMinTags.push(teeFrameworkTag); } }); const { orders } = await fetchAppOrderbook( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), { app, requester, ...(useDataset && { dataset }), ...(runOnWorkerpool && { workerpool }), - ...{ minTag: encodeTag(minTags) }, + ...{ minTag: encodeTag(appMinTags) }, maxTag: tag, }, ); @@ -820,7 +797,7 @@ run spinner.info('Fetching datasetorder from iExec Marketplace'); const { orders } = await fetchDatasetOrderbook( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), { dataset, app, @@ -886,7 +863,7 @@ run debug('try category', catid, 'strict', strict); const { orders } = await fetchWorkerpoolOrderbook( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), { category: catid, app, @@ -1006,9 +983,7 @@ run await checkDatasetRequirements( { contracts: chain.contracts, - smsURL: getSmsUrlFromChain(chain, { - teeFramework: await resolveTeeFrameworkFromTag(resolvedTag), - }), + smsURL: getPropertyFromChain(chain, 'sms'), }, datasetorder, { tagOverride: resolvedTag }, @@ -1024,9 +999,7 @@ run await checkRequestRequirements( { contracts: chain.contracts, - smsURL: getSmsUrlFromChain(chain, { - teeFramework: await resolveTeeFrameworkFromTag(resolvedTag), - }), + smsURL: getPropertyFromChain(chain, 'sms'), }, requestorderToSign, ).catch((e) => { @@ -1325,7 +1298,7 @@ requestRun await checkRequestRequirements( { contracts: chain.contracts, - smsURL: getSmsUrlFromChain(chain), + smsURL: getPropertyFromChain(chain, 'sms'), }, requestorderToSign, ).catch((e) => { @@ -1401,7 +1374,7 @@ requestRun spinner.start('Publishing requestorder'); const orderHash = await publishRequestorder( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), requestorder, ); spinner.succeed( diff --git a/src/cli/cmd/iexec-dataset.js b/src/cli/cmd/iexec-dataset.js index 21277253..ee83702d 100644 --- a/src/cli/cmd/iexec-dataset.js +++ b/src/cli/cmd/iexec-dataset.js @@ -57,16 +57,11 @@ import { info, prompt, isEthAddress, - getPropertyFormChain, - getSmsUrlFromChain, - optionCreator, + getPropertyFromChain, } from '../utils/cli-helper.js'; import { lookupAddress } from '../../common/ens/resolution.js'; import { ConfigurationError } from '../../common/utils/errors.js'; -import { - checkDatasetRequirements, - resolveTeeFrameworkFromTag, -} from '../../common/execution/order-helper.js'; +import { checkDatasetRequirements } from '../../common/execution/order-helper.js'; const { ensureDir, pathExists, readFile, lstat, readdir } = fsExtra; @@ -406,7 +401,6 @@ addWalletLoadOptions(pushSecret); pushSecret .option(...option.chain()) .option(...option.secretPath()) - .addOption(optionCreator.teeFramework()) .description(desc.pushDatasetSecret()) .action(async (objAddress, opts) => { await checkUpdate(opts); @@ -416,9 +410,7 @@ pushSecret const keystore = Keystore(Object.assign(walletOptions)); const chain = await loadChain(opts.chain, { spinner }); const { contracts } = chain; - const sms = getSmsUrlFromChain(chain, { - teeFramework: opts.teeFramework, - }); + const sms = getPropertyFromChain(chain, 'sms'); const [address] = await keystore.accounts(); debug('address', address); const resourceAddress = @@ -470,7 +462,6 @@ const checkSecret = cli.command('check-secret [datasetAddress]'); addGlobalOptions(checkSecret); checkSecret .option(...option.chain()) - .addOption(optionCreator.teeFramework()) .description(desc.checkSecret()) .action(async (objAddress, opts) => { await checkUpdate(opts); @@ -488,9 +479,7 @@ checkSecret ); } spinner.info(`Checking secret for address ${resourceAddress}`); - const sms = getSmsUrlFromChain(chain, { - teeFramework: opts.teeFramework, - }); + const sms = getPropertyFromChain(chain, 'sms'); const secretIsSet = await checkWeb3SecretExists( chain.contracts, sms, @@ -561,9 +550,7 @@ publish }; const orderToSign = await createDatasetorder(chain.contracts, overrides); if (!opts.skipPreflightCheck) { - const sms = getSmsUrlFromChain(chain, { - teeFramework: await resolveTeeFrameworkFromTag(orderToSign.tag), - }); + const sms = getPropertyFromChain(chain, 'sms'); await checkDatasetRequirements( { contracts: chain.contracts, smsURL: sms }, orderToSign, @@ -576,7 +563,7 @@ publish const signedOrder = await signDatasetorder(chain.contracts, orderToSign); const orderHash = await publishDatasetorder( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), signedOrder, ); spinner.succeed( @@ -630,12 +617,12 @@ unpublish const unpublished = all ? await unpublishAllDatasetorders( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), address, ) : await unpublishLastDatasetorder( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), address, ); spinner.succeed( diff --git a/src/cli/cmd/iexec-ens.js b/src/cli/cmd/iexec-ens.js index a3a08fc4..daaf7843 100644 --- a/src/cli/cmd/iexec-ens.js +++ b/src/cli/cmd/iexec-ens.js @@ -22,7 +22,7 @@ import { handleError, option, Spinner, - getPropertyFormChain, + getPropertyFromChain, prompt, } from '../utils/cli-helper.js'; import { Keystore } from '../utils/keystore.js'; @@ -179,7 +179,7 @@ register setNameTxHash, } = await configureResolution( chain.contracts, - getPropertyFormChain(chain, 'ensPublicResolver'), + getPropertyFromChain(chain, 'ensPublicResolver'), name, targetAddress, ); diff --git a/src/cli/cmd/iexec-order.js b/src/cli/cmd/iexec-order.js index 4e9c58f8..6a863a19 100644 --- a/src/cli/cmd/iexec-order.js +++ b/src/cli/cmd/iexec-order.js @@ -60,12 +60,10 @@ import { info, isBytes32, prompt, - getPropertyFormChain, - getSmsUrlFromChain, + getPropertyFromChain, } from '../utils/cli-helper.js'; import { checkRequestRequirements, - resolveTeeFrameworkFromTag, checkDatasetRequirements, checkAppRequirements, } from '../../common/execution/order-helper.js'; @@ -266,9 +264,7 @@ sign await checkDatasetRequirements( { contracts: chain.contracts, - smsURL: getSmsUrlFromChain(chain, { - teeFramework: await resolveTeeFrameworkFromTag(orderObj.tag), - }), + smsURL: getPropertyFromChain(chain, 'sms'), }, orderObj, ).catch((e) => { @@ -355,9 +351,7 @@ sign await checkRequestRequirements( { contracts: chain.contracts, - smsURL: getSmsUrlFromChain(chain, { - teeFramework: await resolveTeeFrameworkFromTag(orderObj.tag), - }), + smsURL: getPropertyFromChain(chain, 'sms'), }, orderObj, ).catch((e) => { @@ -440,7 +434,7 @@ fill `Fetching ${orderName} ${orderHash} from iexec marketplace`, ); const orderRes = await fetchPublishedOrderByHash( - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), orderName, chain.id, orderHash, @@ -548,9 +542,7 @@ fill await checkDatasetRequirements( { contracts: chain.contracts, - smsURL: getSmsUrlFromChain(chain, { - teeFramework: await resolveTeeFrameworkFromTag(resolvedTag), - }), + smsURL: getPropertyFromChain(chain, 'sms'), }, datasetorder, { tagOverride: resolvedTag }, @@ -567,9 +559,7 @@ fill await checkRequestRequirements( { contracts: chain.contracts, - smsURL: getSmsUrlFromChain(chain, { - teeFramework: await resolveTeeFrameworkFromTag(resolvedTag), - }), + smsURL: getPropertyFromChain(chain, 'sms'), }, requestorder, ).catch((e) => { @@ -667,7 +657,7 @@ publish } orderHash = await publishApporder( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), orderToPublish, ); break; @@ -676,11 +666,7 @@ publish await checkDatasetRequirements( { contracts: chain.contracts, - smsURL: getSmsUrlFromChain(chain, { - teeFramework: await resolveTeeFrameworkFromTag( - orderToPublish.tag, - ), - }), + smsURL: getPropertyFromChain(chain, 'sms'), }, orderToPublish, ).catch((e) => { @@ -695,14 +681,14 @@ publish } orderHash = await publishDatasetorder( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), orderToPublish, ); break; case WORKERPOOL_ORDER: orderHash = await publishWorkerpoolorder( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), orderToPublish, ); break; @@ -711,11 +697,7 @@ publish await checkRequestRequirements( { contracts: chain.contracts, - smsURL: getSmsUrlFromChain(chain, { - teeFramework: await resolveTeeFrameworkFromTag( - orderToPublish.tag, - ), - }), + smsURL: getPropertyFromChain(chain, 'sms'), }, orderToPublish, ).catch((e) => { @@ -730,7 +712,7 @@ publish } orderHash = await publishRequestorder( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), orderToPublish, ); break; @@ -830,28 +812,28 @@ unpublish case APP_ORDER: unpublished = await unpublishApporder( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), orderHashToUnpublish, ); break; case DATASET_ORDER: unpublished = await unpublishDatasetorder( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), orderHashToUnpublish, ); break; case WORKERPOOL_ORDER: unpublished = await unpublishWorkerpoolorder( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), orderHashToUnpublish, ); break; case REQUEST_ORDER: unpublished = await unpublishRequestorder( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), orderHashToUnpublish, ); break; @@ -1028,7 +1010,7 @@ show isBytes32(orderHash); spinner.start(info.showing(orderName)); const orderToShow = await fetchPublishedOrderByHash( - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), orderName, chain.id, orderHash, @@ -1036,7 +1018,7 @@ show let deals; if (opts.deals) { deals = await fetchDealsByOrderHash( - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), orderName, chain.id, orderHash, diff --git a/src/cli/cmd/iexec-orderbook.js b/src/cli/cmd/iexec-orderbook.js index 2350db6d..5450ba58 100644 --- a/src/cli/cmd/iexec-orderbook.js +++ b/src/cli/cmd/iexec-orderbook.js @@ -19,7 +19,7 @@ import { displayPaginableRequest, pretty, info, - getPropertyFormChain, + getPropertyFromChain, } from '../utils/cli-helper.js'; import { loadChain } from '../utils/chains.js'; @@ -65,7 +65,7 @@ orderbookApp const request = fetchAppOrderbook( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), { app, dataset, @@ -179,7 +179,7 @@ orderbookDataset const request = fetchDatasetOrderbook( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), { dataset, app, @@ -297,7 +297,7 @@ orderbookWorkerpool const request = fetchWorkerpoolOrderbook( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), { category, workerpool, @@ -422,7 +422,7 @@ orderbookRequester const request = fetchRequestOrderbook( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), { category, requester: address, diff --git a/src/cli/cmd/iexec-requester.js b/src/cli/cmd/iexec-requester.js index ffb2fae9..ee191956 100644 --- a/src/cli/cmd/iexec-requester.js +++ b/src/cli/cmd/iexec-requester.js @@ -14,8 +14,7 @@ import { option, prompt, Spinner, - getSmsUrlFromChain, - optionCreator, + getPropertyFromChain, } from '../utils/cli-helper.js'; import { loadChain, connectKeystore } from '../utils/chains.js'; import { Keystore } from '../utils/keystore.js'; @@ -28,7 +27,6 @@ addWalletLoadOptions(pushSecret); pushSecret .option(...option.chain()) .option(...option.secretValue()) - .addOption(optionCreator.teeFramework()) .description(desc.pushRequesterSecret()) .action(async (secretName, opts) => { await checkUpdate(opts); @@ -44,9 +42,7 @@ pushSecret ]); await connectKeystore(chain, keystore); const { contracts } = chain; - const sms = getSmsUrlFromChain(chain, { - teeFramework: opts.teeFramework, - }); + const sms = getPropertyFromChain(chain, 'sms'); spinner.info(`Secret "${secretName}" for address ${address}`); const secretValue = opts.secretValue || @@ -77,7 +73,6 @@ addGlobalOptions(checkSecret); addWalletLoadOptions(checkSecret); checkSecret .option(...option.chain()) - .addOption(optionCreator.teeFramework()) .description(desc.checkSecret()) .action(async (secretName, requesterAddress, opts) => { await checkUpdate(opts); @@ -100,9 +95,7 @@ checkSecret ); } const { contracts } = chain; - const sms = getSmsUrlFromChain(chain, { - teeFramework: opts.teeFramework, - }); + const sms = getPropertyFromChain(chain, 'sms'); const secretExists = await checkRequesterSecretExists( contracts, sms, diff --git a/src/cli/cmd/iexec-result.js b/src/cli/cmd/iexec-result.js index 7132721e..95a21889 100644 --- a/src/cli/cmd/iexec-result.js +++ b/src/cli/cmd/iexec-result.js @@ -27,8 +27,7 @@ import { DEFAULT_DECRYPTED_RESULTS_NAME, publicKeyName, privateKeyName, - getSmsUrlFromChain, - optionCreator, + getPropertyFromChain, } from '../utils/cli-helper.js'; import { loadChain, connectKeystore } from '../utils/chains.js'; import { saveTextToFile } from '../utils/fs.js'; @@ -210,7 +209,6 @@ pushSecret .option(...option.chain()) .option(...option.forceUpdateSecret()) .option(...option.secretPath()) - .addOption(optionCreator.teeFramework()) .description(desc.pushResultKey()) .action(async (opts) => { await checkUpdate(opts); @@ -226,9 +224,7 @@ pushSecret ]); await connectKeystore(chain, keystore); const { contracts } = chain; - const sms = getSmsUrlFromChain(chain, { - teeFramework: opts.teeFramework, - }); + const sms = getPropertyFromChain(chain, 'sms'); let secretFilePath; if (opts.secretPath) { secretFilePath = opts.secretPath; @@ -267,7 +263,6 @@ addGlobalOptions(checkSecret); addWalletLoadOptions(checkSecret); checkSecret .option(...option.chain()) - .addOption(optionCreator.teeFramework()) .description(desc.checkSecret()) .action(async (address, opts) => { await checkUpdate(opts); @@ -288,9 +283,7 @@ checkSecret spinner.info(`Checking encryption key exists for wallet ${keyAddress}`); } const { contracts } = chain; - const sms = getSmsUrlFromChain(chain, { - teeFramework: opts.teeFramework, - }); + const sms = getPropertyFromChain(chain, 'sms'); const secretExists = await checkWeb2SecretExists( contracts, sms, diff --git a/src/cli/cmd/iexec-storage.js b/src/cli/cmd/iexec-storage.js index 132572b3..6b4ce060 100644 --- a/src/cli/cmd/iexec-storage.js +++ b/src/cli/cmd/iexec-storage.js @@ -16,9 +16,7 @@ import { option, prompt, Spinner, - getPropertyFormChain, - getSmsUrlFromChain, - optionCreator, + getPropertyFromChain, } from '../utils/cli-helper.js'; import { loadChain, connectKeystore } from '../utils/chains.js'; import { Keystore } from '../utils/keystore.js'; @@ -32,7 +30,6 @@ initStorage .option(...option.chain()) .option(...option.forceUpdateSecret()) .option(...option.storageToken()) - .addOption(optionCreator.teeFramework()) .description(desc.initStorage()) .action(async (provider, opts) => { await checkUpdate(opts); @@ -45,14 +42,10 @@ initStorage keystore.accounts(), ]); const { contracts } = chain; - const smsURL = getSmsUrlFromChain(chain, { - teeFramework: opts.teeFramework, - }); - const resultProxyURL = getPropertyFormChain(chain, 'resultProxy'); - + const smsURL = getPropertyFromChain(chain, 'sms'); + const resultProxyURL = getPropertyFromChain(chain, 'resultProxy'); const providerName = provider || 'default'; const tokenKeyName = getStorageTokenKeyName(providerName); - const tokenExists = await checkWeb2SecretExists( contracts, smsURL, @@ -107,7 +100,6 @@ addWalletLoadOptions(checkStorage); checkStorage .option(...option.chain()) .option(...option.user()) - .addOption(optionCreator.teeFramework()) .description(desc.checkStorage()) .action(async (provider, opts) => { await checkUpdate(opts); @@ -120,9 +112,7 @@ checkStorage keystore.accounts(), ]); const { contracts } = chain; - const smsURL = getSmsUrlFromChain(chain, { - teeFramework: opts.teeFramework, - }); + const smsURL = getPropertyFromChain(chain, 'sms'); const providerName = provider || 'default'; const tokenKeyName = getStorageTokenKeyName(providerName); const userAddress = opts.user || address; diff --git a/src/cli/cmd/iexec-wallet.js b/src/cli/cmd/iexec-wallet.js index 7ec53f6e..cfdee3aa 100644 --- a/src/cli/cmd/iexec-wallet.js +++ b/src/cli/cmd/iexec-wallet.js @@ -38,7 +38,7 @@ import { prompt, pretty, info, - getPropertyFormChain, + getPropertyFromChain, } from '../utils/cli-helper.js'; import { loadChain, connectKeystore } from '../utils/chains.js'; import { lookupAddress } from '../../common/ens/resolution.js'; @@ -381,7 +381,7 @@ bridgeToSidechain await connectKeystore(chain, keystore, { txOptions }); if (chain.contracts.isNative) throw new Error('Cannot bridge sidechain to sidechain'); - const bridgeConf = getPropertyFormChain(chain, 'bridge'); + const bridgeConf = getPropertyFromChain(chain, 'bridge'); const bridgeAddress = bridgeConf && bridgeConf.contract; const bridgedChainId = bridgeConf && bridgeConf.bridgedChainId; if (!bridgeAddress) { @@ -468,7 +468,7 @@ bridgeToMainchain await connectKeystore(chain, keystore, { txOptions }); if (!chain.contracts.isNative) throw new Error('Cannot bridge mainchain to mainchain'); - const bridgeConf = getPropertyFormChain(chain, 'bridge'); + const bridgeConf = getPropertyFromChain(chain, 'bridge'); const bridgeAddress = bridgeConf && bridgeConf.contract; const bridgedChainId = bridgeConf && bridgeConf.bridgedChainId; if (!bridgeAddress) { diff --git a/src/cli/cmd/iexec-workerpool.js b/src/cli/cmd/iexec-workerpool.js index 5ff25661..bd2890c0 100644 --- a/src/cli/cmd/iexec-workerpool.js +++ b/src/cli/cmd/iexec-workerpool.js @@ -36,7 +36,7 @@ import { pretty, info, prompt, - getPropertyFormChain, + getPropertyFromChain, isEthAddress, } from '../utils/cli-helper.js'; import { @@ -358,7 +358,7 @@ publish ); const orderHash = await publishWorkerpoolorder( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), signedOrder, ); spinner.succeed( @@ -412,12 +412,12 @@ unpublish const unpublished = all ? await unpublishAllWorkerpoolorders( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), address, ) : await unpublishLastWorkerpoolorder( chain.contracts, - getPropertyFormChain(chain, 'iexecGateway'), + getPropertyFromChain(chain, 'iexecGateway'), address, ); spinner.succeed( diff --git a/src/cli/utils/cli-helper.js b/src/cli/utils/cli-helper.js index 8a98ad8c..e3533cd5 100644 --- a/src/cli/utils/cli-helper.js +++ b/src/cli/utils/cli-helper.js @@ -870,7 +870,7 @@ export const computeTxOptions = async (opts) => { return { gasPrice, confirms }; }; -export const getPropertyFormChain = ( +export const getPropertyFromChain = ( chain, property, { strict = true } = {}, @@ -883,33 +883,6 @@ export const getPropertyFormChain = ( return value; }; -export const getDefaultTeeFrameworkFromChain = (chain) => - getPropertyFormChain(chain, 'defaultTeeFramework', { strict: false }) || - TEE_FRAMEWORKS.SCONE; - -export const getSmsUrlFromChain = ( - chain, - { teeFramework, strict = true } = {}, -) => { - const selectedTeeFramework = - teeFramework || getDefaultTeeFrameworkFromChain(chain); - let smsUrl; - const smsUrlOrMap = getPropertyFormChain(chain, 'sms', { strict }); - if (typeof smsUrlOrMap === 'string') { - smsUrl = smsUrlOrMap; - } else if ( - typeof smsUrlOrMap === 'object' && - smsUrlOrMap[selectedTeeFramework] - ) { - smsUrl = smsUrlOrMap[selectedTeeFramework]; - } - if (smsUrl === undefined && strict) - throw new Error( - `Missing sms for tee framework ${selectedTeeFramework} in "chain.json" for chain ${chain.id}`, - ); - return smsUrl; -}; - export const handleError = (error, cli, opts) => { debug('error', error); const spinner = Spinner(opts); diff --git a/src/cli/utils/fs.js b/src/cli/utils/fs.js index a59f2659..60747e34 100644 --- a/src/cli/utils/fs.js +++ b/src/cli/utils/fs.js @@ -5,9 +5,8 @@ import { object, string, number, boolean, lazy } from 'yup'; import { APP, DATASET } from '../../common/utils/constant.js'; import { addressSchema, + basicUrlSchema, chainIdSchema, - smsUrlOrMapSchema, - teeFrameworkSchema, } from '../../common/utils/validator.js'; import { prompt, info } from './cli-helper.js'; import templates, { @@ -28,7 +27,7 @@ const chainConfSchema = () => hub: string(), // todo address ensRegistry: string(), // TODO: DEPRECATED not used anymore ensPublicResolver: string(), // todo address - sms: smsUrlOrMapSchema(), + sms: basicUrlSchema(), resultProxy: string(), ipfsGateway: string(), iexecGateway: string(), @@ -36,7 +35,6 @@ const chainConfSchema = () => pocoSubgraph: string(), native: boolean(), useGas: boolean().default(true), - defaultTeeFramework: teeFrameworkSchema(), bridge: object({ bridgedChainName: string().required(), contract: addressSchema().required(), diff --git a/src/cli/utils/templates.js b/src/cli/utils/templates.js index 0674d006..bc1eb68e 100644 --- a/src/cli/utils/templates.js +++ b/src/cli/utils/templates.js @@ -39,21 +39,6 @@ export const sconeTeeApp = { }, }; -export const gramineTeeApp = { - owner: '0x0000000000000000000000000000000000000000', - name: 'hello-world-gramine', - type: 'DOCKER', - multiaddr: 'iexechub/tee-python-hello-world:8.0.3-gramine', - checksum: - '0x8e13b1592bff2e1651225b1533282ed2e1939ce173c9f0c2c39ed02a4963401f', - mrenclave: { - framework: 'GRAMINE', - version: 'v0', - fingerprint: - 'c879351b3640a21331c4d931d3e32bfbb8373b502966f9c639538666b2cf3641', - }, -}; - export const buyConf = { params: { [IEXEC_REQUEST_PARAMS.IEXEC_ARGS]: '', diff --git a/src/common/execution/order-helper.js b/src/common/execution/order-helper.js index e35b9835..6feffe36 100644 --- a/src/common/execution/order-helper.js +++ b/src/common/execution/order-helper.js @@ -32,8 +32,9 @@ import { tagSchema, positiveStrictIntSchema, signedDatasetorderBulkSchema, + objMrenclaveSchema, } from '../utils/validator.js'; -import { resolveTeeFrameworkFromApp, showApp } from '../protocol/registries.js'; +import { showApp } from '../protocol/registries.js'; import { add } from '../utils/ipfs.js'; const debug = Debug('iexec:execution:order-helper'); @@ -46,10 +47,18 @@ export const resolveTeeFrameworkFromTag = async (tag) => { if (checkActiveBitInTag(vTag, TAG_MAP[TEE_FRAMEWORKS.TDX])) { return TEE_FRAMEWORKS.TDX; } - if (checkActiveBitInTag(vTag, TAG_MAP[TEE_FRAMEWORKS.GRAMINE])) { - return TEE_FRAMEWORKS.GRAMINE; - } + return undefined; +}; +const resolveTeeFrameworkFromApp = async (app) => { + if (app.appMREnclave) { + try { + const mrenclave = await objMrenclaveSchema().validate(app.appMREnclave); + return mrenclave.framework; + } catch (err) { + debug('resolveTeeFrameworkFromApp()', err); + } + } return undefined; }; @@ -211,11 +220,11 @@ export const checkAppRequirements = async ( tagOverride ? await tagSchema().validate(tagOverride) : tag, ); const appTeeFramework = await showApp(contracts, app).then((res) => - resolveTeeFrameworkFromApp(res.app, { strict: false }), + resolveTeeFrameworkFromApp(res.app), ); const tagMatchesApp = appTeeFramework === tagTeeFramework || - (tagTeeFramework === undefined && appTeeFramework === TEE_FRAMEWORKS.TDX); + (tagTeeFramework === TEE_FRAMEWORKS.TDX && appTeeFramework === undefined); if (!tagMatchesApp) { throw new Error('Tag mismatch the TEE framework specified by app'); } diff --git a/src/common/protocol/registries.js b/src/common/protocol/registries.js index d9f0b56b..f094c9ff 100644 --- a/src/common/protocol/registries.js +++ b/src/common/protocol/registries.js @@ -7,7 +7,6 @@ import { datasetSchema, workerpoolSchema, uint256Schema, - objMrenclaveSchema, throwIfMissing, } from '../utils/validator.js'; import { @@ -20,7 +19,7 @@ import { hexToBuffer, BN, } from '../utils/utils.js'; -import { APP, DATASET, TEE_FRAMEWORKS, WORKERPOOL } from '../utils/constant.js'; +import { APP, DATASET, WORKERPOOL } from '../utils/constant.js'; import { wrapCall, wrapSend, wrapWait } from '../utils/errorWrappers.js'; import { ObjectNotFoundError } from '../utils/errors.js'; @@ -517,23 +516,3 @@ export const transferWorkerpool = async ( .required() .validate(to), ); - -export const resolveTeeFrameworkFromApp = async ( - app, - { strict = true } = {}, -) => { - if (app.appMREnclave) { - try { - const mrenclave = await objMrenclaveSchema().validate(app.appMREnclave); - return mrenclave.framework; - } catch (err) { - debug('resolveTeeFrameworkFromApp()', err); - if (strict) { - throw new Error('Failed to resolve TEE framework from app'); - } - } - } else { - return TEE_FRAMEWORKS.TDX; - } - return undefined; -}; diff --git a/src/common/types.d.ts b/src/common/types.d.ts index 02812df5..d525af28 100644 --- a/src/common/types.d.ts +++ b/src/common/types.d.ts @@ -126,7 +126,6 @@ export type HumanSingleTag = string; * ```js * const gpuTag = ['gpu']; * const sconeTeeTag = ['tee', 'scone']; - * const gramineTeeTag = ['tee', 'gramine']; * ``` */ export type Tag = Bytes32 | HumanSingleTag[]; @@ -144,7 +143,7 @@ export type Multiaddress = string | Buffer; /** * Trusted Execution Environment name */ -export type TeeFramework = 'scone' | 'gramine' | 'tdx'; +export type TeeFramework = 'scone' | 'tdx'; export type AnyRecord = Record; diff --git a/src/common/utils/config.js b/src/common/utils/config.js index 3fb02c83..f95029b2 100644 --- a/src/common/utils/config.js +++ b/src/common/utils/config.js @@ -1,5 +1,4 @@ import { EnsPlugin, Network } from 'ethers'; -import { TEE_FRAMEWORKS } from './constant.js'; import { ConfigurationError } from './errors.js'; export const CHAIN_SPECIFIC_FEATURES = { @@ -18,10 +17,7 @@ const networkConfigs = [ host: 'https://bellecour.iex.ec', ensRegistry: '0x5f5B93fca68c9C79318d1F3868A354EE67D8c006', ensPublicResolver: '0x1347d8a1840A810B990d0B774A6b7Bb8A1bd62BB', - sms: { - [TEE_FRAMEWORKS.SCONE]: 'https://sms.iex.ec', - [TEE_FRAMEWORKS.GRAMINE]: 'https://sms.gramine.v8-bellecour.iex.ec', - }, + sms: 'https://sms.iex.ec', resultProxy: 'https://result.v8-bellecour.iex.ec', ipfsGateway: 'https://ipfs-gateway.v8-bellecour.iex.ec', ipfsNode: 'https://ipfs-upload.v8-bellecour.iex.ec', @@ -71,10 +67,7 @@ const networkConfigs = [ host: 'https://sepolia-rollup.arbitrum.io/rpc', ensRegistry: undefined, // not supported ensPublicResolver: undefined, // not supported - sms: { - [TEE_FRAMEWORKS.SCONE]: 'https://sms.arbitrum-sepolia-testnet.iex.ec', - [TEE_FRAMEWORKS.TDX]: 'https://sms.arbitrum-sepolia-testnet.iex.ec', - }, + sms: 'https://sms.arbitrum-sepolia-testnet.iex.ec', resultProxy: undefined, // not exposed ipfsGateway: 'https://ipfs-gateway.arbitrum-sepolia-testnet.iex.ec', ipfsNode: 'https://ipfs-upload.arbitrum-sepolia-testnet.iex.ec', @@ -99,10 +92,7 @@ const networkConfigs = [ host: 'https://arb1.arbitrum.io/rpc', ensRegistry: undefined, // not supported ensPublicResolver: undefined, // not supported - sms: { - [TEE_FRAMEWORKS.SCONE]: 'https://sms.arbitrum-mainnet.iex.ec', - [TEE_FRAMEWORKS.TDX]: 'https://sms.arbitrum-mainnet.iex.ec', - }, + sms: 'https://sms.arbitrum-mainnet.iex.ec', resultProxy: undefined, // not exposed ipfsGateway: 'https://ipfs-gateway.arbitrum-mainnet.iex.ec', ipfsNode: 'https://ipfs-upload.arbitrum-mainnet.iex.ec', diff --git a/src/common/utils/constant.js b/src/common/utils/constant.js index 3fdfe9f9..d00bc6cc 100644 --- a/src/common/utils/constant.js +++ b/src/common/utils/constant.js @@ -30,7 +30,6 @@ export const WORKERPOOL_URL_TEXT_RECORD_KEY = 'iexec:workerpool-api:url'; export const TEE_FRAMEWORKS = { SCONE: 'scone', - GRAMINE: 'gramine', TDX: 'tdx', }; diff --git a/src/common/utils/utils.js b/src/common/utils/utils.js index fae94cfe..2112b40e 100644 --- a/src/common/utils/utils.js +++ b/src/common/utils/utils.js @@ -216,7 +216,7 @@ export const getSalt = () => hexlify(randomBytes(32)); export const TAG_MAP = { tee: 0, [TEE_FRAMEWORKS.SCONE]: 1, - [TEE_FRAMEWORKS.GRAMINE]: 2, + gramine: 2, // previously supported tee framework [TEE_FRAMEWORKS.TDX]: 3, gpu: 8, }; diff --git a/src/common/utils/validator.js b/src/common/utils/validator.js index 17e1787a..0c61117c 100644 --- a/src/common/utils/validator.js +++ b/src/common/utils/validator.js @@ -1,6 +1,6 @@ import { Buffer } from 'buffer'; import Debug from 'debug'; -import { string, number, object, mixed, boolean, array, lazy } from 'yup'; +import { string, number, object, mixed, boolean, array } from 'yup'; import { getAddress, isAddress, namehash } from 'ethers'; // import-js/eslint-plugin-import/issues/2703 // eslint-disable-next-line import/no-unresolved @@ -627,27 +627,11 @@ export const multiaddressSchema = () => export const objMrenclaveSchema = () => object({ - // common keys framework: teeFrameworkSchema().required(), version: string().required(), fingerprint: string().required(), - // framework specific keys - entrypoint: mixed().when('framework', ([framework], entrypointSchema) => - framework && framework.toLowerCase() === TEE_FRAMEWORKS.SCONE - ? string().required() - : entrypointSchema.is( - [undefined], - 'Unknown key "${path}" in mrenclave', - ), - ), - heapSize: mixed().when('framework', ([framework], entrypointSchema) => - framework && framework.toLowerCase() === TEE_FRAMEWORKS.SCONE - ? positiveIntSchema().required() - : entrypointSchema.is( - [undefined], - 'Unknown key "${path}" in mrenclave', - ), - ), + entrypoint: string().required(), + heapSize: positiveIntSchema().required(), }) .json() .noUnknown(true, 'Unknown key "${unknown}" in mrenclave'); @@ -873,22 +857,6 @@ export const workerpoolApiUrlSchema = () => .matches(/^(https?:\/\/.*)?$/, '${path} "${value}" is not a valid URL') // accept empty string to reset workerpool URL .default(''); -export const smsUrlOrMapSchema = () => - lazy((stringOrMap) => { - if (typeof stringOrMap === 'object' && stringOrMap !== null) { - return object( - teeFrameworksList.reduce( - (acc, curr) => ({ ...acc, [curr]: basicUrlSchema() }), - {}, - ), - ) - .noUnknown(true) - .nonNullable() - .strict(true); - } - return basicUrlSchema(); - }); - export const throwIfMissing = () => { throw new ValidationError('Missing parameter'); }; diff --git a/src/lib/IExecAppModule.d.ts b/src/lib/IExecAppModule.d.ts index 2c5aa938..5785688c 100644 --- a/src/lib/IExecAppModule.d.ts +++ b/src/lib/IExecAppModule.d.ts @@ -10,7 +10,6 @@ import { BNish, Bytes32, Multiaddress, - TeeFramework, TxHash, } from '../common/types.js'; @@ -37,21 +36,6 @@ export interface SconeMREnclave { fingerprint: string; } -export interface GramineMREnclave { - /** - * TEE framework name 'GRAMINE' - */ - framework: string; - /** - * framework's protocol version - */ - version: string; - /** - * app tee fingerprint - */ - fingerprint: string; -} - export interface AppDeploymentArgs { /** * the app owner @@ -76,7 +60,7 @@ export interface AppDeploymentArgs { /** * optional for TEE apps only, specify the TEE protocol to use */ - mrenclave?: SconeMREnclave | GramineMREnclave; + mrenclave?: SconeMREnclave; } /** * IExec app @@ -207,10 +191,7 @@ export default class IExecAppModule extends IExecModule { * - each TEE framework comes with a distinct Secret Management Service, if not specified the TEE framework is inferred from the app * */ - checkAppSecretExists( - appAddress: Addressish, - options?: { teeFramework?: TeeFramework }, - ): Promise; + checkAppSecretExists(appAddress: Addressish): Promise; /** * **SIGNER REQUIRED, ONLY APP OWNER** * @@ -227,11 +208,7 @@ export default class IExecAppModule extends IExecModule { * console.log('pushed App secret:', isPushed); * ``` */ - pushAppSecret( - appAddress: Addressish, - secretValue: String, - options?: { teeFramework?: TeeFramework }, - ): Promise; + pushAppSecret(appAddress: Addressish, secretValue: String): Promise; /** * **ONLY APP OWNER** * diff --git a/src/lib/IExecAppModule.js b/src/lib/IExecAppModule.js index f27c8126..f13008a6 100644 --- a/src/lib/IExecAppModule.js +++ b/src/lib/IExecAppModule.js @@ -6,7 +6,6 @@ import { countUserApps, predictAppAddress, checkDeployedApp, - resolveTeeFrameworkFromApp, transferApp, } from '../common/protocol/registries.js'; import { checkAppSecretExists } from '../common/sms/check.js'; @@ -28,37 +27,17 @@ export default class IExecAppModule extends IExecModule { ); this.countUserApps = async (address) => countUserApps(await this.config.resolveContractsClient(), address); - this.checkAppSecretExists = async (appAddress, { teeFramework } = {}) => { - let appTeeFramework = teeFramework; - if (appTeeFramework === undefined) { - const { app } = await showApp( - await this.config.resolveContractsClient(), - appAddress, - ); - appTeeFramework = await resolveTeeFrameworkFromApp(app); - } + this.checkAppSecretExists = async (appAddress) => { return checkAppSecretExists( await this.config.resolveContractsClient(), - await this.config.resolveSmsURL({ teeFramework: appTeeFramework }), + await this.config.resolveSmsURL(), appAddress, ); }; - this.pushAppSecret = async ( - appAddress, - appSecret, - { teeFramework } = {}, - ) => { - let appTeeFramework = teeFramework; - if (appTeeFramework === undefined) { - const { app } = await showApp( - await this.config.resolveContractsClient(), - appAddress, - ); - appTeeFramework = await resolveTeeFrameworkFromApp(app); - } + this.pushAppSecret = async (appAddress, appSecret) => { return pushAppSecret( await this.config.resolveContractsClient(), - await this.config.resolveSmsURL({ teeFramework: appTeeFramework }), + await this.config.resolveSmsURL(), appAddress, appSecret, ); diff --git a/src/lib/IExecConfig.d.ts b/src/lib/IExecConfig.d.ts index c6f84e41..155e2fca 100644 --- a/src/lib/IExecConfig.d.ts +++ b/src/lib/IExecConfig.d.ts @@ -2,7 +2,7 @@ export type * from '../common/types.js'; export type * from './IExecConfig.js'; import IExecContractsClient from '../common/utils/IExecContractsClient.js'; -import { AnyRecord, ProviderOptions, TeeFramework } from '../common/types.js'; +import { AnyRecord, ProviderOptions } from '../common/types.js'; import { AbstractProvider, AbstractSigner, BrowserProvider } from 'ethers'; export interface Eip1193Provider { @@ -85,11 +85,7 @@ export interface IExecConfigOptions { /** * override the SMS URL to target a custom instance */ - smsURL?: Record | string; - /** - * override the TEE framework to use when as default - */ - defaultTeeFramework?: TeeFramework; + smsURL?: string; /** * override the IPFS gateway URL to target a custom instance */ @@ -179,7 +175,7 @@ export default class IExecConfig { /** * resolve the current SMS URL */ - resolveSmsURL(options?: { teeFramework?: TeeFramework }): Promise; + resolveSmsURL(): Promise; /** * resolve the current result proxy URL */ diff --git a/src/lib/IExecConfig.js b/src/lib/IExecConfig.js index 0346ec16..b9197808 100644 --- a/src/lib/IExecConfig.js +++ b/src/lib/IExecConfig.js @@ -3,13 +3,9 @@ import { BrowserProvider, AbstractProvider, AbstractSigner } from 'ethers'; import IExecContractsClient from '../common/utils/IExecContractsClient.js'; import { ConfigurationError } from '../common/utils/errors.js'; import { getChainDefaults } from '../common/utils/config.js'; -import { TEE_FRAMEWORKS } from '../common/utils/constant.js'; import { getReadOnlyProvider } from '../common/utils/providers.js'; import { BrowserProviderSignerAdapter } from '../common/utils/signers.js'; -import { - smsUrlOrMapSchema, - teeFrameworkSchema, -} from '../common/utils/validator.js'; +import { basicUrlSchema } from '../common/utils/validator.js'; const debug = Debug('iexec:IExecConfig'); @@ -31,7 +27,6 @@ export default class IExecConfig { iexecGatewayURL, compassURL, pocoSubgraphURL, - defaultTeeFramework, providerOptions, allowExperimentalNetworks = false, } = {}, @@ -99,21 +94,53 @@ export default class IExecConfig { } catch (err) { throw new ConfigurationError(`Invalid ethProvider: ${err.message}`); } - let vSmsUrlOrMap; + let vSmsUrl; try { - vSmsUrlOrMap = smsUrlOrMapSchema().validateSync(smsURL); + vSmsUrl = basicUrlSchema().validateSync(smsURL); } catch (err) { throw new ConfigurationError(`Invalid smsURL: ${err.message}`); } - let vDefaultTeeFramework; + let vIexecGatewayURL; try { - vDefaultTeeFramework = - teeFrameworkSchema().validateSync(defaultTeeFramework); + vIexecGatewayURL = basicUrlSchema().validateSync(iexecGatewayURL); } catch (err) { - throw new ConfigurationError( - `Invalid defaultTeeFramework: ${err.message}`, - ); + throw new ConfigurationError(`Invalid iexecGatewayURL: ${err.message}`); + } + + let vIpfsGatewayURL; + try { + vIpfsGatewayURL = basicUrlSchema().validateSync(ipfsGatewayURL); + } catch (err) { + throw new ConfigurationError(`Invalid ipfsGatewayURL: ${err.message}`); + } + + let vIpfsNodeURL; + try { + vIpfsNodeURL = basicUrlSchema().validateSync(ipfsNodeURL); + } catch (err) { + throw new ConfigurationError(`Invalid ipfsNodeURL: ${err.message}`); + } + + let vPocoSubgraphURL; + try { + vPocoSubgraphURL = basicUrlSchema().validateSync(pocoSubgraphURL); + } catch (err) { + throw new ConfigurationError(`Invalid pocoSubgraphURL: ${err.message}`); + } + + let vResultProxyURL; + try { + vResultProxyURL = basicUrlSchema().validateSync(resultProxyURL); + } catch (err) { + throw new ConfigurationError(`Invalid resultProxyURL: ${err.message}`); + } + + let vCompassURL; + try { + vCompassURL = basicUrlSchema().validateSync(compassURL); + } catch (err) { + throw new ConfigurationError(`Invalid compassURL: ${err.message}`); } const networkPromise = (async () => { @@ -258,18 +285,10 @@ export default class IExecConfig { this.resolveBridgedContractsClient = async () => bridgedContractsPromise; - this.resolveSmsURL = async ({ - teeFramework = vDefaultTeeFramework || TEE_FRAMEWORKS.SCONE, - } = {}) => { + this.resolveSmsURL = async () => { const { chainId } = await networkPromise; const chainConfDefaults = await chainConfDefaultsPromise; - const vTeeFramework = await teeFrameworkSchema() - .label('teeFramework') - .validate(teeFramework); - const value = - (typeof vSmsUrlOrMap === 'string' && vSmsUrlOrMap) || - (typeof vSmsUrlOrMap === 'object' && vSmsUrlOrMap[vTeeFramework]) || - (chainConfDefaults.sms && chainConfDefaults.sms[vTeeFramework]); + const value = vSmsUrl || chainConfDefaults.sms; if (value !== undefined) { return value; } @@ -281,7 +300,7 @@ export default class IExecConfig { this.resolveResultProxyURL = async () => { const { chainId } = await networkPromise; const chainConfDefaults = await chainConfDefaultsPromise; - const value = resultProxyURL || chainConfDefaults.resultProxy; + const value = vResultProxyURL || chainConfDefaults.resultProxy; if (value !== undefined) { return value; } @@ -293,7 +312,7 @@ export default class IExecConfig { this.resolveIexecGatewayURL = async () => { const { chainId } = await networkPromise; const chainConfDefaults = await chainConfDefaultsPromise; - const value = iexecGatewayURL || chainConfDefaults.iexecGateway; + const value = vIexecGatewayURL || chainConfDefaults.iexecGateway; if (value !== undefined) { return value; } @@ -304,13 +323,13 @@ export default class IExecConfig { this.resolveCompassURL = async () => { const chainConfDefaults = await chainConfDefaultsPromise; - return compassURL || chainConfDefaults.compass; + return vCompassURL || chainConfDefaults.compass; }; this.resolveIpfsGatewayURL = async () => { const { chainId } = await networkPromise; const chainConfDefaults = await chainConfDefaultsPromise; - const value = ipfsGatewayURL || chainConfDefaults.ipfsGateway; + const value = vIpfsGatewayURL || chainConfDefaults.ipfsGateway; if (value !== undefined) { return value; } @@ -322,7 +341,7 @@ export default class IExecConfig { this.resolveIpfsNodeURL = async () => { const { chainId } = await networkPromise; const chainConfDefaults = await chainConfDefaultsPromise; - const value = ipfsNodeURL || chainConfDefaults.ipfsNode; + const value = vIpfsNodeURL || chainConfDefaults.ipfsNode; if (value !== undefined) { return value; } @@ -334,7 +353,7 @@ export default class IExecConfig { this.resolvePocoSubgraphURL = async () => { const { chainId } = await networkPromise; const chainConfDefaults = await chainConfDefaultsPromise; - const value = pocoSubgraphURL || chainConfDefaults.pocoSubgraph; + const value = vPocoSubgraphURL || chainConfDefaults.pocoSubgraph; if (value !== undefined) { return value; } diff --git a/src/lib/IExecDatasetModule.d.ts b/src/lib/IExecDatasetModule.d.ts index 269caf63..04537952 100644 --- a/src/lib/IExecDatasetModule.d.ts +++ b/src/lib/IExecDatasetModule.d.ts @@ -11,7 +11,6 @@ import { Bytes32, Multiaddress, TxHash, - TeeFramework, } from '../common/types.js'; export interface DatasetDeploymentArgs { @@ -212,12 +211,7 @@ export default class IExecDatasetModule extends IExecModule { * console.log('secret exists:', isSecretSet); * ``` */ - checkDatasetSecretExists( - datasetAddress: Addressish, - options?: { - teeFramework?: TeeFramework; - }, - ): Promise; + checkDatasetSecretExists(datasetAddress: Addressish): Promise; /** * **SIGNER REQUIRED, ONLY DATASET OWNER** * @@ -234,9 +228,6 @@ export default class IExecDatasetModule extends IExecModule { pushDatasetSecret( datasetAddress: Addressish, encryptionKey: string, - options?: { - teeFramework?: TeeFramework; - }, ): Promise; /** * **ONLY DATASET OWNER** diff --git a/src/lib/IExecDatasetModule.js b/src/lib/IExecDatasetModule.js index f8958677..5b274352 100644 --- a/src/lib/IExecDatasetModule.js +++ b/src/lib/IExecDatasetModule.js @@ -37,23 +37,16 @@ export default class IExecDatasetModule extends IExecModule { ); this.countUserDatasets = async (address) => countUserDatasets(await this.config.resolveContractsClient(), address); - this.checkDatasetSecretExists = async ( - datasetAddress, - { teeFramework } = {}, - ) => + this.checkDatasetSecretExists = async (datasetAddress) => checkWeb3SecretExists( await this.config.resolveContractsClient(), - await this.config.resolveSmsURL({ teeFramework }), + await this.config.resolveSmsURL(), datasetAddress, ); - this.pushDatasetSecret = async ( - datasetAddress, - datasetSecret, - { teeFramework } = {}, - ) => + this.pushDatasetSecret = async (datasetAddress, datasetSecret) => pushWeb3Secret( await this.config.resolveContractsClient(), - await this.config.resolveSmsURL({ teeFramework }), + await this.config.resolveSmsURL(), datasetAddress, datasetSecret, ); diff --git a/src/lib/IExecOrderModule.js b/src/lib/IExecOrderModule.js index a8ef40de..846806d0 100644 --- a/src/lib/IExecOrderModule.js +++ b/src/lib/IExecOrderModule.js @@ -39,7 +39,6 @@ import { } from '../common/market/marketplace.js'; import { checkRequestRequirements, - resolveTeeFrameworkFromTag, checkAppRequirements, checkDatasetRequirements, prepareDatasetBulk, @@ -112,11 +111,7 @@ export default class IExecOrderModule extends IExecModule { ? await checkDatasetRequirements( { contracts: await this.config.resolveContractsClient(), - smsURL: await this.config.resolveSmsURL({ - teeFramework: await resolveTeeFrameworkFromTag( - (await datasetorderSchema().validate(datasetorder)).tag, - ), - }), + smsURL: await this.config.resolveSmsURL(), }, datasetorder, ).then(() => datasetorder) @@ -137,11 +132,7 @@ export default class IExecOrderModule extends IExecModule { ? await checkRequestRequirements( { contracts: await this.config.resolveContractsClient(), - smsURL: await this.config.resolveSmsURL({ - teeFramework: await resolveTeeFrameworkFromTag( - (await requestorderSchema().validate(requestorder)).tag, - ), - }), + smsURL: await this.config.resolveSmsURL(), }, requestorder, ).then(() => requestorder) @@ -194,12 +185,7 @@ export default class IExecOrderModule extends IExecModule { ? await checkDatasetRequirements( { contracts: await this.config.resolveContractsClient(), - smsURL: await this.config.resolveSmsURL({ - teeFramework: await resolveTeeFrameworkFromTag( - (await datasetorderSchema().validate(signedDatasetorder)) - .tag, - ), - }), + smsURL: await this.config.resolveSmsURL(), }, signedDatasetorder, ).then(() => signedDatasetorder) @@ -222,12 +208,7 @@ export default class IExecOrderModule extends IExecModule { ? await checkRequestRequirements( { contracts: await this.config.resolveContractsClient(), - smsURL: await this.config.resolveSmsURL({ - teeFramework: await resolveTeeFrameworkFromTag( - (await requestorderSchema().validate(signedRequestorder)) - .tag, - ), - }), + smsURL: await this.config.resolveSmsURL(), }, signedRequestorder, ).then(() => signedRequestorder) @@ -341,9 +322,7 @@ export default class IExecOrderModule extends IExecModule { datasetorder: await checkDatasetRequirements( { contracts, - smsURL: await this.config.resolveSmsURL({ - teeFramework: await resolveTeeFrameworkFromTag(resolvedTag), - }), + smsURL: await this.config.resolveSmsURL(), }, datasetorder, { tagOverride: resolvedTag }, @@ -352,9 +331,7 @@ export default class IExecOrderModule extends IExecModule { requestorder: await checkRequestRequirements( { contracts, - smsURL: await this.config.resolveSmsURL({ - teeFramework: await resolveTeeFrameworkFromTag(resolvedTag), - }), + smsURL: await this.config.resolveSmsURL(), }, requestorder, ).then(() => requestorder), diff --git a/src/lib/IExecResultModule.d.ts b/src/lib/IExecResultModule.d.ts index c09da5eb..19fb54fc 100644 --- a/src/lib/IExecResultModule.d.ts +++ b/src/lib/IExecResultModule.d.ts @@ -3,7 +3,7 @@ export type * from './IExecConfig.js'; import IExecConfig from './IExecConfig.js'; import IExecModule from './IExecModule.js'; -import { Addressish, TeeFramework } from '../common/types.js'; +import { Addressish } from '../common/types.js'; /** * module exposing result methods @@ -20,7 +20,6 @@ export default class IExecResultModule extends IExecModule { */ checkResultEncryptionKeyExists( beneficiaryAddress: Addressish, - options: { teeFramework?: TeeFramework }, ): Promise; /** * **SIGNER REQUIRED, ONLY BENEFICIARY** @@ -71,7 +70,6 @@ export default class IExecResultModule extends IExecModule { rsaPublicKey: string | CryptoKey, options?: { forceUpdate?: boolean; - teeFramework?: TeeFramework; }, ): Promise<{ isPushed: boolean; isUpdated: boolean }>; /** diff --git a/src/lib/IExecResultModule.js b/src/lib/IExecResultModule.js index 39ec7a0e..6d256303 100644 --- a/src/lib/IExecResultModule.js +++ b/src/lib/IExecResultModule.js @@ -8,19 +8,16 @@ export default class IExecResultModule extends IExecModule { constructor(...args) { super(...args); - this.checkResultEncryptionKeyExists = async ( - address, - { teeFramework } = {}, - ) => + this.checkResultEncryptionKeyExists = async (address) => checkWeb2SecretExists( await this.config.resolveContractsClient(), - await this.config.resolveSmsURL({ teeFramework }), + await this.config.resolveSmsURL(), address, getResultEncryptionKeyName(), ); this.pushResultEncryptionKey = async ( publicKey, - { forceUpdate = false, teeFramework } = {}, + { forceUpdate = false } = {}, ) => { // secretValue can be: // - a PEM public key @@ -29,7 +26,7 @@ export default class IExecResultModule extends IExecModule { const formattedPublicKey = await formatEncryptionKey(publicKey); return pushWeb2Secret( await this.config.resolveContractsClient(), - await this.config.resolveSmsURL({ teeFramework }), + await this.config.resolveSmsURL(), getResultEncryptionKeyName(), formattedPublicKey, { forceUpdate }, diff --git a/src/lib/IExecSecretsModule.d.ts b/src/lib/IExecSecretsModule.d.ts index 42a5fa4d..8dad0ca6 100644 --- a/src/lib/IExecSecretsModule.d.ts +++ b/src/lib/IExecSecretsModule.d.ts @@ -3,7 +3,7 @@ export type * from './IExecConfig.js'; import IExecConfig from './IExecConfig.js'; import IExecModule from './IExecModule.js'; -import { Addressish, TeeFramework } from '../common/types.js'; +import { Addressish } from '../common/types.js'; /** * module exposing secrets methods @@ -21,9 +21,6 @@ export default class IExecSecretsModule extends IExecModule { checkRequesterSecretExists( requesterAddress: Addressish, secretName: String, - options?: { - teeFramework?: TeeFramework; - }, ): Promise; /** * **SIGNER REQUIRED, ONLY REQUESTER** @@ -43,9 +40,6 @@ export default class IExecSecretsModule extends IExecModule { pushRequesterSecret( secretName: String, secretValue: String, - options?: { - teeFramework?: TeeFramework; - }, ): Promise<{ isPushed: boolean }>; /** * Create an IExecSecretsModule instance using an IExecConfig instance diff --git a/src/lib/IExecSecretsModule.js b/src/lib/IExecSecretsModule.js index e22b502a..bcbc9880 100644 --- a/src/lib/IExecSecretsModule.js +++ b/src/lib/IExecSecretsModule.js @@ -6,25 +6,17 @@ export default class IExecSecretModule extends IExecModule { constructor(...args) { super(...args); - this.checkRequesterSecretExists = async ( - address, - secretName, - { teeFramework } = {}, - ) => + this.checkRequesterSecretExists = async (address, secretName) => checkRequesterSecretExists( await this.config.resolveContractsClient(), - await this.config.resolveSmsURL({ teeFramework }), + await this.config.resolveSmsURL(), address, secretName, ); - this.pushRequesterSecret = async ( - secretName, - secretValue, - { teeFramework } = {}, - ) => + this.pushRequesterSecret = async (secretName, secretValue) => pushRequesterSecret( await this.config.resolveContractsClient(), - await this.config.resolveSmsURL({ teeFramework }), + await this.config.resolveSmsURL(), secretName, secretValue, ); diff --git a/src/lib/IExecStorageModule.d.ts b/src/lib/IExecStorageModule.d.ts index ef50486f..052ae2bf 100644 --- a/src/lib/IExecStorageModule.d.ts +++ b/src/lib/IExecStorageModule.d.ts @@ -3,7 +3,7 @@ export type * from './IExecConfig.js'; import IExecConfig from './IExecConfig.js'; import IExecModule from './IExecModule.js'; -import { Addressish, TeeFramework } from '../common/types.js'; +import { Addressish } from '../common/types.js'; /** * module exposing storage methods @@ -24,7 +24,6 @@ export default class IExecStorageModule extends IExecModule { beneficiaryAddress: Addressish, options?: { provider?: string; - teeFramework?: TeeFramework; }, ): Promise; /** @@ -66,7 +65,6 @@ export default class IExecStorageModule extends IExecModule { token: string, options?: { provider?: string; - teeFramework?: TeeFramework; forceUpdate?: boolean; }, ): Promise<{ isPushed: boolean; isUpdated: boolean }>; diff --git a/src/lib/IExecStorageModule.js b/src/lib/IExecStorageModule.js index c42ec5ee..b3158215 100644 --- a/src/lib/IExecStorageModule.js +++ b/src/lib/IExecStorageModule.js @@ -13,24 +13,21 @@ export default class IExecStorageModule extends IExecModule { await this.config.resolveContractsClient(), await this.config.resolveResultProxyURL(), ); - this.checkStorageTokenExists = async ( - address, - { provider, teeFramework } = {}, - ) => + this.checkStorageTokenExists = async (address, { provider } = {}) => checkWeb2SecretExists( await this.config.resolveContractsClient(), - await this.config.resolveSmsURL({ teeFramework }), + await this.config.resolveSmsURL(), address, getStorageTokenKeyName(provider), ); this.pushStorageToken = async ( token, - { provider, teeFramework, forceUpdate = false } = {}, + { provider, forceUpdate = false } = {}, ) => pushWeb2Secret( await this.config.resolveContractsClient(), - await this.config.resolveSmsURL({ teeFramework }), + await this.config.resolveSmsURL(), getStorageTokenKeyName(provider), token, { forceUpdate }, diff --git a/test/cli/cli-common.test.js b/test/cli/cli-common.test.js index 56cde5c8..c34d3978 100644 --- a/test/cli/cli-common.test.js +++ b/test/cli/cli-common.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { execAsync } from '../test-utils.js'; import { diff --git a/test/cli/cli-iexec-account.test.js b/test/cli/cli-iexec-account.test.js index 12ec7ff4..da1cf1cf 100644 --- a/test/cli/cli-iexec-account.test.js +++ b/test/cli/cli-iexec-account.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { BN } from 'bn.js'; import { diff --git a/test/cli/cli-iexec-app.test.js b/test/cli/cli-iexec-app.test.js index 21fe473e..e04c5ede 100644 --- a/test/cli/cli-iexec-app.test.js +++ b/test/cli/cli-iexec-app.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { NULL_ADDRESS, @@ -55,26 +53,6 @@ describe('iexec app', () => { expect(res.app.mrenclave).toBeUndefined(); }); - test('--tee', async () => { - const raw = await execAsync(`${iexecPath} app init --tee --raw`); - const res = JSON.parse(raw); - expect(res.ok).toBe(true); - expect(res.app).toBeDefined(); - expect(res.app.mrenclave).toBeDefined(); - expect(res.app.mrenclave.framework).toBe('SCONE'); - }); - - test('--tee-framework gramine', async () => { - const raw = await execAsync( - `${iexecPath} app init --tee-framework gramine --raw`, - ); - const res = JSON.parse(raw); - expect(res.ok).toBe(true); - expect(res.app).toBeDefined(); - expect(res.app.mrenclave).toBeDefined(); - expect(res.app.mrenclave.framework).toBe('GRAMINE'); - }); - test('--tee-framework scone', async () => { const raw = await execAsync( `${iexecPath} app init --tee-framework scone --raw`, @@ -99,7 +77,7 @@ describe('iexec app', () => { describe('deploy', () => { test('iexec app deploy', async () => { - await execAsync(`${iexecPath} app init --tee --raw`); + await execAsync(`${iexecPath} app init --tee-framework scone --raw`); await setAppUniqueName(); const raw = await execAsync(`${iexecPath} app deploy --raw`); const res = JSON.parse(raw); @@ -114,7 +92,7 @@ describe('iexec app', () => { describe('show', () => { test('iexec app show (from deployed.json)', async () => { - await execAsync(`${iexecPath} app init --tee --raw`); + await execAsync(`${iexecPath} app init --tee-framework scone --raw`); await setAppUniqueName(); const { address } = await execAsync(`${iexecPath} app deploy --raw`).then( JSON.parse, @@ -435,20 +413,6 @@ describe('iexec app', () => { ); expect(resPushed.ok).toBe(true); expect(resPushed.isSecretSet).toBe(true); - - const resGramineNotPushed = await runIExecCliRaw( - `${iexecPath} app check-secret ${appAddress} --tee-framework gramine`, - ); - expect(resGramineNotPushed.ok).toBe(true); - expect(resGramineNotPushed.isSecretSet).toBe(false); - await runIExecCliRaw( - `${iexecPath} app push-secret ${appAddress} --secret-value foo --tee-framework gramine`, - ); - const resGraminePushed = await runIExecCliRaw( - `${iexecPath} app check-secret ${appAddress} --tee-framework gramine`, - ); - expect(resGraminePushed.ok).toBe(true); - expect(resGraminePushed.isSecretSet).toBe(true); }); }); diff --git a/test/cli/cli-iexec-category.test.js b/test/cli/cli-iexec-category.test.js index 2c9f05d2..0bfaef19 100644 --- a/test/cli/cli-iexec-category.test.js +++ b/test/cli/cli-iexec-category.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { TEST_CHAINS, execAsync } from '../test-utils.js'; import { diff --git a/test/cli/cli-iexec-dataset.test.js b/test/cli/cli-iexec-dataset.test.js index b2cf927f..46563d44 100644 --- a/test/cli/cli-iexec-dataset.test.js +++ b/test/cli/cli-iexec-dataset.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { NULL_ADDRESS, @@ -228,29 +226,6 @@ describe('iexec dataset', () => { expect(resAlreadyExists.error.message).toBe( `Secret already exists for ${address} and can't be updated`, ); - // new dataset to push secret on another TEE framework - await execAsync(`${iexecPath} dataset init`); - await setDatasetUniqueName(); - const { address: address2 } = JSON.parse( - await execAsync(`${iexecPath} dataset deploy --raw`), - ); - await expect( - execAsync( - `${iexecPath} dataset push-secret ${address2} --tee-framework foo --raw`, - ), - ).rejects.toThrow(); - const resPush2 = JSON.parse( - await execAsync( - `${iexecPath} dataset push-secret ${address2} --tee-framework gramine --raw`, - ), - ); - expect(resPush2.ok).toBe(true); - const resAlreadyExists2 = JSON.parse( - await execAsync( - `${iexecPath} dataset push-secret ${address2} --tee-framework gramine --raw`, - ).catch((e) => e.message), - ); - expect(resAlreadyExists2.ok).toBe(false); }); test('iexec dataset check-secret', async () => { @@ -271,53 +246,6 @@ describe('iexec dataset', () => { const resAlreadyExists = JSON.parse(rawAlreadyExists); expect(resAlreadyExists.ok).toBe(true); expect(resAlreadyExists.isSecretSet).toBe(true); - const rawRandomDataset = await execAsync( - `${iexecPath} dataset check-secret ${getRandomAddress()} --raw`, - ); - const resRandomDataset = JSON.parse(rawRandomDataset); - expect(resRandomDataset.ok).toBe(true); - expect(resRandomDataset.isSecretSet).toBe(false); - - // testing on gramine dataset - - await execAsync(`${iexecPath} dataset init`); - await setDatasetUniqueName(); - await execAsync(`${iexecPath} dataset deploy --raw`); - const resMyDataset2 = JSON.parse( - await execAsync(`${iexecPath} dataset check-secret --raw`), - ); - expect(resMyDataset2.ok).toBe(true); - expect(resMyDataset2.isSecretSet).toBe(false); - - await execAsync( - `${iexecPath} dataset push-secret --tee-framework gramine --raw`, - ); - const rawWrongTee = await execAsync( - `${iexecPath} dataset check-secret --raw`, - ); - const resWrongTee = JSON.parse(rawWrongTee); - expect(resWrongTee.ok).toBe(true); - expect(resWrongTee.isSecretSet).toBe(false); - - const rawGoodTee = await execAsync( - `${iexecPath} dataset check-secret --tee-framework gramine --raw`, - ); - const resGoodTee = JSON.parse(rawGoodTee); - expect(resGoodTee.ok).toBe(true); - expect(resGoodTee.isSecretSet).toBe(true); - - const rawRandomDataset2 = await execAsync( - `${iexecPath} dataset check-secret ${getRandomAddress()} --raw`, - ); - const resRandomDataset2 = JSON.parse(rawRandomDataset2); - expect(resRandomDataset2.ok).toBe(true); - expect(resRandomDataset2.isSecretSet).toBe(false); - - await expect( - execAsync( - `${iexecPath} dataset check-secret ${getRandomAddress()} --tee-framework foo --raw`, - ), - ).rejects.toThrow(); }); }); diff --git a/test/cli/cli-iexec-deal.test.js b/test/cli/cli-iexec-deal.test.js index f5407c10..5b1cd759 100644 --- a/test/cli/cli-iexec-deal.test.js +++ b/test/cli/cli-iexec-deal.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { TEST_CHAINS, diff --git a/test/cli/cli-iexec-ens.test.js b/test/cli/cli-iexec-ens.test.js index e4baf4dc..45d41003 100644 --- a/test/cli/cli-iexec-ens.test.js +++ b/test/cli/cli-iexec-ens.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { TEST_CHAINS, execAsync } from '../test-utils.js'; import { diff --git a/test/cli/cli-iexec-info.test.js b/test/cli/cli-iexec-info.test.js index 26935d88..49baef9b 100644 --- a/test/cli/cli-iexec-info.test.js +++ b/test/cli/cli-iexec-info.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { TEST_CHAINS, execAsync } from '../test-utils.js'; import { diff --git a/test/cli/cli-iexec-init.test.js b/test/cli/cli-iexec-init.test.js index dd7e5fca..0c387f92 100644 --- a/test/cli/cli-iexec-init.test.js +++ b/test/cli/cli-iexec-init.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { TEST_CHAINS, execAsync } from '../test-utils.js'; import { diff --git a/test/cli/cli-iexec-order.test.js b/test/cli/cli-iexec-order.test.js index 0ad1ab58..9047e166 100644 --- a/test/cli/cli-iexec-order.test.js +++ b/test/cli/cli-iexec-order.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { TEST_CHAINS, execAsync } from '../test-utils.js'; import { @@ -145,7 +143,7 @@ describe('iexec order', () => { expect(failRes.fail).toStrictEqual([ 'apporder: App requirements check failed: Tag mismatch the TEE framework specified by app (If you consider this is not an issue, use --skip-preflight-check to skip preflight requirement check)', `datasetorder: Dataset requirements check failed: Dataset encryption key is not set for dataset ${userDataset} in the SMS. Dataset decryption will fail. (If you consider this is not an issue, use --skip-preflight-check to skip preflight requirement check)`, - "workerpoolorder: 'tee' tag must be used with a tee framework ('scone'|'gramine'|'tdx')", + "workerpoolorder: 'tee' tag must be used with a tee framework ('scone'|'tdx')", `requestorder: Request requirements check failed: Dataset encryption key is not set for dataset ${userDataset} in the SMS. Dataset decryption will fail. (If you consider this is not an issue, use --skip-preflight-check to skip preflight requirement check)`, ]); }); diff --git a/test/cli/cli-iexec-requester.test.js b/test/cli/cli-iexec-requester.test.js index 2819d2e3..100df368 100644 --- a/test/cli/cli-iexec-requester.test.js +++ b/test/cli/cli-iexec-requester.test.js @@ -1,12 +1,5 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; -import { - TEST_CHAINS, - TEE_FRAMEWORKS, - execAsync, - getRandomAddress, -} from '../test-utils.js'; +import { TEST_CHAINS, execAsync, getRandomAddress } from '../test-utils.js'; import { globalSetup, globalTeardown, @@ -85,39 +78,6 @@ describe('iexec requester', () => { expect(checkPushed.ok).toBe(true); expect(checkPushed.name).toBe('foo'); expect(checkPushed.isSet).toBe(true); - - // check secret TEE framework validation - await expect( - execAsync( - `${iexecPath} requester check-secret foo ${userWallet.address} --tee-framework tee --raw`, - ), - ).rejects.toThrow(); - - // check secret TEE framework override - const checkOtherFramework = JSON.parse( - await execAsync( - `${iexecPath} requester check-secret foo ${userWallet.address} --tee-framework ${TEE_FRAMEWORKS.GRAMINE} --raw`, - ), - ); - expect(checkOtherFramework.ok).toBe(true); - expect(checkOtherFramework.name).toBe('foo'); - expect(checkOtherFramework.isSet).toBe(false); - - // push secret TEE framework override - const pushOtherFramework = JSON.parse( - await execAsync( - `${iexecPath} requester push-secret foo --secret-value foo --tee-framework ${TEE_FRAMEWORKS.GRAMINE} --raw`, - ), - ); - expect(pushOtherFramework.ok).toBe(true); - const checkOtherFrameworkPushed = JSON.parse( - await execAsync( - `${iexecPath} requester check-secret foo ${userWallet.address} --tee-framework ${TEE_FRAMEWORKS.GRAMINE} --raw`, - ), - ); - expect(checkOtherFrameworkPushed.ok).toBe(true); - expect(checkOtherFrameworkPushed.name).toBe('foo'); - expect(checkOtherFrameworkPushed.isSet).toBe(true); }); }); }); diff --git a/test/cli/cli-iexec-result.test.js b/test/cli/cli-iexec-result.test.js index a1e7e3fc..c8decbd2 100644 --- a/test/cli/cli-iexec-result.test.js +++ b/test/cli/cli-iexec-result.test.js @@ -1,12 +1,5 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; -import { - TEST_CHAINS, - TEE_FRAMEWORKS, - execAsync, - getRandomAddress, -} from '../test-utils.js'; +import { TEST_CHAINS, execAsync, getRandomAddress } from '../test-utils.js'; import { globalSetup, globalTeardown, @@ -79,21 +72,6 @@ describe('iexec result', () => { ).catch((e) => e.message); const resAlreadyExists = JSON.parse(rawAlreadyExists); expect(resAlreadyExists.ok).toBe(false); - const rawAlreadyExistsForTeeFramework = await execAsync( - `${iexecPath} result push-encryption-key --tee-framework scone --raw`, - ).catch((e) => e.message); - const resAlreadyExistsForTeeFramework = JSON.parse( - rawAlreadyExistsForTeeFramework, - ); - expect(resAlreadyExistsForTeeFramework.ok).toBe(false); - const resNotExistsForTeeFramework = JSON.parse( - await execAsync( - `${iexecPath} result push-encryption-key --tee-framework gramine --raw`, - ), - ); - expect(resNotExistsForTeeFramework.ok).toBe(true); - expect(resNotExistsForTeeFramework.isPushed).toBe(true); - expect(resNotExistsForTeeFramework.isUpdated).toBe(false); }); test('iexec result push-encryption-key --force-update', async () => { @@ -144,20 +122,6 @@ describe('iexec result', () => { const resExists = JSON.parse(rawExists); expect(resExists.ok).toBe(true); expect(resExists.isEncryptionKeySet).toBe(true); - - const rawExistsOnTeeFramework = await execAsync( - `${iexecPath} result check-encryption-key --tee-framework ${TEE_FRAMEWORKS.SCONE} --raw`, - ); - const resExistsOnTeeFramework = JSON.parse(rawExistsOnTeeFramework); - expect(resExistsOnTeeFramework.ok).toBe(true); - expect(resExistsOnTeeFramework.isEncryptionKeySet).toBe(true); - - const rawNotExistsOnTeeFramework = await execAsync( - `${iexecPath} result check-encryption-key --tee-framework ${TEE_FRAMEWORKS.GRAMINE} --raw`, - ); - const resNotExistsOnTeeFramework = JSON.parse(rawNotExistsOnTeeFramework); - expect(resNotExistsOnTeeFramework.ok).toBe(true); - expect(resNotExistsOnTeeFramework.isEncryptionKeySet).toBe(false); }); test('check-secret (v4 legacy name)', async () => { diff --git a/test/cli/cli-iexec-storage.test.js b/test/cli/cli-iexec-storage.test.js index b2addbbf..909dd71d 100644 --- a/test/cli/cli-iexec-storage.test.js +++ b/test/cli/cli-iexec-storage.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { TEST_CHAINS, execAsync, getRandomAddress } from '../test-utils.js'; import { @@ -43,13 +41,6 @@ describe('iexec storage', () => { expect(resAlreadyExists.error.message).toBe( 'default storage is already initialized, use --force-update option to update your storage token', ); - const rawInitWithTeeFramework = await execAsync( - `${iexecPath} storage init --tee-framework gramine --raw`, - ); - const resInitWithTeeFramework = JSON.parse(rawInitWithTeeFramework); - expect(resInitWithTeeFramework.ok).toBe(true); - expect(resInitWithTeeFramework.isInitialized).toBe(true); - expect(resInitWithTeeFramework.isUpdated).toBe(false); }); test('iexec storage init --force-update', async () => { @@ -108,12 +99,6 @@ describe('iexec storage', () => { const resAlreadyExists = JSON.parse(rawAlreadyExists); expect(resAlreadyExists.ok).toBe(true); expect(resAlreadyExists.isInitialized).toBe(true); - const rawWithTeeFramework = await execAsync( - `${iexecPath} storage check --tee-framework gramine --raw`, - ); - const resWithTeeFramework = JSON.parse(rawWithTeeFramework); - expect(resWithTeeFramework.ok).toBe(true); - expect(resWithTeeFramework.isInitialized).toBe(false); }); test('iexec storage check --user', async () => { diff --git a/test/cli/cli-iexec-task.test.js b/test/cli/cli-iexec-task.test.js index 85b03e49..9528aee2 100644 --- a/test/cli/cli-iexec-task.test.js +++ b/test/cli/cli-iexec-task.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { TEST_CHAINS, diff --git a/test/cli/cli-iexec-wallet.test.js b/test/cli/cli-iexec-wallet.test.js index 3a5753a5..ecae2345 100644 --- a/test/cli/cli-iexec-wallet.test.js +++ b/test/cli/cli-iexec-wallet.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { TEST_CHAINS, @@ -59,7 +57,7 @@ describe('iexec wallet', () => { expect(res.wallet).toBeDefined(); expect(res.address).toBe(wallet.address); expect(res.fileName).toBeDefined(); - expect(await checkExists(res.fileName)); + expect(await checkExists(res.fileName)).toBe(true); }); test('--unencrypted', async () => { @@ -73,7 +71,7 @@ describe('iexec wallet', () => { expect(res.wallet.address).toBe(wallet.address); expect(res.address).toBe(wallet.address); expect(res.fileName.indexOf('/')).toBe(-1); - expect(await checkExists(res.fileName)); + expect(await checkExists(res.fileName)).toBe(true); }); test('--keystoredir ', async () => { @@ -84,7 +82,7 @@ describe('iexec wallet', () => { expect(res.wallet).toBeDefined(); expect(res.address).toBe(userWallet.address); expect(res.fileName.indexOf('out/keystore/')).not.toBe(-1); - expect(await checkExists(res.fileName)); + expect(await checkExists(res.fileName)).toBe(true); }); test('--keystoredir local', async () => { @@ -95,7 +93,7 @@ describe('iexec wallet', () => { expect(res.wallet).toBeDefined(); expect(res.address).toBe(userWallet.address); expect(res.fileName.indexOf('/')).toBe(-1); - expect(await checkExists(res.fileName)); + expect(await checkExists(res.fileName)).toBe(true); }); }); @@ -120,7 +118,7 @@ describe('iexec wallet', () => { expect(res.wallet.address).toBeDefined(); expect(res.address).toBeDefined(); expect(res.fileName.indexOf('/')).toBe(-1); - expect(await checkExists(res.fileName)); + expect(await checkExists(res.fileName)).toBe(true); }); test('--keystoredir ', async () => { @@ -131,7 +129,7 @@ describe('iexec wallet', () => { expect(res.wallet).toBeDefined(); expect(res.address).toBeDefined(); expect(res.fileName.indexOf('out/keystore/')).not.toBe(-1); - expect(await checkExists(res.fileName)); + expect(await checkExists(res.fileName)).toBe(true); }); test('--keystoredir local', async () => { @@ -142,7 +140,7 @@ describe('iexec wallet', () => { expect(res.wallet).toBeDefined(); expect(res.address).toBeDefined(); expect(res.fileName.indexOf('/')).toBe(-1); - expect(await checkExists(res.fileName)); + expect(await checkExists(res.fileName)).toBe(true); }); }); diff --git a/test/cli/cli-iexec-workerpool.test.js b/test/cli/cli-iexec-workerpool.test.js index 457507c6..a165b0c0 100644 --- a/test/cli/cli-iexec-workerpool.test.js +++ b/test/cli/cli-iexec-workerpool.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { TEST_CHAINS, diff --git a/test/cli/cli-test-utils.js b/test/cli/cli-test-utils.js index d36faa52..762a6304 100644 --- a/test/cli/cli-test-utils.js +++ b/test/cli/cli-test-utils.js @@ -69,7 +69,7 @@ export const setChain = id: chain.chainId, host: chain.rpcURL, hub: chain.hubAddress, - sms: chain.smsMap, + sms: chain.smsURL, iexecGateway: chain.iexecGatewayURL, resultProxy: chain.resultProxyURL, ensPublicResolver: chain.ensPublicResolverAddress, diff --git a/test/cli/cli-tx-options.test.js b/test/cli/cli-tx-options.test.js index ce2adfd8..5b7c44a8 100644 --- a/test/cli/cli-tx-options.test.js +++ b/test/cli/cli-tx-options.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { TEST_CHAINS, diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 5d91fb33..fcb0ae04 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -117,48 +117,6 @@ services: bellecour-fork: condition: service_healthy - sms-gramine: - image: iexechub/iexec-sms:8.7.0 - restart: unless-stopped - environment: - JAVA_TOOL_OPTIONS: '-Xmx256M' - IEXEC_SMS_BLOCKCHAIN_NODE_ADDRESS: http://bellecour-fork:8545 - IEXEC_HUB_ADDRESS: '0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f' - IEXEC_SMS_TEE_RUNTIME_FRAMEWORK: scone - IEXEC_SMS_IMAGE_LAS_IMAGE: 'las-image' - IEXEC_TEE_WORKER_PRE_COMPUTE_IMAGE: 'pre-compute-image' - IEXEC_TEE_WORKER_PRE_COMPUTE_FINGERPRINT: 'pre-compute-fingerprint' - IEXEC_TEE_WORKER_POST_COMPUTE_IMAGE: 'post-compute-image' - IEXEC_TEE_WORKER_POST_COMPUTE_FINGERPRINT: 'post-compute-fingerprint' - ports: - - 13302:13300 - healthcheck: - test: curl -f localhost:13300/actuator/health || exit 1 - depends_on: - bellecour-fork: - condition: service_healthy - - sms-tdx: - image: iexechub/iexec-sms:8.7.0 - restart: unless-stopped - environment: - JAVA_TOOL_OPTIONS: '-Xmx256M' - IEXEC_SMS_BLOCKCHAIN_NODE_ADDRESS: http://bellecour-fork:8545 - IEXEC_HUB_ADDRESS: '0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f' - IEXEC_SMS_TEE_RUNTIME_FRAMEWORK: scone - IEXEC_SMS_IMAGE_LAS_IMAGE: 'las-image' - IEXEC_TEE_WORKER_PRE_COMPUTE_IMAGE: 'pre-compute-image' - IEXEC_TEE_WORKER_PRE_COMPUTE_FINGERPRINT: 'pre-compute-fingerprint' - IEXEC_TEE_WORKER_POST_COMPUTE_IMAGE: 'post-compute-image' - IEXEC_TEE_WORKER_POST_COMPUTE_FINGERPRINT: 'post-compute-fingerprint' - ports: - - 13303:13300 - healthcheck: - test: curl -f localhost:13300/actuator/health || exit 1 - depends_on: - bellecour-fork: - condition: service_healthy - result-proxy: image: iexechub/iexec-result-proxy:7.1.0 restart: unless-stopped @@ -297,10 +255,6 @@ services: condition: service_healthy sms: condition: service_healthy - sms-gramine: - condition: service_healthy - sms-tdx: - condition: service_healthy market-watcher: condition: service_started market-api: diff --git a/test/jest-setup.js b/test/jest-setup.js index 6ed9dd09..7432c9bc 100644 --- a/test/jest-setup.js +++ b/test/jest-setup.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { jest, expect } from '@jest/globals'; import { getAddress } from 'ethers'; diff --git a/test/lib/e2e/IExecAccountModule.test.js b/test/lib/e2e/IExecAccountModule.test.js index da9d0aca..a4210f58 100644 --- a/test/lib/e2e/IExecAccountModule.test.js +++ b/test/lib/e2e/IExecAccountModule.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { BN } from 'bn.js'; import { ONE_ETH, ONE_RLC, getTestConfig } from '../lib-test-utils.js'; diff --git a/test/lib/e2e/IExecAppModule.test.js b/test/lib/e2e/IExecAppModule.test.js index 01a60356..109484d6 100644 --- a/test/lib/e2e/IExecAppModule.test.js +++ b/test/lib/e2e/IExecAppModule.test.js @@ -1,10 +1,7 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { BN } from 'bn.js'; import { TEST_CHAINS, - TEE_FRAMEWORKS, getId, getRandomAddress, SERVICE_UNREACHABLE_URL, @@ -302,74 +299,19 @@ describe('app', () => { ); }); - test('checks an app secret exist on SMS inferred from gramine app TEE framework', async () => { + test('checks an app secret exist on SMS', async () => { const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ readOnly: true, }); const { iexec } = getTestConfig(iexecTestChain)(); - const { address } = await deployRandomApp(iexec, { - teeFramework: TEE_FRAMEWORKS.GRAMINE, - }); - await expect( - readOnlyIExec.app.checkAppSecretExists(address), - ).resolves.toBe(false); - await iexec.app.pushAppSecret(address, 'foo'); - // infer teeFramework to use - await expect( - readOnlyIExec.app.checkAppSecretExists(address), - ).resolves.toBe(true); - // check inferred teeFramework with teeFramework option - await expect( - readOnlyIExec.app.checkAppSecretExists(address, { - teeFramework: TEE_FRAMEWORKS.GRAMINE, - }), - ).resolves.toBe(true); - }); - - test('checks an app secret exist on SMS inferred from tdx app TEE framework', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ - readOnly: true, - }); - const { iexec } = getTestConfig(iexecTestChain)(); - const { address } = await deployRandomApp(iexec, { - teeFramework: TEE_FRAMEWORKS.TDX, - }); + const { address } = await deployRandomApp(iexec); await expect( readOnlyIExec.app.checkAppSecretExists(address), ).resolves.toBe(false); await iexec.app.pushAppSecret(address, 'foo'); - // infer teeFramework to use await expect( readOnlyIExec.app.checkAppSecretExists(address), ).resolves.toBe(true); - // check inferred teeFramework with teeFramework option - await expect( - readOnlyIExec.app.checkAppSecretExists(address, { - teeFramework: TEE_FRAMEWORKS.TDX, - }), - ).resolves.toBe(true); - }); - - test('allows teeFramework override', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ - readOnly: true, - }); - const { iexec } = getTestConfig(iexecTestChain)(); - const { address } = await deployRandomApp(iexec, { - teeFramework: TEE_FRAMEWORKS.GRAMINE, - }); - await iexec.app.pushAppSecret(address, 'foo'); - await expect( - readOnlyIExec.app.checkAppSecretExists(address, { - teeFramework: TEE_FRAMEWORKS.SCONE, - }), - ).resolves.toBe(false); - // validate teeFramework - await expect( - readOnlyIExec.app.checkAppSecretExists(getRandomAddress(), { - teeFramework: 'foo', - }), - ).rejects.toThrow(Error('teeFramework is not a valid TEE framework')); }); }); @@ -419,9 +361,7 @@ describe('app', () => { const { iexec: iexecAppOwner } = getTestConfig(iexecTestChain)(); const { iexec: iexecRandom, wallet: randomWallet } = getTestConfig(iexecTestChain)(); - const { address: appAddress } = await deployRandomApp(iexecAppOwner, { - teeFramework: TEE_FRAMEWORKS.GRAMINE, - }); + const { address: appAddress } = await deployRandomApp(iexecAppOwner); // only owner can push secret await expect( iexecRandom.app.pushAppSecret(appAddress, 'foo'), @@ -432,53 +372,9 @@ describe('app', () => { ); }); - test('infers the SMS from gramine app TEE framework', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { address: appAddress } = await deployRandomApp(iexec, { - teeFramework: TEE_FRAMEWORKS.GRAMINE, - }); - // infer teeFramework to use - await expect(iexec.app.pushAppSecret(appAddress, 'foo')).resolves.toBe( - true, - ); - // check inferred teeFramework with teeFramework option - await expect( - iexec.app.pushAppSecret(appAddress, 'foo', { - teeFramework: TEE_FRAMEWORKS.GRAMINE, - }), - ).rejects.toThrow( - new Error( - `Secret already exists for ${appAddress} and can't be updated`, - ), - ); - }); - - test('infers the SMS from tdx app TEE framework', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { address: appAddress } = await deployRandomApp(iexec, { - teeFramework: TEE_FRAMEWORKS.TDX, - }); - // infer teeFramework to use - await expect(iexec.app.pushAppSecret(appAddress, 'foo')).resolves.toBe( - true, - ); - // check inferred teeFramework with teeFramework option - await expect( - iexec.app.pushAppSecret(appAddress, 'foo', { - teeFramework: TEE_FRAMEWORKS.TDX, - }), - ).rejects.toThrow( - new Error( - `Secret already exists for ${appAddress} and can't be updated`, - ), - ); - }); - test('cannot update existing secret', async () => { const { iexec: iexecAppOwner } = getTestConfig(iexecTestChain)(); - const { address: appAddress } = await deployRandomApp(iexecAppOwner, { - teeFramework: TEE_FRAMEWORKS.GRAMINE, - }); + const { address: appAddress } = await deployRandomApp(iexecAppOwner); await expect( iexecAppOwner.app.pushAppSecret(appAddress, 'foo'), @@ -492,36 +388,5 @@ describe('app', () => { ), ); }); - - test('allow teeFramework override', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { address: appAddress } = await deployRandomApp(iexec); - // infer teeFramework to use - await expect(iexec.app.pushAppSecret(appAddress, 'foo')).resolves.toBe( - true, - ); - await expect( - iexec.app.checkAppSecretExists(appAddress, { - teeFramework: TEE_FRAMEWORKS.GRAMINE, - }), - ).resolves.toBe(false); - await expect( - iexec.app.pushAppSecret(appAddress, 'foo', { - teeFramework: TEE_FRAMEWORKS.GRAMINE, - }), - ).resolves.toBe(true); - await expect( - iexec.app.checkAppSecretExists(appAddress, { - teeFramework: TEE_FRAMEWORKS.GRAMINE, - }), - ).resolves.toBe(true); - - // validate teeFramework - await expect( - iexec.app.pushAppSecret(appAddress, 'foo', { - teeFramework: 'foo', - }), - ).rejects.toThrow(Error('teeFramework is not a valid TEE framework')); - }); }); }); diff --git a/test/lib/e2e/IExecConfig.test.js b/test/lib/e2e/IExecConfig.test.js index 23029164..840ce21a 100644 --- a/test/lib/e2e/IExecConfig.test.js +++ b/test/lib/e2e/IExecConfig.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { JsonRpcProvider, @@ -18,7 +16,6 @@ import { INFURA_PROJECT_ID, InjectedProvider, TEST_CHAINS, - TEE_FRAMEWORKS, getRandomAddress, getRandomWallet, DEFAULT_PROVIDER_OPTIONS, @@ -58,29 +55,12 @@ describe('[IExecConfig]', () => { }); describe('throw Invalid option smsURL', () => { - test('IExecConfig({ ethProvider }, { smsURL: { foo: "https://foo.com" } })', () => { + test('IExecConfig({ ethProvider }, { smsURL: { } })', () => { const createConfig = () => - new IExecConfig( - { ethProvider: 'bellecour' }, - { smsURL: { foo: 'https://foo.com' } }, - ); - expect(createConfig).toThrow( - new Error('Invalid smsURL: this field has unspecified keys: foo'), - ); - expect(createConfig).toThrow(errors.ConfigurationError); - }); - }); - - describe('throw Invalid option defaultTeeFramework', () => { - test('IExecConfig({ ethProvider }, { defaultTeeFramework: "foo" })', () => { - const createConfig = () => - new IExecConfig( - { ethProvider: 'bellecour' }, - { defaultTeeFramework: 'foo' }, - ); + new IExecConfig({ ethProvider: 'bellecour' }, { smsURL: {} }); expect(createConfig).toThrow( new Error( - 'Invalid defaultTeeFramework: this is not a valid TEE framework', + 'Invalid smsURL: this must be a `string` type, but the final value was: `{}`.', ), ); expect(createConfig).toThrow(errors.ConfigurationError); @@ -130,6 +110,7 @@ describe('[IExecConfig]', () => { ); expect(createConfig).toThrow(errors.ConfigurationError); }); + // skipped because no experimental networks are currently defined describe.skip('allowExperimentalNetworks', () => { test('throw with experimental chains when allowExperimentalNetworks is not enabled', () => { const createConfig = () => @@ -242,6 +223,7 @@ describe('[IExecConfig]', () => { ); expect(createConfig).toThrow(errors.ConfigurationError); }); + // skipped because no experimental networks are currently defined describe.skip('allowExperimentalNetworks', () => { test('throw with experimental chains when allowExperimentalNetworks is not enabled', () => { const createConfig = () => new IExecConfig({ ethProvider: 421614 }); @@ -421,6 +403,7 @@ describe('[IExecConfig]', () => { network.getPlugin('org.ethers.plugins.network.Ens').address, ).toBe('0x5f5B93fca68c9C79318d1F3868A354EE67D8c006'); }); + // skipped because no experimental networks are currently defined describe.skip('allowExperimentalNetworks', () => { const experimentalNetworkRpcUrl = getChainDefaults(421614, { allowExperimentalNetworks: true, @@ -526,6 +509,7 @@ describe('[IExecConfig]', () => { network.getPlugin('org.ethers.plugins.network.Ens').address, ).toBe(iexecTestChain.defaults.ensRegistryAddress); }); + // skipped because no experimental networks are currently defined describe.skip('allowExperimentalNetworks', () => { const experimentalNetworkRpcUrl = getChainDefaults(421614, { allowExperimentalNetworks: true, @@ -881,74 +865,7 @@ describe('[IExecConfig]', () => { expect(typeof url).toBe('string'); expect(url.length > 0).toBe(true); }); - test('success default resolves to scone', async () => { - const defaultSms = await new IExecConfig({ - ethProvider: 'bellecour', - }).resolveSmsURL(); - const sconeSmsUrl = await new IExecConfig({ - ethProvider: 'bellecour', - }).resolveSmsURL({ teeFramework: TEE_FRAMEWORKS.SCONE }); - const gramineSmsUrl = await new IExecConfig({ - ethProvider: 'bellecour', - }).resolveSmsURL({ teeFramework: TEE_FRAMEWORKS.GRAMINE }); - expect(defaultSms).toBe(sconeSmsUrl); - expect(defaultSms).not.toBe(gramineSmsUrl); - }); - test('success override defaultTeeFramework', async () => { - const defaultSms = await new IExecConfig({ - ethProvider: 'bellecour', - }).resolveSmsURL(); - const defaultSmsTeeFrameworkOverride = await new IExecConfig( - { - ethProvider: 'bellecour', - }, - { defaultTeeFramework: TEE_FRAMEWORKS.GRAMINE }, - ).resolveSmsURL(); - const gramineSms = await new IExecConfig({ - ethProvider: 'bellecour', - }).resolveSmsURL({ teeFramework: TEE_FRAMEWORKS.GRAMINE }); - expect(defaultSmsTeeFrameworkOverride).toBe(gramineSms); - expect(defaultSmsTeeFrameworkOverride).not.toBe(defaultSms); - }); - test('success smsURL object override per teeFramework', async () => { - const smsMap = { - scone: 'http://foo.io', - gramine: 'http://bar.io', - }; - const config = new IExecConfig( - { - ethProvider: 'bellecour', - }, - { smsURL: smsMap }, - ); - await expect( - config.resolveSmsURL({ teeFramework: TEE_FRAMEWORKS.SCONE }), - ).resolves.toBe(smsMap.scone); - await expect( - config.resolveSmsURL({ teeFramework: TEE_FRAMEWORKS.GRAMINE }), - ).resolves.toBe(smsMap.gramine); - }); - test('success smsURL object override only one teeFramework', async () => { - const sconeDefaultSms = await new IExecConfig({ - ethProvider: 'bellecour', - }).resolveSmsURL({ teeFramework: TEE_FRAMEWORKS.SCONE }); - const smsMap = { - gramine: 'http://bar.io', - }; - const config = new IExecConfig( - { - ethProvider: 'bellecour', - }, - { smsURL: smsMap }, - ); - await expect( - config.resolveSmsURL({ teeFramework: TEE_FRAMEWORKS.SCONE }), - ).resolves.toBe(sconeDefaultSms); - await expect( - config.resolveSmsURL({ teeFramework: TEE_FRAMEWORKS.GRAMINE }), - ).resolves.toBe(smsMap.gramine); - }); - test('success smsURL string override all teeFramework', async () => { + test('success smsURL override default URL', async () => { const smsOverride = 'http://sms-override.iex.ec'; const config = new IExecConfig( { @@ -957,14 +874,9 @@ describe('[IExecConfig]', () => { { smsURL: smsOverride }, ); await expect(config.resolveSmsURL()).resolves.toBe(smsOverride); - await expect( - config.resolveSmsURL({ teeFramework: TEE_FRAMEWORKS.SCONE }), - ).resolves.toBe(smsOverride); - await expect( - config.resolveSmsURL({ teeFramework: TEE_FRAMEWORKS.GRAMINE }), - ).resolves.toBe(smsOverride); + await expect(config.resolveSmsURL()).resolves.toBe(smsOverride); }); - test('success with smsURL string on custom chain', async () => { + test('success smsURL sets the URL on custom chain', async () => { const smsOverride = 'http://sms-override.iex.ec'; const config = new IExecConfig( { @@ -995,16 +907,6 @@ describe('[IExecConfig]', () => { await expect(promise).rejects.toThrow('Failed to detect network:'); await expect(promise).rejects.toThrow(Error); }); - test('throw with invalid TEE framework', async () => { - const config = new IExecConfig({ - ethProvider: iexecTestChain.rpcURL, - }); - const promise = config.resolveSmsURL({ teeFramework: 'foo' }); - await expect(promise).rejects.toThrow( - new Error(`teeFramework is not a valid TEE framework`), - ); - await expect(promise).rejects.toThrow(errors.ValidationError); - }); }); describe('resolveResultProxyURL()', () => { diff --git a/test/lib/e2e/IExecDatasetModule.test.js b/test/lib/e2e/IExecDatasetModule.test.js index 7dfd8a30..de9ad10d 100644 --- a/test/lib/e2e/IExecDatasetModule.test.js +++ b/test/lib/e2e/IExecDatasetModule.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { join } from 'path'; import { BN } from 'bn.js'; @@ -11,7 +9,6 @@ import { } from '../lib-test-utils.js'; import { TEST_CHAINS, - TEE_FRAMEWORKS, execAsync, getId, getRandomAddress, @@ -366,7 +363,7 @@ describe('dataset', () => { ); }); - test('checks a dataset secret exist on default TEE framework SMS', async () => { + test('checks a dataset secret exist in the SMS', async () => { const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ readOnly: true, }); @@ -379,38 +376,6 @@ describe('dataset', () => { await expect( readOnlyIExec.dataset.checkDatasetSecretExists(address), ).resolves.toBe(true); - await expect( - readOnlyIExec.dataset.checkDatasetSecretExists(address, { - teeFramework: TEE_FRAMEWORKS.SCONE, - }), - ).resolves.toBe(true); - }); - - test('allows teeFramework override', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ - readOnly: true, - }); - const { iexec } = getTestConfig(iexecTestChain)(); - const { address } = await deployRandomDataset(iexec); - await iexec.dataset.pushDatasetSecret(address, 'foo', { - teeFramework: TEE_FRAMEWORKS.GRAMINE, - }); - await expect( - readOnlyIExec.dataset.checkDatasetSecretExists(address, { - teeFramework: TEE_FRAMEWORKS.GRAMINE, - }), - ).resolves.toBe(true); - await expect( - readOnlyIExec.dataset.checkDatasetSecretExists(address, { - teeFramework: TEE_FRAMEWORKS.SCONE, - }), - ).resolves.toBe(false); - // validate teeFramework - await expect( - readOnlyIExec.dataset.checkDatasetSecretExists(getRandomAddress(), { - teeFramework: 'foo', - }), - ).rejects.toThrow(Error('teeFramework is not a valid TEE framework')); }); }); @@ -472,23 +437,18 @@ describe('dataset', () => { ); }); - test('use the default TEE framework SMS', async () => { + test('pushes secret to SMS', async () => { const { iexec } = getTestConfig(iexecTestChain)(); - const { address: datasetAddress } = await deployRandomDataset(iexec, { - teeFramework: TEE_FRAMEWORKS.GRAMINE, - }); + const { address: datasetAddress } = await deployRandomDataset(iexec); + await expect( + iexec.dataset.checkDatasetSecretExists(datasetAddress), + ).resolves.toBe(false); await expect( iexec.dataset.pushDatasetSecret(datasetAddress, 'foo'), ).resolves.toBe(true); await expect( - iexec.dataset.pushDatasetSecret(datasetAddress, 'foo', { - teeFramework: TEE_FRAMEWORKS.SCONE, - }), - ).rejects.toThrow( - new Error( - `Secret already exists for ${datasetAddress} and can't be updated`, - ), - ); + iexec.dataset.checkDatasetSecretExists(datasetAddress), + ).resolves.toBe(true); }); test('cannot update existing secret', async () => { @@ -508,35 +468,5 @@ describe('dataset', () => { ), ); }); - - test('allow teeFramework override', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { address: datasetAddress } = await deployRandomDataset(iexec); - await expect( - iexec.dataset.pushDatasetSecret(datasetAddress, 'foo'), - ).resolves.toBe(true); - await expect( - iexec.dataset.checkDatasetSecretExists(datasetAddress, { - teeFramework: TEE_FRAMEWORKS.GRAMINE, - }), - ).resolves.toBe(false); - await expect( - iexec.dataset.pushDatasetSecret(datasetAddress, 'foo', { - teeFramework: TEE_FRAMEWORKS.GRAMINE, - }), - ).resolves.toBe(true); - await expect( - iexec.dataset.checkDatasetSecretExists(datasetAddress, { - teeFramework: TEE_FRAMEWORKS.GRAMINE, - }), - ).resolves.toBe(true); - - // validate teeFramework - await expect( - iexec.dataset.pushDatasetSecret(datasetAddress, 'foo', { - teeFramework: 'foo', - }), - ).rejects.toThrow(Error('teeFramework is not a valid TEE framework')); - }); }); }); diff --git a/test/lib/e2e/IExecDealModule.test.js b/test/lib/e2e/IExecDealModule.test.js index acba1c6b..d0609660 100644 --- a/test/lib/e2e/IExecDealModule.test.js +++ b/test/lib/e2e/IExecDealModule.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { deployAndGetApporder, diff --git a/test/lib/e2e/IExecEnsModule.test.js b/test/lib/e2e/IExecEnsModule.test.js index 6f3dbd45..db5b4e99 100644 --- a/test/lib/e2e/IExecEnsModule.test.js +++ b/test/lib/e2e/IExecEnsModule.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { BN } from 'bn.js'; import { diff --git a/test/lib/e2e/IExecHubModule.test.js b/test/lib/e2e/IExecHubModule.test.js index f63536ad..ca022826 100644 --- a/test/lib/e2e/IExecHubModule.test.js +++ b/test/lib/e2e/IExecHubModule.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { BN } from 'bn.js'; import { getTestConfig } from '../lib-test-utils.js'; diff --git a/test/lib/e2e/IExecOrderModule.test.js b/test/lib/e2e/IExecOrderModule.test.js index 6b294a1f..4943cd0c 100644 --- a/test/lib/e2e/IExecOrderModule.test.js +++ b/test/lib/e2e/IExecOrderModule.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect, beforeAll } from '@jest/globals'; import { BN } from 'bn.js'; import { @@ -77,799 +75,761 @@ describe('order', () => { }); }); - describe('createApporder()', () => { - test('creates a default apporder template', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const app = getRandomAddress(); - const order = await iexec.order.createApporder({ - app, - }); - expect(order).toEqual({ - app, - appprice: '0', - datasetrestrict: '0x0000000000000000000000000000000000000000', - requesterrestrict: '0x0000000000000000000000000000000000000000', - tag: '0x0000000000000000000000000000000000000000000000000000000000000000', - volume: '1', - workerpoolrestrict: '0x0000000000000000000000000000000000000000', - }); - }); - - test('override defaults', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const app = getRandomAddress(); - const datasetrestrict = getRandomAddress(); - const workerpoolrestrict = getRandomAddress(); - const requesterrestrict = getRandomAddress(); - const order = await iexec.order.createApporder({ - app, - appprice: '1 RLC', - datasetrestrict, - workerpoolrestrict, - requesterrestrict, - tag: ['tee', 'scone'], - volume: 100, - }); - expect(order).toEqual({ - app, - appprice: '1000000000', - datasetrestrict, - requesterrestrict, - tag: '0x0000000000000000000000000000000000000000000000000000000000000003', - volume: '100', - workerpoolrestrict, + describe('create...order()', () => { + describe('createApporder()', () => { + test('creates a default apporder template', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const app = getRandomAddress(); + const order = await iexec.order.createApporder({ + app, + }); + expect(order).toEqual({ + app, + appprice: '0', + datasetrestrict: '0x0000000000000000000000000000000000000000', + requesterrestrict: '0x0000000000000000000000000000000000000000', + tag: '0x0000000000000000000000000000000000000000000000000000000000000000', + volume: '1', + workerpoolrestrict: '0x0000000000000000000000000000000000000000', + }); }); - }); - }); - describe('createDatasetorder()', () => { - test('creates a default datasetorder template', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const dataset = getRandomAddress(); - const order = await iexec.order.createDatasetorder({ - dataset, - }); - expect(order).toEqual({ - apprestrict: '0x0000000000000000000000000000000000000000', - dataset, - datasetprice: '0', - requesterrestrict: '0x0000000000000000000000000000000000000000', - tag: '0x0000000000000000000000000000000000000000000000000000000000000000', - volume: '1', - workerpoolrestrict: '0x0000000000000000000000000000000000000000', + test('override defaults', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const app = getRandomAddress(); + const datasetrestrict = getRandomAddress(); + const workerpoolrestrict = getRandomAddress(); + const requesterrestrict = getRandomAddress(); + const order = await iexec.order.createApporder({ + app, + appprice: '1 RLC', + datasetrestrict, + workerpoolrestrict, + requesterrestrict, + tag: ['tee', 'scone'], + volume: 100, + }); + expect(order).toEqual({ + app, + appprice: '1000000000', + datasetrestrict, + requesterrestrict, + tag: '0x0000000000000000000000000000000000000000000000000000000000000003', + volume: '100', + workerpoolrestrict, + }); }); }); - test('override defaults', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const dataset = getRandomAddress(); - const apprestrict = getRandomAddress(); - const workerpoolrestrict = getRandomAddress(); - const requesterrestrict = getRandomAddress(); - const order = await iexec.order.createDatasetorder({ - dataset, - datasetprice: '1 RLC', - apprestrict, - workerpoolrestrict, - requesterrestrict, - tag: ['tee'], - volume: 100, - }); - expect(order).toEqual({ - dataset, - datasetprice: '1000000000', - apprestrict, - requesterrestrict, - tag: '0x0000000000000000000000000000000000000000000000000000000000000001', - volume: '100', - workerpoolrestrict, + describe('createDatasetorder()', () => { + test('creates a default datasetorder template', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const dataset = getRandomAddress(); + const order = await iexec.order.createDatasetorder({ + dataset, + }); + expect(order).toEqual({ + apprestrict: '0x0000000000000000000000000000000000000000', + dataset, + datasetprice: '0', + requesterrestrict: '0x0000000000000000000000000000000000000000', + tag: '0x0000000000000000000000000000000000000000000000000000000000000000', + volume: '1', + workerpoolrestrict: '0x0000000000000000000000000000000000000000', + }); }); - }); - }); - describe('createWorkerpoolorder()', () => { - test('creates a default workerpoolorder template', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const workerpool = getRandomAddress(); - const order = await iexec.order.createWorkerpoolorder({ - workerpool, - category: 5, - }); - expect(order).toEqual({ - apprestrict: '0x0000000000000000000000000000000000000000', - category: '5', - datasetrestrict: '0x0000000000000000000000000000000000000000', - requesterrestrict: '0x0000000000000000000000000000000000000000', - tag: '0x0000000000000000000000000000000000000000000000000000000000000000', - trust: '0', - volume: '1', - workerpool, - workerpoolprice: '0', + test('override defaults', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const dataset = getRandomAddress(); + const apprestrict = getRandomAddress(); + const workerpoolrestrict = getRandomAddress(); + const requesterrestrict = getRandomAddress(); + const order = await iexec.order.createDatasetorder({ + dataset, + datasetprice: '1 RLC', + apprestrict, + workerpoolrestrict, + requesterrestrict, + tag: ['tee'], + volume: 100, + }); + expect(order).toEqual({ + dataset, + datasetprice: '1000000000', + apprestrict, + requesterrestrict, + tag: '0x0000000000000000000000000000000000000000000000000000000000000001', + volume: '100', + workerpoolrestrict, + }); }); }); - test('override defaults', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const workerpool = getRandomAddress(); - const apprestrict = getRandomAddress(); - const datasetrestrict = getRandomAddress(); - const requesterrestrict = getRandomAddress(); - const order = await iexec.order.createWorkerpoolorder({ - workerpool, - workerpoolprice: '0.1 RLC', - category: 5, - apprestrict, - datasetrestrict, - requesterrestrict, - tag: ['tee', 'scone'], - trust: '10', - volume: '100', - }); - expect(order).toEqual({ - apprestrict, - category: '5', - datasetrestrict, - requesterrestrict, - tag: '0x0000000000000000000000000000000000000000000000000000000000000003', - trust: '10', - volume: '100', - workerpool, - workerpoolprice: '100000000', + describe('createWorkerpoolorder()', () => { + test('creates a default workerpoolorder template', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const workerpool = getRandomAddress(); + const order = await iexec.order.createWorkerpoolorder({ + workerpool, + category: 5, + }); + expect(order).toEqual({ + apprestrict: '0x0000000000000000000000000000000000000000', + category: '5', + datasetrestrict: '0x0000000000000000000000000000000000000000', + requesterrestrict: '0x0000000000000000000000000000000000000000', + tag: '0x0000000000000000000000000000000000000000000000000000000000000000', + trust: '0', + volume: '1', + workerpool, + workerpoolprice: '0', + }); }); - }); - }); - describe('createRequestorder()', () => { - test('creates a default requestorder template', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - const app = getRandomAddress(); - const order = await iexec.order.createRequestorder({ - app, - category: 5, - }); - expect(order).toEqual({ - app, - appmaxprice: '0', - beneficiary: wallet.address, - callback: '0x0000000000000000000000000000000000000000', - category: '5', - dataset: '0x0000000000000000000000000000000000000000', - datasetmaxprice: '0', - params: { - iexec_result_storage_provider: 'ipfs', - }, - requester: wallet.address, - tag: '0x0000000000000000000000000000000000000000000000000000000000000000', - trust: '0', - volume: '1', - workerpool: '0x0000000000000000000000000000000000000000', - workerpoolmaxprice: '0', + test('override defaults', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const workerpool = getRandomAddress(); + const apprestrict = getRandomAddress(); + const datasetrestrict = getRandomAddress(); + const requesterrestrict = getRandomAddress(); + const order = await iexec.order.createWorkerpoolorder({ + workerpool, + workerpoolprice: '0.1 RLC', + category: 5, + apprestrict, + datasetrestrict, + requesterrestrict, + tag: ['tee', 'scone'], + trust: '10', + volume: '100', + }); + expect(order).toEqual({ + apprestrict, + category: '5', + datasetrestrict, + requesterrestrict, + tag: '0x0000000000000000000000000000000000000000000000000000000000000003', + trust: '10', + volume: '100', + workerpool, + workerpoolprice: '100000000', + }); }); }); - test('override defaults', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - const app = getRandomAddress(); - const dataset = getRandomAddress(); - const workerpool = getRandomAddress(); - const callback = getRandomAddress(); - const order = await iexec.order.createRequestorder({ - app, - category: 5, - dataset, - workerpool, - callback, - appmaxprice: '1 nRLC', - datasetmaxprice: '100 nRLC', - workerpoolmaxprice: '0.1 RLC', - params: { - iexec_result_storage_provider: 'dropbox', - iexec_result_encryption: true, - iexec_result_storage_proxy: 'https://custom-result-proxy.iex.ec', - }, - tag: ['tee', 'scone'], - trust: '100', - volume: '5', - }); - expect(order).toEqual({ - app, - appmaxprice: '1', - beneficiary: wallet.address, - callback, - category: '5', - dataset, - datasetmaxprice: '100', - params: { - iexec_result_storage_provider: 'dropbox', - iexec_result_encryption: true, - iexec_result_storage_proxy: 'https://custom-result-proxy.iex.ec', - }, - requester: wallet.address, - tag: '0x0000000000000000000000000000000000000000000000000000000000000003', - trust: '100', - volume: '5', - workerpool, - workerpoolmaxprice: '100000000', + describe('createRequestorder()', () => { + test('creates a default requestorder template', async () => { + const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const app = getRandomAddress(); + const order = await iexec.order.createRequestorder({ + app, + category: 5, + }); + expect(order).toEqual({ + app, + appmaxprice: '0', + beneficiary: wallet.address, + callback: '0x0000000000000000000000000000000000000000', + category: '5', + dataset: '0x0000000000000000000000000000000000000000', + datasetmaxprice: '0', + params: { + iexec_result_storage_provider: 'ipfs', + }, + requester: wallet.address, + tag: '0x0000000000000000000000000000000000000000000000000000000000000000', + trust: '0', + volume: '1', + workerpool: '0x0000000000000000000000000000000000000000', + workerpoolmaxprice: '0', + }); }); - }); - test('with iexec_secrets', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - const app = getRandomAddress(); - const order = await iexec.order.createRequestorder({ - app, - category: 5, - params: { - iexec_secrets: { - 1: 'foo', + test('override defaults', async () => { + const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const app = getRandomAddress(); + const dataset = getRandomAddress(); + const workerpool = getRandomAddress(); + const callback = getRandomAddress(); + const order = await iexec.order.createRequestorder({ + app, + category: 5, + dataset, + workerpool, + callback, + appmaxprice: '1 nRLC', + datasetmaxprice: '100 nRLC', + workerpoolmaxprice: '0.1 RLC', + params: { + iexec_result_storage_provider: 'dropbox', + iexec_result_encryption: true, + iexec_result_storage_proxy: 'https://custom-result-proxy.iex.ec', }, - }, - tag: ['tee', 'scone'], - }); - expect(order).toEqual({ - app, - appmaxprice: '0', - beneficiary: wallet.address, - callback: '0x0000000000000000000000000000000000000000', - category: '5', - dataset: '0x0000000000000000000000000000000000000000', - datasetmaxprice: '0', - params: { - iexec_secrets: { - 1: 'foo', + tag: ['tee', 'scone'], + trust: '100', + volume: '5', + }); + expect(order).toEqual({ + app, + appmaxprice: '1', + beneficiary: wallet.address, + callback, + category: '5', + dataset, + datasetmaxprice: '100', + params: { + iexec_result_storage_provider: 'dropbox', + iexec_result_encryption: true, + iexec_result_storage_proxy: 'https://custom-result-proxy.iex.ec', }, - iexec_result_storage_provider: 'ipfs', - }, - requester: wallet.address, - tag: '0x0000000000000000000000000000000000000000000000000000000000000003', - trust: '0', - volume: '1', - workerpool: '0x0000000000000000000000000000000000000000', - workerpoolmaxprice: '0', + requester: wallet.address, + tag: '0x0000000000000000000000000000000000000000000000000000000000000003', + trust: '100', + volume: '5', + workerpool, + workerpoolmaxprice: '100000000', + }); }); }); }); - describe('signApporder()', () => { - test('signs the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { address } = await deployRandomApp(iexec); - const order = await iexec.order.createApporder({ - app: address, - }); + describe('sign...order()', () => { + describe('signApporder()', () => { + test('signs the order', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const { address } = await deployRandomApp(iexec); + const order = await iexec.order.createApporder({ + app: address, + }); - const res = await iexec.order.signApporder(order); - expect(res.salt).toBeTxHash(); - expect(res.sign).toMatch(signRegex); - expect(res).toEqual({ - ...order, - ...{ sign: res.sign, salt: res.salt }, + const res = await iexec.order.signApporder(order); + expect(res.salt).toBeTxHash(); + expect(res.sign).toMatch(signRegex); + expect(res).toEqual({ + ...order, + ...{ sign: res.sign, salt: res.salt }, + }); }); - }); - test('preflightCheck TEE framework', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { address } = await deployRandomApp(iexec, { - teeFramework: TEE_FRAMEWORKS.GRAMINE, - }); - const order = await iexec.order.createApporder({ - app: address, - }); - await expect(iexec.order.signApporder(order)).rejects.toThrow( - new Error('Tag mismatch the TEE framework specified by app'), - ); - await expect( - iexec.order.signApporder({ ...order, tag: ['tee', 'scone'] }), - ).rejects.toThrow( - new Error('Tag mismatch the TEE framework specified by app'), - ); - await expect( - iexec.order.signApporder({ ...order, tag: ['tee', 'gramine'] }), - ).resolves.toBeDefined(); - }); + test('preflightCheck TEE framework', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const { address: sconeAppAddress } = await deployRandomApp(iexec, { + teeFramework: TEE_FRAMEWORKS.SCONE, + }); - test('preflightCheck fails with invalid tag', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const order = await iexec.order.createApporder({ - app: getRandomAddress(), - }); - await expect( - iexec.order.signApporder({ ...order, tag: ['tee'] }), - ).rejects.toThrow( - new Error( - "'tee' tag must be used with a tee framework ('scone'|'gramine'|'tdx')", - ), - ); - await expect( - iexec.order.signApporder({ ...order, tag: ['scone'] }), - ).rejects.toThrow(Error("'scone' tag must be used with 'tee' tag")); - await expect( - iexec.order.signApporder({ ...order, tag: ['gramine'] }), - ).rejects.toThrow(Error("'gramine' tag must be used with 'tee' tag")); - await expect( - iexec.order.signApporder({ - ...order, - tag: ['tee', 'scone', 'gramine'], - }), - ).rejects.toThrow( - new Error("tee framework tags are exclusive ('scone'|'gramine'|'tdx')"), - ); - }); - }); + const sconeAppOrder = await iexec.order.createApporder({ + app: sconeAppAddress, + }); + await expect(iexec.order.signApporder(sconeAppOrder)).rejects.toThrow( + new Error('Tag mismatch the TEE framework specified by app'), + ); + await expect( + iexec.order.signApporder({ ...sconeAppOrder, tag: ['tee', 'scone'] }), + ).resolves.toBeDefined(); - describe('signDatasetorder()', () => { - test('signs the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { address } = await deployRandomDataset(iexec); - const order = await iexec.order.createDatasetorder({ - dataset: address, + const { address: tdxAppAddress } = await deployRandomApp(iexec, { + teeFramework: TEE_FRAMEWORKS.TDX, + }); + const tdxAppOrder = await iexec.order.createApporder({ + app: tdxAppAddress, + }); + await expect( + iexec.order.signApporder({ ...tdxAppOrder, tag: ['tee', 'scone'] }), + ).rejects.toThrow( + new Error('Tag mismatch the TEE framework specified by app'), + ); + await expect( + iexec.order.signApporder({ ...tdxAppOrder, tag: ['tee', 'tdx'] }), + ).resolves.toBeDefined(); }); - const res = await iexec.order.signDatasetorder(order, { - preflightCheck: false, - }); - expect(res.salt).toBeTxHash(); - expect(res.sign).toMatch(signRegex); - expect(res).toEqual({ - ...order, - ...{ sign: res.sign, salt: res.salt }, + test('preflightCheck fails with invalid tag', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const order = await iexec.order.createApporder({ + app: getRandomAddress(), + }); + await expect( + iexec.order.signApporder({ ...order, tag: ['tee'] }), + ).rejects.toThrow( + new Error( + "'tee' tag must be used with a tee framework ('scone'|'tdx')", + ), + ); + await expect( + iexec.order.signApporder({ ...order, tag: ['scone'] }), + ).rejects.toThrow(Error("'scone' tag must be used with 'tee' tag")); + await expect( + iexec.order.signApporder({ ...order, tag: ['tdx'] }), + ).rejects.toThrow(Error("'tdx' tag must be used with 'tee' tag")); + await expect( + iexec.order.signApporder({ + ...order, + tag: ['tee', 'scone', 'tdx'], + }), + ).rejects.toThrow( + new Error("tee framework tags are exclusive ('scone'|'tdx')"), + ); }); }); - test('preflightCheck dataset secret', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { address } = await deployRandomDataset(iexec); - const order = await iexec.order.createDatasetorder({ - dataset: address, - }); - await expect( - iexec.order.signDatasetorder({ ...order, tag: ['tee'] }), - ).rejects.toThrow( - new Error( - `Dataset encryption key is not set for dataset ${address} in the SMS. Dataset decryption will fail.`, - ), - ); - await expect( - iexec.order.signDatasetorder({ ...order, tag: ['tee', 'scone'] }), - ).rejects.toThrow( - new Error( - `Dataset encryption key is not set for dataset ${address} in the SMS. Dataset decryption will fail.`, - ), - ); - - // default SMS push (scone) - await iexec.dataset.pushDatasetSecret( - address, - iexec.dataset.generateEncryptionKey(), - ); - await iexec.dataset.pushDatasetSecret( - address, - iexec.dataset.generateEncryptionKey(), - { teeFramework: TEE_FRAMEWORKS.TDX }, - ); - - await expect( - iexec.order.signDatasetorder({ ...order, tag: ['tee'] }), - ).resolves.toBeDefined(); - await expect( - iexec.order.signDatasetorder({ ...order, tag: ['tee', 'scone'] }), - ).resolves.toBeDefined(); - await expect( - iexec.order.signDatasetorder({ ...order, tag: ['tee', 'tdx'] }), - ).resolves.toBeDefined(); - await expect( - iexec.order.signDatasetorder({ ...order, tag: ['tee', 'gramine'] }), - ).rejects.toThrow( - new Error( - `Dataset encryption key is not set for dataset ${address} in the SMS. Dataset decryption will fail.`, - ), - ); - }); + describe('signDatasetorder()', () => { + test('signs the order', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const { address } = await deployRandomDataset(iexec); + const order = await iexec.order.createDatasetorder({ + dataset: address, + }); - test('preflightCheck fails with invalid tag', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const order = await iexec.order.createDatasetorder({ - dataset: getRandomAddress(), - }); - await expect( - iexec.order.signDatasetorder({ ...order, tag: ['scone'] }), - ).rejects.toThrow(Error("'scone' tag must be used with 'tee' tag")); - await expect( - iexec.order.signDatasetorder({ ...order, tag: ['gramine'] }), - ).rejects.toThrow(Error("'gramine' tag must be used with 'tee' tag")); - await expect( - iexec.order.signDatasetorder({ + const res = await iexec.order.signDatasetorder(order, { + preflightCheck: false, + }); + expect(res.salt).toBeTxHash(); + expect(res.sign).toMatch(signRegex); + expect(res).toEqual({ ...order, - tag: ['tee', 'scone', 'gramine'], - }), - ).rejects.toThrow( - new Error("tee framework tags are exclusive ('scone'|'gramine'|'tdx')"), - ); - }); - }); + ...{ sign: res.sign, salt: res.salt }, + }); + }); - describe('signWorkerpoolorder()', () => { - test('signs the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { address } = await deployRandomWorkerpool(iexec); - const order = await iexec.order.createWorkerpoolorder({ - workerpool: address, - category: 5, + test('preflightCheck dataset secret', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const { address } = await deployRandomDataset(iexec); + const order = await iexec.order.createDatasetorder({ + dataset: address, + }); + await expect( + iexec.order.signDatasetorder({ ...order, tag: ['tee'] }), + ).rejects.toThrow( + new Error( + `Dataset encryption key is not set for dataset ${address} in the SMS. Dataset decryption will fail.`, + ), + ); + await iexec.dataset.pushDatasetSecret( + address, + iexec.dataset.generateEncryptionKey(), + ); + await expect( + iexec.order.signDatasetorder({ ...order, tag: ['tee'] }), + ).resolves.toBeDefined(); }); - const res = await iexec.order.signWorkerpoolorder(order); - expect(res.salt).toBeTxHash(); - expect(res.sign).toMatch(signRegex); - expect(res).toEqual({ - ...order, - ...{ sign: res.sign, salt: res.salt }, + test('preflightCheck fails with invalid tag', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const order = await iexec.order.createDatasetorder({ + dataset: getRandomAddress(), + }); + await expect( + iexec.order.signDatasetorder({ ...order, tag: ['scone'] }), + ).rejects.toThrow(Error("'scone' tag must be used with 'tee' tag")); }); }); - }); - describe('signRequestorder()', () => { - test('signs the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const order = await iexec.order.createRequestorder({ - app: getRandomAddress(), - category: 5, - }); + describe('signWorkerpoolorder()', () => { + test('signs the order', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const { address } = await deployRandomWorkerpool(iexec); + const order = await iexec.order.createWorkerpoolorder({ + workerpool: address, + category: 5, + }); - const res = await iexec.order.signRequestorder(order, { - preflightCheck: false, - }); - expect(res.salt).toBeTxHash(); - expect(res.sign).toMatch(signRegex); - expect(res).toEqual({ - ...order, - ...{ params: JSON.stringify(order.params) }, - ...{ sign: res.sign, salt: res.salt }, + const res = await iexec.order.signWorkerpoolorder(order); + expect(res.salt).toBeTxHash(); + expect(res.sign).toMatch(signRegex); + expect(res).toEqual({ + ...order, + ...{ sign: res.sign, salt: res.salt }, + }); }); }); - test('preflightCheck fails with invalid tag', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const order = await iexec.order.createRequestorder({ - app: getRandomAddress(), - category: 5, - }); - await expect( - iexec.order.signRequestorder({ ...order, tag: ['scone'] }), - ).rejects.toThrow(Error("'scone' tag must be used with 'tee' tag")); - await expect( - iexec.order.signRequestorder({ ...order, tag: ['gramine'] }), - ).rejects.toThrow(Error("'gramine' tag must be used with 'tee' tag")); - await expect( - iexec.order.signRequestorder({ + describe('signRequestorder()', () => { + test('signs the order', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const order = await iexec.order.createRequestorder({ + app: getRandomAddress(), + category: 5, + }); + + const res = await iexec.order.signRequestorder(order, { + preflightCheck: false, + }); + expect(res.salt).toBeTxHash(); + expect(res.sign).toMatch(signRegex); + expect(res).toEqual({ ...order, - tag: ['tee', 'scone', 'gramine'], - }), - ).rejects.toThrow( - new Error("tee framework tags are exclusive ('scone'|'gramine'|'tdx')"), - ); - }); + ...{ params: JSON.stringify(order.params) }, + ...{ sign: res.sign, salt: res.salt }, + }); + }); - test('preflightCheck dropbox storage token exists', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const order = await iexec.order.createRequestorder({ - app: getRandomAddress(), - category: 5, - tag: ['tee', 'scone'], - params: { - iexec_result_storage_provider: 'dropbox', - }, + test('preflightCheck fails with invalid tag', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const order = await iexec.order.createRequestorder({ + app: getRandomAddress(), + category: 5, + }); + await expect( + iexec.order.signRequestorder({ ...order, tag: ['scone'] }), + ).rejects.toThrow(Error("'scone' tag must be used with 'tee' tag")); + await expect( + iexec.order.signRequestorder({ ...order, tag: ['scone'] }), + ).rejects.toThrow(Error("'scone' tag must be used with 'tee' tag")); + await expect( + iexec.order.signRequestorder({ ...order, tag: ['tdx'] }), + ).rejects.toThrow(Error("'tdx' tag must be used with 'tee' tag")); + await expect( + iexec.order.signRequestorder({ + ...order, + tag: ['tee', 'scone', 'tdx'], + }), + ).rejects.toThrow( + new Error("tee framework tags are exclusive ('scone'|'tdx')"), + ); }); - await expect(iexec.order.signRequestorder(order)).rejects.toThrow( - new Error( - 'Requester storage token is not set for selected provider "dropbox". Result archive upload will fail.', - ), - ); + test('preflightCheck dropbox storage token exists', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const order = await iexec.order.createRequestorder({ + app: getRandomAddress(), + category: 5, + tag: ['tee', 'scone'], + params: { + iexec_result_storage_provider: 'dropbox', + }, + }); - await iexec.storage.pushStorageToken('oops', { provider: 'dropbox' }); - const res = await iexec.order.signRequestorder(order); - expect(res.salt).toBeTxHash(); - expect(res.sign).toMatch(signRegex); - expect(res).toEqual({ - ...order, - ...{ params: JSON.stringify(order.params) }, - ...{ sign: res.sign, salt: res.salt }, - }); - }); + await expect(iexec.order.signRequestorder(order)).rejects.toThrow( + new Error( + 'Requester storage token is not set for selected provider "dropbox". Result archive upload will fail.', + ), + ); - test('preflightCheck result encryption exists', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const order = await iexec.order.createRequestorder({ - app: getRandomAddress(), - category: 5, - params: { iexec_result_encryption: true }, - }); - await iexec.storage - .defaultStorageLogin() - .then(iexec.storage.pushStorageToken); - await expect(iexec.order.signRequestorder(order)).rejects.toThrow( - new Error( - 'Beneficiary result encryption key is not set in the SMS. Result encryption will fail.', - ), - ); - await iexec.result.pushResultEncryptionKey('oops'); - const res = await iexec.order.signRequestorder(order); - expect(res.salt).toBeTxHash(); - expect(res.sign).toMatch(signRegex); - expect(res).toEqual({ - ...order, - ...{ params: JSON.stringify(order.params) }, - ...{ sign: res.sign, salt: res.salt }, + await iexec.storage.pushStorageToken('oops', { provider: 'dropbox' }); + const res = await iexec.order.signRequestorder(order); + expect(res.salt).toBeTxHash(); + expect(res.sign).toMatch(signRegex); + expect(res).toEqual({ + ...order, + ...{ params: JSON.stringify(order.params) }, + ...{ sign: res.sign, salt: res.salt }, + }); }); - }); - - test('preflightCheck checks dataset encryption key exists for tee datasets', async () => { - const { iexec: iexecDatasetProvider } = getTestConfig(iexecTestChain)(); - const { iexec: iexecDatasetConsumer } = getTestConfig(iexecTestChain)(); - await iexecDatasetConsumer.storage - .defaultStorageLogin() - .then(iexecDatasetConsumer.storage.pushStorageToken); - const { address: dataset } = - await deployRandomDataset(iexecDatasetProvider); + test('preflightCheck result encryption exists', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const order = await iexec.order.createRequestorder({ + app: getRandomAddress(), + category: 5, + params: { iexec_result_encryption: true }, + }); + await iexec.storage + .defaultStorageLogin() + .then(iexec.storage.pushStorageToken); + await expect(iexec.order.signRequestorder(order)).rejects.toThrow( + new Error( + 'Beneficiary result encryption key is not set in the SMS. Result encryption will fail.', + ), + ); + await iexec.result.pushResultEncryptionKey('oops'); + const res = await iexec.order.signRequestorder(order); + expect(res.salt).toBeTxHash(); + expect(res.sign).toMatch(signRegex); + expect(res).toEqual({ + ...order, + ...{ params: JSON.stringify(order.params) }, + ...{ sign: res.sign, salt: res.salt }, + }); + }); - // non tee pass - await expect( - iexecDatasetConsumer.order - .createRequestorder({ - app: getRandomAddress(), - category: 5, - dataset, - }) - .then(iexecDatasetConsumer.order.signRequestorder), - ).resolves.toBeDefined(); + test('preflightCheck checks dataset encryption key exists for tee datasets', async () => { + const { iexec: iexecDatasetProvider } = getTestConfig(iexecTestChain)(); + const { iexec: iexecDatasetConsumer } = getTestConfig(iexecTestChain)(); - // tee fail without secret - await expect( - iexecDatasetConsumer.order - .createRequestorder({ - app: getRandomAddress(), - category: 5, - dataset, - tag: ['tee', 'scone'], - }) - .then(iexecDatasetConsumer.order.signRequestorder), - ).rejects.toThrow( - new Error( - `Dataset encryption key is not set for dataset ${dataset} in the SMS. Dataset decryption will fail.`, - ), - ); + await iexecDatasetConsumer.storage + .defaultStorageLogin() + .then(iexecDatasetConsumer.storage.pushStorageToken); + const { address: dataset } = + await deployRandomDataset(iexecDatasetProvider); - // tee pass with secret - await iexecDatasetProvider.dataset.pushDatasetSecret( - dataset, - iexecDatasetProvider.dataset.generateEncryptionKey(), - ); - await expect( - iexecDatasetConsumer.order - .createRequestorder({ - app: getRandomAddress(), - category: 5, - dataset, - tag: ['tee', 'scone'], - }) - .then(iexecDatasetConsumer.order.signRequestorder), - ).resolves.toBeDefined(); - }); + // non tee pass + await expect( + iexecDatasetConsumer.order + .createRequestorder({ + app: getRandomAddress(), + category: 5, + dataset, + }) + .then(iexecDatasetConsumer.order.signRequestorder), + ).resolves.toBeDefined(); + + // tee fail without secret + await expect( + iexecDatasetConsumer.order + .createRequestorder({ + app: getRandomAddress(), + category: 5, + dataset, + tag: ['tee', 'scone'], + }) + .then(iexecDatasetConsumer.order.signRequestorder), + ).rejects.toThrow( + new Error( + `Dataset encryption key is not set for dataset ${dataset} in the SMS. Dataset decryption will fail.`, + ), + ); - test('preflightCheck requester secrets exist', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - await iexec.storage - .defaultStorageLogin() - .then(iexec.storage.pushStorageToken); + await expect( + iexecDatasetConsumer.order + .createRequestorder({ + app: getRandomAddress(), + category: 5, + dataset, + tag: ['tee', 'tdx'], + }) + .then(iexecDatasetConsumer.order.signRequestorder), + ).rejects.toThrow( + new Error( + `Dataset encryption key is not set for dataset ${dataset} in the SMS. Dataset decryption will fail.`, + ), + ); - // non requester secret pass - await expect( - iexec.order - .createRequestorder({ - app: getRandomAddress(), - category: 5, - tag: ['tee', 'scone'], - }) - .then(iexec.order.signRequestorder), - ).resolves.toBeDefined(); + // tee pass with secret + await iexecDatasetProvider.dataset.pushDatasetSecret( + dataset, + iexecDatasetProvider.dataset.generateEncryptionKey(), + ); + await expect( + iexecDatasetConsumer.order + .createRequestorder({ + app: getRandomAddress(), + category: 5, + dataset, + tag: ['tee', 'scone'], + }) + .then(iexecDatasetConsumer.order.signRequestorder), + ).resolves.toBeDefined(); + }); + + test('preflightCheck requester secrets exist', async () => { + const { iexec, wallet } = getTestConfig(iexecTestChain)(); + await iexec.storage + .defaultStorageLogin() + .then(iexec.storage.pushStorageToken); - // unset secret fail - await iexec.secrets.pushRequesterSecret('foo', 'secret'); - await expect( - iexec.order - .createRequestorder({ - app: getRandomAddress(), - category: 5, - tag: ['tee', 'scone'], - params: { - iexec_secrets: { - 1: 'foo', - 2: 'bar', + // non requester secret pass + await expect( + iexec.order + .createRequestorder({ + app: getRandomAddress(), + category: 5, + tag: ['tee', 'scone'], + }) + .then(iexec.order.signRequestorder), + ).resolves.toBeDefined(); + + // unset secret fail + await iexec.secrets.pushRequesterSecret('foo', 'secret'); + await expect( + iexec.order + .createRequestorder({ + app: getRandomAddress(), + category: 5, + tag: ['tee', 'scone'], + params: { + iexec_secrets: { + 1: 'foo', + 2: 'bar', + }, }, - }, - }) - .then(iexec.order.signRequestorder), - ).rejects.toThrow( - new Error( - `Requester secret "bar" is not set for requester ${wallet.address} in the SMS. Requester secret provisioning will fail.`, - ), - ); - // set secrets pass - await iexec.secrets.pushRequesterSecret('bar', 'secret'); - await expect( - iexec.order - .createRequestorder({ - app: getRandomAddress(), - category: 5, - tag: ['tee', 'scone'], - params: { - iexec_secrets: { - 1: 'foo', - 2: 'bar', + }) + .then(iexec.order.signRequestorder), + ).rejects.toThrow( + new Error( + `Requester secret "bar" is not set for requester ${wallet.address} in the SMS. Requester secret provisioning will fail.`, + ), + ); + // set secrets pass + await iexec.secrets.pushRequesterSecret('bar', 'secret'); + await expect( + iexec.order + .createRequestorder({ + app: getRandomAddress(), + category: 5, + tag: ['tee', 'scone'], + params: { + iexec_secrets: { + 1: 'foo', + 2: 'bar', + }, }, - }, - }) - .then(iexec.order.signRequestorder), - ).resolves.toBeDefined(); + }) + .then(iexec.order.signRequestorder), + ).resolves.toBeDefined(); + }); }); }); - describe('hashApporder()', () => { - test('gives the order hash', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); - const order = { - app: '0x76fE91568d50C5fF9411223df5A0c50Ec5fa326A', - appprice: 0, - volume: 1000000, - tag: '0x0000000000000000000000000000000000000000000000000000000000000005', - datasetrestrict: '0x0000000000000000000000000000000000000000', - workerpoolrestrict: '0x0000000000000000000000000000000000000000', - requesterrestrict: '0x0000000000000000000000000000000000000000', - salt: '0xcadb4f169d98b940ae506dfc8ee7832e1ff36854aab92f89b7408257693207b3', - sign: '0x5b84b81dd0450897568fa1afdb7969f92259c2f9003a1bed0da96e00c9891957233ad6a0e16101b4ab7b2bf4d4aa117b58bae5fa2bad46522ec62e16ff3c36fe1b', - }; - const res = await iexec.order.hashApporder(order); - expect(res).toBe( - '0x210576e452027bc2430a32f6fae97bec8bd1f7bb7a96f59202d6947ec7d6de8f', - ); + describe('hash...order()', () => { + describe('hashApporder()', () => { + test('gives the order hash', async () => { + const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const order = { + app: '0x76fE91568d50C5fF9411223df5A0c50Ec5fa326A', + appprice: 0, + volume: 1000000, + tag: '0x0000000000000000000000000000000000000000000000000000000000000003', + datasetrestrict: '0x0000000000000000000000000000000000000000', + workerpoolrestrict: '0x0000000000000000000000000000000000000000', + requesterrestrict: '0x0000000000000000000000000000000000000000', + salt: '0xcadb4f169d98b940ae506dfc8ee7832e1ff36854aab92f89b7408257693207b3', + sign: '0x5b84b81dd0450897568fa1afdb7969f92259c2f9003a1bed0da96e00c9891957233ad6a0e16101b4ab7b2bf4d4aa117b58bae5fa2bad46522ec62e16ff3c36fe1b', + }; + const res = await iexec.order.hashApporder(order); + expect(res).toBe( + '0x97f0160eb49618d267b3fd203b488ac09fb50760158455abe1f06cbb8a6edc72', + ); + }); }); - }); - describe('hashDatasetorder()', () => { - test('gives the order hash', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); - const order = { - dataset: '0x2Ad5773db1a705DB568fAd403cd247fee4808Fb8', - datasetprice: 0, - volume: 1, - tag: '0x0000000000000000000000000000000000000000000000000000000000000000', - apprestrict: '0x0000000000000000000000000000000000000000', - workerpoolrestrict: '0x0000000000000000000000000000000000000000', - requesterrestrict: '0x0000000000000000000000000000000000000000', - salt: '0x48380ababf82c79128c1e3ebcba70ce94c6a3ff0ba4125358d1e0c0f871e29e7', - sign: '0x4ce323a70464eb3b35aa90fcd1582e4733a57b16b0d6fb13ffa3189c2e970ffb399779d0c9d4a2d4b0a65adfc2037a7916a9a004148edcdf3dd1a9e12b3c1b0c1b', - }; - const res = await iexec.order.hashDatasetorder(order); - expect(res).toBe( - '0x5831e4e2911c431236a3df6d82698fcb849da8c781d7c4e9eb75ed551e4d35d4', - ); + describe('hashDatasetorder()', () => { + test('gives the order hash', async () => { + const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const order = { + dataset: '0x2Ad5773db1a705DB568fAd403cd247fee4808Fb8', + datasetprice: 0, + volume: 1, + tag: '0x0000000000000000000000000000000000000000000000000000000000000000', + apprestrict: '0x0000000000000000000000000000000000000000', + workerpoolrestrict: '0x0000000000000000000000000000000000000000', + requesterrestrict: '0x0000000000000000000000000000000000000000', + salt: '0x48380ababf82c79128c1e3ebcba70ce94c6a3ff0ba4125358d1e0c0f871e29e7', + sign: '0x4ce323a70464eb3b35aa90fcd1582e4733a57b16b0d6fb13ffa3189c2e970ffb399779d0c9d4a2d4b0a65adfc2037a7916a9a004148edcdf3dd1a9e12b3c1b0c1b', + }; + const res = await iexec.order.hashDatasetorder(order); + expect(res).toBe( + '0x5831e4e2911c431236a3df6d82698fcb849da8c781d7c4e9eb75ed551e4d35d4', + ); + }); }); - }); - describe('hashWorkerpoolorder()', () => { - test('gives the order hash', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); - const order = { - workerpool: '0x9DEB16F7861123CE34AE755F48D30697eD066793', - workerpoolprice: 0, - volume: 4, - tag: '0x0000000000000000000000000000000000000000000000000000000000000000', - category: 3, - trust: 1, - apprestrict: '0x0000000000000000000000000000000000000000', - datasetrestrict: '0x0000000000000000000000000000000000000000', - requesterrestrict: '0x0000000000000000000000000000000000000000', - salt: '0x0c8d51b480466c65b459e828ed8549cf4b15ba1abda0ef5d454964c23f3edf62', - sign: '0xd8941d9974d6b6468a6dac46e88eb80a1575aedd5921d78e002483bf4faa72e319e4c128f9a7f927857c6039988ba456de8ec337078eb538b13488d2374c379e1c', - }; - const res = await iexec.order.hashWorkerpoolorder(order); - expect(res).toBe( - '0x7b23e26344284e809d7809395467d611ba148ef83b2ff3854e03430311f3f8fa', - ); + describe('hashWorkerpoolorder()', () => { + test('gives the order hash', async () => { + const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const order = { + workerpool: '0x9DEB16F7861123CE34AE755F48D30697eD066793', + workerpoolprice: 0, + volume: 4, + tag: '0x0000000000000000000000000000000000000000000000000000000000000000', + category: 3, + trust: 1, + apprestrict: '0x0000000000000000000000000000000000000000', + datasetrestrict: '0x0000000000000000000000000000000000000000', + requesterrestrict: '0x0000000000000000000000000000000000000000', + salt: '0x0c8d51b480466c65b459e828ed8549cf4b15ba1abda0ef5d454964c23f3edf62', + sign: '0xd8941d9974d6b6468a6dac46e88eb80a1575aedd5921d78e002483bf4faa72e319e4c128f9a7f927857c6039988ba456de8ec337078eb538b13488d2374c379e1c', + }; + const res = await iexec.order.hashWorkerpoolorder(order); + expect(res).toBe( + '0x7b23e26344284e809d7809395467d611ba148ef83b2ff3854e03430311f3f8fa', + ); + }); }); - }); - describe('hashRequestorder()', () => { - test('gives the order hash', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); - const order = { - app: '0x33c791fE02eDDBfF3D3d37176737Eb3F488E150F', - dataset: '0x69d4a400CFf9838985cD2950aafF28289afc6ad3', - workerpool: '0x0000000000000000000000000000000000000000', - params: - '{"iexec_result_storage_provider":"ipfs","iexec_result_storage_proxy":"https://result.v8-bellecour.iex.ec","iexec_result_encryption":false,"iexec_args":"\\"0x4e64fb5fa96eb73ef37dacd416eb2bade0ea8f9e7efebe42abe9a062a9caede836ee4da1ec1a72264e1287e74fba7fdc76edce05729c4b2ecf6fb8970f13f8321b 22\\""}', - appmaxprice: 0, - datasetmaxprice: 0, - workerpoolmaxprice: 0, - volume: 1, - tag: '0x0000000000000000000000000000000000000000000000000000000000000000', - category: 0, - trust: 0, - requester: '0x4CF114732732c072D49a783e80C6Fe9fe8BA420a', - beneficiary: '0x4CF114732732c072D49a783e80C6Fe9fe8BA420a', - callback: '0x0000000000000000000000000000000000000000', - salt: '0xef743ff11d68960e724362944b6cd22b59b88402a17f8a1ffabf8fb9be2f4008', - sign: '0xdcd90a96f4c5cd05a0f907220e173a038e01e2a647bd9c8e04714be5dd4f986b0478cb69cf46b3cb3eb05ee74d2b91868bee4d96a89bc79ac8d8cccc96810bf21c', - }; - const res = await iexec.order.hashRequestorder(order); - expect(res).toBeTxHash(); - expect(res).toBe( - '0x8096dd3852b29d6e86b03505ded47fbc96b0bacc9be097f11de3a747ee0e4283', - ); + describe('hashRequestorder()', () => { + test('gives the order hash', async () => { + const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const order = { + app: '0x33c791fE02eDDBfF3D3d37176737Eb3F488E150F', + dataset: '0x69d4a400CFf9838985cD2950aafF28289afc6ad3', + workerpool: '0x0000000000000000000000000000000000000000', + params: + '{"iexec_result_storage_provider":"ipfs","iexec_result_storage_proxy":"https://result.v8-bellecour.iex.ec","iexec_result_encryption":false,"iexec_args":"\\"0x4e64fb5fa96eb73ef37dacd416eb2bade0ea8f9e7efebe42abe9a062a9caede836ee4da1ec1a72264e1287e74fba7fdc76edce05729c4b2ecf6fb8970f13f8321b 22\\""}', + appmaxprice: 0, + datasetmaxprice: 0, + workerpoolmaxprice: 0, + volume: 1, + tag: '0x0000000000000000000000000000000000000000000000000000000000000000', + category: 0, + trust: 0, + requester: '0x4CF114732732c072D49a783e80C6Fe9fe8BA420a', + beneficiary: '0x4CF114732732c072D49a783e80C6Fe9fe8BA420a', + callback: '0x0000000000000000000000000000000000000000', + salt: '0xef743ff11d68960e724362944b6cd22b59b88402a17f8a1ffabf8fb9be2f4008', + sign: '0xdcd90a96f4c5cd05a0f907220e173a038e01e2a647bd9c8e04714be5dd4f986b0478cb69cf46b3cb3eb05ee74d2b91868bee4d96a89bc79ac8d8cccc96810bf21c', + }; + const res = await iexec.order.hashRequestorder(order); + expect(res).toBeTxHash(); + expect(res).toBe( + '0x8096dd3852b29d6e86b03505ded47fbc96b0bacc9be097f11de3a747ee0e4283', + ); + }); }); }); - describe('cancelApporder()', () => { - test('revokes the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const order = await deployAndGetApporder(iexec); - const res = await iexec.order.cancelApporder(order); - expect(res.order).toEqual(order); - expect(res.txHash).toBeTxHash(); - await expect(iexec.order.cancelApporder(order)).rejects.toThrow( - new Error('apporder already canceled'), - ); + describe('cancel...order()', () => { + describe('cancelApporder()', () => { + test('revokes the order', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const order = await deployAndGetApporder(iexec); + const res = await iexec.order.cancelApporder(order); + expect(res.order).toEqual(order); + expect(res.txHash).toBeTxHash(); + await expect(iexec.order.cancelApporder(order)).rejects.toThrow( + new Error('apporder already canceled'), + ); + }); }); - }); - describe('cancelDatasetorder()', () => { - test('revokes the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const order = await deployAndGetDatasetorder(iexec); - const res = await iexec.order.cancelDatasetorder(order); - expect(res.order).toEqual(order); - expect(res.txHash).toBeTxHash(); - await expect(iexec.order.cancelDatasetorder(order)).rejects.toThrow( - new Error('datasetorder already canceled'), - ); + describe('cancelDatasetorder()', () => { + test('revokes the order', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const order = await deployAndGetDatasetorder(iexec); + const res = await iexec.order.cancelDatasetorder(order); + expect(res.order).toEqual(order); + expect(res.txHash).toBeTxHash(); + await expect(iexec.order.cancelDatasetorder(order)).rejects.toThrow( + new Error('datasetorder already canceled'), + ); + }); }); - }); - describe('cancelWorkerpoolorder()', () => { - test('revokes the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const order = await deployAndGetWorkerpoolorder(iexec); - const res = await iexec.order.cancelWorkerpoolorder(order); - expect(res.order).toEqual(order); - expect(res.txHash).toBeTxHash(); - await expect(iexec.order.cancelWorkerpoolorder(order)).rejects.toThrow( - new Error('workerpoolorder already canceled'), - ); + describe('cancelWorkerpoolorder()', () => { + test('revokes the order', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const order = await deployAndGetWorkerpoolorder(iexec); + const res = await iexec.order.cancelWorkerpoolorder(order); + expect(res.order).toEqual(order); + expect(res.txHash).toBeTxHash(); + await expect(iexec.order.cancelWorkerpoolorder(order)).rejects.toThrow( + new Error('workerpoolorder already canceled'), + ); + }); }); - }); - describe('cancelRequestorder()', () => { - test('revokes the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const order = await iexec.order - .createRequestorder({ - app: getRandomAddress(), - appmaxprice: 0, - workerpoolmaxprice: 0, - requester: await iexec.wallet.getAddress(), - volume: 1, - category: 1, - }) - .then((o) => - iexec.order.signRequestorder(o, { preflightCheck: false }), + describe('cancelRequestorder()', () => { + test('revokes the order', async () => { + const { iexec } = getTestConfig(iexecTestChain)(); + const order = await iexec.order + .createRequestorder({ + app: getRandomAddress(), + appmaxprice: 0, + workerpoolmaxprice: 0, + requester: await iexec.wallet.getAddress(), + volume: 1, + category: 1, + }) + .then((o) => + iexec.order.signRequestorder(o, { preflightCheck: false }), + ); + const res = await iexec.order.cancelRequestorder(order); + expect(res.order).toEqual(order); + expect(res.txHash).toBeTxHash(); + await expect(iexec.order.cancelRequestorder(order)).rejects.toThrow( + new Error('requestorder already canceled'), ); - const res = await iexec.order.cancelRequestorder(order); - expect(res.order).toEqual(order); - expect(res.txHash).toBeTxHash(); - await expect(iexec.order.cancelRequestorder(order)).rejects.toThrow( - new Error('requestorder already canceled'), - ); + }); }); }); diff --git a/test/lib/e2e/IExecOrderbookModule.test.js b/test/lib/e2e/IExecOrderbookModule.test.js index dddad8cd..4e11a6e2 100644 --- a/test/lib/e2e/IExecOrderbookModule.test.js +++ b/test/lib/e2e/IExecOrderbookModule.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { deployAndGetApporder, diff --git a/test/lib/e2e/IExecResultModule.test.js b/test/lib/e2e/IExecResultModule.test.js index d5ef2bc4..dbaba5ac 100644 --- a/test/lib/e2e/IExecResultModule.test.js +++ b/test/lib/e2e/IExecResultModule.test.js @@ -1,8 +1,6 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { getTestConfig } from '../lib-test-utils.js'; -import { TEST_CHAINS, TEE_FRAMEWORKS } from '../../test-utils.js'; +import { TEST_CHAINS } from '../../test-utils.js'; import '../../jest-setup.js'; const iexecTestChain = TEST_CHAINS['bellecour-fork']; @@ -21,21 +19,6 @@ describe('result', () => { `Secret "iexec-result-encryption-public-key" already exists for ${wallet.address}`, ), ); - await expect( - iexec.result.pushResultEncryptionKey('oops', { - teeFramework: TEE_FRAMEWORKS.SCONE, - }), - ).rejects.toThrow( - new Error( - `Secret "iexec-result-encryption-public-key" already exists for ${wallet.address}`, - ), - ); - const pushForTeeFrameworkRes = await iexec.result.pushResultEncryptionKey( - 'oops', - { teeFramework: TEE_FRAMEWORKS.GRAMINE }, - ); - expect(pushForTeeFrameworkRes.isPushed).toBe(true); - expect(pushForTeeFrameworkRes.isUpdated).toBe(false); }); test('forceUpdate allows updating the key', async () => { @@ -68,22 +51,6 @@ describe('result', () => { wallet.address, ); expect(withSecretRes).toBe(true); - const withSecretForTeeFrameworkRes = - await iexecReadOnly.result.checkResultEncryptionKeyExists( - wallet.address, - { - teeFramework: TEE_FRAMEWORKS.SCONE, - }, - ); - expect(withSecretForTeeFrameworkRes).toBe(true); - const withoutSecretForTeeFrameworkRes = - await iexecReadOnly.result.checkResultEncryptionKeyExists( - wallet.address, - { - teeFramework: TEE_FRAMEWORKS.GRAMINE, - }, - ); - expect(withoutSecretForTeeFrameworkRes).toBe(false); }); }); }); diff --git a/test/lib/e2e/IExecSecretsModule.test.js b/test/lib/e2e/IExecSecretsModule.test.js index 2ba268e0..e9448eb7 100644 --- a/test/lib/e2e/IExecSecretsModule.test.js +++ b/test/lib/e2e/IExecSecretsModule.test.js @@ -1,10 +1,7 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { expectAsyncCustomError, getTestConfig } from '../lib-test-utils.js'; import { TEST_CHAINS, - TEE_FRAMEWORKS, SERVICE_UNREACHABLE_URL, SERVICE_HTTP_500_URL, getRandomAddress, @@ -57,12 +54,6 @@ describe('secrets', () => { ).rejects.toThrow( new Error(`Secret "foo" already exists for ${wallet.address}`), ); - const pushForTeeFrameworkRes = await iexec.secrets.pushRequesterSecret( - 'foo', - 'oops', - { teeFramework: TEE_FRAMEWORKS.GRAMINE }, - ); - expect(pushForTeeFrameworkRes.isPushed).toBe(true); }); }); @@ -115,15 +106,6 @@ describe('secrets', () => { await expect( iexecReadOnly.secrets.checkRequesterSecretExists(wallet.address, 'foo'), ).resolves.toBe(true); - await expect( - iexecReadOnly.secrets.checkRequesterSecretExists( - wallet.address, - 'foo', - { - teeFramework: TEE_FRAMEWORKS.GRAMINE, - }, - ), - ).resolves.toBe(false); }); }); }); diff --git a/test/lib/e2e/IExecStorageModule.test.js b/test/lib/e2e/IExecStorageModule.test.js index 6bcf805a..fbfa97de 100644 --- a/test/lib/e2e/IExecStorageModule.test.js +++ b/test/lib/e2e/IExecStorageModule.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { expectAsyncCustomError, getTestConfig } from '../lib-test-utils.js'; import { @@ -86,11 +84,6 @@ describe('storage', () => { `Secret "iexec-result-iexec-ipfs-token" already exists for ${wallet.address}`, ), ); - const pushForTeeFramework = await iexec.storage.pushStorageToken('oops', { - teeFramework: 'gramine', - }); - expect(pushForTeeFramework.isPushed).toBe(true); - expect(pushForTeeFramework.isUpdated).toBe(false); }); test('provider "default" pushes result proxy ipfs token', async () => { @@ -195,17 +188,6 @@ describe('storage', () => { provider: 'test', }), ).rejects.toThrow(Error('"test" not supported')); - const unsetForTeeFramework = - await iexecReadOnly.storage.checkStorageTokenExists(wallet.address, { - teeFramework: 'gramine', - }); - expect(unsetForTeeFramework).toBe(false); - await iexec.storage.pushStorageToken('oops', { teeFramework: 'gramine' }); - const setForTeeFramework = - await iexecReadOnly.storage.checkStorageTokenExists(wallet.address, { - teeFramework: 'gramine', - }); - expect(setForTeeFramework).toBe(true); }); }); }); diff --git a/test/lib/e2e/IExecTaskModule.test.js b/test/lib/e2e/IExecTaskModule.test.js index 2b79355f..9178d5de 100644 --- a/test/lib/e2e/IExecTaskModule.test.js +++ b/test/lib/e2e/IExecTaskModule.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect, beforeAll } from '@jest/globals'; import { deployAndGetApporder, diff --git a/test/lib/e2e/IExecWalletModule.test.js b/test/lib/e2e/IExecWalletModule.test.js index 627dd766..19adffb7 100644 --- a/test/lib/e2e/IExecWalletModule.test.js +++ b/test/lib/e2e/IExecWalletModule.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { BN } from 'bn.js'; import { ONE_ETH, ONE_RLC, getTestConfig } from '../lib-test-utils.js'; diff --git a/test/lib/e2e/IExecWorkerpoolModule.test.js b/test/lib/e2e/IExecWorkerpoolModule.test.js index eb6e2b7e..e38f999b 100644 --- a/test/lib/e2e/IExecWorkerpoolModule.test.js +++ b/test/lib/e2e/IExecWorkerpoolModule.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { BN } from 'bn.js'; import { deployRandomWorkerpool, getTestConfig } from '../lib-test-utils.js'; diff --git a/test/lib/e2e/utils.test.js b/test/lib/e2e/utils.test.js index 7d0ab0d1..f4ce68ad 100644 --- a/test/lib/e2e/utils.test.js +++ b/test/lib/e2e/utils.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { readFile } from 'fs/promises'; import { join } from 'path'; @@ -449,6 +447,7 @@ describe('utils', () => { expect(tx2).toBeTxHash(); }); + // skipped because reliant on ethers selected providers test.skip('providers option allow passing JSON RPC API providers api keys', async () => { const providerOptions = { infura: INFURA_PROJECT_ID, @@ -609,6 +608,7 @@ describe('utils', () => { ).wallet.checkBalances(NULL_ADDRESS), ).resolves.toBeDefined(); }); + // skipped because no experimental networks are currently defined test.skip('allowExperimentalNetworks option allow creating signer connected to an experimental network', async () => { expect(() => utils.getSignerFromPrivateKey( diff --git a/test/lib/e2e/workflow.test.js b/test/lib/e2e/workflow.test.js index 76553e17..990c135e 100644 --- a/test/lib/e2e/workflow.test.js +++ b/test/lib/e2e/workflow.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { BN } from 'bn.js'; import { getTestConfig } from '../lib-test-utils.js'; diff --git a/test/lib/lib-test-utils.js b/test/lib/lib-test-utils.js index aa6725af..bb107e14 100644 --- a/test/lib/lib-test-utils.js +++ b/test/lib/lib-test-utils.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { expect } from '@jest/globals'; import { NULL_ADDRESS, TEE_FRAMEWORKS, getId, sleep } from '../test-utils.js'; export { getTestConfig, getTestConfigOptions } from '../test-config-utils.js'; @@ -19,15 +17,13 @@ export const deployRandomApp = async (iexec, { owner, teeFramework } = {}) => checksum: '0x00f51494d7a42a3c1c43464d9f09e06b2a99968e3b978f6cd11ab3410b7bcd14', mrenclave: - teeFramework && teeFramework !== TEE_FRAMEWORKS.TDX + teeFramework === TEE_FRAMEWORKS.SCONE ? { framework: teeFramework, version: 'v1', fingerprint: 'fingerprint', - ...(teeFramework.toLowerCase() === TEE_FRAMEWORKS.SCONE && { - entrypoint: 'entrypoint.sh', - heapSize: 4096, - }), + entrypoint: 'entrypoint.sh', + heapSize: 4096, } : undefined, }); diff --git a/test/lib/unit/config.test.js b/test/lib/unit/config.test.js index 90fff87f..b7b4ee69 100644 --- a/test/lib/unit/config.test.js +++ b/test/lib/unit/config.test.js @@ -36,16 +36,14 @@ describe('getChainDefaults', () => { name: 'bellecour', pocoSubgraph: 'https://thegraph.iex.ec/subgraphs/name/bellecour/poco-v5', resultProxy: 'https://result.v8-bellecour.iex.ec', - sms: { - gramine: 'https://sms.gramine.v8-bellecour.iex.ec', - scone: 'https://sms.iex.ec', - }, + sms: 'https://sms.iex.ec', compass: undefined, }); }); test('unknown id returns empty object', () => { expect(getChainDefaults(0)).toEqual({}); }); + // skipped because no experimental networks are currently defined test.skip('experimental networks are accessible with `allowExperimentalNetworks:true` hidden by default', () => { expect(getChainDefaults(421614)).toEqual({}); expect( diff --git a/test/lib/unit/errorWrappers.test.js b/test/lib/unit/errorWrappers.test.js index 6254d282..346f2693 100644 --- a/test/lib/unit/errorWrappers.test.js +++ b/test/lib/unit/errorWrappers.test.js @@ -1,5 +1,3 @@ -// @jest/global comes with jest -// eslint-disable-next-line import/no-extraneous-dependencies import { describe, test, expect } from '@jest/globals'; import { BrowserProvider } from 'ethers'; import { diff --git a/test/lib/unit/validator.test.js b/test/lib/unit/validator.test.js index 7a7da89f..affa7abc 100644 --- a/test/lib/unit/validator.test.js +++ b/test/lib/unit/validator.test.js @@ -28,7 +28,6 @@ import { textRecordKeySchema, textRecordValueSchema, workerpoolApiUrlSchema, - smsUrlOrMapSchema, teeFrameworkSchema, addressOrAnySchema, signedDatasetorderBulkSchema, @@ -835,7 +834,7 @@ describe('[tagSchema]', () => { test('invalid tee tag', async () => { await expect(tagSchema().validate('tee')).rejects.toThrow( new ValidationError( - "'tee' tag must be used with a tee framework ('scone'|'gramine'|'tdx')", + "'tee' tag must be used with a tee framework ('scone'|'tdx')", ), ); await expect( @@ -844,7 +843,7 @@ describe('[tagSchema]', () => { ), ).rejects.toThrow( new ValidationError( - "'tee' tag must be used with a tee framework ('scone'|'gramine'|'tdx')", + "'tee' tag must be used with a tee framework ('scone'|'tdx')", ), ); await expect(tagSchema().validate('scone')).rejects.toThrow( @@ -857,16 +856,6 @@ describe('[tagSchema]', () => { ).rejects.toThrow( new ValidationError("'scone' tag must be used with 'tee' tag"), ); - await expect(tagSchema().validate('gramine')).rejects.toThrow( - new ValidationError("'gramine' tag must be used with 'tee' tag"), - ); - await expect( - tagSchema().validate( - '0x0000000000000000000000000000000000000000000000000000000000000004', - ), - ).rejects.toThrow( - new ValidationError("'gramine' tag must be used with 'tee' tag"), - ); await expect(tagSchema().validate('tdx')).rejects.toThrow( new ValidationError("'tdx' tag must be used with 'tee' tag"), ); @@ -883,19 +872,15 @@ describe('[tagSchema]', () => { expect(agnosticTeeTag).toBe( '0x0000000000000000000000000000000000000000000000000000000000000001', ); - await expect(tagSchema().validate('tee,gramine,scone')).rejects.toThrow( - new ValidationError( - "tee framework tags are exclusive ('scone'|'gramine'|'tdx')", - ), + await expect(tagSchema().validate('tee,scone,tdx')).rejects.toThrow( + new ValidationError("tee framework tags are exclusive ('scone'|'tdx')"), ); await expect( tagSchema().validate( - '0x0000000000000000000000000000000000000000000000000000000000000007', + '0x000000000000000000000000000000000000000000000000000000000000000b', ), ).rejects.toThrow( - new ValidationError( - "tee framework tags are exclusive ('scone'|'gramine'|'tdx')", - ), + new ValidationError("tee framework tags are exclusive ('scone'|'tdx')"), ); const teeTdxTag = await tagSchema().validate(['tee', 'tdx']); expect(teeTdxTag).toBe( @@ -1082,17 +1067,6 @@ describe('[fileBufferSchema]', () => { }); describe('[mrenclaveSchema]', () => { - test('valid obj', async () => { - const obj = { - framework: 'GRAMINE', - version: 'v5', - fingerprint: - '5036854f3f108465726a1374430ad0963b72a27a0e83dfea2ca11dae4cdbdf7d', - }; - await expect(mrenclaveSchema().validate(obj)).resolves.toEqual( - Buffer.from(JSON.stringify(obj), 'utf8'), - ); - }); test('valid SCONE obj', async () => { const obj = { framework: 'SCONE', @@ -1151,30 +1125,6 @@ describe('[mrenclaveSchema]', () => { Buffer.from([]), ); }); - test('throw when "entrypoint" is set for non SCONE framework', async () => { - const obj = { - framework: 'GRAMINE', - version: 'v5', - entrypoint: '/app/helloworld', - fingerprint: - '5036854f3f108465726a1374430ad0963b72a27a0e83dfea2ca11dae4cdbdf7d', - }; - await expect(mrenclaveSchema().validate(obj)).rejects.toThrow( - new ValidationError('Unknown key "entrypoint" in mrenclave'), - ); - }); - test('throw when "heapSize" is set for non SCONE framework', async () => { - const obj = { - framework: 'GRAMINE', - version: 'v5', - heapSize: 1073741824, - fingerprint: - '5036854f3f108465726a1374430ad0963b72a27a0e83dfea2ca11dae4cdbdf7d', - }; - await expect(mrenclaveSchema().validate(obj)).rejects.toThrow( - new ValidationError('Unknown key "heapSize" in mrenclave'), - ); - }); test('throw with null', async () => { await expect(mrenclaveSchema().validate(null)).rejects.toThrow( new ValidationError('this is not a valid mrenclave'), @@ -1414,65 +1364,6 @@ describe('[workerpoolApiUrlSchema]', () => { }); }); -describe('[smsUrlOrMapSchema]', () => { - test('allow IP with port', async () => { - const res = await smsUrlOrMapSchema().validate('http://192.168.0.1:8080'); - expect(res).toBe('http://192.168.0.1:8080'); - }); - test('allow url', async () => { - const res = await smsUrlOrMapSchema().validate('https://my-sms.com'); - expect(res).toBe('https://my-sms.com'); - }); - test('allow docker url', async () => { - const res = await smsUrlOrMapSchema().validate('http://my-sms'); - expect(res).toBe('http://my-sms'); - }); - test('allow undefined', async () => { - const res = await smsUrlOrMapSchema().validate(); - expect(res).toBe(undefined); - }); - test('allow Record', async () => { - const smsMap = { - scone: 'http://scone-sms', - gramine: 'http://gramine-sms', - }; - const res = await smsUrlOrMapSchema().validate(smsMap); - expect(res).toEqual(smsMap); - }); - test('allow partial Record', async () => { - const smsMap = { - gramine: 'http://gramine-sms', - }; - const res = await smsUrlOrMapSchema().validate(smsMap); - expect(res).toEqual(smsMap); - }); - test('throw with empty string', async () => { - await expect(smsUrlOrMapSchema().validate('')).rejects.toThrow( - 'this "" is not a valid URL', - ); - }); - test('throw with null', async () => { - await expect(smsUrlOrMapSchema().validate(null)).rejects.toThrow( - 'this cannot be null', - ); - }); - test('throw with invalid url', async () => { - await expect(smsUrlOrMapSchema().validate('foo')).rejects.toThrow( - 'this "foo" is not a valid URL', - ); - }); - test('throw with unknown TEE framework key', async () => { - await expect( - smsUrlOrMapSchema().validate({ foo: 'https://my-sms.com' }), - ).rejects.toThrow('this field has unspecified keys: foo'); - }); - test('throw with invalid url on a TEE framework key', async () => { - await expect( - smsUrlOrMapSchema().validate({ scone: 'foo' }), - ).rejects.toThrow('scone "foo" is not a valid URL'); - }); -}); - describe('[teeFrameworkSchema]', () => { test('allow known TEE frameworks', async () => { await Promise.all( diff --git a/test/test-config-utils.js b/test/test-config-utils.js index 29280ffa..56fab67c 100644 --- a/test/test-config-utils.js +++ b/test/test-config-utils.js @@ -7,8 +7,6 @@ export const getTestConfigOptions = bridgeAddress: options.bridgeAddress ?? chain.bridgeAddress, bridgedNetworkConf: options.bridgedNetworkConf ?? chain.bridgedNetworkConf, confirms: options.confirms ?? chain.confirms, - defaultTeeFramework: - options.defaultTeeFramework ?? chain.defaultTeeFramework, ensPublicResolverAddress: options.ensPublicResolverAddress ?? chain.ensPublicResolverAddress, ensRegistryAddress: options.ensRegistryAddress ?? chain.ensRegistryAddress, @@ -21,7 +19,7 @@ export const getTestConfigOptions = providerOptions: options.providerOptions ?? chain.providerOptions, resultProxyURL: options.resultProxyURL ?? chain.resultProxyURL, compassURL: options.compassURL ?? chain.compassURL, - smsURL: options.smsURL ?? chain.smsMap, + smsURL: options.smsURL ?? chain.smsURL, useGas: options.useGas ?? chain.useGas, }); diff --git a/test/test-utils.js b/test/test-utils.js index 76306bd7..f897ad8b 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -104,9 +104,7 @@ export const TEST_CHAINS = { 'bellecour-fork': { rpcURL: 'http://localhost:8545', chainId: '134', - sconeSmsURL: 'http://localhost:13300', - gramineSmsURL: 'http://localhost:13302', - tdxSmsURL: 'http://localhost:13303', + smsURL: 'http://localhost:13300', iexecGatewayURL: 'http://localhost:3000', resultProxyURL: 'http://localhost:13200', ipfsNodeURL: 'http://localhost:5001', @@ -132,16 +130,6 @@ export const TEST_CHAINS = { }, }; -Object.keys(TEST_CHAINS).forEach((chain) => { - if (!TEST_CHAINS[chain].smsMap) { - TEST_CHAINS[chain].smsMap = { - gramine: TEST_CHAINS[chain].gramineSmsURL, - scone: TEST_CHAINS[chain].sconeSmsURL, - tdx: TEST_CHAINS[chain].tdxSmsURL, - }; - } -}); - export const getId = () => randomInt(0, 1000000); export const getRandomWallet = () => { From c64926758532bafb48776e62779e0168116c3c0a Mon Sep 17 00:00:00 2001 From: pjt <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Wed, 22 Apr 2026 15:32:32 +0200 Subject: [PATCH 03/13] chore: move tests to arbitrum sepolia fork (#557) * chore: prepare test based on arbitrum-sepolia-fork * chore: remove now useless faucet based setBalance methods * refactor: rename prepare script * test: remove gasPrice option tests (not applicable on bellecour nor arbitrum) * test: migrate tests from bellecour fork to arbitrum-sepolia fork * fix: await promise * chore: document magic storage location in anvilSetNRlcTokenBalance --- package.json | 2 +- src/cli/utils/cli-helper.js | 1 + src/common/utils/signers.js | 2 +- src/lib/utils.d.ts | 2 +- test/cli/cli-iexec-account.test.js | 23 +- test/cli/cli-iexec-app.test.js | 12 +- test/cli/cli-iexec-category.test.js | 7 +- test/cli/cli-iexec-dataset.test.js | 7 +- test/cli/cli-iexec-deal.test.js | 4 +- test/cli/cli-iexec-ens.test.js | 20 +- test/cli/cli-iexec-info.test.js | 26 +- test/cli/cli-iexec-init.test.js | 2 +- test/cli/cli-iexec-order.test.js | 25 +- test/cli/cli-iexec-requester.test.js | 4 +- test/cli/cli-iexec-result.test.js | 4 +- test/cli/cli-iexec-storage.test.js | 4 +- test/cli/cli-iexec-task.test.js | 4 +- test/cli/cli-iexec-wallet.test.js | 68 ++--- test/cli/cli-iexec-workerpool.test.js | 50 +--- test/cli/cli-test-utils.js | 11 +- test/cli/cli-tx-options.test.js | 102 ------- test/docker-compose.yml | 200 ++++++++----- test/lib/e2e/IExecAccountModule.test.js | 69 ++--- test/lib/e2e/IExecAppModule.test.js | 62 ++-- test/lib/e2e/IExecConfig.test.js | 55 ++-- test/lib/e2e/IExecDatasetModule.test.js | 84 +++--- test/lib/e2e/IExecDealModule.test.js | 38 +-- test/lib/e2e/IExecEnsModule.test.js | 74 +++-- test/lib/e2e/IExecHubModule.test.js | 8 +- test/lib/e2e/IExecOrderModule.test.js | 197 ++++++------- test/lib/e2e/IExecOrderbookModule.test.js | 74 ++--- test/lib/e2e/IExecResultModule.test.js | 10 +- test/lib/e2e/IExecSecretsModule.test.js | 16 +- test/lib/e2e/IExecStorageModule.test.js | 28 +- test/lib/e2e/IExecTaskModule.test.js | 178 +++--------- test/lib/e2e/IExecWalletModule.test.js | 55 ++-- test/lib/e2e/IExecWorkerpoolModule.test.js | 123 ++++---- test/lib/e2e/utils.test.js | 92 +++--- test/lib/e2e/workflow.test.js | 26 +- test/mock/compass/data.json | 13 +- .../prepare-bellecour-fork-for-tests.js | 117 -------- test/scripts/prepare-forks-for-tests.js | 130 +++++++++ test/scripts/prepare-test-env.js | 73 +++-- test/test-config-utils.js | 38 ++- test/test-utils.js | 267 +++++++----------- 45 files changed, 1115 insertions(+), 1292 deletions(-) delete mode 100644 test/cli/cli-tx-options.test.js delete mode 100755 test/scripts/prepare-bellecour-fork-for-tests.js create mode 100755 test/scripts/prepare-forks-for-tests.js diff --git a/package.json b/package.json index 52f9c0a2..391dedba 100644 --- a/package.json +++ b/package.json @@ -155,7 +155,7 @@ "build:doc": "npm run build:doc:lib && npm run build:doc:cli", "build:doc:lib": "./node_modules/typedoc/bin/typedoc --tsconfig tsconfig.doc.json --disableSources", "build:doc:cli": "node generateCliDoc.cjs", - "test:prepare": "node test/scripts/prepare-bellecour-fork-for-tests.js" + "test:prepare": "node test/scripts/prepare-forks-for-tests.js" }, "files": [ "src/", diff --git a/src/cli/utils/cli-helper.js b/src/cli/utils/cli-helper.js index e3533cd5..94e32450 100644 --- a/src/cli/utils/cli-helper.js +++ b/src/cli/utils/cli-helper.js @@ -358,6 +358,7 @@ export const option = { 'specify the original dataset directory', ], txGasPrice: () => [ + // TODO remove this option (not applicable on supported chains) '--gas-price ', 'set custom gas price for transactions (default unit wei)', ], diff --git a/src/common/utils/signers.js b/src/common/utils/signers.js index d8a65686..13bb4f24 100644 --- a/src/common/utils/signers.js +++ b/src/common/utils/signers.js @@ -101,7 +101,7 @@ export const getSignerFromPrivateKey = ( host, privateKey, { - gasPrice, + gasPrice, // TODO remove this option (not applicable on supported chains) getTransactionCount, providers, allowExperimentalNetworks = false, diff --git a/src/lib/utils.d.ts b/src/lib/utils.d.ts index 20b4ae7d..cab7962f 100644 --- a/src/lib/utils.d.ts +++ b/src/lib/utils.d.ts @@ -33,7 +33,7 @@ export const getSignerFromPrivateKey: ( /** * gas price override */ - gasPrice?: bigint | number | string; + gasPrice?: bigint | number | string; // TODO remove this option (not applicable on supported chains) /** * nonce override */ diff --git a/test/cli/cli-iexec-account.test.js b/test/cli/cli-iexec-account.test.js index da1cf1cf..98bf70f8 100644 --- a/test/cli/cli-iexec-account.test.js +++ b/test/cli/cli-iexec-account.test.js @@ -5,7 +5,7 @@ import { execAsync, getRandomAddress, getRandomWallet, - setBalance, + setNRlcBalance, } from '../test-utils.js'; import { globalSetup, @@ -18,7 +18,7 @@ import { } from './cli-test-utils.js'; import '../jest-setup.js'; -const testChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('iexec account', () => { let userWallet; @@ -28,8 +28,8 @@ describe('iexec account', () => { // init the project await execAsync(`${iexecPath} init --skip-wallet --force`); await setChain(testChain)(); - userWallet = await setRandomWallet(); - await setBalance(testChain)(userWallet.address, 50n * 10n ** 18n); + userWallet = await setRandomWallet(testChain)(); + await setNRlcBalance(testChain)(userWallet.address, 50n * 10n ** 9n); }); afterAll(async () => { @@ -54,9 +54,6 @@ describe('iexec account', () => { expect(res.ok).toBe(true); expect(res.amount).toBe(amount); expect(res.txHash).toBeDefined(); - const tx = await testChain.provider.getTransaction(res.txHash); - expect(tx).toBeDefined(); - expect(tx.gasPrice.toString()).toBe('0'); const bnAmount = new BN(amount); const finalWalletBalance = new BN( @@ -171,9 +168,7 @@ describe('iexec account', () => { expect(res.ok).toBe(true); expect(res.amount).toBe(amount); expect(res.txHash).toBeDefined(); - const tx = await testChain.provider.getTransaction(res.txHash); - expect(tx).toBeDefined(); - expect(tx.gasPrice.toString()).toBe('0'); + const bnAmount = new BN(amount); const finalWalletBalance = new BN( JSON.parse(await execAsync(`${iexecPath} wallet show --raw`)).balance @@ -240,9 +235,6 @@ describe('iexec account', () => { const res = JSON.parse(raw); expect(res.ok).toBe(true); expect(res.txHash).toBeDefined(); - const tx = await testChain.provider.getTransaction(res.txHash); - expect(tx).toBeDefined(); - expect(tx.gasPrice.toString()).toBe('0'); const raw1 = await execAsync( `${iexecPath} account allowance ${spender} --raw`, @@ -262,9 +254,6 @@ describe('iexec account', () => { const res = JSON.parse(raw); expect(res.ok).toBe(true); expect(res.txHash).toBeDefined(); - const tx = await testChain.provider.getTransaction(res.txHash); - expect(tx).toBeDefined(); - expect(tx.gasPrice.toString()).toBe('0'); const raw1 = await execAsync( `${iexecPath} account allowance ${spender} --raw`, @@ -312,7 +301,7 @@ describe('iexec account', () => { const amount = '500'; const spender = getRandomAddress(); const { privateKey, address: owner } = getRandomWallet(); - await setWallet(privateKey); + await setWallet(testChain)(privateKey); await execAsync( `${iexecPath} account approve ${amount} ${spender} --raw`, ); diff --git a/test/cli/cli-iexec-app.test.js b/test/cli/cli-iexec-app.test.js index e04c5ede..42cf2569 100644 --- a/test/cli/cli-iexec-app.test.js +++ b/test/cli/cli-iexec-app.test.js @@ -20,7 +20,7 @@ import { } from './cli-test-utils.js'; import '../jest-setup.js'; -const testChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('iexec app', () => { let userWallet; @@ -32,7 +32,7 @@ describe('iexec app', () => { await execAsync(`${iexecPath} init --skip-wallet --force`); await setChain(testChain)(); - userWallet = await setRandomWallet(); + userWallet = await setRandomWallet(testChain)(); await execAsync(`${iexecPath} app init`); await setAppUniqueName(); const deployed = await runIExecCliRaw(`${iexecPath} app deploy`); @@ -84,9 +84,6 @@ describe('iexec app', () => { expect(res.ok).toBe(true); expect(res.address).toBeDefined(); expect(res.txHash).toBeDefined(); - const tx = await testChain.provider.getTransaction(res.txHash); - expect(tx).toBeDefined(); - expect(tx.gasPrice.toString()).toBe('0'); }); }); @@ -161,9 +158,6 @@ describe('iexec app', () => { expect(res.address).toBe(address); expect(res.to).toBe(receiverAddress); expect(res.txHash).toBeDefined(); - const tx = await testChain.provider.getTransaction(res.txHash); - expect(tx).toBeDefined(); - expect(tx.gasPrice.toString()).toBe('0'); }); }); @@ -179,7 +173,7 @@ describe('iexec app', () => { workClockTimeRef: '0', }).then(({ catid }) => catid.toString()); // restore user wallet - await setWallet(userWallet.privateKey); + await setWallet(testChain)(userWallet.privateKey); await execAsync(`${iexecPath} app init`); await setAppUniqueName(); await execAsync(`${iexecPath} dataset init`); diff --git a/test/cli/cli-iexec-category.test.js b/test/cli/cli-iexec-category.test.js index 0bfaef19..b5073cb9 100644 --- a/test/cli/cli-iexec-category.test.js +++ b/test/cli/cli-iexec-category.test.js @@ -11,7 +11,7 @@ import { } from './cli-test-utils.js'; import '../jest-setup.js'; -const testChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('iexec category', () => { beforeAll(async () => { @@ -25,7 +25,7 @@ describe('iexec category', () => { }); describe('as user', () => { beforeAll(async () => { - await setRandomWallet(); + await setRandomWallet(testChain)(); }); test('iexec category init', async () => { @@ -77,9 +77,6 @@ describe('iexec category', () => { expect(res.ok).toBe(true); expect(res.catid).toBeDefined(); expect(res.txHash).toBeDefined(); - const tx = await testChain.provider.getTransaction(res.txHash); - expect(tx).toBeDefined(); - expect(tx.gasPrice.toString()).toBe('0'); }); }); }); diff --git a/test/cli/cli-iexec-dataset.test.js b/test/cli/cli-iexec-dataset.test.js index 46563d44..9d2b1698 100644 --- a/test/cli/cli-iexec-dataset.test.js +++ b/test/cli/cli-iexec-dataset.test.js @@ -18,7 +18,7 @@ import { } from './cli-test-utils.js'; import '../jest-setup.js'; -const testChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('iexec dataset', () => { let userWallet; @@ -29,7 +29,7 @@ describe('iexec dataset', () => { // init the project await execAsync(`${iexecPath} init --skip-wallet --force`); await setChain(testChain)(); - userWallet = await setRandomWallet(); + userWallet = await setRandomWallet(testChain)(); await execAsync(`${iexecPath} dataset init`); await setDatasetUniqueName(); const deployed = await runIExecCliRaw(`${iexecPath} dataset deploy`); @@ -79,9 +79,6 @@ describe('iexec dataset', () => { expect(res.ok).toBe(true); expect(res.address).toBeDefined(); expect(res.txHash).toBeDefined(); - const tx = await testChain.provider.getTransaction(res.txHash); - expect(tx).toBeDefined(); - expect(tx.gasPrice.toString()).toBe('0'); }); }); diff --git a/test/cli/cli-iexec-deal.test.js b/test/cli/cli-iexec-deal.test.js index 5b1cd759..182ad049 100644 --- a/test/cli/cli-iexec-deal.test.js +++ b/test/cli/cli-iexec-deal.test.js @@ -16,7 +16,7 @@ import { } from './cli-test-utils.js'; import '../jest-setup.js'; -const testChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('iexec deal', () => { let userWallet; @@ -37,7 +37,7 @@ describe('iexec deal', () => { workClockTimeRef: '0', }).then(({ catid }) => catid.toString()); // restore user wallet - userWallet = await setRandomWallet(); + userWallet = await setRandomWallet(testChain)(); await execAsync(`${iexecPath} app init`); await execAsync(`${iexecPath} dataset init`); await execAsync(`${iexecPath} workerpool init`); diff --git a/test/cli/cli-iexec-ens.test.js b/test/cli/cli-iexec-ens.test.js index 45d41003..558012e0 100644 --- a/test/cli/cli-iexec-ens.test.js +++ b/test/cli/cli-iexec-ens.test.js @@ -10,7 +10,7 @@ import { } from './cli-test-utils.js'; import '../jest-setup.js'; -const testChain = TEST_CHAINS['bellecour-fork']; +const ensFeaturedChain = TEST_CHAINS['bellecour-fork']; describe('iexec ens', () => { let userWallet; @@ -21,8 +21,8 @@ describe('iexec ens', () => { beforeAll(async () => { await globalSetup('cli-iexec-ens'); await execAsync(`${iexecPath} init --skip-wallet --force`); - await setChain(testChain)(); - userWallet = await setRandomWallet(); + await setChain(ensFeaturedChain)(); + userWallet = await setRandomWallet(ensFeaturedChain)(); await execAsync(`${iexecPath} app init`); await execAsync(`${iexecPath} dataset init`); await execAsync(`${iexecPath} workerpool init`); @@ -54,20 +54,6 @@ describe('iexec ens', () => { expect(res.setResolverTxHash).toBeTxHash(); expect(res.setAddrTxHash).toBeTxHash(); expect(res.setNameTxHash).toBeTxHash(); - await testChain.provider.getTransaction(res.registerTxHash).then((tx) => { - expect(tx.gasPrice.toString()).toBe('0'); - }); - await testChain.provider - .getTransaction(res.setResolverTxHash) - .then((tx) => { - expect(tx.gasPrice.toString()).toBe('0'); - }); - await testChain.provider.getTransaction(res.setAddrTxHash).then((tx) => { - expect(tx.gasPrice.toString()).toBe('0'); - }); - await testChain.provider.getTransaction(res.setNameTxHash).then((tx) => { - expect(tx.gasPrice.toString()).toBe('0'); - }); const showAddressRes = await runIExecCliRaw(`${iexecPath} wallet show`); expect(showAddressRes.ens).toBe(expectedEns); diff --git a/test/cli/cli-iexec-info.test.js b/test/cli/cli-iexec-info.test.js index 49baef9b..9107f31d 100644 --- a/test/cli/cli-iexec-info.test.js +++ b/test/cli/cli-iexec-info.test.js @@ -8,17 +8,17 @@ import { } from './cli-test-utils.js'; import '../jest-setup.js'; -const testChain = TEST_CHAINS['bellecour-fork']; - describe('iexec info', () => { beforeAll(async () => { await globalSetup('cli-iexec-info'); - await setChain(testChain)(); }); afterAll(async () => { await globalTeardown(); }); - test('iexec info', async () => { + + test('iexec info (bellecour)', async () => { + const testChain = TEST_CHAINS['bellecour-fork']; + await setChain(testChain)(); const raw = await execAsync(`${iexecPath} info --raw`); const res = JSON.parse(raw); expect(res.ok).toBe(true); @@ -34,6 +34,24 @@ describe('iexec info', () => { expect(res.useNative).toBe(true); }); + test('iexec info (arbitrum-sepolia)', async () => { + const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; + await setChain(testChain)(); + const raw = await execAsync(`${iexecPath} info --raw`); + const res = JSON.parse(raw); + expect(res.ok).toBe(true); + expect(res.pocoVersion).toBeDefined(); + expect(res.host).toBe(testChain.rpcURL); + expect(res.hubAddress).toBe( + testChain.hubAddress || testChain.defaults.hubAddress, + ); + expect(res.appRegistryAddress).toBeDefined(); + expect(res.datasetRegistryAddress).toBeDefined(); + expect(res.workerpoolRegistryAddress).toBeDefined(); + expect(res.rlcAddress).toBeDefined(); + expect(res.useNative).toBe(false); + }); + test('iexec info --chain mainnet', async () => { const raw = await execAsync(`${iexecPath} info --raw --chain mainnet`); const res = JSON.parse(raw); diff --git a/test/cli/cli-iexec-init.test.js b/test/cli/cli-iexec-init.test.js index 0c387f92..3eadaad9 100644 --- a/test/cli/cli-iexec-init.test.js +++ b/test/cli/cli-iexec-init.test.js @@ -9,7 +9,7 @@ import { } from './cli-test-utils.js'; import '../jest-setup.js'; -const testChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('iexec init', () => { beforeAll(async () => { diff --git a/test/cli/cli-iexec-order.test.js b/test/cli/cli-iexec-order.test.js index 9047e166..3d899710 100644 --- a/test/cli/cli-iexec-order.test.js +++ b/test/cli/cli-iexec-order.test.js @@ -13,7 +13,7 @@ import { } from './cli-test-utils.js'; import '../jest-setup.js'; -const testChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('iexec order', () => { let userWallet; @@ -26,7 +26,7 @@ describe('iexec order', () => { // init the project await execAsync(`${iexecPath} init --skip-wallet --force`); await setChain(testChain)(); - userWallet = await setRandomWallet(); + userWallet = await setRandomWallet(testChain)(); await execAsync(`${iexecPath} app init`); await execAsync(`${iexecPath} dataset init`); await execAsync(`${iexecPath} workerpool init`); @@ -157,9 +157,6 @@ describe('iexec order', () => { expect(res.volume).toBe('1'); expect(res.dealid).toBeDefined(); expect(res.txHash).toBeDefined(); - await testChain.provider.getTransaction(res.txHash).then((tx) => { - expect(tx.gasPrice.toString()).toBe('0'); - }); }); test('iexec order sign --app', async () => { @@ -258,9 +255,6 @@ describe('iexec order', () => { expect(res.workerpoolorder).toBeUndefined(); expect(res.requestorder).toBeUndefined(); expect(res.fail).toBeUndefined(); - await testChain.provider.getTransaction(res.apporder.txHash).then((tx) => { - expect(tx.gasPrice.toString()).toBe('0'); - }); }); test('iexec order cancel --dataset', async () => { @@ -276,11 +270,6 @@ describe('iexec order', () => { expect(res.workerpoolorder).toBeUndefined(); expect(res.requestorder).toBeUndefined(); expect(res.fail).toBeUndefined(); - await testChain.provider - .getTransaction(res.datasetorder.txHash) - .then((tx) => { - expect(tx.gasPrice.toString()).toBe('0'); - }); }); test('iexec order cancel --workerpool', async () => { @@ -296,11 +285,6 @@ describe('iexec order', () => { expect(res.workerpoolorder.txHash).toBeDefined(); expect(res.requestorder).toBeUndefined(); expect(res.fail).toBeUndefined(); - await testChain.provider - .getTransaction(res.workerpoolorder.txHash) - .then((tx) => { - expect(tx.gasPrice.toString()).toBe('0'); - }); }); test('iexec order cancel --request', async () => { @@ -318,10 +302,5 @@ describe('iexec order', () => { expect(res.requestorder).toBeDefined(); expect(res.requestorder.txHash).toBeDefined(); expect(res.fail).toBeUndefined(); - await testChain.provider - .getTransaction(res.requestorder.txHash) - .then((tx) => { - expect(tx.gasPrice.toString()).toBe('0'); - }); }); }); diff --git a/test/cli/cli-iexec-requester.test.js b/test/cli/cli-iexec-requester.test.js index 100df368..2478a5f8 100644 --- a/test/cli/cli-iexec-requester.test.js +++ b/test/cli/cli-iexec-requester.test.js @@ -9,7 +9,7 @@ import { } from './cli-test-utils.js'; import '../jest-setup.js'; -const testChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('iexec requester', () => { let userWallet; @@ -19,7 +19,7 @@ describe('iexec requester', () => { // init the project await execAsync(`${iexecPath} init --skip-wallet --force`); await setChain(testChain)(); - userWallet = await setRandomWallet(); + userWallet = await setRandomWallet(testChain)(); }); afterAll(async () => { await globalTeardown(); diff --git a/test/cli/cli-iexec-result.test.js b/test/cli/cli-iexec-result.test.js index c8decbd2..bf35550d 100644 --- a/test/cli/cli-iexec-result.test.js +++ b/test/cli/cli-iexec-result.test.js @@ -10,7 +10,7 @@ import { } from './cli-test-utils.js'; import '../jest-setup.js'; -const testChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('iexec result', () => { let userWallet; @@ -26,7 +26,7 @@ describe('iexec result', () => { }); beforeEach(async () => { - userWallet = await setRandomWallet(); + userWallet = await setRandomWallet(testChain)(); }); describe('generate-encryption-keypair', () => { diff --git a/test/cli/cli-iexec-storage.test.js b/test/cli/cli-iexec-storage.test.js index 909dd71d..d2baf06a 100644 --- a/test/cli/cli-iexec-storage.test.js +++ b/test/cli/cli-iexec-storage.test.js @@ -9,7 +9,7 @@ import { } from './cli-test-utils.js'; import '../jest-setup.js'; -const testChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('iexec storage', () => { beforeAll(async () => { @@ -20,7 +20,7 @@ describe('iexec storage', () => { }); beforeEach(async () => { - await setRandomWallet(); + await setRandomWallet(testChain)(); }); afterAll(async () => { diff --git a/test/cli/cli-iexec-task.test.js b/test/cli/cli-iexec-task.test.js index 9528aee2..5ed6f0bf 100644 --- a/test/cli/cli-iexec-task.test.js +++ b/test/cli/cli-iexec-task.test.js @@ -17,7 +17,7 @@ import { } from './cli-test-utils.js'; import '../jest-setup.js'; -const testChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('iexec task', () => { let userApp; @@ -36,7 +36,7 @@ describe('iexec task', () => { workClockTimeRef: '0', }).then(({ catid }) => catid.toString()); // restore user wallet - await setRandomWallet(); + await setRandomWallet(testChain)(); await execAsync(`${iexecPath} app init`); await execAsync(`${iexecPath} dataset init`); await execAsync(`${iexecPath} workerpool init`); diff --git a/test/cli/cli-iexec-wallet.test.js b/test/cli/cli-iexec-wallet.test.js index ecae2345..091415c3 100644 --- a/test/cli/cli-iexec-wallet.test.js +++ b/test/cli/cli-iexec-wallet.test.js @@ -1,10 +1,11 @@ -import { describe, test, expect } from '@jest/globals'; +import { describe, test, expect, beforeEach } from '@jest/globals'; import { TEST_CHAINS, execAsync, getRandomAddress, getRandomWallet, setBalance, + setNRlcBalance, } from '../test-utils.js'; import { checkExists, @@ -18,7 +19,8 @@ import { } from './cli-test-utils.js'; import '../jest-setup.js'; -const testChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; +const nativeTestChain = TEST_CHAINS['bellecour-fork']; describe('iexec wallet', () => { let userWallet; @@ -29,8 +31,7 @@ describe('iexec wallet', () => { await globalSetup('cli-iexec-wallet'); // init the project await execAsync(`${iexecPath} init --skip-wallet --force`); - await setChain(testChain)(); - userWallet = await setRandomWallet(); + userWallet = await setRandomWallet(testChain)(); importedWallet = getRandomWallet(); const { fileName } = await runIExecCliRaw( `${iexecPath} wallet import ${importedWallet.privateKey} --password test --force`, @@ -40,7 +41,9 @@ describe('iexec wallet', () => { beforeEach(async () => { // reset user wallet - await setWallet(userWallet.privateKey); + await setWallet(testChain)(userWallet.privateKey); + // reset chain + await setChain(testChain)(); }); afterAll(async () => { @@ -146,16 +149,18 @@ describe('iexec wallet', () => { describe('show', () => { beforeAll(async () => { - await setBalance(testChain)(userWallet.address, 10n * 10n ** 18n); + await setBalance(testChain)(userWallet.address, 1n * 10n ** 18n); + await setNRlcBalance(testChain)(userWallet.address, 10n * 10n ** 9n); }); test('iexec wallet show (user wallet)', async () => { + await setNRlcBalance(testChain)(userWallet.address, 10n * 10n ** 9n); const res = await runIExecCliRaw(`${iexecPath} wallet show`); expect(res.ok).toBe(true); expect(res.wallet.address).toBe(userWallet.address); expect(res.wallet.publicKey).toBeUndefined(); expect(res.wallet.privateKey).toBeUndefined(); - expect(res.balance.ether).toBeUndefined(); + expect(res.balance.ether).toBe('1.0'); expect(res.balance.RLC).toBe('10.0'); expect(res.balance.nRLC).toBe('10000000000'); }); @@ -168,7 +173,7 @@ describe('iexec wallet', () => { expect(res.wallet.address).toBe(userWallet.address); // expect(res.wallet.publicKey).toBe(userWallet.publicKey); // unexpected format expect(res.wallet.privateKey).toBe(userWallet.privateKey); - expect(res.balance.ether).toBeUndefined(); + expect(res.balance.ether).toBe('1.0'); expect(res.balance.RLC).toBe('10.0'); expect(res.balance.nRLC).toBe('10000000000'); }); @@ -179,8 +184,7 @@ describe('iexec wallet', () => { ); expect(res.ok).toBe(true); expect(res.wallet).toBeUndefined(); - expect(res.balance.ether).toBeUndefined(); - expect(res.balance.nRLC).toBeDefined(); + expect(res.balance.ether).toBe('0.0'); expect(res.balance.RLC).toBe('0.0'); expect(res.balance.nRLC).toBe('0'); }); @@ -280,7 +284,8 @@ describe('iexec wallet', () => { describe('send-ether', () => { test('iexec wallet send-ether (error on sidechain)', async () => { - await setBalance(testChain)(userWallet.address, 10n * 10n ** 18n); + await setChain(nativeTestChain)(); + await setBalance(nativeTestChain)(userWallet.address, 10n * 10n ** 18n); const to = getRandomAddress(); const res = await runIExecCliRaw( `${iexecPath} wallet send-ether 1 gwei --to ${to} --force`, @@ -293,12 +298,8 @@ describe('iexec wallet', () => { }); describe('send-RLC', () => { - beforeAll(async () => { - await setBalance(testChain)(userWallet.address, 10n * 10n ** 18n); - }); - test('iexec wallet send-RLC 0.5', async () => { - await setBalance(testChain)(userWallet.address, 10n * 10n ** 18n); + await setNRlcBalance(testChain)(userWallet.address, 10n ** 9n); const to = getRandomAddress(); const res = await runIExecCliRaw( `${iexecPath} wallet send-RLC 0.5 --to ${to} --force`, @@ -312,13 +313,11 @@ describe('iexec wallet', () => { `${iexecPath} wallet show ${to}`, ); expect(balance.RLC).toBe('0.5'); - await testChain.provider.getTransaction(res.txHash).then((tx) => { - expect(tx.gasPrice.toString()).toBe('0'); - }); }); test('iexec wallet send-RLC 1000000000 nRLC', async () => { const to = getRandomAddress(); + await setNRlcBalance(testChain)(userWallet.address, 10n ** 9n); const res = await runIExecCliRaw( `${iexecPath} wallet send-RLC 1000000000 nRLC --to ${to} --force`, ); @@ -336,34 +335,35 @@ describe('iexec wallet', () => { describe('sweep', () => { test('iexec wallet sweep', async () => { - const walletToSweep = getRandomWallet(); + const walletToSweep = await setRandomWallet(testChain)(); const rlcBalance = 10n; - await setBalance(testChain)( + await setNRlcBalance(testChain)( walletToSweep.address, - rlcBalance * 10n ** 18n, + rlcBalance * 10n ** 9n, ); const to = getRandomAddress(); - await runIExecCliRaw( - `${iexecPath} wallet import ${walletToSweep.privateKey} --password test`, - ); const res = await runIExecCliRaw( - `${iexecPath} wallet sweep --to ${to} --wallet-address ${walletToSweep.address} --password test --force`, + `${iexecPath} wallet sweep --to ${to} --force`, ); + expect(res.ok).toBe(true); expect(res.from).toBe(walletToSweep.address); expect(res.to).toBe(to); - expect(res.sendERC20TxHash).toBeUndefined(); + expect(res.sendERC20TxHash).toBeDefined(); expect(res.sendNativeTxHash).toBeDefined(); expect(res.errors).toBeUndefined(); - const { balance } = await runIExecCliRaw( + const { balance: balanceTo } = await runIExecCliRaw( `${iexecPath} wallet show ${to}`, ); - expect(balance.RLC).toBe(`${rlcBalance}.0`); - await testChain.provider - .getTransaction(res.sendNativeTxHash) - .then((tx) => { - expect(tx.gasPrice.toString()).toBe('0'); - }); + const { balance: balanceFrom } = await runIExecCliRaw( + `${iexecPath} wallet show ${walletToSweep.address}`, + ); + + expect(balanceTo.RLC).toBe(`${rlcBalance}.0`); + expect(balanceTo.ether).not.toBe('0.0'); + + expect(balanceFrom.RLC).toBe('0.0'); + expect(balanceFrom.ether).toBe('0.0'); }); }); }); diff --git a/test/cli/cli-iexec-workerpool.test.js b/test/cli/cli-iexec-workerpool.test.js index a165b0c0..4bd263bc 100644 --- a/test/cli/cli-iexec-workerpool.test.js +++ b/test/cli/cli-iexec-workerpool.test.js @@ -17,7 +17,7 @@ import { } from './cli-test-utils.js'; import '../jest-setup.js'; -const testChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('iexec workerpool', () => { let userWallet; @@ -28,7 +28,7 @@ describe('iexec workerpool', () => { // init the project await execAsync(`${iexecPath} init --skip-wallet --force`); await setChain(testChain)(); - userWallet = await setRandomWallet(); + userWallet = await setRandomWallet(testChain)(); await execAsync(`${iexecPath} workerpool init`); const deployed = await execAsync( `${iexecPath} workerpool deploy --raw`, @@ -58,49 +58,6 @@ describe('iexec workerpool', () => { expect(res.ok).toBe(true); expect(res.address).toBeDefined(); expect(res.txHash).toBeDefined(); - await testChain.provider.getTransaction(res.txHash).then((tx) => { - expect(tx.gasPrice.toString()).toBe('0'); - }); - }); - }); - - describe('set-api-url', () => { - test('iexec workerpool set-api-url', async () => { - await execAsync( - `${iexecPath} ens register ${userFirstDeployedWorkerpoolAddress.toLowerCase()} --for ${userFirstDeployedWorkerpoolAddress}`, - ); - const raw = await execAsync( - `${iexecPath} workerpool set-api-url https://my-workerpool.com ${userFirstDeployedWorkerpoolAddress} --raw`, - ); - const res = JSON.parse(raw); - expect(res.ok).toBe(true); - expect(res.address).toBe(userFirstDeployedWorkerpoolAddress); - expect(res.url).toBe('https://my-workerpool.com'); - expect(res.txHash).toBeTxHash(); - await testChain.provider.getTransaction(res.txHash).then((tx) => { - expect(tx.gasPrice.toString()).toBe('0'); - }); - - const showRes = await runIExecCliRaw( - `${iexecPath} workerpool show ${userFirstDeployedWorkerpoolAddress}`, - ); - expect(showRes.apiUrl).toBe('https://my-workerpool.com'); - }); - - test('iexec workerpool set-api-url (fail no ENS)', async () => { - await setWorkerpoolUniqueDescription(); - const { address } = await runIExecCliRaw( - `${iexecPath} workerpool deploy`, - ); - const raw = await execAsync( - `${iexecPath} workerpool set-api-url https://my-workerpool.com --raw`, - ).catch((e) => e.message); - const res = JSON.parse(raw); - expect(res.ok).toBe(false); - expect(res.error.name).toBe('Error'); - expect(res.error.message).toBe( - `Missing ENS for workerpool ${address}. You probably forgot to run "iexec ens register --for ${address}"`, - ); }); }); @@ -171,9 +128,6 @@ describe('iexec workerpool', () => { expect(res.address).toBe(address); expect(res.to).toBe(receiverAddress); expect(res.txHash).toBeDefined(); - await testChain.provider.getTransaction(res.txHash).then((tx) => { - expect(tx.gasPrice.toString()).toBe('0'); - }); }); }); diff --git a/test/cli/cli-test-utils.js b/test/cli/cli-test-utils.js index 762a6304..c75da08a 100644 --- a/test/cli/cli-test-utils.js +++ b/test/cli/cli-test-utils.js @@ -2,7 +2,7 @@ import { readFile, writeFile } from 'fs/promises'; import { pathExists, remove } from 'fs-extra'; import { join } from 'path'; import { Wallet } from 'ethers'; -import { execAsync, getId } from '../test-utils.js'; +import { execAsync, getId, setBalance } from '../test-utils.js'; const IEXEC_JSON = 'iexec.json'; const CHAIN_JSON = 'chain.json'; @@ -41,8 +41,11 @@ export const saveJSONToFile = async (json, fileName) => { await writeFile(filePath(fileName), text); }; -export const setWallet = async (privateKey) => { +export const setWallet = (chain) => async (privateKey) => { const wallet = privateKey ? new Wallet(privateKey) : Wallet.createRandom(); + if (chain.defaultInitBalance) { + await setBalance(chain)(wallet.address, chain.defaultInitBalance); + } const jsonWallet = { privateKey: wallet.privateKey, publicKey: wallet.publicKey, @@ -51,10 +54,10 @@ export const setWallet = async (privateKey) => { await saveJSONToFile(jsonWallet, 'wallet.json'); return jsonWallet; }; -export const setRandomWallet = () => setWallet(); +export const setRandomWallet = (chain) => () => setWallet(chain)(); export const setChainsPocoAdminWallet = (chain) => () => - setWallet(chain.pocoAdminWallet.privateKey); + setWallet(chain)(chain.pocoAdminWallet.privateKey); export const removeWallet = () => remove('./wallet.json').catch(() => {}); diff --git a/test/cli/cli-tx-options.test.js b/test/cli/cli-tx-options.test.js deleted file mode 100644 index 5b7c44a8..00000000 --- a/test/cli/cli-tx-options.test.js +++ /dev/null @@ -1,102 +0,0 @@ -import { describe, test, expect } from '@jest/globals'; -import { - TEST_CHAINS, - execAsync, - getRandomAddress, - setBalance, -} from '../test-utils.js'; -import { - globalSetup, - globalTeardown, - iexecPath, - setChain, - setRandomWallet, -} from './cli-test-utils.js'; -import '../jest-setup.js'; - -const testChain = TEST_CHAINS['custom-token-chain']; - -describe('tx options', () => { - let userWallet; - - beforeAll(async () => { - await globalSetup('cli-tx-options'); - // init the project - await execAsync(`${iexecPath} init --skip-wallet`); - await setChain(testChain)(); - userWallet = await setRandomWallet(); - await setBalance(testChain)(userWallet.address, 50n * 10n ** 18n); - }); - - afterAll(async () => { - await globalTeardown(); - }); - - describe('--gas-price', () => { - test('--gas-price 1000000001', async () => { - const raw = await execAsync( - `${iexecPath} wallet send-ether 1 wei --to ${getRandomAddress()} --force --gas-price 1000000001 --raw`, - ); - const res = JSON.parse(raw); - expect(res.ok).toBe(true); - expect(res.txHash).toBeDefined(); - const tx = await testChain.provider.getTransaction(res.txHash); - expect(tx).toBeDefined(); - expect(tx.gasPrice.toString()).toBe('1000000001'); - }); - - test('--gas-price 0', async () => { - const raw = await execAsync( - `${iexecPath} wallet send-ether 1 wei --to ${getRandomAddress()} --force --gas-price 0 --raw`, - ); - const res = JSON.parse(raw); - expect(res.ok).toBe(true); - expect(res.txHash).toBeDefined(); - const tx = await testChain.provider.getTransaction(res.txHash); - expect(tx).toBeDefined(); - expect(tx.gasPrice.toString()).toBe('0'); - }); - - test('--gas-price 1.1 gwei', async () => { - const raw = await execAsync( - `${iexecPath} wallet send-ether 1 wei --to ${getRandomAddress()} --force --gas-price 1.1 gwei --raw`, - ); - const res = JSON.parse(raw); - expect(res.ok).toBe(true); - expect(res.txHash).toBeDefined(); - const tx = await testChain.provider.getTransaction(res.txHash); - expect(tx).toBeDefined(); - expect(tx.gasPrice.toString()).toBe('1100000000'); - }); - - test('--gas-price -1 (invalid gas-price)', async () => { - const raw = await execAsync( - `${iexecPath} wallet send-ether 1 wei --to ${getRandomAddress()} --force --gas-price -1 --raw`, - ).catch((e) => e.message); - const res = JSON.parse(raw); - expect(res.ok).toBe(false); - expect(res.txHash).toBeUndefined(); - expect(res.error.message).toBe('-1 is not a valid amount'); - }); - - test('--gas-price 0.1 wei (invalid gas-price)', async () => { - const raw = await execAsync( - `${iexecPath} wallet send-ether 1 wei --to ${getRandomAddress()} --force --gas-price 0.1 wei --raw`, - ).catch((e) => e.message); - const res = JSON.parse(raw); - expect(res.ok).toBe(false); - expect(res.txHash).toBeUndefined(); - expect(res.error.message).toBe('0.1 wei is not a valid amount'); - }); - - test('--gas-price 1 ethereum (invalid gas-price)', async () => { - const raw = await execAsync( - `${iexecPath} wallet send-ether 1 wei --to ${getRandomAddress()} --force --gas-price 1 ethereum --raw`, - ).catch((e) => e.message); - const res = JSON.parse(raw); - expect(res.ok).toBe(false); - expect(res.txHash).toBeUndefined(); - expect(res.error.message).toBe('1 ethereum is not a valid amount'); - }); - }); -}); diff --git a/test/docker-compose.yml b/test/docker-compose.yml index fcb0ae04..e1434b8e 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -1,18 +1,4 @@ services: - custom-token-chain: - restart: unless-stopped - image: 'iexechub/poco-chaintest:5.3.2-token-openethereum' - expose: - - 8545 - ports: - - 18545:8545 - healthcheck: - test: nc -z 0.0.0.0 8545 - interval: 10s - timeout: 5s - retries: 3 - start_period: 30s - bellecour-fork: restart: 'no' image: ghcr.io/foundry-rs/foundry:v1.0.0 @@ -30,61 +16,38 @@ services: retries: 3 start_period: 30s - graphnode-postgres: - image: postgres:12 - restart: unless-stopped - command: - - 'postgres' - - '-cshared_preload_libraries=pg_stat_statements' + arbitrum-sepolia-fork: + restart: 'no' + image: ghcr.io/foundry-rs/foundry:v1.0.0 + entrypoint: anvil + command: '--host 0.0.0.0 --port 8545 --block-time 1 --fork-url $ARBITRUM_SEPOLIA_FORK_URL --fork-block-number $ARBITRUM_SEPOLIA_FORK_BLOCK --chain-id 421614' expose: - - 5432 - environment: - POSTGRES_USER: graphnode - POSTGRES_PASSWORD: password - POSTGRES_DB: graphnode-db + - 8545 + ports: + - 8555:8545 healthcheck: - test: pg_isready -U graphnode -d graphnode-db + # check port 8545 is open without nc + test: (echo >/dev/tcp/$(hostname)/8545) &>/dev/null interval: 10s timeout: 5s retries: 3 start_period: 30s - graphnode: - image: graphprotocol/graph-node:v0.27.0 - restart: unless-stopped + unknown-chain-fork: + restart: 'no' + image: ghcr.io/foundry-rs/foundry:v1.0.0 + entrypoint: anvil + command: '--host 0.0.0.0 --port 8545 --block-time 1 --fork-url $ARBITRUM_SEPOLIA_FORK_URL --fork-block-number $ARBITRUM_SEPOLIA_FORK_BLOCK --chain-id 421615' expose: - - 8000 - - 8020 + - 8545 ports: - # GraphQL HTTP - - 8000:8000 - # GraphQL WS - # - 8001:8001 - # admin RPC - - 8020:8020 - # metrics - # - 8040:8040 - environment: - postgres_host: graphnode-postgres - postgres_port: 5432 - postgres_user: graphnode - postgres_pass: password - postgres_db: graphnode-db - ipfs: ipfs:5001 - ethereum: bellecour:http://bellecour-fork:8545 - GRAPH_ETHEREUM_GENESIS_BLOCK_NUMBER: $BELLECOUR_FORK_BLOCK - depends_on: - bellecour-fork: - condition: service_healthy - graphnode-postgres: - condition: service_healthy - ipfs: - condition: service_healthy + - 8565:8545 healthcheck: - test: netcat -w 1 0.0.0.0 8020 + # check port 8545 is open without nc + test: (echo >/dev/tcp/$(hostname)/8545) &>/dev/null interval: 10s timeout: 5s - retries: 5 + retries: 3 start_period: 30s service-internal-error: @@ -96,7 +59,7 @@ services: ports: - 5500:80 - sms: + sms-bellecour: image: iexechub/iexec-sms:8.7.0 restart: unless-stopped environment: @@ -117,7 +80,28 @@ services: bellecour-fork: condition: service_healthy - result-proxy: + sms-arbitrum-sepolia: + image: iexechub/iexec-sms:8.7.0 + restart: unless-stopped + environment: + JAVA_TOOL_OPTIONS: '-Xmx256M' + IEXEC_SMS_BLOCKCHAIN_NODE_ADDRESS: http://arbitrum-sepolia-fork:8545 + IEXEC_HUB_ADDRESS: '0xB2157BF2fAb286b2A4170E3491Ac39770111Da3E' + IEXEC_SMS_TEE_RUNTIME_FRAMEWORK: scone + IEXEC_SMS_IMAGE_LAS_IMAGE: 'las-image' + IEXEC_TEE_WORKER_PRE_COMPUTE_IMAGE: 'pre-compute-image' + IEXEC_TEE_WORKER_PRE_COMPUTE_FINGERPRINT: 'pre-compute-fingerprint' + IEXEC_TEE_WORKER_POST_COMPUTE_IMAGE: 'post-compute-image' + IEXEC_TEE_WORKER_POST_COMPUTE_FINGERPRINT: 'post-compute-fingerprint' + ports: + - 13350:13300 + healthcheck: + test: curl -f localhost:13300/actuator/health || exit 1 + depends_on: + arbitrum-sepolia-fork: + condition: service_healthy + + result-proxy-bellecour: image: iexechub/iexec-result-proxy:7.1.0 restart: unless-stopped environment: @@ -137,6 +121,26 @@ services: ipfs: condition: service_healthy + result-proxy-arbitrum-sepolia: + image: iexechub/iexec-result-proxy:7.1.0 + restart: unless-stopped + environment: + IEXEC_PRIVATE_CHAIN_ADDRESS: http://arbitrum-sepolia-fork:8545 + IEXEC_PUBLIC_CHAIN_ADDRESS: http://arbitrum-sepolia-fork:8545 + IEXEC_HUB_ADDRESS: '0xB2157BF2fAb286b2A4170E3491Ac39770111Da3E' + MONGO_HOST: result-proxy-mongo + MONGO_PORT: 13202 + IEXEC_IPFS_HOST: ipfs + ports: + - 13250:13200 + depends_on: + arbitrum-sepolia-fork: + condition: service_healthy + result-proxy-mongo: + condition: service_started + ipfs: + condition: service_healthy + result-proxy-mongo: restart: unless-stopped image: library/mongo:4.2 @@ -186,7 +190,7 @@ services: retries: 3 start_period: 30s - market-watcher: + market-watcher-bellecour: image: iexechub/iexec-market-watcher:7.0.1 restart: unless-stopped environment: @@ -204,7 +208,28 @@ services: market-mongo: condition: service_started - market-api: + market-watcher-arbitrum-sepolia: + image: iexechub/iexec-market-watcher:7.0.1 + restart: unless-stopped + environment: + CHAIN: ARBITRUM_SEPOLIA + START_BLOCK: $ARBITRUM_SEPOLIA_FORK_BLOCK + CHAIN_ID: 421614 + IEXEC_ADDRESS: '0xB2157BF2fAb286b2A4170E3491Ac39770111Da3E' + IS_NATIVE: 'false' + ETH_WS_HOST: ws://arbitrum-sepolia-fork:8545 + ETH_RPC_HOST: http://arbitrum-sepolia-fork:8545 + MONGO_HOST: market-mongo + REDIS_HOST: market-redis + depends_on: + arbitrum-sepolia-fork: + condition: service_healthy + market-redis: + condition: service_healthy + market-mongo: + condition: service_started + + market-api-bellecour: image: iexechub/iexec-market-api:7.1.2 restart: unless-stopped ports: @@ -230,7 +255,33 @@ services: market-mongo: condition: service_started - custom-token-chain-compass: + market-api-arbitrum-sepolia: + image: iexechub/iexec-market-api:7.1.2 + restart: unless-stopped + ports: + - 3050:3000 + expose: + - 3000 + environment: + CHAINS: ARBITRUM_SEPOLIA_FORK + ARBITRUM_SEPOLIA_FORK_ETH_RPC_HOST: http://arbitrum-sepolia-fork:8545 + ARBITRUM_SEPOLIA_FORK_CHAIN_ID: 421614 + ARBITRUM_SEPOLIA_FORK_IS_NATIVE: 'false' + ARBITRUM_SEPOLIA_FORK_IEXEC_ADDRESS: '0xB2157BF2fAb286b2A4170E3491Ac39770111Da3E' + MONGO_HOST: market-mongo + REDIS_HOST: market-redis + RATE_LIMIT_MAX: 10000 + RATE_LIMIT_PERIOD: 60000 + MAX_OPEN_ORDERS_PER_WALLET: 1000 + depends_on: + arbitrum-sepolia-fork: + condition: service_healthy + market-redis: + condition: service_healthy + market-mongo: + condition: service_started + + compass-arbitrum-sepolia: image: iexechub/compass:v0.1.1 restart: unless-stopped environment: @@ -247,19 +298,30 @@ services: command: - echo "all services ready" depends_on: + # bellecour stack bellecour-fork: condition: service_healthy - custom-token-chain: + sms-bellecour: condition: service_healthy - graphnode: + market-watcher-bellecour: + condition: service_started + market-api-bellecour: + condition: service_started + result-proxy-bellecour: + condition: service_started + # arbitrum-sepolia stack + arbitrum-sepolia-fork: condition: service_healthy - sms: + sms-arbitrum-sepolia: condition: service_healthy - market-watcher: + market-watcher-arbitrum-sepolia: condition: service_started - market-api: + market-api-arbitrum-sepolia: condition: service_started - result-proxy: + result-proxy-arbitrum-sepolia: condition: service_started - custom-token-chain-compass: + compass-arbitrum-sepolia: + condition: service_healthy + # unknown chain + unknown-chain-fork: condition: service_healthy diff --git a/test/lib/e2e/IExecAccountModule.test.js b/test/lib/e2e/IExecAccountModule.test.js index a4210f58..2c1d290c 100644 --- a/test/lib/e2e/IExecAccountModule.test.js +++ b/test/lib/e2e/IExecAccountModule.test.js @@ -11,15 +11,16 @@ import { import '../../jest-setup.js'; import { IExec } from '../../../src/lib/index.js'; -const iexecTestChain = TEST_CHAINS['bellecour-fork']; -const tokenTestChain = TEST_CHAINS['custom-token-chain']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; +const tokenTestChain = TEST_CHAINS['arbitrum-sepolia-fork']; +const nativeTestChain = TEST_CHAINS['bellecour-fork']; describe('account', () => { describe('checkBalance()', () => { test('shows account nRLC stake and locked balances', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - await setNRlcBalance(iexecTestChain)(wallet.address, 10); - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec, wallet } = await getTestConfig(testChain)(); + await setNRlcBalance(testChain)(wallet.address, 10); + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); const initialBalance = await readOnlyIExec.account.checkBalance( @@ -74,7 +75,7 @@ describe('account', () => { describe('approve()', () => { test('require a signer', async () => { const spenderAddress = getRandomAddress(); - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); await expect(iexec.account.approve(10, spenderAddress)).rejects.toThrow( new Error( 'The current provider is not a signer, impossible to sign messages or transactions', @@ -83,7 +84,7 @@ describe('account', () => { }); test('rejects invalid address', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const spenderAddress = 'invalid_address'; const amount = 10; @@ -95,7 +96,7 @@ describe('account', () => { }); test('rejects invalid amount', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const spenderAddress = wallet.address; const amount = 'invalid_amount'; @@ -105,7 +106,7 @@ describe('account', () => { }); test('prevents approve negative amount', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const spenderAddress = wallet.address; const negativeAmount = -999; await expect( @@ -114,7 +115,7 @@ describe('account', () => { }); test('approve succeeds', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const spenderAddress = getRandomAddress(); const txHash = await iexec.account.approve(10, spenderAddress); expect(txHash).toBeDefined(); @@ -123,7 +124,7 @@ describe('account', () => { describe('checkAllowance()', () => { test('rejects invalid ownerAddress', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); const ownerAddress = 'invalid_address'; const spenderAddress = getRandomAddress(); @@ -135,7 +136,7 @@ describe('account', () => { }); test('rejects invalid spenderAddress', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); const ownerAddress = getRandomAddress(); const spenderAddress = "'invalid_address'"; @@ -147,7 +148,7 @@ describe('account', () => { }); test('return zero allowance if no approval exists', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); const ownerAddress = getRandomAddress(); const spenderAddress = getRandomAddress(); @@ -160,7 +161,7 @@ describe('account', () => { }); test('return the allowed amount as a BigNumber', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const ownerAddress = iexec.wallet.getAddress(); const spenderAddress = getRandomAddress(); const allowanceValue = '10'; @@ -184,7 +185,7 @@ describe('account', () => { describe('revokeApproval()', () => { test('require a signer', async () => { const spenderAddress = getRandomAddress(); - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); await expect( iexec.account.revokeApproval(spenderAddress), ).rejects.toThrow( @@ -195,7 +196,7 @@ describe('account', () => { }); test('rejects invalid address', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const spenderAddress = 'invalid_address'; await expect( @@ -206,7 +207,7 @@ describe('account', () => { }); test('revokeApproval succeeds', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const spenderAddress = getRandomAddress(); const approvalTxHash = await iexec.account.approve(10, spenderAddress); expect(approvalTxHash).toBeDefined(); @@ -224,7 +225,7 @@ describe('account', () => { describe('deposit()', () => { test('require a signer', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); await expect(iexec.account.deposit(10)).rejects.toThrow( new Error( 'The current provider is not a signer, impossible to sign messages or transactions', @@ -233,7 +234,7 @@ describe('account', () => { }); test('prevents deposit 0', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); await expect(iexec.account.deposit(0)).rejects.toThrow( new Error('Deposit amount must be greater than 0'), ); @@ -241,8 +242,8 @@ describe('account', () => { describe('native chain', () => { test('deposits native asset (1 nRLC = 10⁹ wei)', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - await setNRlcBalance(iexecTestChain)(wallet.address, 10); + const { iexec, wallet } = await getTestConfig(nativeTestChain)(); + await setNRlcBalance(nativeTestChain)(wallet.address, 10); const accountInitialBalance = await iexec.account.checkBalance( wallet.address, ); @@ -272,8 +273,8 @@ describe('account', () => { }); test('deposits specified unit', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - await setNRlcBalance(iexecTestChain)(wallet.address, ONE_RLC); + const { iexec, wallet } = await getTestConfig(nativeTestChain)(); + await setNRlcBalance(nativeTestChain)(wallet.address, ONE_RLC); const accountInitialBalance = await iexec.account.checkBalance( wallet.address, ); @@ -305,7 +306,7 @@ describe('account', () => { }); test('fails if amount exceed wallet balance', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(nativeTestChain)(); const accountInitialBalance = await iexec.account.checkBalance( wallet.address, ); @@ -335,7 +336,7 @@ describe('account', () => { describe('token chain', () => { test('deposits ERC20', async () => { - const { iexec, wallet } = getTestConfig(tokenTestChain)(); + const { iexec, wallet } = await getTestConfig(tokenTestChain)(); await setNRlcBalance(tokenTestChain)(wallet.address, 10); await setBalance(tokenTestChain)(wallet.address, ONE_ETH); const accountInitialBalance = await iexec.account.checkBalance( @@ -367,7 +368,7 @@ describe('account', () => { }); test('fails if amount exceed wallet balance', async () => { - const { iexec, wallet } = getTestConfig(tokenTestChain)(); + const { iexec, wallet } = await getTestConfig(tokenTestChain)(); await setNRlcBalance(tokenTestChain)(wallet.address, 10); await setBalance(tokenTestChain)(wallet.address, ONE_ETH); const accountInitialBalance = await iexec.account.checkBalance( @@ -400,7 +401,7 @@ describe('account', () => { describe('withdraw()', () => { test('require a signer', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); await expect(iexec.account.withdraw(10)).rejects.toThrow( new Error( 'The current provider is not a signer, impossible to sign messages or transactions', @@ -409,15 +410,15 @@ describe('account', () => { }); test('prevents withdraw 0', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); await expect(iexec.account.withdraw(0)).rejects.toThrow( new Error('Withdraw amount must be greater than 0'), ); }); test('withdraws stacked nRLC', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - await setNRlcBalance(iexecTestChain)(wallet.address, 10); + const { iexec, wallet } = await getTestConfig(testChain)(); + await setNRlcBalance(testChain)(wallet.address, 10); await iexec.account.deposit(10); const accountInitialBalance = await iexec.account.checkBalance( wallet.address, @@ -448,8 +449,8 @@ describe('account', () => { }); test('withdraws specified unit', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - await setNRlcBalance(iexecTestChain)(wallet.address, 10000); + const { iexec, wallet } = await getTestConfig(testChain)(); + await setNRlcBalance(testChain)(wallet.address, 10000); await iexec.account.deposit(10000); const accountInitialBalance = await iexec.account.checkBalance( wallet.address, @@ -480,8 +481,8 @@ describe('account', () => { }); test('fails if amount exceeds account balance)', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - await setNRlcBalance(iexecTestChain)(wallet.address, 10); + const { iexec, wallet } = await getTestConfig(testChain)(); + await setNRlcBalance(testChain)(wallet.address, 10); await iexec.account.deposit(10); const accountInitialBalance = await iexec.account.checkBalance( wallet.address, diff --git a/test/lib/e2e/IExecAppModule.test.js b/test/lib/e2e/IExecAppModule.test.js index 109484d6..4e0f6e63 100644 --- a/test/lib/e2e/IExecAppModule.test.js +++ b/test/lib/e2e/IExecAppModule.test.js @@ -17,15 +17,15 @@ import { errors } from '../../../src/lib/index.js'; const { SmsCallError } = errors; -const iexecTestChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('app', () => { describe('showApp()', () => { test('shows a deployed app', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const app = { owner: await iexec.wallet.getAddress(), name: `app${getId()}`, @@ -55,22 +55,22 @@ describe('app', () => { }); test('fails if the app is not deployed', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); const address = getRandomAddress(); await expect(readOnlyIExec.app.showApp(address)).rejects.toThrow( - new errors.ObjectNotFoundError('app', address, iexecTestChain.chainId), + new errors.ObjectNotFoundError('app', address, testChain.chainId), ); }); }); describe('showUserApp()', () => { test('shows the user app', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const app = { owner: wallet.address, name: `app${getId()}`, @@ -100,7 +100,7 @@ describe('app', () => { }); test('fails if the app is not deployed', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); const address = getRandomAddress(); @@ -112,10 +112,10 @@ describe('app', () => { describe('countUserApps()', () => { test('counts user app', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const resBeforeDeploy = await readOnlyIExec.app.countUserApps( wallet.address, ); @@ -129,7 +129,7 @@ describe('app', () => { describe('deployApp()', () => { test('require a signer', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); const app = { owner: getRandomAddress(), name: `app${getId()}`, @@ -146,7 +146,7 @@ describe('app', () => { }); test('deploys an app', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const app = { owner: getRandomAddress(), name: `app${getId()}`, @@ -161,7 +161,7 @@ describe('app', () => { }); test('cannot deploy twice with the same params', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const app = { owner: getRandomAddress(), name: `app${getId()}`, @@ -179,10 +179,10 @@ describe('app', () => { describe('predictAppAddress()', () => { test('predicts the deployment address', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const app = { owner: getRandomAddress(), name: `app${getId()}`, @@ -204,10 +204,10 @@ describe('app', () => { describe('checkDeployedApp()', () => { test('checks an app is deployed', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const app = { owner: getRandomAddress(), name: `app${getId()}`, @@ -229,7 +229,7 @@ describe('app', () => { describe('transferApp()', () => { test('require a signer', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); await expect( iexec.app.transferApp(getRandomAddress(), getRandomAddress()), ).rejects.toThrow( @@ -241,8 +241,8 @@ describe('app', () => { test('transfers the ownership', async () => { const receiverAddress = getRandomAddress(); - const { iexec: iexecAppOwner } = getTestConfig(iexecTestChain)(); - const { iexec: iexecRandom } = getTestConfig(iexecTestChain)(); + const { iexec: iexecAppOwner } = await getTestConfig(testChain)(); + const { iexec: iexecRandom } = await getTestConfig(testChain)(); const { address } = await deployRandomApp(iexecAppOwner); await expect( iexecRandom.app.transferApp(getRandomAddress(), receiverAddress), @@ -262,13 +262,13 @@ describe('app', () => { describe('checkAppSecretExists()', () => { let randomAppAddress; beforeAll(async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const { address } = await deployRandomApp(iexec); randomAppAddress = address; }); test("throw a SmsCallError when the SMS can't be reached", async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, options: { smsURL: SERVICE_UNREACHABLE_URL, @@ -284,7 +284,7 @@ describe('app', () => { }); test('throw a SmsCallError when the SMS encounters an error', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, options: { smsURL: SERVICE_HTTP_500_URL, @@ -300,10 +300,10 @@ describe('app', () => { }); test('checks an app secret exist on SMS', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const { address } = await deployRandomApp(iexec); await expect( readOnlyIExec.app.checkAppSecretExists(address), @@ -319,14 +319,14 @@ describe('app', () => { let randomAppAddress; let randomAppOwnerWallet; beforeAll(async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const { address } = await deployRandomApp(iexec); randomAppAddress = address; randomAppOwnerWallet = wallet; }); test("throw a SmsCallError when the SMS can't be reached", async () => { - const { iexec } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)({ privateKey: randomAppOwnerWallet.privateKey, options: { smsURL: SERVICE_UNREACHABLE_URL, @@ -342,7 +342,7 @@ describe('app', () => { }); test('throw a SmsCallError when the SMS encounters an error', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)({ privateKey: randomAppOwnerWallet.privateKey, options: { smsURL: SERVICE_HTTP_500_URL, @@ -358,9 +358,9 @@ describe('app', () => { }); test('only owner can push secret', async () => { - const { iexec: iexecAppOwner } = getTestConfig(iexecTestChain)(); + const { iexec: iexecAppOwner } = await getTestConfig(testChain)(); const { iexec: iexecRandom, wallet: randomWallet } = - getTestConfig(iexecTestChain)(); + await getTestConfig(testChain)(); const { address: appAddress } = await deployRandomApp(iexecAppOwner); // only owner can push secret await expect( @@ -373,7 +373,7 @@ describe('app', () => { }); test('cannot update existing secret', async () => { - const { iexec: iexecAppOwner } = getTestConfig(iexecTestChain)(); + const { iexec: iexecAppOwner } = await getTestConfig(testChain)(); const { address: appAddress } = await deployRandomApp(iexecAppOwner); await expect( diff --git a/test/lib/e2e/IExecConfig.test.js b/test/lib/e2e/IExecConfig.test.js index 840ce21a..4d27f9aa 100644 --- a/test/lib/e2e/IExecConfig.test.js +++ b/test/lib/e2e/IExecConfig.test.js @@ -26,8 +26,8 @@ import { utils, IExecConfig, errors } from '../../../src/lib/index.js'; import IExecContractsClient from '../../../src/common/utils/IExecContractsClient.js'; import { getChainDefaults } from '../../../src/common/utils/config.js'; -const iexecTestChain = TEST_CHAINS['bellecour-fork']; -const unknownTestChain = TEST_CHAINS['custom-token-chain']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; +const unknownTestChain = TEST_CHAINS['unknown-chain']; describe('[IExecConfig]', () => { describe('constructor', () => { @@ -443,7 +443,7 @@ describe('[IExecConfig]', () => { const wallet = getRandomWallet(); const config = new IExecConfig({ ethProvider: utils.getSignerFromPrivateKey( - iexecTestChain.rpcURL, + testChain.rpcURL, wallet.privateKey, ), }); @@ -452,13 +452,10 @@ describe('[IExecConfig]', () => { expect(signer).toBeDefined(); expect(provider).toBeDefined(); expect(provider).toBeInstanceOf(JsonRpcProvider); - expect(chainId).toBe(iexecTestChain.chainId); + expect(chainId).toBe(testChain.chainId); const network = await provider.getNetwork(); - expect(network.chainId).toBe(BigInt(iexecTestChain.chainId)); - expect(network.name).toBe(iexecTestChain.defaults.name); - expect( - network.getPlugin('org.ethers.plugins.network.Ens').address, - ).toBe(iexecTestChain.defaults.ensRegistryAddress); + expect(network.chainId).toBe(BigInt(testChain.chainId)); + expect(network.name).toBe(testChain.defaults.name); }); test('getSignerFromPrivateKey() with network fallback', async () => { @@ -490,7 +487,7 @@ describe('[IExecConfig]', () => { describe('web3 provider', () => { test('InjectedProvider', async () => { const injectedProvider = new InjectedProvider( - iexecTestChain.rpcURL, + testChain.rpcURL, getRandomWallet().privateKey, ); const config = new IExecConfig({ @@ -501,13 +498,10 @@ describe('[IExecConfig]', () => { expect(signer).toBeDefined(); expect(provider).toBeDefined(); expect(provider).toBeInstanceOf(BrowserProvider); - expect(chainId).toBe(iexecTestChain.chainId); + expect(chainId).toBe(testChain.chainId); const network = await provider.getNetwork(); - expect(network.chainId).toBe(BigInt(iexecTestChain.chainId)); - expect(network.name).toBe(iexecTestChain.defaults.name); - expect( - network.getPlugin('org.ethers.plugins.network.Ens').address, - ).toBe(iexecTestChain.defaults.ensRegistryAddress); + expect(network.chainId).toBe(BigInt(testChain.chainId)); + expect(network.name).toBe(testChain.defaults.name); }); // skipped because no experimental networks are currently defined describe.skip('allowExperimentalNetworks', () => { @@ -554,7 +548,7 @@ describe('[IExecConfig]', () => { describe('ethers AbstractProvider', () => { test('JsonRpcProvider', async () => { - const ethersProvider = new JsonRpcProvider(iexecTestChain.rpcURL); + const ethersProvider = new JsonRpcProvider(testChain.rpcURL); const config = new IExecConfig({ ethProvider: ethersProvider, }); @@ -563,13 +557,10 @@ describe('[IExecConfig]', () => { expect(signer).toBeUndefined(); expect(provider).toBeDefined(); expect(provider).toBeInstanceOf(JsonRpcProvider); - expect(chainId).toBe(iexecTestChain.chainId); + expect(chainId).toBe(testChain.chainId); const network = await provider.getNetwork(); - expect(network.chainId).toBe(BigInt(iexecTestChain.chainId)); - expect(network.name).toBe(iexecTestChain.defaults.name); - expect( - network.getPlugin('org.ethers.plugins.network.Ens').address, - ).toBe(iexecTestChain.defaults.ensRegistryAddress); + expect(network.chainId).toBe(BigInt(testChain.chainId)); + expect(network.name).toBe(testChain.defaults.name); }); test('JsonRpcProvider with custom network (including ens)', async () => { @@ -584,7 +575,6 @@ describe('[IExecConfig]', () => { }, { hubAddress: unknownTestChain.hubAddress, - ensRegistryAddress: unknownTestChain.ensRegistryAddress, }, ); const { provider, signer, chainId } = @@ -615,7 +605,7 @@ describe('[IExecConfig]', () => { test('Wallet with provider', async () => { const ethersSigner = Wallet.createRandom( - new JsonRpcProvider(iexecTestChain.rpcURL), + new JsonRpcProvider(testChain.rpcURL), ); const config = new IExecConfig({ ethProvider: ethersSigner, @@ -626,13 +616,10 @@ describe('[IExecConfig]', () => { expect(signer).toBeInstanceOf(HDNodeWallet); expect(provider).toBeDefined(); expect(provider).toBeInstanceOf(JsonRpcProvider); - expect(chainId).toBe(iexecTestChain.chainId); + expect(chainId).toBe(testChain.chainId); const network = await provider.getNetwork(); - expect(network.chainId).toBe(BigInt(iexecTestChain.chainId)); - expect(network.name).toBe(iexecTestChain.defaults.name); - expect( - network.getPlugin('org.ethers.plugins.network.Ens').address, - ).toBe(iexecTestChain.defaults.ensRegistryAddress); + expect(network.chainId).toBe(BigInt(testChain.chainId)); + expect(network.name).toBe(testChain.defaults.name); }); }); @@ -709,7 +696,7 @@ describe('[IExecConfig]', () => { }); test('IExecConfig({ ethProvider: "http://localhost:8545" }, { hubAddress, bridgedNetworkConf })', async () => { const config = new IExecConfig( - { ethProvider: iexecTestChain.rpcURL }, + { ethProvider: testChain.rpcURL }, { bridgedNetworkConf: { rpcURL: unknownTestChain.rpcURL, @@ -736,10 +723,10 @@ describe('[IExecConfig]', () => { describe('resolveChainId()', () => { test('success', async () => { const config = new IExecConfig({ - ethProvider: iexecTestChain.rpcURL, + ethProvider: testChain.rpcURL, }); await expect(config.resolveChainId()).resolves.toBe( - parseInt(iexecTestChain.chainId, 10), + parseInt(testChain.chainId, 10), ); }); test('throw on network error', async () => { diff --git a/test/lib/e2e/IExecDatasetModule.test.js b/test/lib/e2e/IExecDatasetModule.test.js index de9ad10d..8f87a8e8 100644 --- a/test/lib/e2e/IExecDatasetModule.test.js +++ b/test/lib/e2e/IExecDatasetModule.test.js @@ -22,15 +22,15 @@ const { SmsCallError } = errors; const { readFile, ensureDir, writeFile } = fsExtra; -const iexecTestChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('dataset', () => { describe('showDataset()', () => { test('shows a deployed dataset', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const dataset = { owner: await iexec.wallet.getAddress(), name: `dataset${getId()}`, @@ -50,26 +50,22 @@ describe('dataset', () => { }); test('fails if the dataset is not deployed', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); const address = getRandomAddress(); await expect(readOnlyIExec.dataset.showDataset(address)).rejects.toThrow( - new errors.ObjectNotFoundError( - 'dataset', - address, - iexecTestChain.chainId, - ), + new errors.ObjectNotFoundError('dataset', address, testChain.chainId), ); }); }); describe('showUserDataset()', () => { test('shows the user dataset', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const dataset = { owner: wallet.address, name: `dataset${getId()}`, @@ -91,7 +87,7 @@ describe('dataset', () => { }); test('fails if the dataset is not deployed', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); const address = getRandomAddress(); @@ -103,10 +99,10 @@ describe('dataset', () => { describe('countUserDatasets()', () => { test('counts user datasets', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const resBeforeDeploy = await readOnlyIExec.dataset.countUserDatasets( wallet.address, ); @@ -120,7 +116,7 @@ describe('dataset', () => { describe('deployDataset()', () => { test('require a signer', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); const dataset = { owner: getRandomAddress(), name: `dataset${getId()}`, @@ -136,7 +132,7 @@ describe('dataset', () => { }); test('deploys a dataset', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const dataset = { owner: await iexec.wallet.getAddress(), name: `dataset${getId()}`, @@ -150,7 +146,7 @@ describe('dataset', () => { }); test('cannot deploy twice with the same params', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const dataset = { owner: await iexec.wallet.getAddress(), name: `dataset${getId()}`, @@ -167,10 +163,10 @@ describe('dataset', () => { describe('predictDatasetAddress()', () => { test('predicts the deployment address', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const dataset = { owner: getRandomAddress(), name: `dataset${getId()}`, @@ -192,10 +188,10 @@ describe('dataset', () => { describe('checkDeployedDataset()', () => { test('checks a dataset is deployed', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const dataset = { owner: getRandomAddress(), name: `dataset${getId()}`, @@ -217,7 +213,7 @@ describe('dataset', () => { describe('transferDataset()', () => { test('require a signer', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); await expect( iexec.dataset.transferDataset(getRandomAddress(), getRandomAddress()), ).rejects.toThrow( @@ -229,8 +225,8 @@ describe('dataset', () => { test('transfers the ownership', async () => { const receiverAddress = getRandomAddress(); - const { iexec: iexecDatasetOwner } = getTestConfig(iexecTestChain)(); - const { iexec: iexecRandom } = getTestConfig(iexecTestChain)(); + const { iexec: iexecDatasetOwner } = await getTestConfig(testChain)(); + const { iexec: iexecRandom } = await getTestConfig(testChain)(); const { address } = await deployRandomDataset(iexecDatasetOwner); await expect( iexecRandom.dataset.transferDataset( @@ -256,17 +252,19 @@ describe('dataset', () => { }); describe('generateEncryptionKey()', () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ - readOnly: true, + test('generates a random 32 bytes key encoded in base64', async () => { + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ + readOnly: true, + }); + const key = readOnlyIExec.dataset.generateEncryptionKey(); + expect(typeof key).toBe('string'); + expect(Buffer.from(key, 'base64').length).toBe(32); }); - const key = readOnlyIExec.dataset.generateEncryptionKey(); - expect(typeof key).toBe('string'); - expect(Buffer.from(key, 'base64').length).toBe(32); }); describe('encrypt()', () => { test('encrypts the input', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)({ readOnly: true, }); const key = iexec.dataset.generateEncryptionKey(); @@ -302,7 +300,7 @@ describe('dataset', () => { describe('computeEncryptedFileChecksum()', () => { test('does the sha256sum of the input', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)({ readOnly: true, }); const key = iexec.dataset.generateEncryptionKey(); @@ -326,13 +324,13 @@ describe('dataset', () => { describe('checkDatasetSecretExists()', () => { let randomDatasetAddress; beforeAll(async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const { address } = await deployRandomDataset(iexec); randomDatasetAddress = address; }); test("throw a SmsCallError when the SMS can't be reached", async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, options: { smsURL: SERVICE_UNREACHABLE_URL, @@ -348,7 +346,7 @@ describe('dataset', () => { }); test('throw a SmsCallError when the SMS encounters an error', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, options: { smsURL: SERVICE_HTTP_500_URL, @@ -364,10 +362,10 @@ describe('dataset', () => { }); test('checks a dataset secret exist in the SMS', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const { address } = await deployRandomDataset(iexec); await expect( readOnlyIExec.dataset.checkDatasetSecretExists(address), @@ -383,14 +381,14 @@ describe('dataset', () => { let randomDatasetAddress; let randomDatasetOwnerWallet; beforeAll(async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const { address } = await deployRandomDataset(iexec); randomDatasetAddress = address; randomDatasetOwnerWallet = wallet; }); test("throw a SmsCallError when the SMS can't be reached", async () => { - const { iexec } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)({ privateKey: randomDatasetOwnerWallet.privateKey, options: { smsURL: SERVICE_UNREACHABLE_URL, @@ -406,7 +404,7 @@ describe('dataset', () => { }); test('throw a SmsCallError when the SMS encounters an error', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)({ privateKey: randomDatasetOwnerWallet.privateKey, options: { smsURL: SERVICE_HTTP_500_URL, @@ -422,9 +420,9 @@ describe('dataset', () => { }); test('only owner can push secret', async () => { - const { iexec: iexecDatasetOwner } = getTestConfig(iexecTestChain)(); + const { iexec: iexecDatasetOwner } = await getTestConfig(testChain)(); const { iexec: iexecRandom, wallet: randomWallet } = - getTestConfig(iexecTestChain)(); + await getTestConfig(testChain)(); const { address: datasetAddress } = await deployRandomDataset(iexecDatasetOwner); // only owner can push secret @@ -438,7 +436,7 @@ describe('dataset', () => { }); test('pushes secret to SMS', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const { address: datasetAddress } = await deployRandomDataset(iexec); await expect( iexec.dataset.checkDatasetSecretExists(datasetAddress), @@ -452,7 +450,7 @@ describe('dataset', () => { }); test('cannot update existing secret', async () => { - const { iexec: iexecDatasetOwner } = getTestConfig(iexecTestChain)(); + const { iexec: iexecDatasetOwner } = await getTestConfig(testChain)(); const { address: datasetAddress } = await deployRandomDataset(iexecDatasetOwner); diff --git a/test/lib/e2e/IExecDealModule.test.js b/test/lib/e2e/IExecDealModule.test.js index d0609660..5ae168fb 100644 --- a/test/lib/e2e/IExecDealModule.test.js +++ b/test/lib/e2e/IExecDealModule.test.js @@ -24,11 +24,11 @@ import { errors } from '../../../src/lib/index.js'; const { ObjectNotFoundError, MarketCallError } = errors; -const iexecTestChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('deal', () => { describe('fetchRequesterDeals()', () => { test("throw a MarketCallError when the Market API can't be reached", async () => { - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, options: { iexecGatewayURL: SERVICE_UNREACHABLE_URL, @@ -44,7 +44,7 @@ describe('deal', () => { }); test('throw a MarketCallError when the Market API encounters an error', async () => { - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, options: { iexecGatewayURL: SERVICE_HTTP_500_URL, @@ -60,7 +60,7 @@ describe('deal', () => { }); test('shows past deals', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const requesterAddress = await iexec.wallet.getAddress(); const apporder = await deployAndGetApporder(iexec); const datasetorder = await deployAndGetDatasetorder(iexec); @@ -123,7 +123,7 @@ describe('deal', () => { describe('fetchDealsBy...order()', () => { test("throw a MarketCallError when the Market API can't be reached", async () => { - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, options: { iexecGatewayURL: SERVICE_UNREACHABLE_URL, @@ -139,7 +139,7 @@ describe('deal', () => { }); test('throw a MarketCallError when the Market API encounters an error', async () => { - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, options: { iexecGatewayURL: SERVICE_HTTP_500_URL, @@ -156,7 +156,7 @@ describe('deal', () => { describe('fetchDealsByApporder()', () => { test('shows past deals', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const apporder = await deployAndGetApporder(iexec); const datasetorder = await deployAndGetDatasetorder(iexec); const workerpoolorder = await deployAndGetWorkerpoolorder(iexec); @@ -187,7 +187,7 @@ describe('deal', () => { describe('fetchDealsByDatasetorder()', () => { test('shows past deals', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const apporder = await deployAndGetApporder(iexec); const datasetorder = await deployAndGetDatasetorder(iexec); const workerpoolorder = await deployAndGetWorkerpoolorder(iexec); @@ -221,7 +221,7 @@ describe('deal', () => { describe('fetchDealsByWorkerpoolorder()', () => { test('shows past deals', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const apporder = await deployAndGetApporder(iexec); const datasetorder = await deployAndGetDatasetorder(iexec); const workerpoolorder = await deployAndGetWorkerpoolorder(iexec); @@ -256,7 +256,7 @@ describe('deal', () => { describe('fetchDealsByRequestorder()', () => { test('shows past deals', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const apporder = await deployAndGetApporder(iexec); const datasetorder = await deployAndGetDatasetorder(iexec); const workerpoolorder = await deployAndGetWorkerpoolorder(iexec); @@ -289,9 +289,9 @@ describe('deal', () => { describe.skip('obsDeal()', () => { test('emits deal updates', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const catid = ( - await adminCreateCategory(iexecTestChain)({ + await adminCreateCategory(testChain)({ name: 'custom', description: 'desc', workClockTimeRef: 10, @@ -321,8 +321,8 @@ describe('deal', () => { const runnerUnsubBeforeInit = runObservableSubscribe(dealObservable); await sleep(6000); runnerUnsubBeforeInit.unsubscribe(); - await initializeTask(iexecTestChain)(dealid, 3); - await initializeTask(iexecTestChain)(dealid, 0); + await initializeTask(testChain)(dealid, 3); + await initializeTask(testChain)(dealid, 0); await sleep(6000); runnerUnsubAfterInit.unsubscribe(); @@ -381,9 +381,9 @@ describe('deal', () => { }); test('exits on deal timeout', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const catid = ( - await adminCreateCategory(iexecTestChain)({ + await adminCreateCategory(testChain)({ name: 'custom', description: 'desc', workClockTimeRef: 2, @@ -421,13 +421,13 @@ describe('deal', () => { runnerUnsub.unsubscribe(); return runnerUnsub.wait(); }), - initializeTask(iexecTestChain)(dealid, 3) + initializeTask(testChain)(dealid, 3) .then(sleep(5000)) - .then(() => initializeTask(iexecTestChain)(dealid, 0)), + .then(() => initializeTask(testChain)(dealid, 0)), ]); expect(wrongDealidRes.error).toStrictEqual( - new ObjectNotFoundError('deal', NULL_BYTES32, iexecTestChain.chainId), + new ObjectNotFoundError('deal', NULL_BYTES32, testChain.chainId), ); expect(wrongDealidRes.messages.length).toBe(0); expect(wrongDealidRes.completed).toBe(false); diff --git a/test/lib/e2e/IExecEnsModule.test.js b/test/lib/e2e/IExecEnsModule.test.js index db5b4e99..a6201a6a 100644 --- a/test/lib/e2e/IExecEnsModule.test.js +++ b/test/lib/e2e/IExecEnsModule.test.js @@ -17,12 +17,12 @@ import { import '../../jest-setup.js'; import { IExec } from '../../../src/lib/index.js'; -const iexecTestChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['bellecour-fork']; describe('ens', () => { describe('ens resolution', () => { test('resolve ens on iExec sidechain', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); const balance = await iexec.wallet.checkBalances('core.v5.iexec.eth'); expect(balance.wei).toBeInstanceOf(BN); expect(balance.nRLC).toBeInstanceOf(BN); @@ -43,13 +43,13 @@ describe('ens', () => { describe('getOwner()', () => { test('get owner address', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); const res = await iexec.ens.getOwner('core.v5.iexec.eth'); expect(res).toBe('0x0B3a38b0A47aB0c5E8b208A703de366751Df5916'); }); test('get address zero for unregistered names', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); const res = await iexec.ens.getOwner('unregistered.iexec.eth'); expect(res).toBe(NULL_ADDRESS); }); @@ -57,15 +57,13 @@ describe('ens', () => { describe('resolveName()', () => { test('known names resolves to address', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); const res = await iexec.ens.resolveName('core.v5.iexec.eth'); - expect(res).toBe( - iexecTestChain.hubAddress || iexecTestChain.defaults.hubAddress, - ); + expect(res).toBe(testChain.hubAddress || testChain.defaults.hubAddress); }); test('unknown name resolves to null', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); const res = await iexec.ens.resolveName('unknown.eth'); expect(res).toBe(null); }); @@ -73,10 +71,10 @@ describe('ens', () => { describe('lookupAddress()', () => { test('return the name when reverse resolution is configured', async () => { - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const label = `ens-${getId()}`; const domain = 'users.iexec.eth'; const name = `${label}.${domain}`; @@ -87,7 +85,7 @@ describe('ens', () => { }); test('return null when no reverse resolution is configured', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); const res = await iexec.ens.lookupAddress(getRandomAddress()); expect(res).toBe(null); }); @@ -95,10 +93,10 @@ describe('ens', () => { describe('getDefaultDomain()', () => { test('returns the domain corresponding to the address', async () => { - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const { address: appAddress } = await deployRandomApp(iexec); const { address: datasetAddress } = await deployRandomDataset(iexec); const { address: workerpoolAddress } = @@ -119,7 +117,7 @@ describe('ens', () => { describe('claimName()', () => { test('get an available name', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const label = `wallet-${wallet.address.toLowerCase()}`; const name = `${label}.users.iexec.eth`; const res = await iexec.ens.claimName(label); @@ -133,7 +131,7 @@ describe('ens', () => { }); test('allow claim on custom domain with FIFS registrar', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const label = `wallet-${wallet.address.toLowerCase()}`; const domain = 'apps.iexec.eth'; const name = `${label}.${domain}`; @@ -146,7 +144,7 @@ describe('ens', () => { }); test('fails if name is not available', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const label = 'users'; const domain = 'iexec.eth'; await expect(iexec.ens.claimName(label, domain)).rejects.toThrow( @@ -157,7 +155,7 @@ describe('ens', () => { }); test('fails if custom domain has no registrar', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const label = 'test'; const domain = 'no-registrar.iexec.eth'; await expect(iexec.ens.claimName(label, domain)).rejects.toThrow( @@ -170,7 +168,7 @@ describe('ens', () => { describe('configureResolution()', () => { test('configures for user address by default', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const label = `wallet-${wallet.address.toLowerCase()}`; const name = `${label}.users.iexec.eth`; await iexec.ens.claimName(label); @@ -191,7 +189,7 @@ describe('ens', () => { }); test('optionally configures for target address', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const app1 = await deployRandomApp(iexec); const label = `address-${wallet.address.toLowerCase()}`; @@ -232,7 +230,7 @@ describe('ens', () => { }); test('fails if name is not owned', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); await expect( iexec.ens.configureResolution('not-owned.eth', wallet.address), ).rejects.toThrow( @@ -243,7 +241,7 @@ describe('ens', () => { }); test('fails if target app address not owned', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const app = await deployRandomApp(iexec, { owner: getRandomAddress() }); const label = `address-${app.address.toLowerCase()}`; const name = `${label}.users.iexec.eth`; @@ -259,7 +257,7 @@ describe('ens', () => { }); test('fails if target address is an EAO different from user wallet', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const targetAddress = getRandomAddress(); const label = `address-${targetAddress.toLowerCase()}`; const name = `${label}.users.iexec.eth`; @@ -277,7 +275,7 @@ describe('ens', () => { describe('obsConfigureResolution()', () => { test('configures for user address by default', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const label = `wallet-${wallet.address.toLowerCase()}`; const name = `${label}.users.iexec.eth`; await iexec.ens.claimName(label); @@ -294,7 +292,7 @@ describe('ens', () => { }); test('optionally configures for target address', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const app1 = await deployRandomApp(iexec); const app2 = await deployRandomApp(iexec); @@ -325,7 +323,7 @@ describe('ens', () => { }); test('ens.obsConfigureResolution(name, address) throw with name not owned', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const configureObs = await iexec.ens.obsConfigureResolution( 'not-owned.eth', wallet.address, @@ -343,7 +341,7 @@ describe('ens', () => { }); test('fails if target app address not owned', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const app = await deployRandomApp(iexec, { owner: getRandomAddress(), }); @@ -368,7 +366,7 @@ describe('ens', () => { }); test('fails if target address is an EAO different from user wallet', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const targetAddress = getRandomAddress(); const label = `address-${targetAddress.toLowerCase()}`; const name = `${label}.users.iexec.eth`; @@ -392,7 +390,7 @@ describe('ens', () => { describe('setTextRecord()', () => { test('fails if resolver is not configured', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const name = `${getId()}.users.iexec.eth`; await expect( iexec.ens.setTextRecord(name, 'key', 'value'), @@ -400,14 +398,14 @@ describe('ens', () => { }); test('fails if the name is not owned', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const label = getId(); const name = `${label}.users.iexec.eth`; await iexec.ens.claimName(label); await iexec.ens.configureResolution(name); const { iexec: iexecNotOwner, wallet: walletNotOwner } = - getTestConfig(iexecTestChain)(); + await getTestConfig(testChain)(); await expect( iexecNotOwner.ens.setTextRecord(name, 'key', 'value'), ).rejects.toThrow( @@ -418,7 +416,7 @@ describe('ens', () => { }); test('sets a text record', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const { address } = await deployRandomWorkerpool(iexec); const label = `workerpool-${address.toLowerCase()}`; const name = `${label}.users.iexec.eth`; @@ -432,7 +430,7 @@ describe('ens', () => { }); test('can reset a text record', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const { address } = await deployRandomWorkerpool(iexec); const label = `workerpool-${address.toLowerCase()}`; const name = `${label}.users.iexec.eth`; @@ -447,7 +445,7 @@ describe('ens', () => { describe('readTextRecord()', () => { test('fails if the resolver not configured', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); const address = getRandomAddress(); const label = `address-${address.toLowerCase()}`; const name = `${label}.users.iexec.eth`; @@ -457,10 +455,10 @@ describe('ens', () => { }); test('returns empty string if the record not set', async () => { - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const label = getId(); const name = `${label}.users.iexec.eth`; await iexec.ens.claimName(label); @@ -470,10 +468,10 @@ describe('ens', () => { }); test('shows an existing text record', async () => { - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const { address } = await deployRandomWorkerpool(iexec); const label = `workerpool-${address.toLowerCase()}`; const name = `${label}.users.iexec.eth`; diff --git a/test/lib/e2e/IExecHubModule.test.js b/test/lib/e2e/IExecHubModule.test.js index ca022826..daf5bd33 100644 --- a/test/lib/e2e/IExecHubModule.test.js +++ b/test/lib/e2e/IExecHubModule.test.js @@ -4,15 +4,15 @@ import { getTestConfig } from '../lib-test-utils.js'; import { TEST_CHAINS, adminCreateCategory } from '../../test-utils.js'; import '../../jest-setup.js'; -const iexecTestChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('hub', () => { describe('showCategory()', () => { test('anyone can show category', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const res = await iexec.hub.showCategory(0); expect(res).toStrictEqual({ - description: '{}', + description: '""', name: 'XS', workClockTimeRef: new BN(300), }); @@ -20,7 +20,7 @@ describe('hub', () => { }); describe('createCategory()', () => { test('admin can create category', async () => { - const res = await adminCreateCategory(iexecTestChain)({ + const res = await adminCreateCategory(testChain)({ description: 'foo', name: 'bar', workClockTimeRef: 10, diff --git a/test/lib/e2e/IExecOrderModule.test.js b/test/lib/e2e/IExecOrderModule.test.js index 4943cd0c..5946e9dc 100644 --- a/test/lib/e2e/IExecOrderModule.test.js +++ b/test/lib/e2e/IExecOrderModule.test.js @@ -25,21 +25,22 @@ import { } from '../../test-utils.js'; import '../../jest-setup.js'; import { errors } from '../../../src/lib/index.js'; -import { DATASET_INFINITE_VOLUME } from '../../../src/lib/utils.js'; +import { DATASET_INFINITE_VOLUME, encodeTag } from '../../../src/lib/utils.js'; const { MarketCallError } = errors; -const iexecTestChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; const signRegex = /^(0x)([0-9a-f]{2}){65}$/; describe('order', () => { describe('prepareDatasetBulk()', () => { - const testChain = TEST_CHAINS['custom-token-chain']; // no bulk processing on bellecour; - const { iexec: iexecRequester } = getTestConfig(testChain)(); + const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; + let iexecRequester; let datasetorders = []; beforeAll(async () => { + iexecRequester = (await getTestConfig(testChain)()).iexec; const requesterAddress = await iexecRequester.wallet.getAddress(); await setBalance(testChain)(requesterAddress, ONE_ETH); const { address: appAddress } = await deployRandomApp(iexecRequester); @@ -47,7 +48,7 @@ describe('order', () => { Array(10) .fill() .map(async () => { - const { iexec: iexecDataOwner } = getTestConfig(iexecTestChain)(); + const { iexec: iexecDataOwner } = await getTestConfig(testChain)(); const { address } = await deployRandomDataset(iexecDataOwner); const datasetBulkOrder = await iexecDataOwner.order .createDatasetorder({ @@ -78,7 +79,7 @@ describe('order', () => { describe('create...order()', () => { describe('createApporder()', () => { test('creates a default apporder template', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const app = getRandomAddress(); const order = await iexec.order.createApporder({ app, @@ -95,7 +96,7 @@ describe('order', () => { }); test('override defaults', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const app = getRandomAddress(); const datasetrestrict = getRandomAddress(); const workerpoolrestrict = getRandomAddress(); @@ -123,7 +124,7 @@ describe('order', () => { describe('createDatasetorder()', () => { test('creates a default datasetorder template', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const dataset = getRandomAddress(); const order = await iexec.order.createDatasetorder({ dataset, @@ -140,7 +141,7 @@ describe('order', () => { }); test('override defaults', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const dataset = getRandomAddress(); const apprestrict = getRandomAddress(); const workerpoolrestrict = getRandomAddress(); @@ -168,7 +169,7 @@ describe('order', () => { describe('createWorkerpoolorder()', () => { test('creates a default workerpoolorder template', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const workerpool = getRandomAddress(); const order = await iexec.order.createWorkerpoolorder({ workerpool, @@ -188,7 +189,7 @@ describe('order', () => { }); test('override defaults', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const workerpool = getRandomAddress(); const apprestrict = getRandomAddress(); const datasetrestrict = getRandomAddress(); @@ -220,7 +221,7 @@ describe('order', () => { describe('createRequestorder()', () => { test('creates a default requestorder template', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const app = getRandomAddress(); const order = await iexec.order.createRequestorder({ app, @@ -247,7 +248,7 @@ describe('order', () => { }); test('override defaults', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const app = getRandomAddress(); const dataset = getRandomAddress(); const workerpool = getRandomAddress(); @@ -297,7 +298,7 @@ describe('order', () => { describe('sign...order()', () => { describe('signApporder()', () => { test('signs the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const { address } = await deployRandomApp(iexec); const order = await iexec.order.createApporder({ app: address, @@ -313,7 +314,7 @@ describe('order', () => { }); test('preflightCheck TEE framework', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const { address: sconeAppAddress } = await deployRandomApp(iexec, { teeFramework: TEE_FRAMEWORKS.SCONE, }); @@ -345,7 +346,7 @@ describe('order', () => { }); test('preflightCheck fails with invalid tag', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const order = await iexec.order.createApporder({ app: getRandomAddress(), }); @@ -375,7 +376,7 @@ describe('order', () => { describe('signDatasetorder()', () => { test('signs the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const { address } = await deployRandomDataset(iexec); const order = await iexec.order.createDatasetorder({ dataset: address, @@ -393,7 +394,7 @@ describe('order', () => { }); test('preflightCheck dataset secret', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const { address } = await deployRandomDataset(iexec); const order = await iexec.order.createDatasetorder({ dataset: address, @@ -415,7 +416,7 @@ describe('order', () => { }); test('preflightCheck fails with invalid tag', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const order = await iexec.order.createDatasetorder({ dataset: getRandomAddress(), }); @@ -427,7 +428,7 @@ describe('order', () => { describe('signWorkerpoolorder()', () => { test('signs the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const { address } = await deployRandomWorkerpool(iexec); const order = await iexec.order.createWorkerpoolorder({ workerpool: address, @@ -446,7 +447,7 @@ describe('order', () => { describe('signRequestorder()', () => { test('signs the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const order = await iexec.order.createRequestorder({ app: getRandomAddress(), category: 5, @@ -465,7 +466,7 @@ describe('order', () => { }); test('preflightCheck fails with invalid tag', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const order = await iexec.order.createRequestorder({ app: getRandomAddress(), category: 5, @@ -490,7 +491,7 @@ describe('order', () => { }); test('preflightCheck dropbox storage token exists', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const order = await iexec.order.createRequestorder({ app: getRandomAddress(), category: 5, @@ -518,7 +519,7 @@ describe('order', () => { }); test('preflightCheck result encryption exists', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const order = await iexec.order.createRequestorder({ app: getRandomAddress(), category: 5, @@ -544,8 +545,10 @@ describe('order', () => { }); test('preflightCheck checks dataset encryption key exists for tee datasets', async () => { - const { iexec: iexecDatasetProvider } = getTestConfig(iexecTestChain)(); - const { iexec: iexecDatasetConsumer } = getTestConfig(iexecTestChain)(); + const { iexec: iexecDatasetProvider } = + await getTestConfig(testChain)(); + const { iexec: iexecDatasetConsumer } = + await getTestConfig(testChain)(); await iexecDatasetConsumer.storage .defaultStorageLogin() @@ -613,7 +616,7 @@ describe('order', () => { }); test('preflightCheck requester secrets exist', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); await iexec.storage .defaultStorageLogin() .then(iexec.storage.pushStorageToken); @@ -674,7 +677,9 @@ describe('order', () => { describe('hash...order()', () => { describe('hashApporder()', () => { test('gives the order hash', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ + readOnly: true, + }); const order = { app: '0x76fE91568d50C5fF9411223df5A0c50Ec5fa326A', appprice: 0, @@ -688,14 +693,16 @@ describe('order', () => { }; const res = await iexec.order.hashApporder(order); expect(res).toBe( - '0x97f0160eb49618d267b3fd203b488ac09fb50760158455abe1f06cbb8a6edc72', + '0x735c56b20217f96aa9a0938cbaf4889721bb4a6421a5fcf47d9bb90b8dcd2b95', ); }); }); describe('hashDatasetorder()', () => { test('gives the order hash', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ + readOnly: true, + }); const order = { dataset: '0x2Ad5773db1a705DB568fAd403cd247fee4808Fb8', datasetprice: 0, @@ -709,14 +716,16 @@ describe('order', () => { }; const res = await iexec.order.hashDatasetorder(order); expect(res).toBe( - '0x5831e4e2911c431236a3df6d82698fcb849da8c781d7c4e9eb75ed551e4d35d4', + '0x3e068f770fddfd85d17978179382e79045fdccacbec7a69f244beb5f4b652947', ); }); }); describe('hashWorkerpoolorder()', () => { test('gives the order hash', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ + readOnly: true, + }); const order = { workerpool: '0x9DEB16F7861123CE34AE755F48D30697eD066793', workerpoolprice: 0, @@ -732,14 +741,16 @@ describe('order', () => { }; const res = await iexec.order.hashWorkerpoolorder(order); expect(res).toBe( - '0x7b23e26344284e809d7809395467d611ba148ef83b2ff3854e03430311f3f8fa', + '0x4e1d29f1ba77a8548fd6c6e2bf7755bd2d0f654ef6ae13d3df03cc71fc4ac5d6', ); }); }); describe('hashRequestorder()', () => { test('gives the order hash', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ + readOnly: true, + }); const order = { app: '0x33c791fE02eDDBfF3D3d37176737Eb3F488E150F', dataset: '0x69d4a400CFf9838985cD2950aafF28289afc6ad3', @@ -762,7 +773,7 @@ describe('order', () => { const res = await iexec.order.hashRequestorder(order); expect(res).toBeTxHash(); expect(res).toBe( - '0x8096dd3852b29d6e86b03505ded47fbc96b0bacc9be097f11de3a747ee0e4283', + '0xa8216862377a316c180fa28ed3bda170e7ef95b20a1b96daaa24c7dae84e35a5', ); }); }); @@ -771,7 +782,7 @@ describe('order', () => { describe('cancel...order()', () => { describe('cancelApporder()', () => { test('revokes the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const order = await deployAndGetApporder(iexec); const res = await iexec.order.cancelApporder(order); expect(res.order).toEqual(order); @@ -784,7 +795,7 @@ describe('order', () => { describe('cancelDatasetorder()', () => { test('revokes the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const order = await deployAndGetDatasetorder(iexec); const res = await iexec.order.cancelDatasetorder(order); expect(res.order).toEqual(order); @@ -797,7 +808,7 @@ describe('order', () => { describe('cancelWorkerpoolorder()', () => { test('revokes the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const order = await deployAndGetWorkerpoolorder(iexec); const res = await iexec.order.cancelWorkerpoolorder(order); expect(res.order).toEqual(order); @@ -810,7 +821,7 @@ describe('order', () => { describe('cancelRequestorder()', () => { test('revokes the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const order = await iexec.order .createRequestorder({ app: getRandomAddress(), @@ -835,7 +846,7 @@ describe('order', () => { describe('publish...order()', () => { test("throw a MarketCallError when the Market API can't be reached", async () => { - const { iexec } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)({ options: { iexecGatewayURL: SERVICE_UNREACHABLE_URL, }, @@ -853,7 +864,7 @@ describe('order', () => { }); test('throw a MarketCallError when the Market API encounters an error', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)({ options: { iexecGatewayURL: SERVICE_HTTP_500_URL, }, @@ -872,7 +883,7 @@ describe('order', () => { describe('publishApporder()', () => { test('publishes the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const apporder = await deployAndGetApporder(iexec); const orderHash = await iexec.order.publishApporder(apporder); expect(orderHash).toBeTxHash(); @@ -881,14 +892,14 @@ describe('order', () => { describe('publishDatasetorder()', () => { test('publishes the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const datasetorder = await deployAndGetDatasetorder(iexec); const orderHash = await iexec.order.publishDatasetorder(datasetorder); expect(orderHash).toBeTxHash(); }); test('preflightChecks dataset secret exists for tee tag', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const datasetorder = await deployAndGetDatasetorder(iexec, { tag: ['tee'], }); @@ -922,7 +933,7 @@ describe('order', () => { describe('publishWorkerpoolorder()', () => { test('publishes the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const workerpoolorder = await deployAndGetWorkerpoolorder(iexec); const orderHash = await iexec.order.publishWorkerpoolorder(workerpoolorder); @@ -932,7 +943,7 @@ describe('order', () => { describe('publishRequestorder()', () => { test('publishes the order (skip preflightCheck)', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const apporder = await deployAndGetApporder(iexec); await iexec.order.publishApporder(apporder); const requestorder = await iexec.order @@ -958,8 +969,8 @@ describe('order', () => { }); test('preflightCheck result encryption key', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { iexec: iexecAppDev } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); + const { iexec: iexecAppDev } = await getTestConfig(testChain)(); const apporder = await deployAndGetApporder(iexecAppDev, { teeFramework: TEE_FRAMEWORKS.SCONE, tag: ['tee', 'scone'], @@ -1003,8 +1014,8 @@ describe('order', () => { }); test('preflightCheck dropbox token', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { iexec: iexecAppDev } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); + const { iexec: iexecAppDev } = await getTestConfig(testChain)(); const apporder = await deployAndGetApporder(iexecAppDev, { teeFramework: TEE_FRAMEWORKS.SCONE, tag: ['tee', 'scone'], @@ -1037,7 +1048,7 @@ describe('order', () => { describe('unpublish...order()', () => { test("throw a MarketCallError when the Market API can't be reached", async () => { - const { iexec } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)({ options: { iexecGatewayURL: SERVICE_UNREACHABLE_URL, }, @@ -1049,7 +1060,7 @@ describe('order', () => { }); test('throw a MarketCallError when the Market API encounters an error', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)({ options: { iexecGatewayURL: SERVICE_HTTP_500_URL, }, @@ -1062,7 +1073,7 @@ describe('order', () => { describe('unpublishApporder()', () => { test('unpublish the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const apporder = await deployAndGetApporder(iexec); const orderHash = await iexec.order.publishApporder(apporder); const unpublishRes = await iexec.order.unpublishApporder(orderHash); @@ -1077,7 +1088,7 @@ describe('order', () => { describe('unpublishDatasetorder()', () => { test('unpublish the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const datasetorder = await deployAndGetDatasetorder(iexec); const orderHash = await iexec.order.publishDatasetorder(datasetorder, { preflightCheck: false, @@ -1096,7 +1107,7 @@ describe('order', () => { describe('unpublishWorkerpoolorder()', () => { test('unpublish the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const workerpoolorder = await deployAndGetWorkerpoolorder(iexec); const orderHash = await iexec.order.publishWorkerpoolorder(workerpoolorder); @@ -1115,7 +1126,7 @@ describe('order', () => { describe('unpublishRequestorder()', () => { test('unpublish the order', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const apporder = await deployAndGetApporder(iexec); await iexec.order.publishApporder(apporder); const requestorder = await iexec.order @@ -1151,7 +1162,7 @@ describe('order', () => { describe('unpublishLastApporder()', () => { test('unpublish the order', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const apporder = await deployAndGetApporder(iexec); const orderHash = await iexec.order.publishApporder(apporder); const lastApporder = await iexec.order.signApporder(apporder); @@ -1176,7 +1187,7 @@ describe('order', () => { describe('unpublishLastDatasetorder()', () => { test('unpublish the order', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const datasetorder = await deployAndGetDatasetorder(iexec); const orderHash = await iexec.order.publishDatasetorder(datasetorder, { preflightCheck: false, @@ -1211,7 +1222,7 @@ describe('order', () => { describe('unpublishLastWorkerpoolorder()', () => { test('unpublish the order', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const workerpoolorder = await deployAndGetWorkerpoolorder(iexec); const orderHash = await iexec.order.publishWorkerpoolorder(workerpoolorder); @@ -1240,7 +1251,7 @@ describe('order', () => { describe('unpublishLastRequestorder()', () => { test('unpublish the order', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const apporder = await deployAndGetApporder(iexec); await iexec.order.publishApporder(apporder); const requestorder = await iexec.order @@ -1292,7 +1303,7 @@ describe('order', () => { describe('unpublishAllApporders()', () => { test('unpublish all orders', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const apporder = await deployAndGetApporder(iexec); const orderHash = await iexec.order.publishApporder(apporder); const lastApporder = await iexec.order.signApporder(apporder); @@ -1316,7 +1327,7 @@ describe('order', () => { describe('unpublishAllDatasetorders()', () => { test('unpublish all orders', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const datasetorder = await deployAndGetDatasetorder(iexec); const orderHash = await iexec.order.publishDatasetorder(datasetorder, { preflightCheck: false, @@ -1350,7 +1361,7 @@ describe('order', () => { describe('unpublishAllWorkerpoolorders()', () => { test('unpublish all orders', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const workerpoolorder = await deployAndGetWorkerpoolorder(iexec); const orderHash = await iexec.order.publishWorkerpoolorder(workerpoolorder); @@ -1377,7 +1388,7 @@ describe('order', () => { describe('unpublishAllRequestorders()', () => { test('unpublish all orders', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const apporder = await deployAndGetApporder(iexec); await iexec.order.publishApporder(apporder); const requestorder = await iexec.order @@ -1429,11 +1440,11 @@ describe('order', () => { describe('estimateMatchOrders()', () => { test('estimates the total cost and volume', async () => { - const { iexec: iexecRequester } = getTestConfig(iexecTestChain)(); + const { iexec: iexecRequester } = await getTestConfig(testChain)(); const { iexec: iexecResourcesProvider, wallet: providerWallet } = - getTestConfig(iexecTestChain)(); + await getTestConfig(testChain)(); - await setBalance(iexecTestChain)(providerWallet.address, ONE_ETH); + await setBalance(testChain)(providerWallet.address, ONE_ETH); const apporder = await deployAndGetApporder(iexecResourcesProvider, { volume: 10, @@ -1471,22 +1482,16 @@ describe('order', () => { describe('matchOrders()', () => { test('order.matchOrders() all tests (split TODO)', async () => { - const { iexec: iexecBroker } = getTestConfig(iexecTestChain)(); + const { iexec: iexecBroker } = await getTestConfig(testChain)(); const { iexec: iexecPoolManager, wallet: poolManagerWallet } = - getTestConfig(iexecTestChain)(); + await getTestConfig(testChain)(); const { iexec: iexecRequester, wallet: requesterWallet } = - getTestConfig(iexecTestChain)(); - const { iexec: iexecAppProvider } = getTestConfig(iexecTestChain)(); - const { iexec: iexecDatasetProvider } = getTestConfig(iexecTestChain)(); + await getTestConfig(testChain)(); + const { iexec: iexecAppProvider } = await getTestConfig(testChain)(); + const { iexec: iexecDatasetProvider } = await getTestConfig(testChain)(); - await setNRlcBalance(iexecTestChain)( - requesterWallet.address, - 10n * ONE_RLC, - ); - await setNRlcBalance(iexecTestChain)( - poolManagerWallet.address, - 10n * ONE_RLC, - ); + await setNRlcBalance(testChain)(requesterWallet.address, 10n * ONE_RLC); + await setNRlcBalance(testChain)(poolManagerWallet.address, 10n * ONE_RLC); const apporderTemplate = await deployAndGetApporder(iexecAppProvider); const datasetorderTemplate = @@ -2077,8 +2082,9 @@ describe('order', () => { }); test('preflightChecks', async () => { - const { iexec: iexecRequester } = getTestConfig(iexecTestChain)(); - const { iexec: iexecResourcesProvider } = getTestConfig(iexecTestChain)(); + const { iexec: iexecRequester } = await getTestConfig(testChain)(); + const { iexec: iexecResourcesProvider } = + await getTestConfig(testChain)(); const apporder = await deployAndGetApporder(iexecResourcesProvider); const datasetorder = await deployAndGetDatasetorder( @@ -2155,8 +2161,9 @@ describe('order', () => { }); test('datasetorder tee framework burned tags are ignored', async () => { - const { iexec: iexecRequester } = getTestConfig(iexecTestChain)(); - const { iexec: iexecResourcesProvider } = getTestConfig(iexecTestChain)(); + const { iexec: iexecRequester } = await getTestConfig(testChain)(); + const { iexec: iexecResourcesProvider } = + await getTestConfig(testChain)(); const apporder = await deployAndGetApporder(iexecResourcesProvider, { teeFramework: TEE_FRAMEWORKS.SCONE, @@ -2183,20 +2190,20 @@ describe('order', () => { datasetorder, workerpoolorder, }); - // on bellecour burned tags are not implemented, so the match reverts on-chain but passes preflight checks - await expect( - iexecRequester.order.matchOrders({ - apporder, - datasetorder, - workerpoolorder, - requestorder, - }), - ).rejects.toThrow('execution reverted: revert: iExecV5-matchOrders-0x06'); + const { dealid } = await iexecRequester.order.matchOrders({ + apporder, + datasetorder, + workerpoolorder, + requestorder, + }); + const deal = await iexecRequester.deal.show(dealid); + expect(deal.tag).toEqual(encodeTag(['tee', 'scone'])); }); test('TDX tag with app without mrenclave passes checkAppRequirements (preflight)', async () => { - const { iexec: iexecRequester } = getTestConfig(iexecTestChain)(); - const { iexec: iexecResourcesProvider } = getTestConfig(iexecTestChain)(); + const { iexec: iexecRequester } = await getTestConfig(testChain)(); + const { iexec: iexecResourcesProvider } = + await getTestConfig(testChain)(); const apporder = await deployAndGetApporder(iexecResourcesProvider, { teeFramework: undefined, diff --git a/test/lib/e2e/IExecOrderbookModule.test.js b/test/lib/e2e/IExecOrderbookModule.test.js index 4e11a6e2..59dccaae 100644 --- a/test/lib/e2e/IExecOrderbookModule.test.js +++ b/test/lib/e2e/IExecOrderbookModule.test.js @@ -21,12 +21,12 @@ import '../../jest-setup.js'; const { MarketCallError } = errors; -const iexecTestChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('orderbook', () => { describe('fetch...Order()', () => { test("throw a MarketCallError when the Market API can't be reached", async () => { - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, options: { iexecGatewayURL: SERVICE_UNREACHABLE_URL, @@ -42,7 +42,7 @@ describe('orderbook', () => { }); test('throw a MarketCallError when the Market API encounters an error', async () => { - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, options: { iexecGatewayURL: SERVICE_HTTP_500_URL, @@ -59,8 +59,8 @@ describe('orderbook', () => { describe('fetchApporder()', () => { test('anyone can get a published order by hash', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)(); + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); const apporder = await deployAndGetApporder(iexec); @@ -79,8 +79,8 @@ describe('orderbook', () => { describe('fetchDatasetorder()', () => { test('anyone can get a published order by hash', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)(); + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); const datasetorder = await deployAndGetDatasetorder(iexec); @@ -102,8 +102,8 @@ describe('orderbook', () => { describe('fetchWorkerpoolorder()', () => { test('anyone can get a published order by hash', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)(); + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); const workerpoolorder = await deployAndGetWorkerpoolorder(iexec); @@ -124,8 +124,8 @@ describe('orderbook', () => { describe('fetchRequestorder()', () => { test('anyone can get a published order by hash', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec, wallet } = await getTestConfig(testChain)(); + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); const apporder = await deployAndGetApporder(iexec); @@ -165,7 +165,7 @@ describe('orderbook', () => { describe('fetch...Orderbook()', () => { test("throw a MarketCallError when the Market API can't be reached", async () => { - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, options: { iexecGatewayURL: SERVICE_UNREACHABLE_URL, @@ -181,7 +181,7 @@ describe('orderbook', () => { }); test('throw a MarketCallError when the Market API encounters an error', async () => { - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, options: { iexecGatewayURL: SERVICE_HTTP_500_URL, @@ -197,8 +197,8 @@ describe('orderbook', () => { }); describe('fetchAppOrderbook()', () => { test('returns orders available fo anyone', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)(); + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); const appAddress = getRandomAddress(); @@ -287,9 +287,9 @@ describe('orderbook', () => { }); test('appOwner returns orders from app owner', async () => { - const { iexec: iexecUser, wallet } = getTestConfig(iexecTestChain)(); - const { iexec: iexecOtherUser } = getTestConfig(iexecTestChain)(); - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecUser, wallet } = await getTestConfig(testChain)(); + const { iexec: iexecOtherUser } = await getTestConfig(testChain)(); + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); // publish orders from two different users @@ -320,8 +320,8 @@ describe('orderbook', () => { }); test('strict option allow filtering only orders for specified dataset, workerpool or requester', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)(); + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); @@ -498,8 +498,8 @@ describe('orderbook', () => { describe('fetchDatasetOrderbook()', () => { test('returns orders available fo anyone', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)(); + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); const datasetAddress = getRandomAddress(); @@ -599,9 +599,9 @@ describe('orderbook', () => { }); test('datasetOwner returns orders from dataset owner', async () => { - const { iexec: iexecUser, wallet } = getTestConfig(iexecTestChain)(); - const { iexec: iexecOtherUser } = getTestConfig(iexecTestChain)(); - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecUser, wallet } = await getTestConfig(testChain)(); + const { iexec: iexecOtherUser } = await getTestConfig(testChain)(); + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); // publish orders from two different users @@ -632,8 +632,8 @@ describe('orderbook', () => { }); test('strict option allow filtering only orders for specified app, workerpool or requester', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)(); + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); // 1 and 2: orders without any restrictions @@ -817,8 +817,8 @@ describe('orderbook', () => { }); test('bulkOnly option allow filtering only orders allowing dataset bulk processing', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)(); + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); // 1 and 2: orders without any restrictions @@ -866,8 +866,8 @@ describe('orderbook', () => { describe('fetchWorkerpoolOrderbook()', () => { test('returns orders available fo anyone', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)(); + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); const workerpoolorder = await deployAndGetWorkerpoolorder(iexec); @@ -953,8 +953,8 @@ describe('orderbook', () => { }); test('strict option allow filtering only orders for specified app, dataset or requester', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)(); + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); // 1 and 2: orders without any restrictions @@ -1130,8 +1130,8 @@ describe('orderbook', () => { describe('fetchRequestOrderbook()', () => { test('returns orders available fo anyone', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec, wallet } = await getTestConfig(testChain)(); + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); const apporder = await deployAndGetApporder(iexec); @@ -1198,8 +1198,8 @@ describe('orderbook', () => { }); test('strict option allow filtering only orders for specified workerpool', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec, wallet } = await getTestConfig(testChain)(); + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); const requesterAddress = wallet.address; diff --git a/test/lib/e2e/IExecResultModule.test.js b/test/lib/e2e/IExecResultModule.test.js index dbaba5ac..fc3573f8 100644 --- a/test/lib/e2e/IExecResultModule.test.js +++ b/test/lib/e2e/IExecResultModule.test.js @@ -3,12 +3,12 @@ import { getTestConfig } from '../lib-test-utils.js'; import { TEST_CHAINS } from '../../test-utils.js'; import '../../jest-setup.js'; -const iexecTestChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('result', () => { describe('pushResultEncryptionKey()', () => { test('pushes the result encryption key', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const pushRes = await iexec.result.pushResultEncryptionKey('oops'); expect(pushRes.isPushed).toBe(true); expect(pushRes.isUpdated).toBe(false); @@ -22,7 +22,7 @@ describe('result', () => { }); test('forceUpdate allows updating the key', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const pushRes = await iexec.result.pushResultEncryptionKey('Oops', { forceUpdate: true, }); @@ -38,8 +38,8 @@ describe('result', () => { describe('checkResultEncryptionKeyExists()', () => { test('anyone can check the key exists', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec, wallet } = await getTestConfig(testChain)(); + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); const withoutSecretRes = diff --git a/test/lib/e2e/IExecSecretsModule.test.js b/test/lib/e2e/IExecSecretsModule.test.js index e9448eb7..9d3d6d3b 100644 --- a/test/lib/e2e/IExecSecretsModule.test.js +++ b/test/lib/e2e/IExecSecretsModule.test.js @@ -11,12 +11,12 @@ import { errors } from '../../../src/lib/index.js'; const { SmsCallError } = errors; -const iexecTestChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('secrets', () => { describe('pushRequesterSecret()', () => { test("throw a SmsCallError when the SMS can't be reached", async () => { - const { iexec } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)({ options: { smsURL: SERVICE_UNREACHABLE_URL, }, @@ -31,7 +31,7 @@ describe('secrets', () => { }); test('throw a SmsCallError when the SMS encounters an error', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)({ options: { smsURL: SERVICE_HTTP_500_URL, }, @@ -46,7 +46,7 @@ describe('secrets', () => { }); test('pushes the secret', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const pushRes = await iexec.secrets.pushRequesterSecret('foo', 'oops'); expect(pushRes.isPushed).toBe(true); await expect( @@ -59,7 +59,7 @@ describe('secrets', () => { describe('checkRequesterSecretExists()', () => { test("throw a SmsCallError when the SMS can't be reached", async () => { - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ options: { smsURL: SERVICE_UNREACHABLE_URL, }, @@ -77,7 +77,7 @@ describe('secrets', () => { }); test('throw a SmsCallError when the SMS encounters an error', async () => { - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ options: { smsURL: SERVICE_HTTP_500_URL, }, @@ -95,8 +95,8 @@ describe('secrets', () => { }); test('anyone can check a secret exists', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec, wallet } = await getTestConfig(testChain)(); + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); await expect( diff --git a/test/lib/e2e/IExecStorageModule.test.js b/test/lib/e2e/IExecStorageModule.test.js index fbfa97de..d0b9d578 100644 --- a/test/lib/e2e/IExecStorageModule.test.js +++ b/test/lib/e2e/IExecStorageModule.test.js @@ -11,12 +11,12 @@ import { errors } from '../../../src/lib/index.js'; const { SmsCallError, ResultProxyCallError } = errors; -const iexecTestChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('storage', () => { describe('defaultStorageLogin()', () => { test("throw a ResultProxyCallError when the Result Proxy can't be reached", async () => { - const { iexec } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)({ options: { resultProxyURL: SERVICE_UNREACHABLE_URL, }, @@ -28,7 +28,7 @@ describe('storage', () => { }); test('throw a ResultProxyCallError when the Result Proxy encounters an error', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)({ options: { resultProxyURL: SERVICE_HTTP_500_URL, }, @@ -40,7 +40,7 @@ describe('storage', () => { }); test('gets a token from the result proxy', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const token = await iexec.storage.defaultStorageLogin(); expect(typeof token).toBe('string'); expect(token.split('.').length).toBe(3); @@ -51,7 +51,7 @@ describe('storage', () => { describe('pushStorageToken()', () => { test("throw a SmsCallError when the SMS can't be reached", async () => { - const { iexec } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)({ options: { smsURL: SERVICE_UNREACHABLE_URL, }, @@ -63,7 +63,7 @@ describe('storage', () => { }); test('throw a SmsCallError when the SMS encounters an error', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)({ options: { smsURL: SERVICE_HTTP_500_URL, }, @@ -75,7 +75,7 @@ describe('storage', () => { }); test('pushes the token on the SMS', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const pushRes = await iexec.storage.pushStorageToken('oops'); expect(pushRes.isPushed).toBe(true); expect(pushRes.isUpdated).toBe(false); @@ -87,7 +87,7 @@ describe('storage', () => { }); test('provider "default" pushes result proxy ipfs token', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const pushRes = await iexec.storage.pushStorageToken('oops', { provider: 'default', }); @@ -103,7 +103,7 @@ describe('storage', () => { }); test('provider "dropbox" pushes dropbox token', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const pushRes = await iexec.storage.pushStorageToken('oops', { provider: 'dropbox', }); @@ -119,7 +119,7 @@ describe('storage', () => { }); test('forceUpdate allows updating the token', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const pushRes = await iexec.storage.pushStorageToken('oops', { forceUpdate: true, }); @@ -135,7 +135,7 @@ describe('storage', () => { describe('checkStorageTokenExists()', () => { test("throw a SmsCallError when the SMS can't be reached", async () => { - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ options: { smsURL: SERVICE_UNREACHABLE_URL, }, @@ -150,7 +150,7 @@ describe('storage', () => { }); test('throw a SmsCallError when the SMS encounters an error', async () => { - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ options: { smsURL: SERVICE_HTTP_500_URL, }, @@ -165,8 +165,8 @@ describe('storage', () => { }); test('anyone can check a token exists', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec, wallet } = await getTestConfig(testChain)(); + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, }); const withoutSecretRes = diff --git a/test/lib/e2e/IExecTaskModule.test.js b/test/lib/e2e/IExecTaskModule.test.js index 9178d5de..2b054e29 100644 --- a/test/lib/e2e/IExecTaskModule.test.js +++ b/test/lib/e2e/IExecTaskModule.test.js @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeAll } from '@jest/globals'; +import { describe, test, expect } from '@jest/globals'; import { deployAndGetApporder, deployAndGetWorkerpoolorder, @@ -21,22 +21,22 @@ import { WorkerpoolCallError } from '../../../src/lib/errors.js'; const { ObjectNotFoundError, IpfsGatewayCallError } = errors; -const iexecTestChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('task', () => { describe('fetchResults()', () => { - const BELLECOUR_COMPLETED_TASK_ID = - '0xb8715386d9b9ab6d2be10aead05c46682af90d9a36a5ed0afb6a085db387f6ee'; + const ARBITRUM_SEPOLIA_COMPLETED_TASK_ID = + '0x07ea14ef6d25eca722575a8d568e64d9fdb44fa1cae1229618988d6222dba7c4'; test("throw a IpfsGatewayCallError when the IPFS gateway can't be reached", async () => { - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, options: { ipfsGatewayURL: SERVICE_UNREACHABLE_URL, }, }); await expectAsyncCustomError( - iexecReadOnly.task.fetchResults(BELLECOUR_COMPLETED_TASK_ID), + iexecReadOnly.task.fetchResults(ARBITRUM_SEPOLIA_COMPLETED_TASK_ID), { constructor: IpfsGatewayCallError, message: `IPFS gateway error: Connection to ${SERVICE_UNREACHABLE_URL} failed with a network error`, @@ -45,14 +45,14 @@ describe('task', () => { }); test('throw a IpfsGatewayCallError when the IPFS gateway encounters an error', async () => { - const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + const { iexec: iexecReadOnly } = await getTestConfig(testChain)({ readOnly: true, options: { ipfsGatewayURL: SERVICE_HTTP_500_URL, }, }); await expectAsyncCustomError( - iexecReadOnly.task.fetchResults(BELLECOUR_COMPLETED_TASK_ID), + iexecReadOnly.task.fetchResults(ARBITRUM_SEPOLIA_COMPLETED_TASK_ID), { constructor: IpfsGatewayCallError, message: `IPFS gateway error: Server at ${SERVICE_HTTP_500_URL} encountered an internal error`, @@ -61,9 +61,11 @@ describe('task', () => { }); test('downloads the result archive from IPFS', async () => { - const iexecReadOnly = new IExec({ ethProvider: 'bellecour' }); + const iexecReadOnly = new IExec({ + ethProvider: 'arbitrum-sepolia-testnet', + }); const res = await iexecReadOnly.task.fetchResults( - BELLECOUR_COMPLETED_TASK_ID, + ARBITRUM_SEPOLIA_COMPLETED_TASK_ID, ); expect(res).toBeInstanceOf(Response); }); @@ -71,9 +73,9 @@ describe('task', () => { describe.skip('obsTask()', () => { test('emits task updates', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const catid = ( - await adminCreateCategory(iexecTestChain)({ + await adminCreateCategory(testChain)({ name: 'custom', description: 'desc', workClockTimeRef: 10, @@ -175,7 +177,7 @@ describe('task', () => { .catch(reject); }); }), - sleep(1000).then(() => initializeTask(iexecTestChain)(dealid, 0)), + sleep(1000).then(() => initializeTask(testChain)(dealid, 0)), ]); expect(unsubObsTaskWithDealid).toBeInstanceOf(Function); @@ -221,9 +223,9 @@ describe('task', () => { }); test('exits on task (deal) timeout', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const catid = ( - await adminCreateCategory(iexecTestChain)({ + await adminCreateCategory(testChain)({ name: 'custom', description: 'desc', workClockTimeRef: 2, @@ -351,16 +353,16 @@ describe('task', () => { }), sleep(2000).then(() => { unsubObsTaskBeforeComplete(); - initializeTask(iexecTestChain)(dealid, 0); + initializeTask(testChain)(dealid, 0); }), ]); expect(obsTaskWithDealidComplete).toBeUndefined(); expect(obsTaskWithWrongDealidError).toEqual( - new ObjectNotFoundError('deal', NULL_BYTES32, iexecTestChain.chainId), + new ObjectNotFoundError('deal', NULL_BYTES32, testChain.chainId), ); expect(obsTaskBeforeInitError).toEqual( - new ObjectNotFoundError('task', taskid, iexecTestChain.chainId), + new ObjectNotFoundError('task', taskid, testChain.chainId), ); expect(obsTaskAfterInitComplete).toBeUndefined(); @@ -420,76 +422,41 @@ describe('task', () => { describe('fetchOffchainInfo()', () => { test('throw when workerpool API is not configured', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); await expect( iexec.task.fetchOffchainInfo( - '0xf835e22624dd305c6a1f6c6b5688b92231455778847e7ef3bee1091e627e8786', + '0x4405e57c6afd6b3ed2399609213b88bbbc4663a02481f097b110ee7dca5a992f', ), ).rejects.toThrow( new Error( - 'Impossible to resolve API url for workerpool 0x13EE8c43Abd7dFAcfa4C42554Dff72d9fbcF3330', + 'Impossible to resolve API url for workerpool 0x0556feC57717B8146B03F8ce003eFa3012490d37', ), ); }); describe('when workerpool API is configured', () => { - const { iexec: iexecRequester } = getTestConfig(iexecTestChain)(); - const { iexec: iexecWorkerpoolOwner } = getTestConfig(iexecTestChain)(); - let taskid; - let workerpool; - - beforeAll(async () => { - const workerpoolorder = - await deployAndGetWorkerpoolorder(iexecWorkerpoolOwner); - const apporder = await deployAndGetApporder(iexecWorkerpoolOwner); - - workerpool = workerpoolorder.workerpool; - const { name: workerpoolEns } = - await iexecWorkerpoolOwner.ens.claimName( - workerpool.toLowerCase(), - await iexecWorkerpoolOwner.ens.getDefaultDomain(workerpool), - ); - await iexecWorkerpoolOwner.ens.configureResolution( - workerpoolEns, - workerpool, - ); - const requestorder = await getMatchableRequestorder(iexecRequester, { - workerpoolorder, - apporder, - }); - const { dealid } = await iexecRequester.order.matchOrders({ - apporder, - workerpoolorder, - requestorder, - }); - await initializeTask(iexecTestChain)(dealid, 0); - taskid = await iexecRequester.deal.computeTaskId(dealid, 0); - }); - test('throw WorkerpoolCallError when the workerpool API is unreachable', async () => { - await iexecWorkerpoolOwner.workerpool.setWorkerpoolApiUrl( - workerpool, - SERVICE_UNREACHABLE_URL, - ); + const { iexec } = await getTestConfig(testChain)(); await expect( - iexecRequester.task.fetchOffchainInfo(taskid), + iexec.task.fetchOffchainInfo( + '0xc6a7f29715b563b75a1daf71458125ecb2f09858380c545ceda9d5652106a92f', + ), ).rejects.toThrow( new WorkerpoolCallError( - `Connection to ${SERVICE_UNREACHABLE_URL} failed with a network error`, + `Connection to https://unreachable-workerpool.iex.ec failed with a network error`, ), ); }); test('throw WorkerpoolCallError when the workerpool API answers with error', async () => { - await iexecWorkerpoolOwner.workerpool.setWorkerpoolApiUrl( - workerpool, - SERVICE_HTTP_500_URL, - ); + const { iexec } = await getTestConfig(testChain)(); await expect( - iexecRequester.task.fetchOffchainInfo(taskid), + iexec.task.fetchOffchainInfo( + '0x22069de2261dfad53437835ff268018105343583fb64d8cd06803bb3a9c49960', + ), ).rejects.toThrow( new WorkerpoolCallError( - `Server at ${SERVICE_HTTP_500_URL} encountered an internal error`, + `Server at http://localhost:5500 encountered an internal error`, new Error('Server internal error: 500 Internal Server Error'), ), ); @@ -499,89 +466,16 @@ describe('task', () => { describe('fetchLogs()', () => { test('throw when workerpool API is not configured', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); await expect( iexec.task.fetchLogs( - '0xf835e22624dd305c6a1f6c6b5688b92231455778847e7ef3bee1091e627e8786', + '0x4405e57c6afd6b3ed2399609213b88bbbc4663a02481f097b110ee7dca5a992f', ), ).rejects.toThrow( new Error( - 'Impossible to resolve API url for workerpool 0x13EE8c43Abd7dFAcfa4C42554Dff72d9fbcF3330', + 'Impossible to resolve API url for workerpool 0x0556feC57717B8146B03F8ce003eFa3012490d37', ), ); }); - - describe('when workerpool API is configured', () => { - const { iexec: iexecRequester } = getTestConfig(iexecTestChain)(); - const { iexec: iexecWorkerpoolOwner } = getTestConfig(iexecTestChain)(); - let taskid; - let workerpool; - - beforeAll(async () => { - const workerpoolorder = - await deployAndGetWorkerpoolorder(iexecWorkerpoolOwner); - const apporder = await deployAndGetApporder(iexecWorkerpoolOwner); - - workerpool = workerpoolorder.workerpool; - const { name: workerpoolEns } = - await iexecWorkerpoolOwner.ens.claimName( - workerpool.toLowerCase(), - await iexecWorkerpoolOwner.ens.getDefaultDomain(workerpool), - ); - await iexecWorkerpoolOwner.ens.configureResolution( - workerpoolEns, - workerpool, - ); - const requestorder = await getMatchableRequestorder(iexecRequester, { - workerpoolorder, - apporder, - }); - const { dealid } = await iexecRequester.order.matchOrders({ - apporder, - workerpoolorder, - requestorder, - }); - await initializeTask(iexecTestChain)(dealid, 0); - taskid = await iexecRequester.deal.computeTaskId(dealid, 0); - }); - - test('throw when user is not the requester', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - await iexecWorkerpoolOwner.workerpool.setWorkerpoolApiUrl( - workerpool, - SERVICE_UNREACHABLE_URL, - ); - await expect(iexec.task.fetchLogs(taskid)).rejects.toThrow( - new Error( - `Only task requester ${await iexecRequester.wallet.getAddress()} can access replicates logs`, - ), - ); - }); - - test('throw WorkerpoolCallError when the workerpool API is unreachable', async () => { - await iexecWorkerpoolOwner.workerpool.setWorkerpoolApiUrl( - workerpool, - SERVICE_UNREACHABLE_URL, - ); - await expect(iexecRequester.task.fetchLogs(taskid)).rejects.toThrow( - new WorkerpoolCallError( - `Connection to ${SERVICE_UNREACHABLE_URL} failed with a network error`, - ), - ); - }); - - test('throw WorkerpoolCallError when the workerpool API answers with error', async () => { - await iexecWorkerpoolOwner.workerpool.setWorkerpoolApiUrl( - workerpool, - SERVICE_HTTP_500_URL, - ); - await expect(iexecRequester.task.fetchLogs(taskid)).rejects.toThrow( - new WorkerpoolCallError( - `Server at ${SERVICE_HTTP_500_URL} encountered an internal error`, - new Error('Server internal error: 500 Internal Server Error'), - ), - ); - }); - }); }); }); diff --git a/test/lib/e2e/IExecWalletModule.test.js b/test/lib/e2e/IExecWalletModule.test.js index 19adffb7..df7717dc 100644 --- a/test/lib/e2e/IExecWalletModule.test.js +++ b/test/lib/e2e/IExecWalletModule.test.js @@ -12,18 +12,19 @@ import { import '../../jest-setup.js'; import { IExec } from '../../../src/lib/index.js'; -const iexecTestChain = TEST_CHAINS['bellecour-fork']; -const tokenTestChain = TEST_CHAINS['custom-token-chain']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; +const tokenTestChain = TEST_CHAINS['arbitrum-sepolia-fork']; +const nativeTestChain = TEST_CHAINS['bellecour-fork']; describe('wallet', () => { describe('getAddress()', () => { test('expose connected wallet', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const res = await iexec.wallet.getAddress(); expect(res).toBe(wallet.address); }); test('require a signer', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)({ readOnly: true, }); await expect(iexec.wallet.getAddress()).rejects.toThrow( @@ -35,9 +36,11 @@ describe('wallet', () => { describe('checkBalances()', () => { describe('native chain', () => { test('expose nRLC (as 10⁹ wei)', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(nativeTestChain)({ + readOnly: true, + }); const address = getRandomAddress(); - await setNRlcBalance(iexecTestChain)(address, 1000); + await setNRlcBalance(nativeTestChain)(address, 1000); const balance = await iexec.wallet.checkBalances(address); expect(balance.nRLC).toBeInstanceOf(BN); expect(balance.wei).toBeInstanceOf(BN); @@ -48,7 +51,9 @@ describe('wallet', () => { describe('token chain', () => { test('expose wei and nRLC', async () => { - const { iexec } = getTestConfig(tokenTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(tokenTestChain)({ + readOnly: true, + }); const address = getRandomAddress(); await setBalance(tokenTestChain)(address, 1000); const balance = await iexec.wallet.checkBalances(address); @@ -95,7 +100,7 @@ describe('wallet', () => { describe('sendETH()', () => { test('require a signer', async () => { - const { iexec } = getTestConfig(tokenTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(tokenTestChain)({ readOnly: true }); await expect( iexec.wallet.sendETH(10, getRandomAddress()), ).rejects.toThrow( @@ -108,7 +113,7 @@ describe('wallet', () => { describe('token chain', () => { test('sends wei', async () => { const receiverAddress = getRandomAddress(); - const { iexec, wallet } = getTestConfig(tokenTestChain)(); + const { iexec, wallet } = await getTestConfig(tokenTestChain)(); await setBalance(tokenTestChain)(wallet.address, ONE_ETH); const initialBalance = await iexec.wallet.checkBalances(wallet.address); const receiverInitialBalance = @@ -134,7 +139,7 @@ describe('wallet', () => { test('sends specified unit', async () => { const receiverAddress = getRandomAddress(); - const { iexec, wallet } = getTestConfig(tokenTestChain)(); + const { iexec, wallet } = await getTestConfig(tokenTestChain)(); await setBalance(tokenTestChain)(wallet.address, ONE_ETH); const initialBalance = await iexec.wallet.checkBalances(wallet.address); const receiverInitialBalance = @@ -162,7 +167,7 @@ describe('wallet', () => { describe('native chain', () => { test('throw on native chain', async () => { const receiverAddress = getRandomAddress(); - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(nativeTestChain)(); await expect(iexec.wallet.sendETH(10, receiverAddress)).rejects.toThrow( new Error('sendETH() is disabled on sidechain, use sendRLC()'), ); @@ -172,7 +177,7 @@ describe('wallet', () => { describe('sendRLC()', () => { test('require a signer', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); await expect( iexec.wallet.sendRLC(10, getRandomAddress()), ).rejects.toThrow( @@ -185,8 +190,8 @@ describe('wallet', () => { describe('native chain', () => { test('sends nRLC', async () => { const receiverAddress = getRandomAddress(); - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - await setNRlcBalance(iexecTestChain)(wallet.address, ONE_RLC); + const { iexec, wallet } = await getTestConfig(nativeTestChain)(); + await setNRlcBalance(nativeTestChain)(wallet.address, ONE_RLC); const initialBalance = await iexec.wallet.checkBalances(wallet.address); const receiverInitialBalance = await iexec.wallet.checkBalances(receiverAddress); @@ -217,8 +222,8 @@ describe('wallet', () => { test('sends specified unit', async () => { const receiverAddress = getRandomAddress(); - const { iexec, wallet } = getTestConfig(iexecTestChain)(); - await setNRlcBalance(iexecTestChain)(wallet.address, ONE_RLC); + const { iexec, wallet } = await getTestConfig(nativeTestChain)(); + await setNRlcBalance(nativeTestChain)(wallet.address, ONE_RLC); const initialBalance = await iexec.wallet.checkBalances(wallet.address); const receiverInitialBalance = await iexec.wallet.checkBalances(receiverAddress); @@ -254,7 +259,7 @@ describe('wallet', () => { describe('token chain', () => { test('sends nRLC', async () => { const receiverAddress = getRandomAddress(); - const { iexec, wallet } = getTestConfig(tokenTestChain)(); + const { iexec, wallet } = await getTestConfig(tokenTestChain)(); await setNRlcBalance(tokenTestChain)(wallet.address, 100); await setBalance(tokenTestChain)(wallet.address, ONE_ETH); const initialBalance = await iexec.wallet.checkBalances(wallet.address); @@ -281,7 +286,7 @@ describe('wallet', () => { test('sends specified unit', async () => { const receiverAddress = getRandomAddress(); - const { iexec, wallet } = getTestConfig(tokenTestChain)(); + const { iexec, wallet } = await getTestConfig(tokenTestChain)(); await setNRlcBalance(tokenTestChain)(wallet.address, ONE_RLC); await setBalance(tokenTestChain)(wallet.address, ONE_ETH); const initialBalance = await iexec.wallet.checkBalances(wallet.address); @@ -312,9 +317,9 @@ describe('wallet', () => { test('sweeps native nRLC', async () => { const receiverWallet = getRandomWallet(); const { iexec, wallet: sweeperWallet } = - getTestConfig(iexecTestChain)(); - await setBalance(iexecTestChain)(sweeperWallet.address, ONE_ETH); - await setNRlcBalance(iexecTestChain)(sweeperWallet.address, ONE_RLC); + await getTestConfig(nativeTestChain)(); + await setBalance(nativeTestChain)(sweeperWallet.address, ONE_ETH); + await setNRlcBalance(nativeTestChain)(sweeperWallet.address, ONE_RLC); const initialBalance = await iexec.wallet.checkBalances( sweeperWallet.address, ); @@ -351,7 +356,7 @@ describe('wallet', () => { test('sweeps wei and nRLC', async () => { const receiverWallet = getRandomWallet(); const { iexec, wallet: sweeperWallet } = - getTestConfig(tokenTestChain)(); + await getTestConfig(tokenTestChain)(); await setBalance(tokenTestChain)(sweeperWallet.address, ONE_ETH); await setNRlcBalance(tokenTestChain)(sweeperWallet.address, ONE_RLC); @@ -387,7 +392,7 @@ describe('wallet', () => { test('stop when ERC20 transfer fails', async () => { const receiverWallet = getRandomWallet(); const { iexec, wallet: sweeperWallet } = - getTestConfig(tokenTestChain)(); + await getTestConfig(tokenTestChain)(); await setNRlcBalance(tokenTestChain)(sweeperWallet.address, ONE_RLC); await setBalance(tokenTestChain)(sweeperWallet.address, 1); const initialBalance = await iexec.wallet.checkBalances( @@ -422,10 +427,10 @@ describe('wallet', () => { test('report sendNativeTxHash and error when remaining wei cannot be sent', async () => { const receiverWallet = getRandomWallet(); const { iexec, wallet: sweeperWallet } = - getTestConfig(tokenTestChain)(); + await getTestConfig(tokenTestChain)(); await setBalance(tokenTestChain)( sweeperWallet.address, - 55000000000000n, + 60000000000000n, ); // enough for erc20 transfer only await setNRlcBalance(tokenTestChain)(sweeperWallet.address, ONE_RLC); const initialBalance = await iexec.wallet.checkBalances( diff --git a/test/lib/e2e/IExecWorkerpoolModule.test.js b/test/lib/e2e/IExecWorkerpoolModule.test.js index e38f999b..f4aa6d4f 100644 --- a/test/lib/e2e/IExecWorkerpoolModule.test.js +++ b/test/lib/e2e/IExecWorkerpoolModule.test.js @@ -10,16 +10,17 @@ import { } from '../../test-utils.js'; import '../../jest-setup.js'; import { errors } from '../../../src/lib/index.js'; +import { ConfigurationError } from '../../../src/lib/errors.js'; -const iexecTestChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('workerpool', () => { describe('showWorkerpool()', () => { test('shows a deployed workerpool', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const workerpool = { owner: await iexec.wallet.getAddress(), description: `workerpool${getId()}`, @@ -36,7 +37,7 @@ describe('workerpool', () => { }); test('fails if the workerpool is not deployed', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); const address = getRandomAddress(); @@ -46,7 +47,7 @@ describe('workerpool', () => { new errors.ObjectNotFoundError( 'workerpool', address, - iexecTestChain.chainId, + testChain.chainId, ), ); }); @@ -54,10 +55,10 @@ describe('workerpool', () => { describe('showUserWorkerpool()', () => { test('shows the user workerpool', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const workerpool = { owner: wallet.address, description: `workerpool${getId()}`, @@ -76,7 +77,7 @@ describe('workerpool', () => { }); test('fails if the workerpool is not deployed', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); const address = getRandomAddress(); @@ -88,10 +89,10 @@ describe('workerpool', () => { describe('countUserWorkerpools()', () => { test('counts user workerpools', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const resBeforeDeploy = await readOnlyIExec.workerpool.countUserWorkerpools(wallet.address); await deployRandomWorkerpool(iexec); @@ -106,7 +107,7 @@ describe('workerpool', () => { describe('deployWorkerpool()', () => { test('require a signer', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ + const { iexec } = await getTestConfig(testChain)({ readOnly: true, }); const workerpool = { @@ -123,7 +124,7 @@ describe('workerpool', () => { }); test('deploys a workerpool', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const workerpool = { owner: await iexec.wallet.getAddress(), description: `workerpool${getId()}`, @@ -134,7 +135,7 @@ describe('workerpool', () => { }); test('cannot deploy twice with the same params', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const workerpool = { owner: await iexec.wallet.getAddress(), description: `workerpool${getId()}`, @@ -150,10 +151,10 @@ describe('workerpool', () => { describe('predictWorkerpoolAddress()', () => { test('predicts the deployment address', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const workerpool = { owner: getRandomAddress(), description: `workerpool${getId()}`, @@ -172,10 +173,10 @@ describe('workerpool', () => { describe('checkDeployedWorkerpool()', () => { test('checks a workerpool is deployed', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChain)({ readOnly: true, }); - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const workerpool = { owner: getRandomAddress(), description: `workerpool${getId()}`, @@ -194,7 +195,7 @@ describe('workerpool', () => { describe('transferWorkerpool()', () => { test('require a signer', async () => { - const { iexec } = getTestConfig(iexecTestChain)({ readOnly: true }); + const { iexec } = await getTestConfig(testChain)({ readOnly: true }); await expect( iexec.workerpool.transferWorkerpool( getRandomAddress(), @@ -209,8 +210,8 @@ describe('workerpool', () => { test('transfers the ownership', async () => { const receiverAddress = getRandomAddress(); - const { iexec: iexecWorkerpoolOwner } = getTestConfig(iexecTestChain)(); - const { iexec: iexecRandom } = getTestConfig(iexecTestChain)(); + const { iexec: iexecWorkerpoolOwner } = await getTestConfig(testChain)(); + const { iexec: iexecRandom } = await getTestConfig(testChain)(); const { address } = await deployRandomWorkerpool(iexecWorkerpoolOwner); await expect( iexecRandom.workerpool.transferWorkerpool( @@ -238,11 +239,12 @@ describe('workerpool', () => { describe('getWorkerpoolApiUrl()', () => { describe('on networks with ENS', () => { + const testChainWithEns = TEST_CHAINS['bellecour-fork']; test('resolves the url against ENS', async () => { - const { iexec: readOnlyIExec } = getTestConfig(iexecTestChain)({ + const { iexec: readOnlyIExec } = await getTestConfig(testChainWithEns)({ readOnly: true, }); - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChainWithEns)(); const { address } = await deployRandomWorkerpool(iexec); const resNoApiUrl = await readOnlyIExec.workerpool.getWorkerpoolApiUrl(address); @@ -261,10 +263,8 @@ describe('workerpool', () => { }); describe('on networks relying on compass', () => { - const noEnsTestChain = TEST_CHAINS['custom-token-chain-no-ens']; - test('resolves the url against Compass', async () => { - const { iexec: readOnlyIExec } = getTestConfig(noEnsTestChain)(); + const { iexec: readOnlyIExec } = await getTestConfig(testChain)(); const apiUrl = await readOnlyIExec.workerpool.getWorkerpoolApiUrl( '0xB967057a21dc6A66A29721d96b8Aa7454B7c383F', ); @@ -273,7 +273,7 @@ describe('workerpool', () => { }); test('returns undefined if the workerpool does not exist in Compass', async () => { - const { iexec: readOnlyIExec } = getTestConfig(noEnsTestChain)(); + const { iexec: readOnlyIExec } = await getTestConfig(testChain)(); const address = getRandomAddress(); await expect( readOnlyIExec.workerpool.getWorkerpoolApiUrl(address), @@ -281,7 +281,7 @@ describe('workerpool', () => { }); test('fails with CompassCallError if Compass is not available', async () => { - const { iexec: iexecCompassNotFound } = getTestConfig(noEnsTestChain)({ + const { iexec: iexecCompassNotFound } = await getTestConfig(testChain)({ options: { compassURL: SERVICE_UNREACHABLE_URL, }, @@ -296,8 +296,8 @@ describe('workerpool', () => { ), ); - const { iexec: iexecCompassInternalError } = getTestConfig( - noEnsTestChain, + const { iexec: iexecCompassInternalError } = await getTestConfig( + testChain, )({ options: { compassURL: SERVICE_HTTP_500_URL, @@ -318,32 +318,53 @@ describe('workerpool', () => { }); describe('setWorkerpoolApiUrl()', () => { - test('require a configured ens name for the workerpool', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { address } = await deployRandomWorkerpool(iexec); - await expect( - iexec.workerpool.setWorkerpoolApiUrl( + describe('on networks with ENS', () => { + const testChainWithEns = TEST_CHAINS['bellecour-fork']; + + test('require a configured ens name for the workerpool', async () => { + const { iexec } = await getTestConfig(testChainWithEns)(); + const { address } = await deployRandomWorkerpool(iexec); + await expect( + iexec.workerpool.setWorkerpoolApiUrl( + address, + 'https://my-workerpool.com', + ), + ).rejects.toThrow( + new Error(`No ENS name reverse resolution configured for ${address}`), + ); + }); + + test('sets the workerpool api url', async () => { + const { iexec } = await getTestConfig(testChainWithEns)(); + const { address } = await deployRandomWorkerpool(iexec); + const label = address.toLowerCase(); + const domain = 'pools.iexec.eth'; + const name = `${label}.${domain}`; + await iexec.ens.claimName(label, domain); + await iexec.ens.configureResolution(name, address); + const res = await iexec.workerpool.setWorkerpoolApiUrl( address, 'https://my-workerpool.com', - ), - ).rejects.toThrow( - new Error(`No ENS name reverse resolution configured for ${address}`), - ); + ); + expect(res).toBeTxHash(); + }); }); - test('sets the workerpool api url', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); - const { address } = await deployRandomWorkerpool(iexec); - const label = address.toLowerCase(); - const domain = 'pools.iexec.eth'; - const name = `${label}.${domain}`; - await iexec.ens.claimName(label, domain); - await iexec.ens.configureResolution(name, address); - const res = await iexec.workerpool.setWorkerpoolApiUrl( - address, - 'https://my-workerpool.com', - ); - expect(res).toBeTxHash(); + describe('on networks relying on compass', () => { + test('setWorkerpoolApiUrl is not supported', async () => { + const { iexec } = await getTestConfig(testChain)(); + const { address } = await deployRandomWorkerpool(iexec); + await expect( + iexec.workerpool.setWorkerpoolApiUrl( + address, + 'https://my-workerpool.com', + ), + ).rejects.toThrow( + new ConfigurationError( + 'Workerpool API Registration is not available on network arbitrum-sepolia-testnet', + ), + ); + }); }); }); }); diff --git a/test/lib/e2e/utils.test.js b/test/lib/e2e/utils.test.js index f4ce68ad..8e2956fc 100644 --- a/test/lib/e2e/utils.test.js +++ b/test/lib/e2e/utils.test.js @@ -357,36 +357,15 @@ describe('utils', () => { }); describe('getSignerFromPrivateKey()', () => { - const iexecTestChain = TEST_CHAINS['bellecour-fork']; - const tokenTestChain = TEST_CHAINS['custom-token-chain']; - - test('gasPrice option allows to specify gasPrice', async () => { - const gasPrice = '123456789'; - const wallet = getRandomWallet(); - const iexec = new IExec( - { - ethProvider: utils.getSignerFromPrivateKey( - tokenTestChain.rpcURL, - wallet.privateKey, - { - gasPrice, - }, - ), - }, - getTestConfigOptions(tokenTestChain)(), - ); - await setBalance(tokenTestChain)(wallet.address, ONE_ETH); - const txHash = await iexec.wallet.sendETH(0, wallet.address); - const tx = await tokenTestChain.provider.getTransaction(txHash); - expect(tx).toBeDefined(); - expect(tx.gasPrice.toString()).toBe(gasPrice); - }); + const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; + const tokenTestChain = TEST_CHAINS['arbitrum-sepolia-fork']; test('getTransactionCount option allows custom nonce management', async () => { const wallet = getRandomWallet(); + await setBalance(testChain)(wallet.address, ONE_ETH); const createNonceProvider = (address) => { - const initNoncePromise = iexecTestChain.provider.getTransactionCount( + const initNoncePromise = testChain.provider.getTransactionCount( address, 'latest', ); @@ -405,7 +384,7 @@ describe('utils', () => { const nonceProvider = createNonceProvider(wallet.address); const signer = utils.getSignerFromPrivateKey( - iexecTestChain.rpcURL, + testChain.rpcURL, wallet.privateKey, { getTransactionCount: nonceProvider.getNonce, @@ -416,34 +395,63 @@ describe('utils', () => { { ethProvider: signer, }, - getTestConfigOptions(iexecTestChain)(), + getTestConfigOptions(testChain)(), ); - const { registerTxHash: tx0 } = await iexec.ens.claimName( - `name-${getId()}`, - ); + const { txHash: tx0 } = await iexec.app.deployApp({ + owner: wallet.address, + name: `app-${getId()}`, + type: 'DOCKER', + multiaddr: 'registry.hub.docker.com/iexechub/vanityeth:1.1.1', + checksum: + '0x00f51494d7a42a3c1c43464d9f09e06b2a99968e3b978f6cd11ab3410b7bcd14', + }); expect(tx0).toBeTxHash(); - await expect(iexec.ens.claimName(`name-${getId()}`)).rejects.toThrow( - 'nonce too low', - ); + await expect( + iexec.app.deployApp({ + owner: wallet.address, + name: `app-${getId()}`, + type: 'DOCKER', + multiaddr: 'registry.hub.docker.com/iexechub/vanityeth:1.1.1', + checksum: + '0x00f51494d7a42a3c1c43464d9f09e06b2a99968e3b978f6cd11ab3410b7bcd14', + }), + ).rejects.toThrow('nonce too low'); nonceProvider.increaseNonce(); - const { registerTxHash: tx1 } = await iexec.ens.claimName( - `name-${getId()}`, - ); + const { txHash: tx1 } = await iexec.app.deployApp({ + owner: wallet.address, + name: `app-${getId()}`, + type: 'DOCKER', + multiaddr: 'registry.hub.docker.com/iexechub/vanityeth:1.1.1', + checksum: + '0x00f51494d7a42a3c1c43464d9f09e06b2a99968e3b978f6cd11ab3410b7bcd14', + }); expect(tx1).toBeTxHash(); - await expect(iexec.ens.claimName(`name-${getId()}`)).rejects.toThrow( - 'nonce too low', - ); + await expect( + iexec.app.deployApp({ + owner: wallet.address, + name: `app-${getId()}`, + type: 'DOCKER', + multiaddr: 'registry.hub.docker.com/iexechub/vanityeth:1.1.1', + checksum: + '0x00f51494d7a42a3c1c43464d9f09e06b2a99968e3b978f6cd11ab3410b7bcd14', + }), + ).rejects.toThrow('nonce too low'); nonceProvider.increaseNonce(); - const { registerTxHash: tx2 } = await iexec.ens.claimName( - `name-${getId()}`, - ); + const { txHash: tx2 } = await iexec.app.deployApp({ + owner: wallet.address, + name: `app-${getId()}`, + type: 'DOCKER', + multiaddr: 'registry.hub.docker.com/iexechub/vanityeth:1.1.1', + checksum: + '0x00f51494d7a42a3c1c43464d9f09e06b2a99968e3b978f6cd11ab3410b7bcd14', + }); expect(tx2).toBeTxHash(); }); diff --git a/test/lib/e2e/workflow.test.js b/test/lib/e2e/workflow.test.js index 990c135e..0d4c33fb 100644 --- a/test/lib/e2e/workflow.test.js +++ b/test/lib/e2e/workflow.test.js @@ -12,7 +12,7 @@ import { import '../../jest-setup.js'; import { errors } from '../../../src/lib/index.js'; -const iexecTestChain = TEST_CHAINS['bellecour-fork']; +const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; describe('[workflow]', () => { let noDurationCatId; @@ -22,7 +22,7 @@ describe('[workflow]', () => { let workerpoolorderToClaim; test('create category', async () => { - const res = await adminCreateCategory(iexecTestChain)({ + const res = await adminCreateCategory(testChain)({ name: 'custom', description: 'desc', workClockTimeRef: '0', @@ -34,7 +34,7 @@ describe('[workflow]', () => { }); test('deploy and sell app', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const owner = await iexec.wallet.getAddress(); const appName = `My app${getId()}`; const appDeployRes = await iexec.app.deployApp({ @@ -74,7 +74,7 @@ describe('[workflow]', () => { }); test('deploy and sell dataset', async () => { - const { iexec } = getTestConfig(iexecTestChain)(); + const { iexec } = await getTestConfig(testChain)(); const owner = await iexec.wallet.getAddress(); const datasetName = `My dataset${getId()}`; const datasetDeployRes = await iexec.dataset.deployDataset({ @@ -113,9 +113,9 @@ describe('[workflow]', () => { }); test('deploy and sell computing power', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const workerpoolPrice = '1000000000'; - await setNRlcBalance(iexecTestChain)(wallet.address, workerpoolPrice); + await setNRlcBalance(testChain)(wallet.address, workerpoolPrice); const owner = await iexec.wallet.getAddress(); const desc = `workerpool${getId()}`; const workerpoolDeployRes = await iexec.workerpool.deployWorkerpool({ @@ -161,7 +161,7 @@ describe('[workflow]', () => { }); test('buy computation', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const order = await iexec.order.createRequestorder({ app: apporder.app, appmaxprice: apporder.appprice, @@ -187,7 +187,7 @@ describe('[workflow]', () => { const totalPrice = new BN(order.appmaxprice) .add(new BN(order.datasetmaxprice)) .add(new BN(order.workerpoolmaxprice)); - await setNRlcBalance(iexecTestChain)(wallet.address, totalPrice); + await setNRlcBalance(testChain)(wallet.address, totalPrice); await iexec.account.deposit(totalPrice); expect(signedorder.sign).toBeDefined(); @@ -207,7 +207,7 @@ describe('[workflow]', () => { }); test('show & claim task, show & claim deal (initialized & uninitialized tasks)', async () => { - const { iexec, wallet } = getTestConfig(iexecTestChain)(); + const { iexec, wallet } = await getTestConfig(testChain)(); const order = await iexec.order.createRequestorder({ app: apporder.app, appmaxprice: apporder.appprice, @@ -225,7 +225,7 @@ describe('[workflow]', () => { .add(new BN(order.datasetmaxprice)) .add(new BN(order.workerpoolmaxprice)) .mul(new BN(order.volume)); - await setNRlcBalance(iexecTestChain)(wallet.address, totalPrice); + await setNRlcBalance(testChain)(wallet.address, totalPrice); await iexec.account.deposit(totalPrice); expect(signedorder.sign).toBeDefined(); const matchOrdersRes = await iexec.order.matchOrders( @@ -291,11 +291,11 @@ describe('[workflow]', () => { .catch((e) => e); expect(showTaskUnsetRes instanceof errors.ObjectNotFoundError).toBe(true); expect(showTaskUnsetRes.message).toBe( - `No task found for id ${showDealRes.tasks[0]} on chain ${iexecTestChain.chainId}`, + `No task found for id ${showDealRes.tasks[0]} on chain ${testChain.chainId}`, ); const taskIdxToInit = 1; - await initializeTask(iexecTestChain)(matchOrdersRes.dealid, taskIdxToInit); + await initializeTask(testChain)(matchOrdersRes.dealid, taskIdxToInit); const showTaskActiveRes = await iexec.task.show( showDealRes.tasks[taskIdxToInit], ); @@ -324,7 +324,7 @@ describe('[workflow]', () => { expect(showTaskActiveRes.taskTimedOut).toBe(true); const taskIdxToClaim = 2; - await initializeTask(iexecTestChain)(matchOrdersRes.dealid, taskIdxToClaim); + await initializeTask(testChain)(matchOrdersRes.dealid, taskIdxToClaim); const claimTaskRes = await iexec.task.claim( showDealRes.tasks[taskIdxToClaim], ); diff --git a/test/mock/compass/data.json b/test/mock/compass/data.json index 3ddfaf0d..293736de 100644 --- a/test/mock/compass/data.json +++ b/test/mock/compass/data.json @@ -1,13 +1,18 @@ [ { - "chainId": "65535", - "description": "custom-token-chain-no-ens", + "chainId": "421614", + "description": "arbitrum-sepolia-fork", "iapps": [], "workerpools": [ { - "name": "custom-token-chain-no-ens-workerpool", - "apiUrl": "https://core.custom-token-chain-no-ens.iex.ec", + "name": "unreachable-workerpool", + "apiUrl": "https://unreachable-workerpool.iex.ec", "address": "0xB967057a21dc6A66A29721d96b8Aa7454B7c383F" + }, + { + "name": "workerpool-http-500", + "apiUrl": "http://localhost:5500", + "address": "0x2956f0cb779904795a5f30d3b3ea88b714c3123f" } ] } diff --git a/test/scripts/prepare-bellecour-fork-for-tests.js b/test/scripts/prepare-bellecour-fork-for-tests.js deleted file mode 100755 index c37c6769..00000000 --- a/test/scripts/prepare-bellecour-fork-for-tests.js +++ /dev/null @@ -1,117 +0,0 @@ -import { - Contract, - JsonRpcProvider, - JsonRpcSigner, - formatEther, - toBeHex, -} from 'ethers'; - -const IEXEC_HUB_ADDRESS = '0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f'; -const TARGET_POCO_ADMIN_WALLET = '0x7bd4783FDCAD405A28052a0d1f11236A741da593'; -const TARGET_FAUCET_WALLET = '0xdFa2585C16cAf9c853086F36d2A37e9b8d1eab87'; - -const rpcURL = 'http://localhost:8545'; - -const provider = new JsonRpcProvider(rpcURL, undefined, { - pollingInterval: 100, // fast polling for tests -}); - -const setBalance = async (address, weiAmount) => { - fetch(rpcURL, { - method: 'POST', - body: JSON.stringify({ - method: 'anvil_setBalance', - params: [address, toBeHex(weiAmount)], - id: 1, - jsonrpc: '2.0', - }), - headers: { - 'Content-Type': 'application/json', - }, - }); - const balance = await provider.getBalance(address); - console.log(`${address} wallet balance is now ${formatEther(balance)} RLC`); -}; - -const impersonate = async (address) => { - await fetch(rpcURL, { - method: 'POST', - body: JSON.stringify({ - method: 'anvil_impersonateAccount', - params: [address], - id: 1, - jsonrpc: '2.0', - }), - headers: { - 'Content-Type': 'application/json', - }, - }); - console.log(`impersonating ${address}`); -}; - -const stopImpersonate = async (address) => { - await fetch(rpcURL, { - method: 'POST', - body: JSON.stringify({ - method: 'anvil_stopImpersonatingAccount', - params: [address], - id: 1, - jsonrpc: '2.0', - }), - headers: { - 'Content-Type': 'application/json', - }, - }); - console.log(`stop impersonating ${address}`); -}; - -const getIExecHubOwnership = async (targetOwner) => { - const iexecContract = new Contract( - IEXEC_HUB_ADDRESS, - [ - { - inputs: [], - name: 'owner', - outputs: [{ internalType: 'address', name: '', type: 'address' }], - stateMutability: 'view', - type: 'function', - constant: true, - }, - { - inputs: [ - { internalType: 'address', name: 'newOwner', type: 'address' }, - ], - name: 'transferOwnership', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - ], - provider, - ); - const iexecOwner = await iexecContract.owner(); - await impersonate(iexecOwner); - await iexecContract - .connect(new JsonRpcSigner(provider, iexecOwner)) - .transferOwnership(targetOwner, { gasPrice: 0 }) - .then((tx) => tx.wait()); - await stopImpersonate(iexecOwner); - - const newOwner = await iexecContract.owner(); - console.log( - `IExecHub proxy at ${IEXEC_HUB_ADDRESS} is now owned by ${newOwner}`, - ); -}; - -const main = async () => { - console.log(`preparing bellecour-fork at ${rpcURL}`); - - // prepare PoCo - await setBalance(TARGET_POCO_ADMIN_WALLET, 1000000n * 10n ** 18n); - await getIExecHubOwnership(TARGET_POCO_ADMIN_WALLET); - - // prepare faucet wallet - await setBalance(TARGET_FAUCET_WALLET, 1000000n * 10n ** 18n); -}; - -main(); diff --git a/test/scripts/prepare-forks-for-tests.js b/test/scripts/prepare-forks-for-tests.js new file mode 100755 index 00000000..f61d646a --- /dev/null +++ b/test/scripts/prepare-forks-for-tests.js @@ -0,0 +1,130 @@ +import { + Contract, + JsonRpcProvider, + JsonRpcSigner, + formatEther, + toBeHex, +} from 'ethers'; + +const TARGET_POCO_ADMIN_WALLET = '0x7bd4783FDCAD405A28052a0d1f11236A741da593'; + +const getProvider = (rpcUrl) => + new JsonRpcProvider(rpcUrl, undefined, { + pollingInterval: 100, // fast polling for tests + }); + +const setBalance = (rpcUrl) => async (address, weiAmount) => { + await fetch(rpcUrl, { + method: 'POST', + body: JSON.stringify({ + method: 'anvil_setBalance', + params: [address, toBeHex(weiAmount)], + id: 1, + jsonrpc: '2.0', + }), + headers: { + 'Content-Type': 'application/json', + }, + }); + const balance = await getProvider(rpcUrl).getBalance(address); + console.log(`${address} wallet balance is now ${formatEther(balance)}`); +}; + +const impersonate = (rpcUrl) => async (address) => { + await fetch(rpcUrl, { + method: 'POST', + body: JSON.stringify({ + method: 'anvil_impersonateAccount', + params: [address], + id: 1, + jsonrpc: '2.0', + }), + headers: { + 'Content-Type': 'application/json', + }, + }); + console.log(`impersonating ${address}`); +}; + +const stopImpersonate = (rpcUrl) => async (address) => { + await fetch(rpcUrl, { + method: 'POST', + body: JSON.stringify({ + method: 'anvil_stopImpersonatingAccount', + params: [address], + id: 1, + jsonrpc: '2.0', + }), + headers: { + 'Content-Type': 'application/json', + }, + }); + console.log(`stop impersonating ${address}`); +}; + +const getIExecHubOwnership = + (rpcUrl, legacyTx = false) => + async (hubAddress, targetOwner) => { + const iexecContract = new Contract( + hubAddress, + [ + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + constant: true, + }, + { + inputs: [ + { internalType: 'address', name: 'newOwner', type: 'address' }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], + getProvider(rpcUrl), + ); + const iexecOwner = await iexecContract.owner(); + await setBalance(rpcUrl)(iexecOwner, 1n * 10n ** 18n); // give some ETH to the owner to be able to send the transaction + await impersonate(rpcUrl)(iexecOwner); + await iexecContract + .connect(new JsonRpcSigner(getProvider(rpcUrl), iexecOwner)) + .transferOwnership(targetOwner, legacyTx ? { gasPrice: 0 } : {}) + .then((tx) => tx.wait()); + await stopImpersonate(rpcUrl)(iexecOwner); + + const newOwner = await iexecContract.owner(); + console.log(`IExecHub proxy at ${hubAddress} is now owned by ${newOwner}`); + }; + +const main = async () => { + const bellecourForkRpcUrl = 'http://localhost:8545'; + console.log(`preparing bellecour-fork at ${bellecourForkRpcUrl}`); + await setBalance(bellecourForkRpcUrl)( + TARGET_POCO_ADMIN_WALLET, + 1000000n * 10n ** 18n, + ); + await getIExecHubOwnership(bellecourForkRpcUrl, true)( + '0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f', + TARGET_POCO_ADMIN_WALLET, + ); + + const arbitrumSepoliaForkRpcUrl = 'http://localhost:8555'; + console.log( + `preparing arbitrum-sepolia-fork at ${arbitrumSepoliaForkRpcUrl}`, + ); + await setBalance(arbitrumSepoliaForkRpcUrl)( + TARGET_POCO_ADMIN_WALLET, + 1000000n * 10n ** 18n, + ); + await getIExecHubOwnership(arbitrumSepoliaForkRpcUrl)( + '0xB2157BF2fAb286b2A4170E3491Ac39770111Da3E', + TARGET_POCO_ADMIN_WALLET, + ); +}; + +main(); diff --git a/test/scripts/prepare-test-env.js b/test/scripts/prepare-test-env.js index 66ff927d..907596a4 100644 --- a/test/scripts/prepare-test-env.js +++ b/test/scripts/prepare-test-env.js @@ -1,32 +1,59 @@ import { writeFileSync } from 'fs'; -const forkUrl = process.env.BELLECOUR_FORK_URL || 'https://bellecour.iex.ec'; +const bellecourForkUrl = + process.env.BELLECOUR_FORK_URL || 'https://bellecour.iex.ec'; +const arbitrumSepoliaForkUrl = + process.env.ARBITRUM_SEPOLIA_FORK_URL || + 'https://sepolia-rollup.arbitrum.io/rpc'; -fetch(forkUrl, { - method: 'POST', - body: JSON.stringify({ - jsonrpc: 2.0, - method: 'eth_blockNumber', - params: [], - id: 1, - }), -}) - .then((res) => res.json()) - .then((jsonRes) => { - const forkBlockNumber = parseInt(jsonRes.result.substring(2), 16); - console.log('Creating .env file for docker-compose test-stack'); - writeFileSync( - '.env', - `############ THIS FILE IS GENERATED ############ +const [bellecourForkBlock, arbitrumSepoliaForkBlock] = await Promise.all([ + getCurrentBlockNumber(bellecourForkUrl), + getCurrentBlockNumber(arbitrumSepoliaForkUrl), +]); + +console.log('Creating .env file for docker-compose test-stack'); +writeFileSync( + '.env', + `############ THIS FILE IS GENERATED ############ # run "node prepare-test-env.js" to regenerate # ################################################ # blockchain node to use as the reference for the local fork -BELLECOUR_FORK_URL=${forkUrl} +BELLECOUR_FORK_URL=${bellecourForkUrl} # block number to fork from -BELLECOUR_FORK_BLOCK=${forkBlockNumber}`, - ); +BELLECOUR_FORK_BLOCK=${bellecourForkBlock} + +# blockchain node to use as the reference for the local fork +ARBITRUM_SEPOLIA_FORK_URL=${arbitrumSepoliaForkUrl} +# block number to fork from +ARBITRUM_SEPOLIA_FORK_BLOCK=${arbitrumSepoliaForkBlock}`, +); + +async function getCurrentBlockNumber(forkUrl) { + const blockNumber = await fetch(forkUrl, { + method: 'POST', + body: JSON.stringify({ + jsonrpc: '2.0', + method: 'eth_blockNumber', + params: [], + id: 1, + }), + headers: { + 'Content-Type': 'application/json', + }, }) - .catch((e) => { - throw new Error(`Failed to get current block number from ${forkUrl}: ${e}`); - }); + .then((res) => res.json()) + .then((jsonRes) => { + console.log( + `Current block number of ${forkUrl} is ${JSON.stringify(jsonRes)}`, + ); + const forkBlockNumber = parseInt(jsonRes.result.substring(2), 16); + return forkBlockNumber; + }) + .catch((e) => { + throw new Error( + `Failed to get current block number from ${forkUrl}: ${e}`, + ); + }); + return blockNumber; +} diff --git a/test/test-config-utils.js b/test/test-config-utils.js index 56fab67c..3f0592bd 100644 --- a/test/test-config-utils.js +++ b/test/test-config-utils.js @@ -1,5 +1,6 @@ import { Wallet, JsonRpcProvider } from 'ethers'; import { IExec } from '../src/lib/index.js'; +import { setBalance } from './test-utils.js'; export const getTestConfigOptions = (chain) => @@ -24,8 +25,37 @@ export const getTestConfigOptions = }); export const getTestConfig = - (chain) => - ({ privateKey, readOnly = false, options = {} } = {}) => { + ( + /** + * Target test blockchain configuration. + */ + chain, + ) => + async ({ + /** + * The private key to use for the wallet, if not provided a random wallet will be created unless `readOnly` is set to true. + * If `readOnly` is true, this parameter is ignored. + * @type {string} + */ + privateKey, + /** + * Whether the IExec instance should be read-only (no transactions will be sent). + * Defaults to false. + * @type {boolean} + */ + readOnly = false, + /** + * The balance to set for the wallet. + * If not provided, defaults to the chain's default initial balance or 0n. + * @type {bigint} + */ + balance = chain.defaultInitBalance || 0n, + /** + * IExec configuration options. + * @type {Object} + */ + options = {}, + } = {}) => { const configOptions = getTestConfigOptions(chain)({ options }); if (readOnly) { return { @@ -36,6 +66,10 @@ export const getTestConfig = pollingInterval: 1000, }); const wallet = privateKey ? new Wallet(privateKey) : Wallet.createRandom(); + // fund wallet if needed + if (balance > 0n) { + await setBalance(chain)(await wallet.getAddress(), balance); + } const ethProvider = new Wallet(wallet.privateKey, provider); return { iexec: new IExec({ ethProvider }, configOptions), diff --git a/test/test-utils.js b/test/test-utils.js index f897ad8b..5e2035b9 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -3,13 +3,15 @@ import { exec } from 'child_process'; import { Wallet, JsonRpcProvider, - ethers, Contract, hexlify, randomBytes, + keccak256, + AbiCoder, + toBeHex, } from 'ethers'; import { IExec } from '../src/lib/index.js'; -import { getSignerFromPrivateKey } from '../src/lib/utils.js'; +import { getSignerFromPrivateKey, NULL_ADDRESS } from '../src/lib/utils.js'; export { TEE_FRAMEWORKS, @@ -55,52 +57,6 @@ export const SERVICE_HTTP_500_URL = 'http://localhost:5500'; export const SERVICE_UNREACHABLE_URL = 'http://unreachable:80'; export const TEST_CHAINS = { - // autoseal chain with iExec token - 'custom-token-chain': { - rpcURL: 'http://localhost:18545', - chainId: '65535', - hubAddress: '0xC129e7917b7c7DeDfAa5Fff1FB18d5D7050fE8ca', - ensRegistryAddress: '0xaf87b82B01E484f8859c980dE69eC8d09D30F22a', - ensPublicResolverAddress: '0x464E9FC01C2970173B183D24B43A0FA07e6A072E', - ipfsNodeURL: 'http://localhost:5001', - ipfsGatewayURL: 'http://localhost:8080', - pocoAdminWallet: new Wallet( - '0x564a9db84969c8159f7aa3d5393c5ecd014fce6a375842a45b12af6677b12407', - ), - // TODO use another wallet - faucetWallet: new Wallet( - '0x564a9db84969c8159f7aa3d5393c5ecd014fce6a375842a45b12af6677b12407', - ), - provider: new JsonRpcProvider('http://localhost:18545', undefined, { - pollingInterval: 100, - }), - defaults: { - isNative: false, - useGas: true, - }, - isAnvil: false, - }, - 'custom-token-chain-no-ens': { - rpcURL: 'http://localhost:18545', - chainId: '65535', - hubAddress: '0xC129e7917b7c7DeDfAa5Fff1FB18d5D7050fE8ca', - pocoAdminWallet: new Wallet( - '0x564a9db84969c8159f7aa3d5393c5ecd014fce6a375842a45b12af6677b12407', - ), - compassURL: 'http://localhost:8069', - // TODO use another wallet - faucetWallet: new Wallet( - '0x564a9db84969c8159f7aa3d5393c5ecd014fce6a375842a45b12af6677b12407', - ), - provider: new JsonRpcProvider('http://localhost:18545', undefined, { - pollingInterval: 100, - }), - defaults: { - isNative: false, - useGas: true, - }, - isAnvil: false, - }, 'bellecour-fork': { rpcURL: 'http://localhost:8545', chainId: '134', @@ -112,9 +68,6 @@ export const TEST_CHAINS = { pocoAdminWallet: new Wallet( '0x564a9db84969c8159f7aa3d5393c5ecd014fce6a375842a45b12af6677b12407', ), - faucetWallet: new Wallet( - '0xde43b282c2931fc41ca9e1486fedc2c45227a3b9b4115c89d37f6333c8816d89', - ), provider: new JsonRpcProvider('http://localhost:8545', undefined, { pollingInterval: 100, }), @@ -126,7 +79,43 @@ export const TEST_CHAINS = { useGas: false, name: 'bellecour', }, - isAnvil: true, + defaultInitBalance: 0n, + }, + 'arbitrum-sepolia-fork': { + rpcURL: 'http://localhost:8555', + chainId: '421614', + smsURL: 'http://localhost:13350', + iexecGatewayURL: 'http://localhost:3050', + resultProxyURL: 'http://localhost:13250', + ipfsNodeURL: 'http://localhost:5001', + ipfsGatewayURL: 'http://localhost:8080', + compassURL: 'http://localhost:8069', + pocoAdminWallet: new Wallet( + '0x564a9db84969c8159f7aa3d5393c5ecd014fce6a375842a45b12af6677b12407', + ), + provider: new JsonRpcProvider('http://localhost:8555', undefined, { + pollingInterval: 100, + }), + defaults: { + hubAddress: '0xB2157BF2fAb286b2A4170E3491Ac39770111Da3E', + isNative: false, + useGas: true, + name: 'arbitrum-sepolia', + }, + defaultInitBalance: 1n * 10n ** 18n, // 1 ETH for gas + }, + 'unknown-chain': { + rpcURL: 'http://localhost:8565', + chainId: '421615', + hubAddress: '0xB2157BF2fAb286b2A4170E3491Ac39770111Da3E', + isNative: false, + useGas: true, + name: 'unknown-chain', + provider: new JsonRpcProvider('http://localhost:8565', undefined, { + pollingInterval: 100, + }), + defaultInitBalance: 1n * 10n ** 18n, // 1 ETH for gas + ensRegistryAddress: NULL_ADDRESS, }, }; @@ -194,47 +183,65 @@ export class InjectedProvider { } } -const faucetSendWeiToReachTargetBalance = - (chain) => - async (address, targetWeiBalance, tryCount = 1) => { - const currentBalance = await chain.provider.getBalance(address); - const delta = BigInt(`${targetWeiBalance}`) - currentBalance; - if (delta < 0n) { - console.warn( - `Faucet send Eth: aborted - current balance exceed target balance`, - ); - return; - } - try { - const tx = await chain.faucetWallet - .connect(chain.provider) - .sendTransaction({ to: address, value: delta }); - await tx.wait(); - } catch (e) { - console.warn(`Faucet send Eth: error (try count ${tryCount}) - ${e}`); - // retry as concurrent calls can lead to nonce collisions on the faucet wallet - if (tryCount < 5) { - await sleep(3000 * tryCount); - await faucetSendWeiToReachTargetBalance(chain)( - address, - targetWeiBalance, - tryCount + 1, - ); - } else { - throw new Error( - `Failed to send Eth from faucet (tried ${tryCount} times)`, - ); - } - } - }; +const anvilSetBalance = (chain) => async (address, targetWeiBalance) => { + await fetch(chain.rpcURL, { + method: 'POST', + body: JSON.stringify({ + method: 'anvil_setBalance', + params: [address, toBeHex(targetWeiBalance)], + id: 1, + jsonrpc: '2.0', + }), + headers: { + 'Content-Type': 'application/json', + }, + }); +}; + +const anvilSetNRlcTokenBalance = + (chain) => async (address, targetNRlcBalance) => { + const rlcAddress = await new Contract( + chain.hubAddress ?? chain.defaults.hubAddress, + [ + { + inputs: [], + name: 'token', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + ], + chain.provider, + ).token(); + + /** [rlc-multichain](https://github.com/iExecBlockchainComputing/rlc-multichain/tree/v0.1.0) is an openzeppelin ERC20Upgradeable contract + * + * ERC20Upgradeable contract use a specific storage slot, which is: + * ``` + * // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ERC20")) - 1)) & ~bytes32(uint256(0xff)) + * bytes32 private constant ERC20StorageLocation = 0x52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00; + * ``` + * sources: https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/v5.3.0/contracts/token/ERC20/ERC20Upgradeable.sol#L43-L44 + */ + const erc20StorageLocation = + '0x52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00'; + + const balanceSlot = keccak256( + AbiCoder.defaultAbiCoder().encode( + ['address', 'uint256'], + [address, erc20StorageLocation], + ), + ); -export const setBalance = (chain) => async (address, targetWeiBalance) => { - if (chain.isAnvil) { await fetch(chain.rpcURL, { method: 'POST', body: JSON.stringify({ - method: 'anvil_setBalance', - params: [address, ethers.toBeHex(targetWeiBalance)], + method: 'anvil_setStorageAt', + params: [ + rlcAddress, + balanceSlot, + toBeHex(BigInt(targetNRlcBalance), 32), + ], id: 1, jsonrpc: '2.0', }), @@ -242,85 +249,25 @@ export const setBalance = (chain) => async (address, targetWeiBalance) => { 'Content-Type': 'application/json', }, }); - } else { - await faucetSendWeiToReachTargetBalance(chain)(address, targetWeiBalance); - } -}; - -const faucetSendNRlcToReachTargetBalance = - (chain) => - async (address, nRlcTargetBalance, tryCount = 1) => { - const iexec = new IExec( - { - ethProvider: getSignerFromPrivateKey( - chain.rpcURL, - chain.faucetWallet.privateKey, - ), - }, - { hubAddress: chain.hubAddress }, - ); - const { nRLC } = await iexec.wallet.checkBalances(address); - const delta = BigInt(`${nRlcTargetBalance}`) - BigInt(`${nRLC}`); - if (delta < 0n) { - console.warn( - `Faucet send RLC: aborted - current balance exceed target balance`, - ); - return; - } - try { - await iexec.wallet.sendRLC(`${delta}`, address); - } catch (e) { - console.warn(`Faucet send RLC: error (try count ${tryCount}) - ${e}`); - // retry as concurrent calls can lead to nonce collisions on the faucet wallet - if (tryCount < 5) { - await sleep(3000 * tryCount); - await faucetSendNRlcToReachTargetBalance(chain)( - address, - nRlcTargetBalance, - tryCount + 1, - ); - } else { - throw new Error( - `Failed to send RLC from faucet (tried ${tryCount} times)`, - ); - } - } }; +export const setBalance = (chain) => async (address, targetWeiBalance) => + anvilSetBalance(chain)(address, targetWeiBalance); + export const setNRlcBalance = (chain) => async (address, nRlcTargetBalance) => { if (chain.isNative || chain.defaults?.isNative) { const weiAmount = BigInt(`${nRlcTargetBalance}`) * 10n ** 9n; // 1 nRLC is 10^9 wei - await setBalance(chain)(address, weiAmount); + await anvilSetBalance(chain)(address, weiAmount); return; } - await faucetSendNRlcToReachTargetBalance(chain)(address, nRlcTargetBalance); + await anvilSetNRlcTokenBalance(chain)(address, nRlcTargetBalance); }; -export const setStakedNRlcBalance = - (chain) => async (address, nRlcTargetBalance) => { - const sponsorWallet = Wallet.createRandom(chain.provider); - const iexec = new IExec( - { - ethProvider: sponsorWallet, - }, - { hubAddress: chain.hubAddress }, - ); - await setNRlcBalance(chain)( - sponsorWallet.address, - BigInt(nRlcTargetBalance), - ); - const contractClient = await iexec.config.resolveContractsClient(); - const iexecContract = contractClient.getIExecContract(); - const tx = await iexecContract.depositFor(address, { - value: BigInt(nRlcTargetBalance) * 10n ** 9n, - gasPrice: 0, // TODO: wont work on non gasless chain - }); - await tx.wait(); - }; - export const initializeTask = (chain) => async (dealid, idx) => { + const wallet = Wallet.createRandom(chain.provider); + await setBalance(chain)(wallet.address, 1n * 10n ** 18n); // fund wallet to pay for initialization const iexecContract = new Contract( - chain.hubAddress || chain.defaults.hubAddress, + chain.hubAddress ?? chain.defaults.hubAddress, [ { constant: false, @@ -346,7 +293,7 @@ export const initializeTask = (chain) => async (dealid, idx) => { type: 'function', }, ], - Wallet.createRandom(chain.provider), // random to avoid nonce collisions + wallet, ); const initTx = await iexecContract.initialize(dealid, idx); await initTx.wait(); @@ -362,7 +309,7 @@ export const adminCreateCategory = chain.pocoAdminWallet.privateKey, ), }, - { hubAddress: chain.hubAddress }, + { hubAddress: chain.hubAddress ?? chain.defaults.hubAddress }, ); let res; try { @@ -371,7 +318,7 @@ export const adminCreateCategory = console.warn( `Admin create category: error (try count ${tryCount}) - ${e}`, ); - // retry as concurrent calls can lead to nonce collisions on the faucet wallet + // retry as concurrent calls can lead to nonce collisions on the admin wallet if (tryCount < 5) { await sleep(3000 * tryCount); res = await adminCreateCategory(chain)(category, tryCount + 1); From 0bb4779e35847136809049921b7ff5391086fa68 Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Tue, 21 Apr 2026 11:43:56 +0200 Subject: [PATCH 04/13] fix!: remove bridge related methods and configuration --- CLI.md | 65 +- cli_template.md | 13 +- docs/-internal-/README.md | 1 - docs/-internal-/classes/BridgeObservable.md | 97 -- docs/classes/IExecAccountModule.md | 24 - docs/classes/IExecConfig.md | 36 - docs/classes/IExecWalletModule.md | 145 -- docs/classes/Observable.md | 1 - docs/iexec/namespaces/errors/README.md | 1 - .../namespaces/errors/classes/BridgeError.md | 67 - docs/interfaces/IExecConfigOptions.md | 40 - eslint.config.js | 2 - src/cli/cmd/iexec-wallet.js | 179 --- src/cli/utils/chains.js | 69 +- src/cli/utils/cli-helper.js | 4 - src/cli/utils/fs.js | 6 - src/common/utils/config.js | 15 - src/common/utils/errors.js | 15 - .../wallet/abi/ForeignBridgeErcToNative.js | 634 --------- .../wallet/abi/HomeBridgeErcToNative.js | 1185 ----------------- src/common/wallet/bridge.js | 568 -------- src/lib/IExecAccountModule.d.ts | 10 - src/lib/IExecAccountModule.js | 2 - src/lib/IExecConfig.d.ts | 37 - src/lib/IExecConfig.js | 104 -- src/lib/IExecWalletModule.d.ts | 153 --- src/lib/IExecWalletModule.js | 48 - src/lib/errors.d.ts | 27 - test/lib/e2e/IExecAccountModule.test.js | 33 - test/lib/e2e/IExecConfig.test.js | 268 ---- test/lib/e2e/IExecWalletModule.test.js | 33 - test/lib/unit/config.test.js | 23 - test/test-config-utils.js | 2 - 33 files changed, 5 insertions(+), 3902 deletions(-) delete mode 100644 docs/-internal-/classes/BridgeObservable.md delete mode 100644 docs/iexec/namespaces/errors/classes/BridgeError.md delete mode 100644 src/common/wallet/abi/ForeignBridgeErcToNative.js delete mode 100644 src/common/wallet/abi/HomeBridgeErcToNative.js delete mode 100644 src/common/wallet/bridge.js diff --git a/CLI.md b/CLI.md index 4ead4dbe..cd984c86 100644 --- a/CLI.md +++ b/CLI.md @@ -356,8 +356,6 @@ Commands: - [send-ether](#iexec-wallet-send-ether) - [send-RLC](#iexec-wallet-send-rlc) - [sweep](#iexec-wallet-sweep) -- [bridge-to-sidechain](#iexec-wallet-bridge-to-sidechain) -- [bridge-to-mainchain](#iexec-wallet-bridge-to-mainchain) - [sendRLC](#iexec-wallet-sendrlc) #### iexec wallet create @@ -505,56 +503,6 @@ Options: | --force | force perform action without prompting user | | --to \ | receiver address | -#### iexec wallet bridge-to-sidechain - -send RLC from the mainchain to the sidechain (default unit nRLC) - -Usage: - -```sh -iexec wallet bridge-to-sidechain [unit] [options] -``` - -Options: - -| option | description | -| --- | --- | -| --raw | use raw output | -| --quiet | stop prompting updates | -| --password \ | password used to encrypt the wallet (unsafe) | -| --wallet-file \ | specify the name of the wallet file to use | -| --wallet-address \ | specify the address of the wallet to use | -| --keystoredir \ | specify the wallet directory \<"global"\|"local"\|custom\> | -| --chain \ | chain name from "chain.json" | -| --gas-price \ | set custom gas price for transactions (default unit wei) | -| --confirms \ | set custom block count to wait for transactions confirmation (default 1 block) | -| --force | force perform action without prompting user | - -#### iexec wallet bridge-to-mainchain - -send RLC from the sidechain to the mainchain (default unit nRLC) - -Usage: - -```sh -iexec wallet bridge-to-mainchain [unit] [options] -``` - -Options: - -| option | description | -| --- | --- | -| --raw | use raw output | -| --quiet | stop prompting updates | -| --password \ | password used to encrypt the wallet (unsafe) | -| --wallet-file \ | specify the name of the wallet file to use | -| --wallet-address \ | specify the address of the wallet to use | -| --keystoredir \ | specify the wallet directory \<"global"\|"local"\|custom\> | -| --chain \ | chain name from "chain.json" | -| --gas-price \ | set custom gas price for transactions (default unit wei) | -| --confirms \ | set custom block count to wait for transactions confirmation (default 1 block) | -| --force | force perform action without prompting user | - #### iexec wallet sendRLC \[DEPRECATED see send-RLC\] send RLC to an address (WARNING! default unit nRLC) @@ -2601,7 +2549,6 @@ The `chain.json` file, located in every iExec project, describes the parameters - optional key `iexecGateway` set the url of the iexec marketplace gateway used by the SDK cli on each chain (overwrite default value). - optional key `ipfsGateway` set the url of the IPFS gateway used by the SDK cli on each chain (overwrite default value). - optional key `pocoSubgraph` set the url of the PoCo subgraph used by the SDK cli on each chain (overwrite default value). - - optional key `bridge` set the bridge used by the SDK cli when working with bridged networks (sidechain). `bridge.contract` set the address of the RLC bridge on the chain, `bridge.bridgedChainName` set the reference to the bridged network. - optional key `native` specify whether or not the chain native token is RLC (overwrite default value: chain value or `false`). - optional key `useGas` specify whether or not the chain requires to spend gas to send a transaction (overwrite default value: chain value or `true`). - optional key `providers` set the backends for public chains @@ -2622,11 +2569,7 @@ The `chain.json` file, located in every iExec project, describes the parameters }, "resultProxy": "http://localhost:8089", "ipfsGateway": "http://localhost:8080", - "hub": "0xC129e7917b7c7DeDfAa5Fff1FB18d5D7050fE8ca", - "bridge": { - "contract": "0x1e32aFA55854B6c015D284E3ccA9aA5a463A1418", - "bridgedChainName": "dev-sidechain" - } + "hub": "0xC129e7917b7c7DeDfAa5Fff1FB18d5D7050fE8ca" }, "dev-sidechain": { "host": "http://localhost:18545", @@ -2638,11 +2581,7 @@ The `chain.json` file, located in every iExec project, describes the parameters "ipfsGateway": "http://localhost:18080", "native": true, "useGas": false, - "hub": "0xC129e7917b7c7DeDfAa5Fff1FB18d5D7050fE8ca", - "bridge": { - "contract": "0x1e32aFA55854B6c015D284E3ccA9aA5a463A1418", - "bridgedChainName": "development" - } + "hub": "0xC129e7917b7c7DeDfAa5Fff1FB18d5D7050fE8ca" }, "mainnet": {}, "bellecour": {} diff --git a/cli_template.md b/cli_template.md index 8b8ad8c5..0521afa2 100644 --- a/cli_template.md +++ b/cli_template.md @@ -401,7 +401,6 @@ The `chain.json` file, located in every iExec project, describes the parameters - optional key `iexecGateway` set the url of the iexec marketplace gateway used by the SDK cli on each chain (overwrite default value). - optional key `ipfsGateway` set the url of the IPFS gateway used by the SDK cli on each chain (overwrite default value). - optional key `pocoSubgraph` set the url of the PoCo subgraph used by the SDK cli on each chain (overwrite default value). - - optional key `bridge` set the bridge used by the SDK cli when working with bridged networks (sidechain). `bridge.contract` set the address of the RLC bridge on the chain, `bridge.bridgedChainName` set the reference to the bridged network. - optional key `native` specify whether or not the chain native token is RLC (overwrite default value: chain value or `false`). - optional key `useGas` specify whether or not the chain requires to spend gas to send a transaction (overwrite default value: chain value or `true`). - optional key `providers` set the backends for public chains @@ -422,11 +421,7 @@ The `chain.json` file, located in every iExec project, describes the parameters }, "resultProxy": "http://localhost:8089", "ipfsGateway": "http://localhost:8080", - "hub": "0xC129e7917b7c7DeDfAa5Fff1FB18d5D7050fE8ca", - "bridge": { - "contract": "0x1e32aFA55854B6c015D284E3ccA9aA5a463A1418", - "bridgedChainName": "dev-sidechain" - } + "hub": "0xC129e7917b7c7DeDfAa5Fff1FB18d5D7050fE8ca" }, "dev-sidechain": { "host": "http://localhost:18545", @@ -438,11 +433,7 @@ The `chain.json` file, located in every iExec project, describes the parameters "ipfsGateway": "http://localhost:18080", "native": true, "useGas": false, - "hub": "0xC129e7917b7c7DeDfAa5Fff1FB18d5D7050fE8ca", - "bridge": { - "contract": "0x1e32aFA55854B6c015D284E3ccA9aA5a463A1418", - "bridgedChainName": "development" - } + "hub": "0xC129e7917b7c7DeDfAa5Fff1FB18d5D7050fE8ca" }, "mainnet": {}, "bellecour": {} diff --git a/docs/-internal-/README.md b/docs/-internal-/README.md index ff3f467c..5ff65230 100644 --- a/docs/-internal-/README.md +++ b/docs/-internal-/README.md @@ -8,7 +8,6 @@ ## Classes -- [BridgeObservable](classes/BridgeObservable.md) - [DealObservable](classes/DealObservable.md) - [ENSConfigurationObservable](classes/ENSConfigurationObservable.md) - [IExecContractsClient](classes/IExecContractsClient.md) diff --git a/docs/-internal-/classes/BridgeObservable.md b/docs/-internal-/classes/BridgeObservable.md deleted file mode 100644 index 2d91065e..00000000 --- a/docs/-internal-/classes/BridgeObservable.md +++ /dev/null @@ -1,97 +0,0 @@ -[**iexec**](../../README.md) - -*** - -[iexec](../../globals.md) / [\](../README.md) / BridgeObservable - -# Class: BridgeObservable - -## Extends - -- [`Observable`](../../classes/Observable.md) - -## Constructors - -### Constructor - -> **new BridgeObservable**(): `BridgeObservable` - -#### Returns - -`BridgeObservable` - -#### Inherited from - -[`Observable`](../../classes/Observable.md).[`constructor`](../../classes/Observable.md#constructor) - -## Methods - -### subscribe() - -> **subscribe**(`callbacks`): () => `void` - -subscribe and start the bridge process to transfer tokens from one chain to another until either `complete()` or `error(error: Error)` is called on the Observer or the subscribtion is canceled by calling the returned cancel method. - -return the `cancel: () => void` method. - -data: -| message | comment | additional entries | -| --- | --- | --- | -| `CHECK_BRIDGE_POLICY` | sent once | | -| `BRIDGE_POLICY_CHECKED` | sent once | `minPerTx`,`maxPerTx`,`dailyLimit` | -| `CHECK_BRIDGE_LIMIT` | sent once | | -| `BRIDGE_LIMIT_CHECKED` | sent once | `totalSpentPerDay` | -| `SEND_TO_BRIDGE_TX_REQUEST` | sent once | `bridgeAddress` | -| `SEND_TO_BRIDGE_TX_SUCCESS` | sent once | `txHash` | -| `WAIT_RECEIVE_TX` | sent once if the bridged chain is configured | `bridgeAddress` | -| `RECEIVE_TX_SUCCESS` | sent once if the bridged chain is configured | `txHash` | - -#### Parameters - -##### callbacks - -###### complete? - -() => `any` - -callback fired once when the bridge process is completed - -no other callback is fired after firing `complete()` - -###### error? - -(`error`) => `any` - -callback fired once when an error occurs - -no other callback is fired after firing `error(error: Error)` - -###### next? - -(`data`) => `any` - -callback fired at every configuration step - -data: -| message | comment | additional entries | -| --- | --- | --- | -| `CHECK_BRIDGE_POLICY` | sent once | | -| `BRIDGE_POLICY_CHECKED` | sent once | `minPerTx`,`maxPerTx`,`dailyLimit` | -| `CHECK_BRIDGE_LIMIT` | sent once | | -| `BRIDGE_LIMIT_CHECKED` | sent once | `totalSpentPerDay` | -| `SEND_TO_BRIDGE_TX_REQUEST` | sent once | `bridgeAddress` | -| `SEND_TO_BRIDGE_TX_SUCCESS` | sent once | `txHash` | -| `WAIT_RECEIVE_TX` | sent once if the bridged chain is configured | `bridgeAddress` | -| `RECEIVE_TX_SUCCESS` | sent once if the bridged chain is configured | `txHash` | - -#### Returns - -> (): `void` - -##### Returns - -`void` - -#### Overrides - -[`Observable`](../../classes/Observable.md).[`subscribe`](../../classes/Observable.md#subscribe) diff --git a/docs/classes/IExecAccountModule.md b/docs/classes/IExecAccountModule.md index aaca2713..4abe39ec 100644 --- a/docs/classes/IExecAccountModule.md +++ b/docs/classes/IExecAccountModule.md @@ -135,30 +135,6 @@ console.log('Nano RLC locked:', balance.locked.toString()); *** -### checkBridgedBalance() - -> **checkBridgedBalance**(`address`): `Promise`\<\{ `locked`: [`BN`](../interfaces/BN.md); `stake`: [`BN`](../interfaces/BN.md); \}\> - -check the account balance on bridged chain of specified address ie: when connected to mainnet, check the account ballance on bellecour -example: -```js -const balance = await checkBridgedBalance(ethAddress); -console.log('Nano RLC staked:', balance.stake.toString()); -console.log('Nano RLC locked:', balance.locked.toString()); -``` - -#### Parameters - -##### address - -`string` - -#### Returns - -`Promise`\<\{ `locked`: [`BN`](../interfaces/BN.md); `stake`: [`BN`](../interfaces/BN.md); \}\> - -*** - ### deposit() > **deposit**(`amount`): `Promise`\<\{ `amount`: [`BN`](../interfaces/BN.md); `txHash`: `string`; \}\> diff --git a/docs/classes/IExecConfig.md b/docs/classes/IExecConfig.md index f176a89a..34c4a6aa 100644 --- a/docs/classes/IExecConfig.md +++ b/docs/classes/IExecConfig.md @@ -60,42 +60,6 @@ const config = new IExecConfig({ ethProvider: getSignerFromPrivateKey('mainnet', ## Methods -### resolveBridgeAddress() - -> **resolveBridgeAddress**(): `Promise`\<`string`\> - -resolve the current bridge contract address - -#### Returns - -`Promise`\<`string`\> - -*** - -### resolveBridgeBackAddress() - -> **resolveBridgeBackAddress**(): `Promise`\<`string`\> - -resolve the bridge contract address on bridged chain - -#### Returns - -`Promise`\<`string`\> - -*** - -### resolveBridgedContractsClient() - -> **resolveBridgedContractsClient**(): `Promise`\<[`IExecContractsClient`](../-internal-/classes/IExecContractsClient.md)\> - -resolve the current bridged IExecContractsClient - -#### Returns - -`Promise`\<[`IExecContractsClient`](../-internal-/classes/IExecContractsClient.md)\> - -*** - ### resolveChainId() > **resolveChainId**(): `Promise`\<`number`\> diff --git a/docs/classes/IExecWalletModule.md b/docs/classes/IExecWalletModule.md index a2409dee..649ab0b9 100644 --- a/docs/classes/IExecWalletModule.md +++ b/docs/classes/IExecWalletModule.md @@ -52,66 +52,6 @@ current IExecConfig ## Methods -### bridgeToMainchain() - -> **bridgeToMainchain**(`nRLCAmount`): `Promise`\<\{ `receiveTxHash?`: `string`; `sendTxHash`: `string`; \}\> - -**SIGNER REQUIRED** - -send some nRLC to the mainchain - -_NB_: -- RLC is send to the sidechain bridge smart contract on sidechain then credited on mainchain by the mainchain bridge smart contract -- the reception of the value on the mainchain (`receiveTxHash`) will not be monitored if the bridged network configuration is missing - -example: -```js -const { sendTxHash, receiveTxHash } = await bridgeToSidechain('1000000000'); -console.log(`sent RLC on sidechain (tx: ${sendTxHash}), wallet credited on mainchain (tx: ${receiveTxHash})`); -``` - -#### Parameters - -##### nRLCAmount - -[`NRLCAmount`](../type-aliases/NRLCAmount.md) - -#### Returns - -`Promise`\<\{ `receiveTxHash?`: `string`; `sendTxHash`: `string`; \}\> - -*** - -### bridgeToSidechain() - -> **bridgeToSidechain**(`nRLCAmount`): `Promise`\<\{ `receiveTxHash?`: `string`; `sendTxHash`: `string`; \}\> - -**SIGNER REQUIRED** - -send some nRLC to the sidechain - -_NB_: -- RLC is send to the mainchain bridge smart contract on mainchain then credited on sidechain by the sidechain bridge smart contract -- the reception of the value on the sidechain (`receiveTxHash`) will not be monitored if the bridged network configuration is missing - -example: -```js -const { sendTxHash, receiveTxHash } = await bridgeToSidechain('1000000000'); -console.log(`sent RLC on mainchain (tx: ${sendTxHash}), wallet credited on sidechain (tx: ${receiveTxHash})`); -``` - -#### Parameters - -##### nRLCAmount - -[`NRLCAmount`](../type-aliases/NRLCAmount.md) - -#### Returns - -`Promise`\<\{ `receiveTxHash?`: `string`; `sendTxHash`: `string`; \}\> - -*** - ### checkBalances() > **checkBalances**(`address`): `Promise`\<\{ `nRLC`: [`BN`](../interfaces/BN.md); `wei`: [`BN`](../interfaces/BN.md); \}\> @@ -137,31 +77,6 @@ console.log('ethereum wei:', wei.toString()); *** -### checkBridgedBalances() - -> **checkBridgedBalances**(`address`): `Promise`\<\{ `nRLC`: [`BN`](../interfaces/BN.md); `wei`: [`BN`](../interfaces/BN.md); \}\> - -check the wallet balances (native and iExec token) of specified address on bridged chain - -example: -```js -const { wei, nRLC } = await checkBalances(address); -console.log('iExec nano RLC:', nRLC.toString()); -console.log('ethereum wei:', wei.toString()); -``` - -#### Parameters - -##### address - -`string` - -#### Returns - -`Promise`\<\{ `nRLC`: [`BN`](../interfaces/BN.md); `wei`: [`BN`](../interfaces/BN.md); \}\> - -*** - ### getAddress() > **getAddress**(): `Promise`\<`string`\> @@ -182,66 +97,6 @@ console.log('user address:', userAddress); *** -### obsBridgeToMainchain() - -> **obsBridgeToMainchain**(`nRLCAmount`): `Promise`\<[`BridgeObservable`](../-internal-/classes/BridgeObservable.md)\> - -**SIGNER REQUIRED** - -return an Observable with a subscribe method to start and monitor the bridge to mainchain process - -example: -```js -const bridgeObservable = await obsBridgeToMainchain('1000000000'); -const cancel = bridgeObservable.subscribe({ - next: ({message, ...rest}) => console.log(message, ...rest), - error: (err) => console.error(err), - complete: () => console.log('completed'), -}); -``` - -#### Parameters - -##### nRLCAmount - -[`NRLCAmount`](../type-aliases/NRLCAmount.md) - -#### Returns - -`Promise`\<[`BridgeObservable`](../-internal-/classes/BridgeObservable.md)\> - -*** - -### obsBridgeToSidechain() - -> **obsBridgeToSidechain**(`nRLCAmount`): `Promise`\<[`BridgeObservable`](../-internal-/classes/BridgeObservable.md)\> - -**SIGNER REQUIRED** - -return an Observable with a subscribe method to start and monitor the bridge to sidechain process - -example: -```js -const bridgeObservable = await obsBridgeToSidechain('1000000000'); -const cancel = bridgeObservable.subscribe({ - next: ({message, ...rest}) => console.log(message, ...rest), - error: (err) => console.error(err), - complete: () => console.log('completed'), -}); -``` - -#### Parameters - -##### nRLCAmount - -[`NRLCAmount`](../type-aliases/NRLCAmount.md) - -#### Returns - -`Promise`\<[`BridgeObservable`](../-internal-/classes/BridgeObservable.md)\> - -*** - ### sendETH() > **sendETH**(`WeiAmount`, `to`): `Promise`\<`string`\> diff --git a/docs/classes/Observable.md b/docs/classes/Observable.md index 7eb04144..d1a79b72 100644 --- a/docs/classes/Observable.md +++ b/docs/classes/Observable.md @@ -11,7 +11,6 @@ - [`DealObservable`](../-internal-/classes/DealObservable.md) - [`ENSConfigurationObservable`](../-internal-/classes/ENSConfigurationObservable.md) - [`TaskObservable`](../-internal-/classes/TaskObservable.md) -- [`BridgeObservable`](../-internal-/classes/BridgeObservable.md) ## Constructors diff --git a/docs/iexec/namespaces/errors/README.md b/docs/iexec/namespaces/errors/README.md index 3ebbcdc6..5ab6d811 100644 --- a/docs/iexec/namespaces/errors/README.md +++ b/docs/iexec/namespaces/errors/README.md @@ -9,7 +9,6 @@ ## Classes - [ApiCallError](classes/ApiCallError.md) -- [BridgeError](classes/BridgeError.md) - [CompassCallError](classes/CompassCallError.md) - [ConfigurationError](classes/ConfigurationError.md) - [IpfsGatewayCallError](classes/IpfsGatewayCallError.md) diff --git a/docs/iexec/namespaces/errors/classes/BridgeError.md b/docs/iexec/namespaces/errors/classes/BridgeError.md deleted file mode 100644 index ffbe74a1..00000000 --- a/docs/iexec/namespaces/errors/classes/BridgeError.md +++ /dev/null @@ -1,67 +0,0 @@ -[**iexec**](../../../../README.md) - -*** - -[iexec](../../../../globals.md) / [errors](../README.md) / BridgeError - -# Class: BridgeError - -BridgeError is thrown when bridging RLC between mainchain and sidechain fail before the value transfer confirmation. - -## Extends - -- `Error` - -## Constructors - -### Constructor - -> **new BridgeError**(`originalError`, `sendTxHash`): `BridgeError` - -#### Parameters - -##### originalError - -`Error` - -The original Error object that caused this API call error. - -##### sendTxHash - -`string` - -Hash of the transaction sending the value to the bridge contract. - -#### Returns - -`BridgeError` - -#### Overrides - -`Error.constructor` - -## Properties - -### cause - -> **cause**: `Error` - -The original Error object that caused this API call error. - -*** - -### ~~originalError~~ - -> **originalError**: `Error` - -#### Deprecated - -use Error cause instead - -*** - -### sendTxHash - -> **sendTxHash**: `string` - -Hash of the transaction sending the value to the bridge contract. diff --git a/docs/interfaces/IExecConfigOptions.md b/docs/interfaces/IExecConfigOptions.md index 7858915c..12bb3711 100644 --- a/docs/interfaces/IExecConfigOptions.md +++ b/docs/interfaces/IExecConfigOptions.md @@ -18,46 +18,6 @@ if true allows using a provider connected to an experimental networks (default f *** -### bridgeAddress? - -> `optional` **bridgeAddress**: `string` - -override the bridge contract address to target a custom instance - -*** - -### bridgedNetworkConf? - -> `optional` **bridgedNetworkConf**: `object` - -override the bridged network configuration - -#### bridgeAddress? - -> `optional` **bridgeAddress**: `string` - -bridge contract address on bridged network - -#### chainId? - -> `optional` **chainId**: `string` \| `number` - -bridged network chainId - -#### hubAddress? - -> `optional` **hubAddress**: `string` - -IExec contract address on bridged network - -#### rpcURL? - -> `optional` **rpcURL**: `string` - -bridged network node url - -*** - ### compassURL? > `optional` **compassURL**: `string` diff --git a/eslint.config.js b/eslint.config.js index ce4dd684..423bf6c3 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -40,9 +40,7 @@ export default [ '_subscribe', '_chainId', '_contracts', - '_bridgedContracts', '_chainConfDefaults', - '_bridgedConf', ], }, ], diff --git a/src/cli/cmd/iexec-wallet.js b/src/cli/cmd/iexec-wallet.js index cfdee3aa..638841fe 100644 --- a/src/cli/cmd/iexec-wallet.js +++ b/src/cli/cmd/iexec-wallet.js @@ -7,10 +7,6 @@ import { sendRLC as walletSendRLC, sweep as walletSweep, } from '../../common/wallet/send.js'; -import { - bridgeToSidechain as walletBridgeToSidechain, - bridgeToMainchain as walletBridgeToMainchain, -} from '../../common/wallet/bridge.js'; import { Keystore, createAndSave, @@ -38,7 +34,6 @@ import { prompt, pretty, info, - getPropertyFromChain, } from '../utils/cli-helper.js'; import { loadChain, connectKeystore } from '../utils/chains.js'; import { lookupAddress } from '../../common/ens/resolution.js'; @@ -357,180 +352,6 @@ sweep } }); -const bridgeToSidechain = cli.command('bridge-to-sidechain [unit]'); -addGlobalOptions(bridgeToSidechain); -addWalletLoadOptions(bridgeToSidechain); -bridgeToSidechain - .option(...option.chain()) - .option(...option.txGasPrice()) - .option(...option.txConfirms()) - .option(...option.force()) - .description(desc.bridgeToSidechain()) - .action(async (amount, unit, opts) => { - await checkUpdate(opts); - const spinner = Spinner(opts); - try { - const nRlcAmount = await nRlcAmountSchema().validate([amount, unit]); - const walletOptions = computeWalletLoadOptions(opts); - const txOptions = await computeTxOptions(opts); - const keystore = Keystore(walletOptions); - const [[address], chain] = await Promise.all([ - keystore.accounts(), - loadChain(opts.chain, { txOptions, spinner }), - ]); - await connectKeystore(chain, keystore, { txOptions }); - if (chain.contracts.isNative) - throw new Error('Cannot bridge sidechain to sidechain'); - const bridgeConf = getPropertyFromChain(chain, 'bridge'); - const bridgeAddress = bridgeConf && bridgeConf.contract; - const bridgedChainId = bridgeConf && bridgeConf.bridgedChainId; - if (!bridgeAddress) { - throw new Error( - `Missing bridge contract address in "chain.json" for chain ${chain.name}`, - ); - } - if (!bridgedChainId) { - throw new Error( - `Missing bridge bridgedChainId in "chain.json" for chain ${chain.name}`, - ); - } - if (!opts.force) { - await prompt.transferRLC( - formatRLC(nRlcAmount), - chain.name, - `bridge contract ${bridgeAddress} (please double check the address)`, - chain.id, - ); - } - const bridgedChainConfigured = !!( - chain.bridgedNetwork && - chain.bridgedNetwork.contracts && - chain.bridgedNetwork.bridge && - chain.bridgedNetwork.bridge.contract - ); - const message = `${formatRLC(nRlcAmount)} ${ - chain.name - } RLC to ${bridgeAddress}`; - spinner.start(`Sending ${message}...`); - const { sendTxHash, receiveTxHash } = await walletBridgeToSidechain( - chain.contracts, - bridgeAddress, - nRlcAmount, - { - sidechainBridgeAddress: - bridgedChainConfigured && chain.bridgedNetwork.bridge.contract, - bridgedContracts: - bridgedChainConfigured && chain.bridgedNetwork.contracts, - }, - ); - spinner.succeed( - `Sent ${message} (tx: ${sendTxHash})\n${ - bridgedChainConfigured - ? `Wallet credited on chain ${bridgedChainId} (tx: ${receiveTxHash})` - : `Please wait for the agent to credit your wallet on chain ${bridgedChainId}` - }`, - { - raw: { - amount: nRlcAmount, - from: address, - to: bridgeAddress, - sendTxHash, - receiveTxHash, - }, - }, - ); - } catch (error) { - handleError(error, cli, opts); - } - }); - -const bridgeToMainchain = cli.command('bridge-to-mainchain [unit]'); -addGlobalOptions(bridgeToMainchain); -addWalletLoadOptions(bridgeToMainchain); -bridgeToMainchain - .option(...option.chain()) - .option(...option.txGasPrice()) - .option(...option.txConfirms()) - .option(...option.force()) - .description(desc.bridgeToMainchain()) - .action(async (amount, unit, opts) => { - await checkUpdate(opts); - const spinner = Spinner(opts); - try { - const nRlcAmount = await nRlcAmountSchema().validate([amount, unit]); - const walletOptions = computeWalletLoadOptions(opts); - const txOptions = await computeTxOptions(opts); - const keystore = Keystore(walletOptions); - const [[address], chain] = await Promise.all([ - keystore.accounts(), - loadChain(opts.chain, { txOptions, spinner }), - ]); - await connectKeystore(chain, keystore, { txOptions }); - if (!chain.contracts.isNative) - throw new Error('Cannot bridge mainchain to mainchain'); - const bridgeConf = getPropertyFromChain(chain, 'bridge'); - const bridgeAddress = bridgeConf && bridgeConf.contract; - const bridgedChainId = bridgeConf && bridgeConf.bridgedChainId; - if (!bridgeAddress) { - throw new Error( - `Missing bridge contract address in "chain.json" for chain ${chain.name}`, - ); - } - if (!bridgedChainId) { - throw new Error( - `Missing bridge bridgedChainId in "chain.json" for chain ${chain.name}`, - ); - } - if (!opts.force) { - await prompt.transferRLC( - formatRLC(nRlcAmount), - chain.name, - `bridge contract ${bridgeAddress} (please double check the address)`, - chain.id, - ); - } - const bridgedChainConfigured = !!( - chain.bridgedNetwork && - chain.bridgedNetwork.contracts && - chain.bridgedNetwork.bridge && - chain.bridgedNetwork.bridge.contract - ); - const message = `${formatRLC(nRlcAmount)} ${ - chain.name - } RLC to ${bridgeAddress}`; - spinner.start(`Sending ${message}...`); - const { sendTxHash, receiveTxHash } = await walletBridgeToMainchain( - chain.contracts, - bridgeAddress, - nRlcAmount, - { - mainchainBridgeAddress: - bridgedChainConfigured && chain.bridgedNetwork.bridge.contract, - bridgedContracts: - bridgedChainConfigured && chain.bridgedNetwork.contracts, - }, - ); - spinner.succeed( - `Sent ${message} (tx: ${sendTxHash})\n${ - bridgedChainConfigured - ? `Wallet credited on chain ${bridgedChainId} (tx: ${receiveTxHash})` - : `Please wait for the agent to credit your wallet on chain ${bridgedChainId}` - }`, - { - raw: { - amount: nRlcAmount, - from: address, - to: bridgeAddress, - sendTxHash, - receiveTxHash, - }, - }, - ); - } catch (error) { - handleError(error, cli, opts); - } - }); - // DEPRECATED const sendNRLC = cli.command('sendRLC [unit]'); addGlobalOptions(sendNRLC); diff --git a/src/cli/utils/chains.js b/src/cli/utils/chains.js index bdb2c774..3512302f 100644 --- a/src/cli/utils/chains.js +++ b/src/cli/utils/chains.js @@ -11,12 +11,7 @@ const debug = Debug('iexec:chains'); const createChainFromConf = ( chainName, chainConf, - { - bridgeConf, - providerOptions, - txOptions = {}, - allowExperimentalNetworks = false, - } = {}, + { providerOptions, txOptions = {}, allowExperimentalNetworks = false } = {}, ) => { try { const chain = { ...chainConf }; @@ -35,21 +30,6 @@ const createChainFromConf = ( confirms: txOptions.confirms, }); chain.contracts = contracts; - if (bridgeConf) { - chain.bridgedNetwork = { ...bridgeConf }; - const bridgeProvider = getReadOnlyProvider(bridgeConf.host, { - providers: providerOptions, - allowExperimentalNetworks, - }); - chain.bridgedNetwork.contracts = new IExecContractsClient({ - provider: bridgeProvider, - chainId: bridgeConf.id, - hubAddress: bridgeConf.hub, - useGas: bridgeConf.useGas, - isNative: bridgeConf.native, - confirms: txOptions.confirms, - }); - } return chain; } catch (error) { debug('createChainFromConf()', error); @@ -122,54 +102,7 @@ export const loadChain = async ( `Missing RPC host, no "host" key in "chain.json" and no default value for chain ${conf.id}`, ); } - - let bridgeConf; - const bridgedChainNameOrId = conf.bridge && conf.bridge.bridgedChainName; - if (bridgedChainNameOrId) { - let bridgeLoadedConf; - if (chainsConf.chains[bridgedChainNameOrId]) { - bridgeLoadedConf = chainsConf.chains[bridgedChainNameOrId]; - } else { - const { name: alias } = getChainDefaults( - getId(bridgedChainNameOrId, { - allowExperimentalNetworks, - }), - { - allowExperimentalNetworks, - }, - ); - if (alias && chainsConf.chains[alias]) { - bridgeLoadedConf = chainsConf.chains[alias]; - } - if (!bridgeLoadedConf) - throw new Error(`Missing "${name}" chain in "chain.json"`); - } - const bridgeIdConf = { - id: - bridgeLoadedConf.id || - getId(bridgedChainNameOrId, { - allowExperimentalNetworks, - }), - }; - const bridgeDefaultConf = getChainDefaults(bridgeIdConf.id, { - allowExperimentalNetworks, - }); - debug('bridgeLoadedConf', bridgeLoadedConf); - debug('bridgeDefaultConf', defaultConf); - bridgeConf = { - ...bridgeIdConf, - ...bridgeDefaultConf, - ...bridgeLoadedConf, - }; - if (!bridgeConf.host) { - throw new Error( - `Missing RPC host for bridged chain, no "host" key in "chain.json" and no default value for bridged chain ${bridgeConf.id}`, - ); - } - } - debug('bridged chain', bridgeConf); const chain = createChainFromConf(name, conf, { - bridgeConf, providerOptions, txOptions, allowExperimentalNetworks, diff --git a/src/cli/utils/cli-helper.js b/src/cli/utils/cli-helper.js index 94e32450..0dd51a0c 100644 --- a/src/cli/utils/cli-helper.js +++ b/src/cli/utils/cli-helper.js @@ -159,10 +159,6 @@ export const desc = { generateKeys: () => 'generate a beneficiary key pair to encrypt and decrypt the results', decryptResults: () => 'decrypt encrypted results with beneficiary key', - bridgeToSidechain: () => - 'send RLC from the mainchain to the sidechain (default unit nRLC)', - bridgeToMainchain: () => - 'send RLC from the sidechain to the mainchain (default unit nRLC)', appRun: () => 'run an iExec application at market price (default run last deployed app)', requestRun: () => 'request an iExec application execution at limit price', diff --git a/src/cli/utils/fs.js b/src/cli/utils/fs.js index 60747e34..905fc88e 100644 --- a/src/cli/utils/fs.js +++ b/src/cli/utils/fs.js @@ -35,12 +35,6 @@ const chainConfSchema = () => pocoSubgraph: string(), native: boolean(), useGas: boolean().default(true), - bridge: object({ - bridgedChainName: string().required(), - contract: addressSchema().required(), - }) - .notRequired() - .strict(), }) .noUnknown(true, 'Unknown key "${unknown}"') .strict(); diff --git a/src/common/utils/config.js b/src/common/utils/config.js index f95029b2..1be6fa2e 100644 --- a/src/common/utils/config.js +++ b/src/common/utils/config.js @@ -5,7 +5,6 @@ export const CHAIN_SPECIFIC_FEATURES = { ENS: 'ENS', WORKERPOOL_API_URL_REGISTRATION: 'Workerpool API Registration', COMPASS: 'iExec Compass', - XRLC_BRIDGE: 'iExec xRLC Bridge', BULK_PROCESSING: 'Bulk processing', }; @@ -24,10 +23,6 @@ const networkConfigs = [ iexecGateway: 'https://api.market.v8-bellecour.iex.ec', compass: undefined, // no compass using ENS pocoSubgraph: 'https://thegraph.iex.ec/subgraphs/name/bellecour/poco-v5', - bridge: { - contract: '0x188A4376a1D818bF2434972Eb34eFd57102a19b7', - bridgedChainId: '1', - }, shouldRegisterNetwork: true, isExperimental: false, notImplemented: [ @@ -49,10 +44,6 @@ const networkConfigs = [ iexecGateway: undefined, // no protocol running compass: undefined, // no protocol running pocoSubgraph: undefined, // no protocol running - bridge: { - contract: '0x4e55c9B8953AB1957ad0A59D413631A66798c6a2', - bridgedChainId: '134', - }, shouldRegisterNetwork: false, isExperimental: false, notImplemented: [ @@ -75,14 +66,12 @@ const networkConfigs = [ compass: 'https://compass.arbitrum-sepolia-testnet.iex.ec', pocoSubgraph: 'https://thegraph.arbitrum-sepolia-testnet.iex.ec/api/subgraphs/id/2GCj8gzLCihsiEDq8cYvC5nUgK6VfwZ6hm3Wj8A3kcxz', - bridge: {}, // no bridge shouldRegisterNetwork: false, isExperimental: false, uploadBulkForThegraph: true, notImplemented: [ CHAIN_SPECIFIC_FEATURES.ENS, CHAIN_SPECIFIC_FEATURES.WORKERPOOL_API_URL_REGISTRATION, - CHAIN_SPECIFIC_FEATURES.XRLC_BRIDGE, ], }, { @@ -100,13 +89,11 @@ const networkConfigs = [ compass: 'https://compass.arbitrum-mainnet.iex.ec', pocoSubgraph: 'https://thegraph.arbitrum.iex.ec/api/subgraphs/id/B1comLe9SANBLrjdnoNTJSubbeC7cY7EoNu6zD82HeKy', - bridge: {}, // no bridge shouldRegisterNetwork: false, uploadBulkForThegraph: true, notImplemented: [ CHAIN_SPECIFIC_FEATURES.ENS, CHAIN_SPECIFIC_FEATURES.WORKERPOOL_API_URL_REGISTRATION, - CHAIN_SPECIFIC_FEATURES.XRLC_BRIDGE, ], }, ]; @@ -140,7 +127,6 @@ export const getChainDefaults = ( ipfsNode, compass, pocoSubgraph, - bridge, } = networkConfigs .filter( @@ -161,7 +147,6 @@ export const getChainDefaults = ( ipfsNode, compass, pocoSubgraph, - bridge, }; }; diff --git a/src/common/utils/errors.js b/src/common/utils/errors.js index da9d2885..0b7cbbca 100644 --- a/src/common/utils/errors.js +++ b/src/common/utils/errors.js @@ -67,21 +67,6 @@ export class ObjectNotFoundError extends Error { } } -export class BridgeError extends Error { - constructor(originalError, sendTxHash) { - super( - `Failed to get bridged chain confirmation for transaction ${sendTxHash}`, - { cause: originalError }, - ); - this.name = this.constructor.name; - this.sendTxHash = sendTxHash; - this.originalError = originalError; // deprecated - if (originalError && typeof originalError === 'object') { - Object.assign(this, getPropsToCopy(originalError)); - } - } -} - export class ApiCallError extends Error { constructor(message, originalError) { super(message, { cause: originalError }); diff --git a/src/common/wallet/abi/ForeignBridgeErcToNative.js b/src/common/wallet/abi/ForeignBridgeErcToNative.js deleted file mode 100644 index b5ec339f..00000000 --- a/src/common/wallet/abi/ForeignBridgeErcToNative.js +++ /dev/null @@ -1,634 +0,0 @@ -export const abi = [ - { - constant: true, - inputs: [ - { - name: '_txHash', - type: 'bytes32', - }, - ], - name: 'relayedMessages', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: 'vs', - type: 'uint8[]', - }, - { - name: 'rs', - type: 'bytes32[]', - }, - { - name: 'ss', - type: 'bytes32[]', - }, - { - name: 'message', - type: 'bytes', - }, - ], - name: 'executeSignatures', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: true, - inputs: [ - { - name: '_day', - type: 'uint256', - }, - ], - name: 'totalSpentPerDay', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'isInitialized', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_dailyLimit', - type: 'uint256', - }, - ], - name: 'setExecutionDailyLimit', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'getCurrentDay', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'requiredBlockConfirmations', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'executionDailyLimit', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [ - { - name: '_day', - type: 'uint256', - }, - ], - name: 'totalExecutedPerDay', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'dailyLimit', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [ - { - name: '_amount', - type: 'uint256', - }, - ], - name: 'withinExecutionLimit', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'executionMaxPerTx', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'requiredSignatures', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'owner', - outputs: [ - { - name: '', - type: 'address', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'validatorContract', - outputs: [ - { - name: '', - type: 'address', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'deployedAtBlock', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'getBridgeInterfacesVersion', - outputs: [ - { - name: 'major', - type: 'uint64', - }, - { - name: 'minor', - type: 'uint64', - }, - { - name: 'patch', - type: 'uint64', - }, - ], - payable: false, - stateMutability: 'pure', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_minPerTx', - type: 'uint256', - }, - ], - name: 'setMinPerTx', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_blockConfirmations', - type: 'uint256', - }, - ], - name: 'setRequiredBlockConfirmations', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_dailyLimit', - type: 'uint256', - }, - ], - name: 'setDailyLimit', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_gasPrice', - type: 'uint256', - }, - ], - name: 'setGasPrice', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_maxPerTx', - type: 'uint256', - }, - ], - name: 'setMaxPerTx', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'upgradeabilityAdmin', - outputs: [ - { - name: '', - type: 'address', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'minPerTx', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [ - { - name: '_amount', - type: 'uint256', - }, - ], - name: 'withinLimit', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_maxPerTx', - type: 'uint256', - }, - ], - name: 'setExecutionMaxPerTx', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: 'newOwner', - type: 'address', - }, - ], - name: 'transferOwnership', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'maxPerTx', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'gasPrice', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - name: 'recipient', - type: 'address', - }, - { - indexed: false, - name: 'value', - type: 'uint256', - }, - { - indexed: false, - name: 'transactionHash', - type: 'bytes32', - }, - ], - name: 'RelayedMessage', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - name: 'gasPrice', - type: 'uint256', - }, - ], - name: 'GasPriceChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - name: 'requiredBlockConfirmations', - type: 'uint256', - }, - ], - name: 'RequiredBlockConfirmationChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - name: 'newLimit', - type: 'uint256', - }, - ], - name: 'DailyLimitChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - name: 'newLimit', - type: 'uint256', - }, - ], - name: 'ExecutionDailyLimitChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - name: 'previousOwner', - type: 'address', - }, - { - indexed: false, - name: 'newOwner', - type: 'address', - }, - ], - name: 'OwnershipTransferred', - type: 'event', - }, - { - constant: false, - inputs: [ - { - name: '_validatorContract', - type: 'address', - }, - { - name: '_erc20token', - type: 'address', - }, - { - name: '_requiredBlockConfirmations', - type: 'uint256', - }, - { - name: '_gasPrice', - type: 'uint256', - }, - { - name: '_maxPerTx', - type: 'uint256', - }, - { - name: '_homeDailyLimit', - type: 'uint256', - }, - { - name: '_homeMaxPerTx', - type: 'uint256', - }, - { - name: '_owner', - type: 'address', - }, - ], - name: 'initialize', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'getBridgeMode', - outputs: [ - { - name: '_data', - type: 'bytes4', - }, - ], - payable: false, - stateMutability: 'pure', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_token', - type: 'address', - }, - { - name: '_to', - type: 'address', - }, - ], - name: 'claimTokens', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'erc20token', - outputs: [ - { - name: '', - type: 'address', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, -]; -export default { abi }; diff --git a/src/common/wallet/abi/HomeBridgeErcToNative.js b/src/common/wallet/abi/HomeBridgeErcToNative.js deleted file mode 100644 index bc0dafd3..00000000 --- a/src/common/wallet/abi/HomeBridgeErcToNative.js +++ /dev/null @@ -1,1185 +0,0 @@ -export const abi = [ - { - constant: true, - inputs: [ - { - name: '_message', - type: 'bytes32', - }, - ], - name: 'numMessagesSigned', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [ - { - name: '_hash', - type: 'bytes32', - }, - { - name: '_index', - type: 'uint256', - }, - ], - name: 'signature', - outputs: [ - { - name: '', - type: 'bytes', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_fee', - type: 'uint256', - }, - ], - name: 'setForeignFee', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: true, - inputs: [ - { - name: '_txHash', - type: 'bytes32', - }, - ], - name: 'fixedAssets', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [ - { - name: '_day', - type: 'uint256', - }, - ], - name: 'totalSpentPerDay', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_fee', - type: 'uint256', - }, - ], - name: 'setHomeFee', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'isInitialized', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_dailyLimit', - type: 'uint256', - }, - ], - name: 'setExecutionDailyLimit', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'getCurrentDay', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'requiredBlockConfirmations', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'requiredMessageLength', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'pure', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'executionDailyLimit', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [ - { - name: '_hash', - type: 'bytes32', - }, - ], - name: 'message', - outputs: [ - { - name: '', - type: 'bytes', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [ - { - name: '_day', - type: 'uint256', - }, - ], - name: 'totalExecutedPerDay', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_feeManager', - type: 'address', - }, - ], - name: 'setFeeManagerContract', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: 'signature', - type: 'bytes', - }, - { - name: 'message', - type: 'bytes', - }, - ], - name: 'submitSignature', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: 'txHash', - type: 'bytes32', - }, - { - name: 'unlockOnForeign', - type: 'bool', - }, - ], - name: 'fixAssetsAboveLimits', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'dailyLimit', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_token', - type: 'address', - }, - { - name: '_to', - type: 'address', - }, - ], - name: 'claimTokens', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: true, - inputs: [ - { - name: '_withdrawal', - type: 'bytes32', - }, - ], - name: 'numAffirmationsSigned', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [ - { - name: '_withdrawal', - type: 'bytes32', - }, - ], - name: 'affirmationsSigned', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [ - { - name: '_amount', - type: 'uint256', - }, - ], - name: 'withinExecutionLimit', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'executionMaxPerTx', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'requiredSignatures', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'owner', - outputs: [ - { - name: '', - type: 'address', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [ - { - name: '_message', - type: 'bytes32', - }, - ], - name: 'messagesSigned', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [ - { - name: '_value', - type: 'uint256', - }, - ], - name: 'getAmountToBurn', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'getHomeFee', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'validatorContract', - outputs: [ - { - name: '', - type: 'address', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: 'recipient', - type: 'address', - }, - { - name: 'value', - type: 'uint256', - }, - { - name: 'transactionHash', - type: 'bytes32', - }, - ], - name: 'executeAffirmation', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'deployedAtBlock', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'getBridgeInterfacesVersion', - outputs: [ - { - name: 'major', - type: 'uint64', - }, - { - name: 'minor', - type: 'uint64', - }, - { - name: 'patch', - type: 'uint64', - }, - ], - payable: false, - stateMutability: 'pure', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'outOfLimitAmount', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_minPerTx', - type: 'uint256', - }, - ], - name: 'setMinPerTx', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_blockConfirmations', - type: 'uint256', - }, - ], - name: 'setRequiredBlockConfirmations', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_dailyLimit', - type: 'uint256', - }, - ], - name: 'setDailyLimit', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_gasPrice', - type: 'uint256', - }, - ], - name: 'setGasPrice', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_maxPerTx', - type: 'uint256', - }, - ], - name: 'setMaxPerTx', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'feeManagerContract', - outputs: [ - { - name: '', - type: 'address', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'upgradeabilityAdmin', - outputs: [ - { - name: '', - type: 'address', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'minPerTx', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [ - { - name: '_amount', - type: 'uint256', - }, - ], - name: 'withinLimit', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_maxPerTx', - type: 'uint256', - }, - ], - name: 'setExecutionMaxPerTx', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'getFeeManagerMode', - outputs: [ - { - name: '', - type: 'bytes4', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: 'newOwner', - type: 'address', - }, - ], - name: 'transferOwnership', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'maxPerTx', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'gasPrice', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [ - { - name: '_number', - type: 'uint256', - }, - ], - name: 'isAlreadyProcessed', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - payable: false, - stateMutability: 'pure', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'getForeignFee', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - payable: true, - stateMutability: 'payable', - type: 'fallback', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - name: 'recipient', - type: 'address', - }, - { - indexed: false, - name: 'value', - type: 'uint256', - }, - { - indexed: false, - name: 'transactionHash', - type: 'bytes32', - }, - ], - name: 'AmountLimitExceeded', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - name: 'feeAmount', - type: 'uint256', - }, - { - indexed: true, - name: 'transactionHash', - type: 'bytes32', - }, - ], - name: 'FeeDistributedFromAffirmation', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - name: 'feeAmount', - type: 'uint256', - }, - { - indexed: true, - name: 'transactionHash', - type: 'bytes32', - }, - ], - name: 'FeeDistributedFromSignatures', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - name: 'recipient', - type: 'address', - }, - { - indexed: false, - name: 'value', - type: 'uint256', - }, - ], - name: 'UserRequestForSignature', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - name: 'recipient', - type: 'address', - }, - { - indexed: false, - name: 'value', - type: 'uint256', - }, - { - indexed: false, - name: 'transactionHash', - type: 'bytes32', - }, - ], - name: 'AffirmationCompleted', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - name: 'signer', - type: 'address', - }, - { - indexed: false, - name: 'messageHash', - type: 'bytes32', - }, - ], - name: 'SignedForUserRequest', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - name: 'signer', - type: 'address', - }, - { - indexed: false, - name: 'transactionHash', - type: 'bytes32', - }, - ], - name: 'SignedForAffirmation', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - name: 'authorityResponsibleForRelay', - type: 'address', - }, - { - indexed: false, - name: 'messageHash', - type: 'bytes32', - }, - { - indexed: false, - name: 'NumberOfCollectedSignatures', - type: 'uint256', - }, - ], - name: 'CollectedSignatures', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - name: 'gasPrice', - type: 'uint256', - }, - ], - name: 'GasPriceChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - name: 'requiredBlockConfirmations', - type: 'uint256', - }, - ], - name: 'RequiredBlockConfirmationChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - name: 'newLimit', - type: 'uint256', - }, - ], - name: 'DailyLimitChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - name: 'newLimit', - type: 'uint256', - }, - ], - name: 'ExecutionDailyLimitChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - name: 'previousOwner', - type: 'address', - }, - { - indexed: false, - name: 'newOwner', - type: 'address', - }, - ], - name: 'OwnershipTransferred', - type: 'event', - }, - { - constant: false, - inputs: [ - { - name: '_validatorContract', - type: 'address', - }, - { - name: '_dailyLimit', - type: 'uint256', - }, - { - name: '_maxPerTx', - type: 'uint256', - }, - { - name: '_minPerTx', - type: 'uint256', - }, - { - name: '_homeGasPrice', - type: 'uint256', - }, - { - name: '_requiredBlockConfirmations', - type: 'uint256', - }, - { - name: '_blockReward', - type: 'address', - }, - { - name: '_foreignDailyLimit', - type: 'uint256', - }, - { - name: '_foreignMaxPerTx', - type: 'uint256', - }, - { - name: '_owner', - type: 'address', - }, - ], - name: 'initialize', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_validatorContract', - type: 'address', - }, - { - name: '_dailyLimit', - type: 'uint256', - }, - { - name: '_maxPerTx', - type: 'uint256', - }, - { - name: '_minPerTx', - type: 'uint256', - }, - { - name: '_homeGasPrice', - type: 'uint256', - }, - { - name: '_requiredBlockConfirmations', - type: 'uint256', - }, - { - name: '_blockReward', - type: 'address', - }, - { - name: '_foreignDailyLimit', - type: 'uint256', - }, - { - name: '_foreignMaxPerTx', - type: 'uint256', - }, - { - name: '_owner', - type: 'address', - }, - { - name: '_feeManager', - type: 'address', - }, - { - name: '_homeFee', - type: 'uint256', - }, - { - name: '_foreignFee', - type: 'uint256', - }, - ], - name: 'rewardableInitialize', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'getBridgeMode', - outputs: [ - { - name: '_data', - type: 'bytes4', - }, - ], - payable: false, - stateMutability: 'pure', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'blockRewardContract', - outputs: [ - { - name: '', - type: 'address', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: true, - inputs: [], - name: 'totalBurntCoins', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - payable: false, - stateMutability: 'view', - type: 'function', - }, - { - constant: false, - inputs: [ - { - name: '_blockReward', - type: 'address', - }, - ], - name: 'setBlockRewardContract', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, -]; -export default { abi }; diff --git a/src/common/wallet/bridge.js b/src/common/wallet/bridge.js deleted file mode 100644 index aebc704f..00000000 --- a/src/common/wallet/bridge.js +++ /dev/null @@ -1,568 +0,0 @@ -import Debug from 'debug'; -import BN from 'bn.js'; -import { Contract } from 'ethers'; -import { - bigIntToBn, - truncateBnWeiToBnNRlc, - bnNRlcToBnWei, - formatRLC, - checkSigner, -} from '../utils/utils.js'; -import { - addressSchema, - nRlcAmountSchema, - throwIfMissing, -} from '../utils/validator.js'; -import { wrapCall } from '../utils/errorWrappers.js'; -import { BridgeError } from '../utils/errors.js'; -import { Observable, SafeObserver } from '../utils/reactive.js'; -import { abi as ForeignBridgeErcToNativeAbi } from './abi/ForeignBridgeErcToNative.js'; -import { abi as HomeBridgeErcToNativeAbi } from './abi/HomeBridgeErcToNative.js'; -import { getAddress } from './address.js'; -import { getRlcBalance } from './balance.js'; -import { sendRLC } from './send.js'; -import { - CHAIN_SPECIFIC_FEATURES, - checkImplementedOnChain, -} from '../utils/config.js'; - -const debug = Debug('iexec:wallet:bridge'); - -const obsBridgeMessages = { - CHECK_BRIDGE_POLICY: 'CHECK_BRIDGE_POLICY', - BRIDGE_POLICY_CHECKED: 'BRIDGE_POLICY_CHECKED', - CHECK_BRIDGE_LIMIT: 'CHECK_BRIDGE_LIMIT', - BRIDGE_LIMIT_CHECKED: 'BRIDGE_LIMIT_CHECKED', - SEND_TO_BRIDGE_TX_REQUEST: 'SEND_TO_BRIDGE_TX_REQUEST', - SEND_TO_BRIDGE_TX_SUCCESS: 'SEND_TO_BRIDGE_TX_SUCCESS', - WAIT_RECEIVE_TX: 'WAIT_RECEIVE_TX', - RECEIVE_TX_SUCCESS: 'RECEIVE_TX_SUCCESS', -}; - -const findBlockNumberBeforeTimestamp = async ( - provider, - targetTimestamp, - { step = 100, refBlock } = {}, -) => { - const lastTriedBlock = refBlock || (await wrapCall(provider.getBlock())); - const triedBlockNumber = Math.max(lastTriedBlock.number - step, 0); - const triedBlock = await wrapCall(provider.getBlock(triedBlockNumber)); - const triedBlockTimestamp = triedBlock.timestamp; - const remainingTime = triedBlockTimestamp - targetTimestamp; - if (remainingTime > 0) { - const stepTime = Math.max( - lastTriedBlock.timestamp - triedBlockTimestamp, - 100, - ); - const nextStep = Math.min( - Math.ceil((remainingTime / stepTime) * step) + 5, - 1000, - ); - return findBlockNumberBeforeTimestamp(provider, targetTimestamp, { - refBlock: triedBlock, - step: nextStep, - }); - } - return triedBlock.number; -}; - -export const obsBridgeToSidechain = ( - contracts = throwIfMissing(), - bridgeAddress, - nRlcAmount, - { sidechainBridgeAddress, bridgedContracts } = {}, -) => - new Observable((observer) => { - checkImplementedOnChain( - contracts.chainId, - CHAIN_SPECIFIC_FEATURES.XRLC_BRIDGE, - ); - const safeObserver = new SafeObserver(observer); - let abort; - let stopWatchPromise; - const bridgeToken = async () => { - try { - checkSigner(contracts); - // input validation - const vBridgeAddress = await addressSchema({ - ethProvider: contracts.provider, - }) - .required() - .validate(bridgeAddress); - const vSidechainBridgeAddress = sidechainBridgeAddress - ? await addressSchema({ - ethProvider: contracts.provider, - }).validate(sidechainBridgeAddress) - : undefined; - const vAmount = await nRlcAmountSchema() - .required() - .validate(nRlcAmount); - if (contracts.isNative) throw new Error('Current chain is a sidechain'); - const balance = await getRlcBalance( - contracts, - await getAddress(contracts), - ); - if (balance.lt(new BN(vAmount))) { - throw new Error('Amount to bridge exceeds wallet balance'); - } - - // check bridge policy - safeObserver.next({ - message: obsBridgeMessages.CHECK_BRIDGE_POLICY, - }); - if (abort) return; - const ercBridgeContract = new Contract( - vBridgeAddress, - ForeignBridgeErcToNativeAbi, - contracts.provider, - ); - const [minPerTx, maxPerTx, dailyLimit] = await Promise.all([ - wrapCall(ercBridgeContract.minPerTx()), - wrapCall(ercBridgeContract.maxPerTx()), - wrapCall(ercBridgeContract.dailyLimit()), - ]); - if (abort) return; - safeObserver.next({ - message: obsBridgeMessages.BRIDGE_POLICY_CHECKED, - minPerTx: bigIntToBn(minPerTx), - maxPerTx: bigIntToBn(maxPerTx), - dailyLimit: bigIntToBn(dailyLimit), - }); - if (new BN(vAmount).lt(bigIntToBn(minPerTx))) { - throw new Error( - `Minimum amount allowed to bridge is ${formatRLC( - minPerTx.toString(), - )} RLC`, - ); - } - if (new BN(vAmount).gt(bigIntToBn(maxPerTx))) { - throw new Error( - `Maximum amount allowed to bridge is ${formatRLC( - maxPerTx.toString(), - )} RLC`, - ); - } - - // check bridge daily limit - if (abort) return; - safeObserver.next({ - message: obsBridgeMessages.CHECK_BRIDGE_LIMIT, - }); - const currentDay = await wrapCall(ercBridgeContract.getCurrentDay()); - const dayStartTimestamp = currentDay.toNumber() * (60 * 60 * 24); - const startBlockNumber = await findBlockNumberBeforeTimestamp( - contracts.provider, - dayStartTimestamp, - ); - if (abort) return; - const erc20Contract = await wrapCall(contracts.fetchTokenContract()); - const transferLogs = await contracts.provider.getLogs({ - fromBlock: startBlockNumber, - toBlock: 'latest', - address: erc20Contract.address, - topics: [ - '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', - ], - }); - - const erc20Interface = erc20Contract.interface; - let totalSpentPerDay = new BN(0); - const processTransferLogs = async (logs, checkTimestamp = true) => { - if (logs.length === 0) return; - let isInvalidTimestamp = checkTimestamp; - if (checkTimestamp) { - const logTimestamp = ( - await wrapCall(contracts.provider.getBlock(logs[0].blockNumber)) - ).timestamp; - isInvalidTimestamp = logTimestamp < dayStartTimestamp; - } - if (!isInvalidTimestamp) { - const parsedLog = erc20Interface.parseLog(logs[0]); - if (parsedLog.args.to === vBridgeAddress) { - totalSpentPerDay = totalSpentPerDay.add( - bigIntToBn(parsedLog.args.value), - ); - } - } - logs.shift(); - if (abort) return; - await processTransferLogs(logs, isInvalidTimestamp); - }; - if (abort) return; - await processTransferLogs(transferLogs); - if (abort) return; - const withinLimit = totalSpentPerDay.lt(bigIntToBn(dailyLimit)); - if (abort) return; - safeObserver.next({ - message: obsBridgeMessages.BRIDGE_LIMIT_CHECKED, - totalSpentPerDay, - }); - if (!withinLimit) { - throw new Error( - `Amount to bridge would exceed bridge daily limit. ${formatRLC( - totalSpentPerDay, - )}/${formatRLC(dailyLimit)} RLC already bridged today.`, - ); - } - - // prepare to watch - const waitReceive = vSidechainBridgeAddress && bridgedContracts; - const sidechainBlockNumber = waitReceive - ? await bridgedContracts.provider.getBlockNumber() - : 0; - - // send to bridge - if (abort) return; - safeObserver.next({ - message: obsBridgeMessages.SEND_TO_BRIDGE_TX_REQUEST, - bridgeAddress: vBridgeAddress, - }); - const sendTxHash = await sendRLC(contracts, vAmount, vBridgeAddress); - if (abort) return; - safeObserver.next({ - message: obsBridgeMessages.SEND_TO_BRIDGE_TX_SUCCESS, - bridgeAddress: vBridgeAddress, - txHash: sendTxHash, - }); - - // watch receive - if (waitReceive) { - safeObserver.next({ - message: obsBridgeMessages.WAIT_RECEIVE_TX, - bridgeAddress: vSidechainBridgeAddress, - }); - const waitAffirmationCompleted = (txHash) => - new Promise((resolve, reject) => { - const sidechainBridge = new Contract( - vSidechainBridgeAddress, - HomeBridgeErcToNativeAbi, - bridgedContracts.provider, - ); - const cleanListeners = () => - sidechainBridge.removeAllListeners('AffirmationCompleted'); - stopWatchPromise = () => { - cleanListeners(); - reject(Error('aborted')); - }; - try { - sidechainBridge.on( - sidechainBridge.filters.AffirmationCompleted(), - (address, amount, refTxHash, event) => { - if (refTxHash === txHash) { - cleanListeners(); - resolve(event); - } - }, - ); - bridgedContracts.provider.resetEventsBlock( - sidechainBlockNumber, - ); - debug( - `watching AffirmationCompleted events from block ${sidechainBlockNumber}`, - ); - } catch (e) { - cleanListeners(); - throw e; - } - }); - if (abort) return; - const event = await waitAffirmationCompleted(sendTxHash); - const receiveTxHash = event.transactionHash; - safeObserver.next({ - message: obsBridgeMessages.RECEIVE_TX_SUCCESS, - txHash: receiveTxHash, - }); - } - - // done - safeObserver.complete(); - } catch (error) { - debug('obsBridgeToSidechain()', error); - safeObserver.error(error); - } - }; - bridgeToken(); - safeObserver.unsub = () => { - abort = true; - if (stopWatchPromise) { - stopWatchPromise(); - } - }; - return safeObserver.unsubscribe.bind(safeObserver); - }); - -export const bridgeToSidechain = async ( - contracts = throwIfMissing(), - bridgeAddress = throwIfMissing(), - nRlcAmount = throwIfMissing(), - { sidechainBridgeAddress, bridgedContracts } = {}, -) => { - checkImplementedOnChain( - contracts.chainId, - CHAIN_SPECIFIC_FEATURES.XRLC_BRIDGE, - ); - checkSigner(contracts); - let sendTxHash; - let receiveTxHash; - try { - await new Promise((resolve, reject) => { - obsBridgeToSidechain(contracts, bridgeAddress, nRlcAmount, { - sidechainBridgeAddress, - bridgedContracts, - }).subscribe({ - next: ({ message, ...data }) => { - if (message === obsBridgeMessages.SEND_TO_BRIDGE_TX_SUCCESS) { - sendTxHash = data.txHash; - } - if (message === obsBridgeMessages.RECEIVE_TX_SUCCESS) { - receiveTxHash = data.txHash; - } - debug(message, data); - }, - error: reject, - complete: resolve, - }); - }); - return { sendTxHash, receiveTxHash }; - } catch (error) { - debug('bridgeToSidechain()', error); - if (sendTxHash) throw new BridgeError(error, sendTxHash); - throw error; - } -}; - -export const obsBridgeToMainchain = ( - contracts = throwIfMissing(), - bridgeAddress, - nRlcAmount, - { mainchainBridgeAddress, bridgedContracts } = {}, -) => - new Observable((observer) => { - checkImplementedOnChain( - contracts.chainId, - CHAIN_SPECIFIC_FEATURES.XRLC_BRIDGE, - ); - const safeObserver = new SafeObserver(observer); - let abort; - let stopWatchPromise; - const bridgeToken = async () => { - try { - checkSigner(contracts); - // input validation - const vBridgeAddress = await addressSchema({ - ethProvider: contracts.provider, - }).validate(bridgeAddress); - const vMainchainBridgeAddress = mainchainBridgeAddress - ? await addressSchema({ - ethProvider: contracts.provider, - }) - .required() - .validate(mainchainBridgeAddress) - : undefined; - const vAmount = await nRlcAmountSchema() - .required() - .validate(nRlcAmount); - if (!contracts.isNative) - throw new Error('Current chain is a mainchain'); - const balance = await getRlcBalance( - contracts, - await getAddress(contracts), - ); - if (balance.lt(new BN(vAmount))) { - throw new Error('Amount to bridge exceeds wallet balance'); - } - const sidechainBridgeContract = new Contract( - vBridgeAddress, - HomeBridgeErcToNativeAbi, - contracts.provider, - ); - const bnWeiValue = bnNRlcToBnWei(new BN(vAmount)); - const weiValue = bnWeiValue.toString(); - - // check bridge policy - safeObserver.next({ - message: obsBridgeMessages.CHECK_BRIDGE_POLICY, - }); - if (abort) return; - const [minPerTx, maxPerTx, dailyLimit] = await Promise.all([ - wrapCall(sidechainBridgeContract.minPerTx()), - wrapCall(sidechainBridgeContract.maxPerTx()), - wrapCall(sidechainBridgeContract.dailyLimit()), - ]); - if (abort) return; - safeObserver.next({ - message: obsBridgeMessages.BRIDGE_POLICY_CHECKED, - minPerTx: bigIntToBn(minPerTx), - maxPerTx: bigIntToBn(maxPerTx), - dailyLimit: bigIntToBn(dailyLimit), - }); - if (bnWeiValue.lt(bigIntToBn(minPerTx))) { - throw new Error( - `Minimum amount allowed to bridge is ${formatRLC( - truncateBnWeiToBnNRlc(bigIntToBn(minPerTx)), - )} RLC`, - ); - } - if (bnWeiValue.gt(bigIntToBn(maxPerTx))) { - throw new Error( - `Maximum amount allowed to bridge is ${formatRLC( - truncateBnWeiToBnNRlc(bigIntToBn(maxPerTx)), - )} RLC`, - ); - } - - // check bridge daily limit - if (abort) return; - safeObserver.next({ - message: obsBridgeMessages.CHECK_BRIDGE_LIMIT, - }); - const [withinLimit, totalSpentPerDay] = await Promise.all([ - wrapCall(sidechainBridgeContract.withinLimit(weiValue)), - wrapCall( - sidechainBridgeContract - .getCurrentDay() - .then((currentDay) => - sidechainBridgeContract.totalSpentPerDay(currentDay), - ), - ), - ]); - if (abort) return; - safeObserver.next({ - message: obsBridgeMessages.BRIDGE_LIMIT_CHECKED, - totalSpentPerDay: bigIntToBn(totalSpentPerDay), - }); - if (!withinLimit) { - throw new Error( - `Amount to bridge would exceed bridge daily limit. ${formatRLC( - truncateBnWeiToBnNRlc(bigIntToBn(totalSpentPerDay)), - )}/${formatRLC( - truncateBnWeiToBnNRlc(bigIntToBn(dailyLimit)), - )} RLC already bridged today`, - ); - } - - // prepare to watch - const waitReceive = vMainchainBridgeAddress && bridgedContracts; - const mainchainBlockNumber = waitReceive - ? await wrapCall(bridgedContracts.provider.getBlockNumber()) - : 0; - - // send to bridge - if (abort) return; - safeObserver.next({ - message: obsBridgeMessages.SEND_TO_BRIDGE_TX_REQUEST, - bridgeAddress: vBridgeAddress, - }); - const sendTxHash = await sendRLC(contracts, vAmount, vBridgeAddress); - if (abort) return; - safeObserver.next({ - message: obsBridgeMessages.SEND_TO_BRIDGE_TX_SUCCESS, - bridgeAddress: vBridgeAddress, - txHash: sendTxHash, - }); - - // watch receive - if (waitReceive) { - safeObserver.next({ - message: obsBridgeMessages.WAIT_RECEIVE_TX, - bridgeAddress: vMainchainBridgeAddress, - }); - const waitRelayedMessage = (txHash) => - new Promise((resolve, reject) => { - const mainchainBridge = new Contract( - vMainchainBridgeAddress, - ForeignBridgeErcToNativeAbi, - bridgedContracts.provider, - ); - const cleanListeners = () => - mainchainBridge.removeAllListeners('RelayedMessage'); - stopWatchPromise = () => { - cleanListeners(); - reject(Error('aborted')); - }; - try { - mainchainBridge.on( - mainchainBridge.filters.RelayedMessage(), - (address, amount, refTxHash, event) => { - if (refTxHash === txHash) { - cleanListeners(); - resolve(event); - } - }, - ); - bridgedContracts.provider.resetEventsBlock( - mainchainBlockNumber, - ); - debug( - `watching RelayedMessage events from block ${mainchainBlockNumber}`, - ); - } catch (e) { - cleanListeners(); - throw e; - } - }); - if (abort) return; - const event = await waitRelayedMessage(sendTxHash); - const receiveTxHash = event.transactionHash; - safeObserver.next({ - message: obsBridgeMessages.RECEIVE_TX_SUCCESS, - txHash: receiveTxHash, - }); - } - - // done - safeObserver.complete(); - } catch (error) { - debug('obsBridgeToMainchain()', error); - safeObserver.error(error); - } - }; - bridgeToken(); - safeObserver.unsub = () => { - abort = true; - if (stopWatchPromise) { - stopWatchPromise(); - } - }; - return safeObserver.unsubscribe.bind(safeObserver); - }); - -export const bridgeToMainchain = async ( - contracts = throwIfMissing(), - bridgeAddress = throwIfMissing(), - nRlcAmount = throwIfMissing(), - { mainchainBridgeAddress, bridgedContracts } = {}, -) => { - checkImplementedOnChain( - contracts.chainId, - CHAIN_SPECIFIC_FEATURES.XRLC_BRIDGE, - ); - checkSigner(contracts); - let sendTxHash; - let receiveTxHash; - try { - await new Promise((resolve, reject) => { - obsBridgeToMainchain(contracts, bridgeAddress, nRlcAmount, { - mainchainBridgeAddress, - bridgedContracts, - }).subscribe({ - next: ({ message, ...data }) => { - if (message === obsBridgeMessages.SEND_TO_BRIDGE_TX_SUCCESS) { - sendTxHash = data.txHash; - } - if (message === obsBridgeMessages.RECEIVE_TX_SUCCESS) { - receiveTxHash = data.txHash; - } - debug(message, data); - }, - error: reject, - complete: resolve, - }); - }); - return { sendTxHash, receiveTxHash }; - } catch (error) { - debug('bridgeToMainchain()', error); - if (sendTxHash) throw new BridgeError(error, sendTxHash); - throw error; - } -}; diff --git a/src/lib/IExecAccountModule.d.ts b/src/lib/IExecAccountModule.d.ts index 57d6d688..327272b6 100644 --- a/src/lib/IExecAccountModule.d.ts +++ b/src/lib/IExecAccountModule.d.ts @@ -83,16 +83,6 @@ export default class IExecAccountModule extends IExecModule { * ``` */ checkBalance(address: Addressish): Promise<{ stake: BN; locked: BN }>; - /** - * check the account balance on bridged chain of specified address ie: when connected to mainnet, check the account ballance on bellecour - * example: - * ```js - * const balance = await checkBridgedBalance(ethAddress); - * console.log('Nano RLC staked:', balance.stake.toString()); - * console.log('Nano RLC locked:', balance.locked.toString()); - * ``` - */ - checkBridgedBalance(address: Addressish): Promise<{ stake: BN; locked: BN }>; /** * Create an IExecAccountModule instance using an IExecConfig instance */ diff --git a/src/lib/IExecAccountModule.js b/src/lib/IExecAccountModule.js index 75f61ebb..b354036c 100644 --- a/src/lib/IExecAccountModule.js +++ b/src/lib/IExecAccountModule.js @@ -8,8 +8,6 @@ export default class IExecAccountModule extends IExecModule { super(...args); this.checkBalance = async (address) => checkBalance(await this.config.resolveContractsClient(), address); - this.checkBridgedBalance = async (address) => - checkBalance(await this.config.resolveBridgedContractsClient(), address); this.deposit = async (nRlcAmount) => deposit(await this.config.resolveContractsClient(), nRlcAmount); this.withdraw = async (nRlcAmount) => diff --git a/src/lib/IExecConfig.d.ts b/src/lib/IExecConfig.d.ts index 155e2fca..a38ee937 100644 --- a/src/lib/IExecConfig.d.ts +++ b/src/lib/IExecConfig.d.ts @@ -53,31 +53,6 @@ export interface IExecConfigOptions { * override the ENS public resolver contract address to target a custom instance */ ensPublicResolverAddress?: string; - /** - * override the bridge contract address to target a custom instance - */ - bridgeAddress?: string; - /** - * override the bridged network configuration - */ - bridgedNetworkConf?: { - /** - * bridged network chainId - */ - chainId?: number | string; - /** - * bridged network node url - */ - rpcURL?: string; - /** - * IExec contract address on bridged network - */ - hubAddress?: string; - /** - * bridge contract address on bridged network - */ - bridgeAddress?: string; - }; /** * override the result proxy URL to target a custom instance */ @@ -168,10 +143,6 @@ export default class IExecConfig { * resolve the current IExecContractsClient */ resolveContractsClient(): Promise; - /** - * resolve the current bridged IExecContractsClient - */ - resolveBridgedContractsClient(): Promise; /** * resolve the current SMS URL */ @@ -201,14 +172,6 @@ export default class IExecConfig { * resolve the current PoCo subgraph URL */ resolvePocoSubgraphURL(): Promise; - /** - * resolve the current bridge contract address - */ - resolveBridgeAddress(): Promise; - /** - * resolve the bridge contract address on bridged chain - */ - resolveBridgeBackAddress(): Promise; /** * resolve the current ENS public resolver contract address */ diff --git a/src/lib/IExecConfig.js b/src/lib/IExecConfig.js index b9197808..8f107355 100644 --- a/src/lib/IExecConfig.js +++ b/src/lib/IExecConfig.js @@ -18,8 +18,6 @@ export default class IExecConfig { isNative, useGas = true, confirms, - bridgeAddress, - bridgedNetworkConf = {}, smsURL, resultProxyURL, ipfsGatewayURL, @@ -198,93 +196,10 @@ export default class IExecConfig { debug('contractsPromise', err); }); - const bridgedConfPromise = (async () => { - const { chainId } = await networkPromise; - const chainConfDefaults = await chainConfDefaultsPromise; - const isBridged = - Object.getOwnPropertyNames(bridgedNetworkConf).length > 0 || - chainConfDefaults.bridge; - if (!isBridged) { - throw new ConfigurationError( - `bridgedNetworkConf option not set and no default value for your chain ${chainId}`, - ); - } - const bridgedChainId = - bridgedNetworkConf.chainId ?? chainConfDefaults.bridge?.bridgedChainId; - if (!bridgedChainId) { - throw new ConfigurationError( - `Missing chainId in bridgedNetworkConf and no default value for your chain ${chainId}`, - ); - } - const bridgedChainConfDefaults = getChainDefaults(bridgedChainId, { - allowExperimentalNetworks, - }); - const bridgedRpcUrl = - bridgedNetworkConf.rpcURL ?? bridgedChainConfDefaults.host; - if (!bridgedRpcUrl) { - throw new ConfigurationError( - `Missing rpcURL in bridgedNetworkConf and no default value for bridged chain ${bridgedChainId}`, - ); - } - const bridgedBridgeAddress = - bridgedNetworkConf.bridgeAddress ?? - bridgedChainConfDefaults.bridge?.contract; - if (!bridgedBridgeAddress) { - throw new ConfigurationError( - `Missing bridgeAddress in bridgedNetworkConf and no default value for bridged chain ${bridgedChainId}`, - ); - } - const bridgedHubAddress = - bridgedNetworkConf.hubAddress ?? bridgedChainConfDefaults.hub; - const contracts = await contractsPromise; - return { - chainId: bridgedChainId, - rpcURL: bridgedRpcUrl, - isNative: !contracts.isNative, - hubAddress: bridgedHubAddress, - bridgeAddress: bridgedBridgeAddress, - }; - })(); - - bridgedConfPromise.catch((err) => { - debug('bridgedConfPromise', err); - }); - - const bridgedContractsPromise = (async () => { - const bridgedConf = await bridgedConfPromise; - const { hubAddress, chainId, isNative, rpcURL } = bridgedConf; - if (!hubAddress) { - throw new ConfigurationError( - `Missing hubAddress in bridgedNetworkConf and no default value for bridged chain ${chainId}`, - ); - } - try { - return new IExecContractsClient({ - chainId, - provider: getReadOnlyProvider(rpcURL, { - providers: providerOptions, - allowExperimentalNetworks, - }), - hubAddress, - confirms, - isNative, - }); - } catch (err) { - throw new ConfigurationError( - `Failed to create bridged contracts client: ${err.message}`, - ); - } - })(); - bridgedContractsPromise.catch((err) => { - debug('bridgedContractsPromise', err); - }); - this.resolveChainId = async () => (await networkPromise).chainId; this.resolveContractsClient = async () => contractsPromise; - this.resolveBridgedContractsClient = async () => bridgedContractsPromise; - this.resolveSmsURL = async () => { const { chainId } = await networkPromise; const chainConfDefaults = await chainConfDefaultsPromise; @@ -362,25 +277,6 @@ export default class IExecConfig { ); }; - this.resolveBridgeAddress = async () => { - const { chainId } = await networkPromise; - const chainConfDefaults = await chainConfDefaultsPromise; - const value = - bridgeAddress || - (chainConfDefaults.bridge && chainConfDefaults.bridge.contract); - if (value !== undefined) { - return value; - } - throw new ConfigurationError( - `bridgeAddress option not set and no default value for your chain ${chainId}`, - ); - }; - - this.resolveBridgeBackAddress = async () => { - const bridgedChainConf = await bridgedConfPromise; - return bridgedChainConf.bridgeAddress; - }; - this.resolveEnsPublicResolverAddress = async () => { const { chainId } = await networkPromise; const chainConfDefaults = await chainConfDefaultsPromise; diff --git a/src/lib/IExecWalletModule.d.ts b/src/lib/IExecWalletModule.d.ts index 216d3aa5..93c68457 100644 --- a/src/lib/IExecWalletModule.d.ts +++ b/src/lib/IExecWalletModule.d.ts @@ -13,77 +13,6 @@ import { } from '../common/types.js'; import { Observable } from '../common/utils/reactive.js'; -declare class BridgeObservable extends Observable { - /** - * subscribe and start the bridge process to transfer tokens from one chain to another until either `complete()` or `error(error: Error)` is called on the Observer or the subscribtion is canceled by calling the returned cancel method. - * - * return the `cancel: () => void` method. - * - * data: - * | message | comment | additional entries | - * | --- | --- | --- | - * | `CHECK_BRIDGE_POLICY` | sent once | | - * | `BRIDGE_POLICY_CHECKED` | sent once | `minPerTx`,`maxPerTx`,`dailyLimit` | - * | `CHECK_BRIDGE_LIMIT` | sent once | | - * | `BRIDGE_LIMIT_CHECKED` | sent once | `totalSpentPerDay` | - * | `SEND_TO_BRIDGE_TX_REQUEST` | sent once | `bridgeAddress` | - * | `SEND_TO_BRIDGE_TX_SUCCESS` | sent once | `txHash` | - * | `WAIT_RECEIVE_TX` | sent once if the bridged chain is configured | `bridgeAddress` | - * | `RECEIVE_TX_SUCCESS` | sent once if the bridged chain is configured | `txHash` | - */ - subscribe(callbacks: { - /** - * callback fired at every configuration step - * - * data: - * | message | comment | additional entries | - * | --- | --- | --- | - * | `CHECK_BRIDGE_POLICY` | sent once | | - * | `BRIDGE_POLICY_CHECKED` | sent once | `minPerTx`,`maxPerTx`,`dailyLimit` | - * | `CHECK_BRIDGE_LIMIT` | sent once | | - * | `BRIDGE_LIMIT_CHECKED` | sent once | `totalSpentPerDay` | - * | `SEND_TO_BRIDGE_TX_REQUEST` | sent once | `bridgeAddress` | - * | `SEND_TO_BRIDGE_TX_SUCCESS` | sent once | `txHash` | - * | `WAIT_RECEIVE_TX` | sent once if the bridged chain is configured | `bridgeAddress` | - * | `RECEIVE_TX_SUCCESS` | sent once if the bridged chain is configured | `txHash` | - */ - next?: (data: { - message: - | 'CHECK_BRIDGE_POLICY' - | 'BRIDGE_POLICY_CHECKED' - | 'CHECK_BRIDGE_LIMIT' - | 'BRIDGE_LIMIT_CHECKED' - | 'SEND_TO_BRIDGE_TX_REQUEST' - | 'SEND_TO_BRIDGE_TX_SUCCESS' - | 'WAIT_RECEIVE_TX' - | 'RECEIVE_TX_SUCCESS'; - minPerTx?: BN; - maxPerTx?: BN; - dailyLimit?: BN; - totalSpentPerDay?: BN; - bridgeAddress?: Address; - txHash?: TxHash; - }) => any; - /** - * callback fired once when the bridge process is completed - * - * no other callback is fired after firing `complete()` - */ - complete?: () => any; - /** - * callback fired once when an error occurs - * - * no other callback is fired after firing `error(error: Error)` - */ - error?: (error: Error) => any; - }): /** - * `cancel: () => void` method, calling this method cancels the subscription - * - * no callback is fired after calling this method - */ - () => void; -} - /** * module exposing wallet methods */ @@ -114,20 +43,6 @@ export default class IExecWalletModule extends IExecModule { wei: BN; nRLC: BN; }>; - /** - * check the wallet balances (native and iExec token) of specified address on bridged chain - * - * example: - * ```js - * const { wei, nRLC } = await checkBalances(address); - * console.log('iExec nano RLC:', nRLC.toString()); - * console.log('ethereum wei:', wei.toString()); - * ``` - */ - checkBridgedBalances(address: Addressish): Promise<{ - wei: BN; - nRLC: BN; - }>; /** * **SIGNER REQUIRED** * @@ -167,74 +82,6 @@ export default class IExecWalletModule extends IExecModule { sweep( to: Addressish, ): Promise<{ sendERC20TxHash: TxHash; sendNativeTxHash: TxHash }>; - /** - * **SIGNER REQUIRED** - * - * send some nRLC to the sidechain - * - * _NB_: - * - RLC is send to the mainchain bridge smart contract on mainchain then credited on sidechain by the sidechain bridge smart contract - * - the reception of the value on the sidechain (`receiveTxHash`) will not be monitored if the bridged network configuration is missing - * - * example: - * ```js - * const { sendTxHash, receiveTxHash } = await bridgeToSidechain('1000000000'); - * console.log(`sent RLC on mainchain (tx: ${sendTxHash}), wallet credited on sidechain (tx: ${receiveTxHash})`); - * ``` - */ - bridgeToSidechain( - nRLCAmount: NRLCAmount, - ): Promise<{ sendTxHash: TxHash; receiveTxHash?: TxHash }>; - /** - * **SIGNER REQUIRED** - * - * send some nRLC to the mainchain - * - * _NB_: - * - RLC is send to the sidechain bridge smart contract on sidechain then credited on mainchain by the mainchain bridge smart contract - * - the reception of the value on the mainchain (`receiveTxHash`) will not be monitored if the bridged network configuration is missing - * - * example: - * ```js - * const { sendTxHash, receiveTxHash } = await bridgeToSidechain('1000000000'); - * console.log(`sent RLC on sidechain (tx: ${sendTxHash}), wallet credited on mainchain (tx: ${receiveTxHash})`); - * ``` - */ - bridgeToMainchain( - nRLCAmount: NRLCAmount, - ): Promise<{ sendTxHash: TxHash; receiveTxHash?: TxHash }>; - /** - * **SIGNER REQUIRED** - * - * return an Observable with a subscribe method to start and monitor the bridge to sidechain process - * - * example: - * ```js - * const bridgeObservable = await obsBridgeToSidechain('1000000000'); - * const cancel = bridgeObservable.subscribe({ - * next: ({message, ...rest}) => console.log(message, ...rest), - * error: (err) => console.error(err), - * complete: () => console.log('completed'), - * }); - * ``` - */ - obsBridgeToSidechain(nRLCAmount: NRLCAmount): Promise; - /** - * **SIGNER REQUIRED** - * - * return an Observable with a subscribe method to start and monitor the bridge to mainchain process - * - * example: - * ```js - * const bridgeObservable = await obsBridgeToMainchain('1000000000'); - * const cancel = bridgeObservable.subscribe({ - * next: ({message, ...rest}) => console.log(message, ...rest), - * error: (err) => console.error(err), - * complete: () => console.log('completed'), - * }); - * ``` - */ - obsBridgeToMainchain(nRLCAmount: NRLCAmount): Promise; /** * Create an IExecWalletModule instance using an IExecConfig instance */ diff --git a/src/lib/IExecWalletModule.js b/src/lib/IExecWalletModule.js index 48ba189a..98882754 100644 --- a/src/lib/IExecWalletModule.js +++ b/src/lib/IExecWalletModule.js @@ -2,12 +2,6 @@ import IExecModule from './IExecModule.js'; import { getAddress } from '../common/wallet/address.js'; import { checkBalances } from '../common/wallet/balance.js'; import { sendETH, sendRLC, sweep } from '../common/wallet/send.js'; -import { - bridgeToMainchain, - bridgeToSidechain, - obsBridgeToMainchain, - obsBridgeToSidechain, -} from '../common/wallet/bridge.js'; export default class IExecWalletModule extends IExecModule { constructor(...args) { @@ -17,53 +11,11 @@ export default class IExecWalletModule extends IExecModule { getAddress(await this.config.resolveContractsClient()); this.checkBalances = async (address) => checkBalances(await this.config.resolveContractsClient(), address); - this.checkBridgedBalances = async (address) => - checkBalances(await this.config.resolveBridgedContractsClient(), address); this.sendETH = async (weiAmount, to) => sendETH(await this.config.resolveContractsClient(), weiAmount, to); this.sendRLC = async (nRlcAmount, to) => sendRLC(await this.config.resolveContractsClient(), nRlcAmount, to); this.sweep = async (to) => sweep(await this.config.resolveContractsClient(), to); - this.bridgeToSidechain = async (nRlcAmount) => - bridgeToSidechain( - await this.config.resolveContractsClient(), - await this.config.resolveBridgeAddress(), - nRlcAmount, - { - bridgedContracts: await this.config.resolveBridgedContractsClient(), - sidechainBridgeAddress: await this.config.resolveBridgeBackAddress(), - }, - ); - this.bridgeToMainchain = async (nRlcAmount) => - bridgeToMainchain( - await this.config.resolveContractsClient(), - await this.config.resolveBridgeAddress(), - nRlcAmount, - { - bridgedContracts: await this.config.resolveBridgedContractsClient(), - mainchainBridgeAddress: await this.config.resolveBridgeBackAddress(), - }, - ); - this.obsBridgeToSidechain = async (nRlcAmount) => - obsBridgeToSidechain( - await this.config.resolveContractsClient(), - await this.config.resolveBridgeAddress(), - nRlcAmount, - { - bridgedContracts: await this.config.resolveBridgedContractsClient(), - sidechainBridgeAddress: await this.config.resolveBridgeBackAddress(), - }, - ); - this.obsBridgeToMainchain = async (nRlcAmount) => - obsBridgeToMainchain( - await this.config.resolveContractsClient(), - await this.config.resolveBridgeAddress(), - nRlcAmount, - { - bridgedContracts: await this.config.resolveBridgedContractsClient(), - mainchainBridgeAddress: await this.config.resolveBridgeBackAddress(), - }, - ); } } diff --git a/src/lib/errors.d.ts b/src/lib/errors.d.ts index e90da877..438688e8 100644 --- a/src/lib/errors.d.ts +++ b/src/lib/errors.d.ts @@ -77,33 +77,6 @@ export class ObjectNotFoundError extends Error { */ chainId: string; } -/** - * BridgeError is thrown when bridging RLC between mainchain and sidechain fail before the value transfer confirmation. - */ -export class BridgeError extends Error { - constructor( - /** - * The original Error object that caused this API call error. - */ - originalError: Error, - /** - * Hash of the transaction sending the value to the bridge contract. - */ - sendTxHash: string, - ); - /** - * Hash of the transaction sending the value to the bridge contract. - */ - sendTxHash: string; - /** - * @deprecated use Error cause instead - */ - originalError: Error; - /** - * The original Error object that caused this API call error. - */ - cause: Error; -} /** * ApiCallError encapsulates an error occurring during a call to an API such as a network error or a server-side internal error. diff --git a/test/lib/e2e/IExecAccountModule.test.js b/test/lib/e2e/IExecAccountModule.test.js index 2c1d290c..9c3dd8be 100644 --- a/test/lib/e2e/IExecAccountModule.test.js +++ b/test/lib/e2e/IExecAccountModule.test.js @@ -2,14 +2,12 @@ import { describe, test, expect } from '@jest/globals'; import { BN } from 'bn.js'; import { ONE_ETH, ONE_RLC, getTestConfig } from '../lib-test-utils.js'; import { - DEFAULT_PROVIDER_OPTIONS, TEST_CHAINS, getRandomAddress, setBalance, setNRlcBalance, } from '../../test-utils.js'; import '../../jest-setup.js'; -import { IExec } from '../../../src/lib/index.js'; const testChain = TEST_CHAINS['arbitrum-sepolia-fork']; const tokenTestChain = TEST_CHAINS['arbitrum-sepolia-fork']; @@ -41,37 +39,6 @@ describe('account', () => { }); }); - describe('checkBridgedBalance()', () => { - describe('native chain', () => { - test('expose bridged balances (mainnet) on bellecour', async () => { - const iexec = new IExec( - { ethProvider: 'bellecour' }, - { - providerOptions: DEFAULT_PROVIDER_OPTIONS, - }, - ); - const res = await iexec.account.checkBridgedBalance(getRandomAddress()); - expect(res.stake).toBeInstanceOf(BN); - expect(res.locked).toBeInstanceOf(BN); - }); - - describe('token chain', () => { - test('expose bridged balances (bellecour) on mainnet', async () => { - const iexec = new IExec( - { ethProvider: 'mainnet' }, - { - providerOptions: DEFAULT_PROVIDER_OPTIONS, - }, - ); - const res = - await iexec.account.checkBridgedBalance(getRandomAddress()); - expect(res.stake).toBeInstanceOf(BN); - expect(res.locked).toBeInstanceOf(BN); - }); - }); - }); - }); - describe('approve()', () => { test('require a signer', async () => { const spenderAddress = getRandomAddress(); diff --git a/test/lib/e2e/IExecConfig.test.js b/test/lib/e2e/IExecConfig.test.js index 4d27f9aa..e19bd0e5 100644 --- a/test/lib/e2e/IExecConfig.test.js +++ b/test/lib/e2e/IExecConfig.test.js @@ -622,102 +622,6 @@ describe('[IExecConfig]', () => { expect(network.name).toBe(testChain.defaults.name); }); }); - - describe('bridged chain provider', () => { - test('IExecConfig({ ethProvider: "bellecour" })', async () => { - const config = new IExecConfig( - { ethProvider: 'bellecour' }, - { - providerOptions: DEFAULT_PROVIDER_OPTIONS, - }, - ); - const { provider, signer, chainId } = - await config.resolveBridgedContractsClient(); - expect(signer).toBeUndefined(); - expect(provider).toBeDefined(); - expect(provider).toBeInstanceOf(FallbackProvider); - expect(chainId).toBe('1'); - const network = await provider.getNetwork(); - expect(network.chainId).toBe(1n); - expect(network.name).toBe('mainnet'); - expect( - network.getPlugin('org.ethers.plugins.network.Ens').address, - ).toBeDefined(); - }); - test('bridged contract IExecConfig({ ethProvider: "bellecour" }, { providerOptions : { infura }})', async () => { - const config = new IExecConfig( - { ethProvider: 'bellecour' }, - { - providerOptions: { - cloudflare: true, - infura: INFURA_PROJECT_ID, - }, - }, - ); - const { provider, signer, chainId } = - await config.resolveBridgedContractsClient(); - expect(signer).toBeUndefined(); - expect(provider).toBeDefined(); - expect(provider).toBeInstanceOf(FallbackProvider); - expect(provider.providerConfigs.length).toBe(2); - expect(provider.providerConfigs[0].provider).toBeInstanceOf( - CloudflareProvider, - ); - expect(provider.providerConfigs[1].provider).toBeInstanceOf( - InfuraProvider, - ); - expect(chainId).toBe('1'); - const network = await provider.getNetwork(); - expect(network.chainId).toBe(1n); - expect(network.name).toBe('mainnet'); - expect( - network.getPlugin('org.ethers.plugins.network.Ens').address, - ).toBeDefined(); - }); - test('IExecConfig({ ethProvider: "mainnet" })', async () => { - const config = new IExecConfig( - { ethProvider: 'mainnet' }, - { - providerOptions: DEFAULT_PROVIDER_OPTIONS, - }, - ); - const { provider, signer, chainId } = - await config.resolveBridgedContractsClient(); - expect(signer).toBeUndefined(); - expect(provider).toBeDefined(); - expect(provider).toBeInstanceOf(JsonRpcProvider); - expect(chainId).toBe('134'); - const network = await provider.getNetwork(); - expect(network.chainId).toBe(134n); - expect(network.name).toBe('bellecour'); - expect( - network.getPlugin('org.ethers.plugins.network.Ens').address, - ).toBeDefined(); - }); - test('IExecConfig({ ethProvider: "http://localhost:8545" }, { hubAddress, bridgedNetworkConf })', async () => { - const config = new IExecConfig( - { ethProvider: testChain.rpcURL }, - { - bridgedNetworkConf: { - rpcURL: unknownTestChain.rpcURL, - chainId: unknownTestChain.chainId, - hubAddress: unknownTestChain.hubAddress, - bridgeAddress: utils.NULL_ADDRESS, - }, - }, - ); - const { provider, signer, chainId } = - await config.resolveBridgedContractsClient(); - expect(signer).toBeUndefined(); - expect(provider).toBeDefined(); - expect(provider).toBeInstanceOf(JsonRpcProvider); - expect(chainId).toBe(unknownTestChain.chainId); - const network = await provider.getNetwork(); - expect(network.chainId).toBe(BigInt(unknownTestChain.chainId)); - expect(network.name).toBe('unknown'); - expect(network.getPlugin('org.ethers.plugins.network.Ens')).toBe(null); - }); - }); }); describe('resolveChainId()', () => { @@ -786,62 +690,6 @@ describe('[IExecConfig]', () => { }); }); - describe('resolveBridgedContractsClient()', () => { - test('success', async () => { - const config = new IExecConfig({ - ethProvider: 'bellecour', - }); - const promise = config.resolveBridgedContractsClient(); - await expect(promise).resolves.toBeInstanceOf(IExecContractsClient); - const contracts = await promise; - expect(contracts.chainId).toBe('1'); - expect(contracts.isNative).toBe(false); - }); - test('success with bridgedNetworkConf on custom chain', async () => { - const homeChain = unknownTestChain; - const bridgedChain = unknownTestChain; - const config = new IExecConfig( - { - ethProvider: homeChain.rpcURL, - }, - { - hubAddress: homeChain.rpcURL, - bridgedNetworkConf: { - chainId: bridgedChain.chainId, - rpcURL: bridgedChain.rpcURL, - hubAddress: bridgedChain.hubAddress, - bridgeAddress: utils.NULL_ADDRESS, - }, - }, - ); - const promise = config.resolveBridgedContractsClient(); - await expect(promise).resolves.toBeInstanceOf(IExecContractsClient); - const contracts = await promise; - expect(contracts.chainId).toBe(bridgedChain.chainId); - expect(contracts.isNative).toBe(true); - }); - test('throw on unknown chain', async () => { - const config = new IExecConfig({ - ethProvider: unknownTestChain.rpcURL, - }); - const promise = config.resolveBridgedContractsClient(); - await expect(promise).rejects.toThrow( - new Error( - `bridgedNetworkConf option not set and no default value for your chain ${unknownTestChain.chainId}`, - ), - ); - await expect(promise).rejects.toThrow(errors.ConfigurationError); - }); - test('throw on network error', async () => { - const config = new IExecConfig({ - ethProvider: 'http://localhost:8888', - }); - const promise = config.resolveBridgedContractsClient(); - await expect(promise).rejects.toThrow('Failed to detect network:'); - await expect(promise).rejects.toThrow(Error); - }); - }); - describe('resolveSmsURL()', () => { test('success', async () => { const config = new IExecConfig({ @@ -1106,122 +954,6 @@ describe('[IExecConfig]', () => { }); }); - describe('resolveBridgeAddress()', () => { - test('success', async () => { - const config = new IExecConfig({ - ethProvider: 'bellecour', - }); - const promise = config.resolveBridgeAddress(); - const address = await promise; - expect(typeof address).toBe('string'); - expect(address.length).toBe(42); - }); - test('success bridgeAddress override', async () => { - const bridgeAddressOverride = getRandomAddress(); - const config = new IExecConfig( - { - ethProvider: 'bellecour', - }, - { bridgeAddress: bridgeAddressOverride }, - ); - const promise = config.resolveBridgeAddress(); - await expect(promise).resolves.toBe(bridgeAddressOverride); - }); - test('success with bridgeAddress on custom chain', async () => { - const bridgeAddressOverride = getRandomAddress(); - const config = new IExecConfig( - { - ethProvider: 'bellecour', - }, - { bridgeAddress: bridgeAddressOverride }, - ); - const promise = config.resolveBridgeAddress(); - await expect(promise).resolves.toBe(bridgeAddressOverride); - }); - test('throw on unknown chain', async () => { - const config = new IExecConfig({ - ethProvider: unknownTestChain.rpcURL, - }); - const promise = config.resolveBridgeAddress(); - await expect(promise).rejects.toThrow( - new Error( - `bridgeAddress option not set and no default value for your chain ${unknownTestChain.chainId}`, - ), - ); - await expect(promise).rejects.toThrow(errors.ConfigurationError); - }); - test('throw on network error', async () => { - const config = new IExecConfig({ - ethProvider: 'http://localhost:8888', - }); - const promise = config.resolveBridgeAddress(); - await expect(promise).rejects.toThrow('Failed to detect network:'); - await expect(promise).rejects.toThrow(Error); - }); - }); - - describe('resolveBridgeBackAddress()', () => { - test('success', async () => { - const config = new IExecConfig({ - ethProvider: 'bellecour', - }); - const promise = config.resolveBridgeBackAddress(); - const address = await promise; - expect(typeof address).toBe('string'); - expect(address.length).toBe(42); - }); - test('success bridgeAddress override', async () => { - const bridgeAddressOverride = getRandomAddress(); - const config = new IExecConfig( - { - ethProvider: 'bellecour', - }, - { - bridgedNetworkConf: { - bridgeAddress: bridgeAddressOverride, - }, - }, - ); - const promise = config.resolveBridgeBackAddress(); - await expect(promise).resolves.toBe(bridgeAddressOverride); - }); - test('success with bridgeAddress on custom chain', async () => { - const bridgeAddressOverride = getRandomAddress(); - const config = new IExecConfig( - { - ethProvider: 'bellecour', - }, - { - bridgedNetworkConf: { - bridgeAddress: bridgeAddressOverride, - }, - }, - ); - const promise = config.resolveBridgeBackAddress(); - await expect(promise).resolves.toBe(bridgeAddressOverride); - }); - test('throw on unknown chain', async () => { - const config = new IExecConfig({ - ethProvider: unknownTestChain.rpcURL, - }); - const promise = config.resolveBridgeBackAddress(); - await expect(promise).rejects.toThrow( - new Error( - `bridgedNetworkConf option not set and no default value for your chain ${unknownTestChain.chainId}`, - ), - ); - await expect(promise).rejects.toThrow(errors.ConfigurationError); - }); - test('throw on network error', async () => { - const config = new IExecConfig({ - ethProvider: 'http://localhost:8888', - }); - const promise = config.resolveBridgeBackAddress(); - await expect(promise).rejects.toThrow('Failed to detect network:'); - await expect(promise).rejects.toThrow(Error); - }); - }); - describe('resolveEnsPublicResolverAddress()', () => { test('success', async () => { const config = new IExecConfig({ diff --git a/test/lib/e2e/IExecWalletModule.test.js b/test/lib/e2e/IExecWalletModule.test.js index df7717dc..bd5ecf82 100644 --- a/test/lib/e2e/IExecWalletModule.test.js +++ b/test/lib/e2e/IExecWalletModule.test.js @@ -65,39 +65,6 @@ describe('wallet', () => { }); }); - describe('checkBridgedBalances()', () => { - describe('native chain', () => { - test('expose bridged balances (mainnet) on bellecour', async () => { - const iexec = new IExec( - { ethProvider: 'bellecour' }, - { - providerOptions: DEFAULT_PROVIDER_OPTIONS, - }, - ); - const address = getRandomAddress(); - const balance = await iexec.wallet.checkBridgedBalances(address); - expect(balance.nRLC).toBeInstanceOf(BN); - expect(balance.wei).toBeInstanceOf(BN); - expect(balance.nRLC).toStrictEqual(new BN(0)); - expect(balance.wei).toStrictEqual(new BN(0)); - }); - }); - describe('token chain', () => { - test('expose bridged balances (bellecour) on mainnet', async () => { - const iexec = new IExec( - { ethProvider: 'mainnet' }, - { - providerOptions: DEFAULT_PROVIDER_OPTIONS, - }, - ); - const address = getRandomAddress(); - const balance = await iexec.wallet.checkBridgedBalances(address); - expect(balance.nRLC).toStrictEqual(new BN(0)); - expect(balance.wei).toStrictEqual(new BN(0)); - }); - }); - }); - describe('sendETH()', () => { test('require a signer', async () => { const { iexec } = await getTestConfig(tokenTestChain)({ readOnly: true }); diff --git a/test/lib/unit/config.test.js b/test/lib/unit/config.test.js index b7b4ee69..1c38374d 100644 --- a/test/lib/unit/config.test.js +++ b/test/lib/unit/config.test.js @@ -22,10 +22,6 @@ describe('getId()', () => { describe('getChainDefaults', () => { test('id 134 returns bellecour config', () => { expect(getChainDefaults(134)).toEqual({ - bridge: { - bridgedChainId: '1', - contract: '0x188A4376a1D818bF2434972Eb34eFd57102a19b7', - }, ensPublicResolver: '0x1347d8a1840A810B990d0B774A6b7Bb8A1bd62BB', ensRegistry: '0x5f5B93fca68c9C79318d1F3868A354EE67D8c006', host: 'https://bellecour.iex.ec', @@ -122,25 +118,6 @@ describe('checkImplementedOnChain', () => { expect(() => checkImplementedOnChain(421614, feature)).not.toThrow(); }); }); - describe(`feature ${CHAIN_SPECIFIC_FEATURES.XRLC_BRIDGE}`, () => { - const feature = CHAIN_SPECIFIC_FEATURES.XRLC_BRIDGE; - test('is implemented on bellecour', () => { - expect(() => checkImplementedOnChain(134, feature)).not.toThrow(); - }); - test('is implemented on mainnet', () => { - expect(() => checkImplementedOnChain(1, feature)).not.toThrow(); - }); - test('is not implemented on arbitrum-mainnet', () => { - expect(() => checkImplementedOnChain(42161, feature)).toThrow( - `${feature} is not available on network arbitrum-mainnet`, - ); - }); - test('is not implemented on arbitrum-sepolia-testnet', () => { - expect(() => checkImplementedOnChain(421614, feature)).toThrow( - `${feature} is not available on network arbitrum-sepolia-testnet`, - ); - }); - }); describe(`feature ${CHAIN_SPECIFIC_FEATURES.BULK_PROCESSING}`, () => { const feature = CHAIN_SPECIFIC_FEATURES.BULK_PROCESSING; test('is not implemented on bellecour', () => { diff --git a/test/test-config-utils.js b/test/test-config-utils.js index 3f0592bd..3116806d 100644 --- a/test/test-config-utils.js +++ b/test/test-config-utils.js @@ -5,8 +5,6 @@ import { setBalance } from './test-utils.js'; export const getTestConfigOptions = (chain) => ({ options = {} } = {}) => ({ - bridgeAddress: options.bridgeAddress ?? chain.bridgeAddress, - bridgedNetworkConf: options.bridgedNetworkConf ?? chain.bridgedNetworkConf, confirms: options.confirms ?? chain.confirms, ensPublicResolverAddress: options.ensPublicResolverAddress ?? chain.ensPublicResolverAddress, From 037b1ea85107cd89bae80dc790d12921ad26a7ee Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Tue, 21 Apr 2026 12:09:34 +0200 Subject: [PATCH 05/13] fix!: remove methods for setting workerpool API url --- CLI.md | 25 ---- docs/classes/IExecWorkerpoolModule.md | 32 ---- src/cli/cmd/iexec-workerpool.js | 44 ------ src/common/execution/debug.js | 23 --- src/common/execution/workerpool.js | 51 ------- src/common/utils/config.js | 11 +- src/common/utils/constant.js | 2 - src/common/utils/validator.js | 5 - src/lib/IExecWorkerpoolModule.d.ts | 17 --- src/lib/IExecWorkerpoolModule.js | 7 - test/lib/e2e/IExecWorkerpoolModule.test.js | 161 ++++++--------------- test/lib/unit/config.test.js | 20 +-- test/lib/unit/validator.test.js | 29 ---- 13 files changed, 44 insertions(+), 383 deletions(-) delete mode 100644 src/common/execution/workerpool.js diff --git a/CLI.md b/CLI.md index cd984c86..6ae3a403 100644 --- a/CLI.md +++ b/CLI.md @@ -1282,7 +1282,6 @@ Commands: - [init](#iexec-workerpool-init) - [deploy](#iexec-workerpool-deploy) -- [set-api-url](#iexec-workerpool-set-api-url) - [show](#iexec-workerpool-show) - [count](#iexec-workerpool-count) - [publish](#iexec-workerpool-publish) @@ -1334,30 +1333,6 @@ Options: | --gas-price \ | set custom gas price for transactions (default unit wei) | | --confirms \ | set custom block count to wait for transactions confirmation (default 1 block) | -#### iexec workerpool set-api-url - -declare the workerpool API URL on the blockchain - -Usage: - -```sh -iexec workerpool set-api-url [workerpoolAddress] [options] -``` - -Options: - -| option | description | -| --- | --- | -| --raw | use raw output | -| --quiet | stop prompting updates | -| --password \ | password used to encrypt the wallet (unsafe) | -| --wallet-file \ | specify the name of the wallet file to use | -| --wallet-address \ | specify the address of the wallet to use | -| --keystoredir \ | specify the wallet directory \<"global"\|"local"\|custom\> | -| --chain \ | chain name from "chain.json" | -| --gas-price \ | set custom gas price for transactions (default unit wei) | -| --confirms \ | set custom block count to wait for transactions confirmation (default 1 block) | - #### iexec workerpool show show user workerpool details diff --git a/docs/classes/IExecWorkerpoolModule.md b/docs/classes/IExecWorkerpoolModule.md index 8297151a..da04b9de 100644 --- a/docs/classes/IExecWorkerpoolModule.md +++ b/docs/classes/IExecWorkerpoolModule.md @@ -182,38 +182,6 @@ console.log('address', address); *** -### setWorkerpoolApiUrl() - -> **setWorkerpoolApiUrl**(`workerpoolAddress`, `url`): `Promise`\<`string`\> - -**ONLY WORKERPOOL ENS NAME OWNER** - -declare the workerpool API url on the blockchain - -_NB_: declaring the workerpool API url require an ENS name with a configured reverse resolution on the workerpool address (see: IExecENSModule obsConfigureResolution/configureResolution) - -example: -```js -const txHash = await setWorkerpoolApiUrl('my-workerpool.eth', 'my-workerpool.com'); -console.log('txHash:', txHash); -``` - -#### Parameters - -##### workerpoolAddress - -`string` - -##### url - -`string` - -#### Returns - -`Promise`\<`string`\> - -*** - ### showUserWorkerpool() > **showUserWorkerpool**(`index`, `address`): `Promise`\<\{ `objAddress`: `string`; `workerpool`: [`Workerpool`](../-internal-/interfaces/Workerpool.md); \}\> diff --git a/src/cli/cmd/iexec-workerpool.js b/src/cli/cmd/iexec-workerpool.js index bd2890c0..ccca3799 100644 --- a/src/cli/cmd/iexec-workerpool.js +++ b/src/cli/cmd/iexec-workerpool.js @@ -47,7 +47,6 @@ import { } from '../utils/fs.js'; import { Keystore } from '../utils/keystore.js'; import { loadChain, connectKeystore } from '../utils/chains.js'; -import { setWorkerpoolApiUrl } from '../../common/execution/workerpool.js'; import { getWorkerpoolApiUrl } from '../../common/execution/debug.js'; import { lookupAddress } from '../../common/ens/resolution.js'; import { ConfigurationError } from '../../common/utils/errors.js'; @@ -124,49 +123,6 @@ deploy } }); -const setApiUrl = cli.command('set-api-url [workerpoolAddress]'); -addGlobalOptions(setApiUrl); -addWalletLoadOptions(setApiUrl); -setApiUrl - .option(...option.chain()) - .option(...option.txGasPrice()) - .option(...option.txConfirms()) - .description('declare the workerpool API URL on the blockchain') - .action(async (url, workerpoolAddress, opts) => { - await checkUpdate(opts); - const spinner = Spinner(opts); - try { - const walletOptions = computeWalletLoadOptions(opts); - const txOptions = await computeTxOptions(opts); - const keystore = Keystore(walletOptions); - const chain = await loadChain(opts.chain, { txOptions, spinner }); - const address = - workerpoolAddress || - (await loadDeployedObj(objName).then( - (deployedObj) => deployedObj && deployedObj[chain.id], - )); - if (!address) { - throw new Error(info.missingAddressOrDeployed(objName, chain.id)); - } - const ens = await lookupAddress(chain.contracts, address); - if (!ens) { - throw new Error(info.missingEnsForObjectAtAddress(objName, address)); - } - - await connectKeystore(chain, keystore, { txOptions }); - spinner.start(`Setting API URL for workerpool ${address}`); - const txHash = await setWorkerpoolApiUrl(chain.contracts, address, url); - spinner.succeed( - `API URL "${url}" is set for ${objName} at address ${address}`, - { - raw: { address, url, txHash }, - }, - ); - } catch (error) { - handleError(error, cli, opts); - } - }); - const show = cli.command('show [addressOrIndex]'); addGlobalOptions(show); addWalletLoadOptions(show); diff --git a/src/common/execution/debug.js b/src/common/execution/debug.js index 7861b1ba..4a941e3c 100644 --- a/src/common/execution/debug.js +++ b/src/common/execution/debug.js @@ -2,14 +2,10 @@ import Debug from 'debug'; import { throwIfMissing, addressSchema, - workerpoolApiUrlSchema, bytes32Schema, } from '../utils/validator.js'; -import { lookupAddress } from '../ens/resolution.js'; -import { readTextRecord } from '../ens/text-record.js'; import { show as dealShow } from './deal.js'; import { show as taskShow } from './task.js'; -import { WORKERPOOL_URL_TEXT_RECORD_KEY } from '../utils/constant.js'; import { jsonApi, getAuthorization } from '../utils/api-utils.js'; import { checkSigner } from '../utils/utils.js'; import { getAddress } from '../wallet/address.js'; @@ -54,25 +50,6 @@ export const getWorkerpoolApiUrl = async ( }); return json?.apiUrl; } - - // ENS based workerpool API URL resolution - const name = await lookupAddress(contracts, vAddress).catch(() => { - /** return undefined */ - }); - if (!name) { - return undefined; - } - const url = await readTextRecord( - contracts, - name, - WORKERPOOL_URL_TEXT_RECORD_KEY, - ); - return await workerpoolApiUrlSchema() - .required() - .validate(url) - .catch(() => { - /** return undefined */ - }); } catch (e) { debug('getWorkerpoolApiUrl()', e); throw e; diff --git a/src/common/execution/workerpool.js b/src/common/execution/workerpool.js deleted file mode 100644 index 6a27522b..00000000 --- a/src/common/execution/workerpool.js +++ /dev/null @@ -1,51 +0,0 @@ -import Debug from 'debug'; -import { - throwIfMissing, - addressSchema, - workerpoolApiUrlSchema, -} from '../utils/validator.js'; -import { lookupAddress } from '../ens/resolution.js'; -import { setTextRecord } from '../ens/text-record.js'; -import { WORKERPOOL_URL_TEXT_RECORD_KEY } from '../utils/constant.js'; -import { - CHAIN_SPECIFIC_FEATURES, - checkImplementedOnChain, -} from '../utils/config.js'; - -const debug = Debug('iexec:execution:workerpool'); - -export const setWorkerpoolApiUrl = async ( - contracts = throwIfMissing(), - workerpoolAddress, - url, -) => { - try { - checkImplementedOnChain( - contracts.chainId, - CHAIN_SPECIFIC_FEATURES.WORKERPOOL_API_URL_REGISTRATION, - ); - const vAddress = await addressSchema({ - ethProvider: contracts.provider, - }) - .required() - .validate(workerpoolAddress); - const vUrl = await workerpoolApiUrlSchema() - .label('workerpool API url') - .validate(url); - const name = await lookupAddress(contracts, vAddress); - if (!name) { - throw new Error( - `No ENS name reverse resolution configured for ${vAddress}`, - ); - } - return await setTextRecord( - contracts, - name, - WORKERPOOL_URL_TEXT_RECORD_KEY, - vUrl, - ); - } catch (e) { - debug('setWorkerpoolApiUrl()', e); - throw e; - } -}; diff --git a/src/common/utils/config.js b/src/common/utils/config.js index 1be6fa2e..d30a3377 100644 --- a/src/common/utils/config.js +++ b/src/common/utils/config.js @@ -3,7 +3,6 @@ import { ConfigurationError } from './errors.js'; export const CHAIN_SPECIFIC_FEATURES = { ENS: 'ENS', - WORKERPOOL_API_URL_REGISTRATION: 'Workerpool API Registration', COMPASS: 'iExec Compass', BULK_PROCESSING: 'Bulk processing', }; @@ -69,10 +68,7 @@ const networkConfigs = [ shouldRegisterNetwork: false, isExperimental: false, uploadBulkForThegraph: true, - notImplemented: [ - CHAIN_SPECIFIC_FEATURES.ENS, - CHAIN_SPECIFIC_FEATURES.WORKERPOOL_API_URL_REGISTRATION, - ], + notImplemented: [CHAIN_SPECIFIC_FEATURES.ENS], }, { id: 42161, @@ -91,10 +87,7 @@ const networkConfigs = [ 'https://thegraph.arbitrum.iex.ec/api/subgraphs/id/B1comLe9SANBLrjdnoNTJSubbeC7cY7EoNu6zD82HeKy', shouldRegisterNetwork: false, uploadBulkForThegraph: true, - notImplemented: [ - CHAIN_SPECIFIC_FEATURES.ENS, - CHAIN_SPECIFIC_FEATURES.WORKERPOOL_API_URL_REGISTRATION, - ], + notImplemented: [CHAIN_SPECIFIC_FEATURES.ENS], }, ]; diff --git a/src/common/utils/constant.js b/src/common/utils/constant.js index d00bc6cc..a987ab99 100644 --- a/src/common/utils/constant.js +++ b/src/common/utils/constant.js @@ -26,8 +26,6 @@ export const NULL_DATASETORDER = { sign: NULL_BYTES, }; -export const WORKERPOOL_URL_TEXT_RECORD_KEY = 'iexec:workerpool-api:url'; - export const TEE_FRAMEWORKS = { SCONE: 'scone', TDX: 'tdx', diff --git a/src/common/utils/validator.js b/src/common/utils/validator.js index 0c61117c..15b3bcbd 100644 --- a/src/common/utils/validator.js +++ b/src/common/utils/validator.js @@ -852,11 +852,6 @@ export const textRecordKeySchema = () => string().required().strict(true); export const textRecordValueSchema = () => string().default('').strict(true); -export const workerpoolApiUrlSchema = () => - string() - .matches(/^(https?:\/\/.*)?$/, '${path} "${value}" is not a valid URL') // accept empty string to reset workerpool URL - .default(''); - export const throwIfMissing = () => { throw new ValidationError('Missing parameter'); }; diff --git a/src/lib/IExecWorkerpoolModule.d.ts b/src/lib/IExecWorkerpoolModule.d.ts index 4b7b55c8..11b68298 100644 --- a/src/lib/IExecWorkerpoolModule.d.ts +++ b/src/lib/IExecWorkerpoolModule.d.ts @@ -117,23 +117,6 @@ export default class IExecWorkerpoolModule extends IExecModule { index: BNish, address: Addressish, ): Promise<{ objAddress: Address; workerpool: Workerpool }>; - /** - * **ONLY WORKERPOOL ENS NAME OWNER** - * - * declare the workerpool API url on the blockchain - * - * _NB_: declaring the workerpool API url require an ENS name with a configured reverse resolution on the workerpool address (see: IExecENSModule obsConfigureResolution/configureResolution) - * - * example: - * ```js - * const txHash = await setWorkerpoolApiUrl('my-workerpool.eth', 'my-workerpool.com'); - * console.log('txHash:', txHash); - * ``` - */ - setWorkerpoolApiUrl( - workerpoolAddress: Addressish, - url: string, - ): Promise; /** * read the workerpool API url on the blockchain * diff --git a/src/lib/IExecWorkerpoolModule.js b/src/lib/IExecWorkerpoolModule.js index 174e7c8e..dcd1b420 100644 --- a/src/lib/IExecWorkerpoolModule.js +++ b/src/lib/IExecWorkerpoolModule.js @@ -8,7 +8,6 @@ import { checkDeployedWorkerpool, transferWorkerpool, } from '../common/protocol/registries.js'; -import { setWorkerpoolApiUrl } from '../common/execution/workerpool.js'; import { getWorkerpoolApiUrl } from '../common/execution/debug.js'; export default class IExecWorkerpoolModule extends IExecModule { @@ -27,12 +26,6 @@ export default class IExecWorkerpoolModule extends IExecModule { ); this.countUserWorkerpools = async (address) => countUserWorkerpools(await this.config.resolveContractsClient(), address); - this.setWorkerpoolApiUrl = async (workerpoolAddress, url) => - setWorkerpoolApiUrl( - await this.config.resolveContractsClient(), - workerpoolAddress, - url, - ); this.getWorkerpoolApiUrl = async (workerpoolAddress) => getWorkerpoolApiUrl( await this.config.resolveContractsClient(), diff --git a/test/lib/e2e/IExecWorkerpoolModule.test.js b/test/lib/e2e/IExecWorkerpoolModule.test.js index f4aa6d4f..ab3f2f1e 100644 --- a/test/lib/e2e/IExecWorkerpoolModule.test.js +++ b/test/lib/e2e/IExecWorkerpoolModule.test.js @@ -238,133 +238,54 @@ describe('workerpool', () => { }); describe('getWorkerpoolApiUrl()', () => { - describe('on networks with ENS', () => { - const testChainWithEns = TEST_CHAINS['bellecour-fork']; - test('resolves the url against ENS', async () => { - const { iexec: readOnlyIExec } = await getTestConfig(testChainWithEns)({ - readOnly: true, - }); - const { iexec } = await getTestConfig(testChainWithEns)(); - const { address } = await deployRandomWorkerpool(iexec); - const resNoApiUrl = - await readOnlyIExec.workerpool.getWorkerpoolApiUrl(address); - expect(resNoApiUrl).toBe(undefined); - const label = address.toLowerCase(); - const domain = 'pools.iexec.eth'; - const name = `${label}.${domain}`; - await iexec.ens.claimName(label, domain); - await iexec.ens.configureResolution(name, address); - const apiUrl = 'https://my-workerpool.com'; - await iexec.workerpool.setWorkerpoolApiUrl(address, apiUrl); - const resConfigured = - await readOnlyIExec.workerpool.getWorkerpoolApiUrl(address); - expect(resConfigured).toBe(apiUrl); - }); + test('resolves the url against Compass', async () => { + const { iexec: readOnlyIExec } = await getTestConfig(testChain)(); + const apiUrl = await readOnlyIExec.workerpool.getWorkerpoolApiUrl( + '0xB967057a21dc6A66A29721d96b8Aa7454B7c383F', + ); + expect(typeof apiUrl).toBe('string'); + expect(apiUrl.startsWith('https://')).toBe(true); }); - describe('on networks relying on compass', () => { - test('resolves the url against Compass', async () => { - const { iexec: readOnlyIExec } = await getTestConfig(testChain)(); - const apiUrl = await readOnlyIExec.workerpool.getWorkerpoolApiUrl( - '0xB967057a21dc6A66A29721d96b8Aa7454B7c383F', - ); - expect(typeof apiUrl).toBe('string'); - expect(apiUrl.startsWith('https://')).toBe(true); - }); - - test('returns undefined if the workerpool does not exist in Compass', async () => { - const { iexec: readOnlyIExec } = await getTestConfig(testChain)(); - const address = getRandomAddress(); - await expect( - readOnlyIExec.workerpool.getWorkerpoolApiUrl(address), - ).resolves.toBe(undefined); - }); - - test('fails with CompassCallError if Compass is not available', async () => { - const { iexec: iexecCompassNotFound } = await getTestConfig(testChain)({ - options: { - compassURL: SERVICE_UNREACHABLE_URL, - }, - }); - await expect( - iexecCompassNotFound.workerpool.getWorkerpoolApiUrl( - getRandomAddress(), - ), - ).rejects.toThrow( - new errors.CompassCallError( - `Connection to ${SERVICE_UNREACHABLE_URL} failed with a network error`, - ), - ); - - const { iexec: iexecCompassInternalError } = await getTestConfig( - testChain, - )({ - options: { - compassURL: SERVICE_HTTP_500_URL, - }, - }); - await expect( - iexecCompassInternalError.workerpool.getWorkerpoolApiUrl( - getRandomAddress(), - ), - ).rejects.toThrow( - new errors.CompassCallError( - `Server at ${SERVICE_HTTP_500_URL} encountered an internal error`, - new Error('Server internal error: 500 Internal Server Error'), - ), - ); - }); + test('returns undefined if the workerpool does not exist in Compass', async () => { + const { iexec: readOnlyIExec } = await getTestConfig(testChain)(); + const address = getRandomAddress(); + await expect( + readOnlyIExec.workerpool.getWorkerpoolApiUrl(address), + ).resolves.toBe(undefined); }); - }); - - describe('setWorkerpoolApiUrl()', () => { - describe('on networks with ENS', () => { - const testChainWithEns = TEST_CHAINS['bellecour-fork']; - - test('require a configured ens name for the workerpool', async () => { - const { iexec } = await getTestConfig(testChainWithEns)(); - const { address } = await deployRandomWorkerpool(iexec); - await expect( - iexec.workerpool.setWorkerpoolApiUrl( - address, - 'https://my-workerpool.com', - ), - ).rejects.toThrow( - new Error(`No ENS name reverse resolution configured for ${address}`), - ); - }); - test('sets the workerpool api url', async () => { - const { iexec } = await getTestConfig(testChainWithEns)(); - const { address } = await deployRandomWorkerpool(iexec); - const label = address.toLowerCase(); - const domain = 'pools.iexec.eth'; - const name = `${label}.${domain}`; - await iexec.ens.claimName(label, domain); - await iexec.ens.configureResolution(name, address); - const res = await iexec.workerpool.setWorkerpoolApiUrl( - address, - 'https://my-workerpool.com', - ); - expect(res).toBeTxHash(); + test('fails with CompassCallError if Compass is not available', async () => { + const { iexec: iexecCompassNotFound } = await getTestConfig(testChain)({ + options: { + compassURL: SERVICE_UNREACHABLE_URL, + }, }); - }); + await expect( + iexecCompassNotFound.workerpool.getWorkerpoolApiUrl(getRandomAddress()), + ).rejects.toThrow( + new errors.CompassCallError( + `Connection to ${SERVICE_UNREACHABLE_URL} failed with a network error`, + ), + ); - describe('on networks relying on compass', () => { - test('setWorkerpoolApiUrl is not supported', async () => { - const { iexec } = await getTestConfig(testChain)(); - const { address } = await deployRandomWorkerpool(iexec); - await expect( - iexec.workerpool.setWorkerpoolApiUrl( - address, - 'https://my-workerpool.com', - ), - ).rejects.toThrow( - new ConfigurationError( - 'Workerpool API Registration is not available on network arbitrum-sepolia-testnet', - ), - ); + const { iexec: iexecCompassInternalError } = await getTestConfig( + testChain, + )({ + options: { + compassURL: SERVICE_HTTP_500_URL, + }, }); + await expect( + iexecCompassInternalError.workerpool.getWorkerpoolApiUrl( + getRandomAddress(), + ), + ).rejects.toThrow( + new errors.CompassCallError( + `Server at ${SERVICE_HTTP_500_URL} encountered an internal error`, + new Error('Server internal error: 500 Internal Server Error'), + ), + ); }); }); }); diff --git a/test/lib/unit/config.test.js b/test/lib/unit/config.test.js index 1c38374d..390fc58f 100644 --- a/test/lib/unit/config.test.js +++ b/test/lib/unit/config.test.js @@ -80,25 +80,7 @@ describe('checkImplementedOnChain', () => { ); }); }); - describe(`feature ${CHAIN_SPECIFIC_FEATURES.WORKERPOOL_API_URL_REGISTRATION}`, () => { - const feature = CHAIN_SPECIFIC_FEATURES.WORKERPOOL_API_URL_REGISTRATION; - test('is implemented on bellecour', () => { - expect(() => checkImplementedOnChain(134, feature)).not.toThrow(); - }); - test('is implemented on mainnet', () => { - expect(() => checkImplementedOnChain(1, feature)).not.toThrow(); - }); - test('is not implemented on arbitrum-mainnet', () => { - expect(() => checkImplementedOnChain(42161, feature)).toThrow( - `${feature} is not available on network arbitrum-mainnet`, - ); - }); - test('is not implemented on arbitrum-sepolia-testnet', () => { - expect(() => checkImplementedOnChain(421614, feature)).toThrow( - `${feature} is not available on network arbitrum-sepolia-testnet`, - ); - }); - }); + describe(`feature ${CHAIN_SPECIFIC_FEATURES.COMPASS}`, () => { const feature = CHAIN_SPECIFIC_FEATURES.COMPASS; test('is not implemented on bellecour', () => { diff --git a/test/lib/unit/validator.test.js b/test/lib/unit/validator.test.js index affa7abc..0001968b 100644 --- a/test/lib/unit/validator.test.js +++ b/test/lib/unit/validator.test.js @@ -27,7 +27,6 @@ import { ensLabelSchema, textRecordKeySchema, textRecordValueSchema, - workerpoolApiUrlSchema, teeFrameworkSchema, addressOrAnySchema, signedDatasetorderBulkSchema, @@ -1336,34 +1335,6 @@ describe('[textRecordValueSchema]', () => { }); }); -describe('[workerpoolApiUrlSchema]', () => { - test('allow IP with port', async () => { - const res = await workerpoolApiUrlSchema().validate( - 'http://192.168.0.1:8080', - ); - expect(res).toBe('http://192.168.0.1:8080'); - }); - test('allow url', async () => { - const res = await workerpoolApiUrlSchema().validate( - 'https://my-workerpool.com', - ); - expect(res).toBe('https://my-workerpool.com'); - }); - test('allow undefined', async () => { - const res = await workerpoolApiUrlSchema().validate(); - expect(res).toBe(''); - }); - test('allow empty string', async () => { - const res = await workerpoolApiUrlSchema().validate(''); - expect(res).toBe(''); - }); - test('throw with null', async () => { - await expect(workerpoolApiUrlSchema().validate(null)).rejects.toThrow( - 'this cannot be null', - ); - }); -}); - describe('[teeFrameworkSchema]', () => { test('allow known TEE frameworks', async () => { await Promise.all( From 88400bb7d56c10d6d46f0aa29756387f922bd590 Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Tue, 21 Apr 2026 15:15:00 +0200 Subject: [PATCH 06/13] fix!: remove ENS related methods and configuration --- CLI.md | 99 ---- docs/-internal-/README.md | 1 - .../classes/ENSConfigurationObservable.md | 101 ---- docs/README.md | 1 - docs/classes/IExec.md | 8 - docs/classes/IExecConfig.md | 12 - docs/classes/IExecENSModule.md | 381 -------------- docs/classes/IExecModule.md | 1 - docs/classes/IExecSecretsModule.md | 2 +- docs/classes/IExecWorkerpoolModule.md | 2 +- docs/classes/Observable.md | 1 - docs/globals.md | 3 - docs/interfaces/IExecConfigOptions.md | 8 - docs/type-aliases/Addressish.md | 11 - docs/type-aliases/ENS.md | 16 - generateEsModulesFromJson.cjs | 16 - package-lock.json | 84 --- package.json | 8 - src/cli/cmd/iexec-app.js | 71 +-- src/cli/cmd/iexec-dataset.js | 50 +- src/cli/cmd/iexec-ens.js | 205 -------- src/cli/cmd/iexec-order.js | 18 +- src/cli/cmd/iexec-requester.js | 2 - src/cli/cmd/iexec-result.js | 2 - src/cli/cmd/iexec-storage.js | 3 - src/cli/cmd/iexec-wallet.js | 17 +- src/cli/cmd/iexec-workerpool.js | 47 +- src/cli/cmd/iexec.js | 2 - src/cli/utils/cli-helper.js | 15 - src/cli/utils/fs.js | 2 - src/common/account/allowance.js | 12 +- src/common/account/balance.js | 6 +- src/common/ens/registration.js | 423 --------------- src/common/ens/registry.js | 29 -- src/common/ens/resolution.js | 68 --- src/common/ens/text-record.js | 94 ---- src/common/execution/deal.js | 17 +- src/common/execution/debug.js | 4 +- src/common/execution/order-helper.js | 25 +- src/common/market/marketplace.js | 36 +- src/common/market/order.js | 203 +++----- src/common/market/orderbook.js | 96 +--- src/common/protocol/registries.js | 127 ++--- src/common/sms/check.js | 22 +- src/common/sms/push.js | 2 - src/common/types.d.ts | 13 - src/common/utils/config.js | 31 +- src/common/utils/validator.js | 276 ++-------- src/common/wallet/balance.js | 18 +- src/common/wallet/send.js | 30 +- src/lib/IExec.d.ts | 5 - src/lib/IExec.js | 2 - src/lib/IExecAccountModule.d.ts | 12 +- src/lib/IExecAppModule.d.ts | 19 +- src/lib/IExecAppModule.js | 1 - src/lib/IExecConfig.d.ts | 8 - src/lib/IExecConfig.js | 18 +- src/lib/IExecDatasetModule.d.ts | 19 +- src/lib/IExecDatasetModule.js | 6 +- src/lib/IExecDealModule.d.ts | 9 +- src/lib/IExecENSModule.d.ts | 267 ---------- src/lib/IExecENSModule.js | 57 -- src/lib/IExecOrderModule.d.ts | 49 +- src/lib/IExecOrderModule.js | 16 +- src/lib/IExecOrderbookModule.d.ts | 55 +- src/lib/IExecResultModule.d.ts | 6 +- src/lib/IExecResultModule.js | 1 - src/lib/IExecSecretsModule.d.ts | 6 +- src/lib/IExecSecretsModule.js | 1 - src/lib/IExecStorageModule.d.ts | 4 +- src/lib/IExecStorageModule.js | 1 - src/lib/IExecWalletModule.d.ts | 18 +- src/lib/IExecWorkerpoolModule.d.ts | 22 +- src/lib/index.d.ts | 1 - src/lib/index.js | 1 - test/cli/cli-iexec-ens.test.js | 137 ----- test/cli/cli-test-utils.js | 1 - test/lib/e2e/IExecAccountModule.test.js | 2 +- test/lib/e2e/IExecConfig.test.js | 128 ----- test/lib/e2e/IExecEnsModule.test.js | 487 ------------------ test/lib/e2e/IExecWalletModule.test.js | 2 - test/lib/e2e/IExecWorkerpoolModule.test.js | 1 - test/lib/unit/config.test.js | 22 - test/lib/unit/validator.test.js | 172 +------ test/test-config-utils.js | 3 - test/test-utils.js | 5 +- typedoc_template.md | 1 - 87 files changed, 363 insertions(+), 3923 deletions(-) delete mode 100644 docs/-internal-/classes/ENSConfigurationObservable.md delete mode 100644 docs/classes/IExecENSModule.md delete mode 100644 docs/type-aliases/Addressish.md delete mode 100644 docs/type-aliases/ENS.md delete mode 100644 src/cli/cmd/iexec-ens.js delete mode 100644 src/common/ens/registration.js delete mode 100644 src/common/ens/registry.js delete mode 100644 src/common/ens/resolution.js delete mode 100644 src/common/ens/text-record.js delete mode 100644 src/lib/IExecENSModule.d.ts delete mode 100644 src/lib/IExecENSModule.js delete mode 100644 test/cli/cli-iexec-ens.test.js delete mode 100644 test/lib/e2e/IExecEnsModule.test.js diff --git a/CLI.md b/CLI.md index 6ae3a403..39f70744 100644 --- a/CLI.md +++ b/CLI.md @@ -312,7 +312,6 @@ Commands: - [iexec task](#iexec-task) - [iexec storage](#iexec-storage) - [iexec result](#iexec-result) -- [iexec ens](#iexec-ens) - [iexec category](#iexec-category) - [info](#iexec-info) @@ -2194,104 +2193,6 @@ Options: | --keystoredir \ | specify the wallet directory \<"global"\|"local"\|custom\> | | --chain \ | chain name from "chain.json" | -### iexec ens - -manage ENS names - -Usage: - -```sh -iexec ens [options] -``` - -Commands: - -- [resolve](#iexec-ens-resolve) -- [lookup](#iexec-ens-lookup) -- [get-owner](#iexec-ens-get-owner) -- [register](#iexec-ens-register) - -#### iexec ens resolve - -resolve an ENS name to an address - -Usage: - -```sh -iexec ens resolve [options] -``` - -Options: - -| option | description | -| --- | --- | -| --raw | use raw output | -| --quiet | stop prompting updates | -| --chain \ | chain name from "chain.json" | - -#### iexec ens lookup - -lookup for the ENS name of an address - -Usage: - -```sh -iexec ens lookup
[options] -``` - -Options: - -| option | description | -| --- | --- | -| --raw | use raw output | -| --quiet | stop prompting updates | -| --chain \ | chain name from "chain.json" | - -#### iexec ens get-owner - -find the the owner address of an ENS name - -Usage: - -```sh -iexec ens get-owner [options] -``` - -Options: - -| option | description | -| --- | --- | -| --raw | use raw output | -| --quiet | stop prompting updates | -| --chain \ | chain name from "chain.json" | - -#### iexec ens register - -register an ENS if needed and setup both ENS resolution and reverse resolution - -Usage: - -```sh -iexec ens register