From c24afaa93633bd6103de6185eacbe96e235ba83a Mon Sep 17 00:00:00 2001 From: Zied <26070035+zguesmi@users.noreply.github.com> Date: Wed, 11 Dec 2024 17:54:44 +0100 Subject: [PATCH 01/16] Clean --- test/000_fullchain.test.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/test/000_fullchain.test.ts b/test/000_fullchain.test.ts index c06c4046f..1b352c132 100644 --- a/test/000_fullchain.test.ts +++ b/test/000_fullchain.test.ts @@ -118,8 +118,9 @@ describe('Integration tests', function () { volume, trust: workers.length ** 2 - 1, }); - const { dealId, dealPrice, schedulerStakePerDeal } = - await iexecWrapper.signAndSponsorMatchOrders(...orders.toArray()); + const { dealId, schedulerStakePerDeal } = await iexecWrapper.signAndSponsorMatchOrders( + ...orders.toArray(), + ); const taskPrice = appPrice + datasetPrice + workerpoolPrice; const schedulerStakePerTask = schedulerStakePerDeal / volume; const workersRewardPerTask = await iexecWrapper.computeWorkersRewardPerTask( @@ -209,7 +210,7 @@ describe('Integration tests', function () { volume, trust: workers.length ** 2 - 1, }); - const { dealId, dealPrice, schedulerStakePerDeal } = await iexecWrapper.signAndMatchOrders( + const { dealId, schedulerStakePerDeal } = await iexecWrapper.signAndMatchOrders( ...orders.toArray(), ); const taskPrice = appPrice + datasetPrice + workerpoolPrice; @@ -298,8 +299,9 @@ describe('Integration tests', function () { volume, trust: 1, }); - const { dealId, dealPrice, schedulerStakePerDeal } = - await iexecWrapper.signAndSponsorMatchOrders(...orders.toArray()); + const { dealId, schedulerStakePerDeal } = await iexecWrapper.signAndSponsorMatchOrders( + ...orders.toArray(), + ); const taskPrice = appPrice + datasetPrice + workerpoolPrice; const schedulerStakePerTask = schedulerStakePerDeal / volume; const workersRewardPerTask = await iexecWrapper.computeWorkersRewardPerTask( @@ -376,7 +378,7 @@ describe('Integration tests', function () { volume, trust: 1, }); - const { dealId, dealPrice, schedulerStakePerDeal } = await iexecWrapper.signAndMatchOrders( + const { dealId, schedulerStakePerDeal } = await iexecWrapper.signAndMatchOrders( ...orders.toArray(), ); const taskPrice = appPrice + datasetPrice + workerpoolPrice; @@ -601,7 +603,8 @@ describe('Integration tests', function () { }); } }); - it(`[7] No sponsorship, no beneficiary, no callback, no BoT, up to 5 workers with 1 bad worker`, async function () { + + it('[7] No sponsorship, no beneficiary, no callback, no BoT, up to 5 workers with 1 bad worker', async function () { const volume = 1; const allWorkers = [worker1, worker2, worker3, worker4, worker5]; const { resultDigest: badResultDigest } = buildUtf8ResultAndDigest('bad-result'); From 9d88679bab041e9d5385796be58dc453291020c7 Mon Sep 17 00:00:00 2001 From: Zied <26070035+zguesmi@users.noreply.github.com> Date: Thu, 12 Dec 2024 10:40:34 +0100 Subject: [PATCH 02/16] Add note --- test/byContract/IexecPoco/IexecPoco1.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/byContract/IexecPoco/IexecPoco1.test.ts b/test/byContract/IexecPoco/IexecPoco1.test.ts index 394293edf..61d4abfd2 100644 --- a/test/byContract/IexecPoco/IexecPoco1.test.ts +++ b/test/byContract/IexecPoco/IexecPoco1.test.ts @@ -638,6 +638,8 @@ describe('IexecPoco1', () => { // - identity groups // - pre-signatures // - low orders volumes + // - test when the lowest volume is in one of the orders + // - test when the lowest volume in order < unconsumed volume // - multiple matches of the same order it('Should fail when categories are different', async () => { From e4691939f93a5f75638508be5dab218cae93e295 Mon Sep 17 00:00:00 2001 From: Zied <26070035+zguesmi@users.noreply.github.com> Date: Thu, 12 Dec 2024 16:12:46 +0100 Subject: [PATCH 03/16] Clean utility files --- test/utils/IexecWrapper.ts | 11 +++++------ utils/poco-tools.ts | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/test/utils/IexecWrapper.ts b/test/utils/IexecWrapper.ts index f5ca9e840..c4537a4c0 100644 --- a/test/utils/IexecWrapper.ts +++ b/test/utils/IexecWrapper.ts @@ -153,8 +153,8 @@ export class IexecWrapper { } /** - * Compute the amount of RLC tokens that the worker receives - * as a reward per task. + * Compute the amount of RLC tokens that all contributing workers receive + * when a task is finalized. * @param dealId * @param mode * @returns @@ -256,10 +256,9 @@ export class IexecWrapper { const workerpoolOrder = orders.workerpool; const requestOrder = orders.requester; const taskIndex = ( - await IexecAccessors__factory.connect( - this.proxyAddress, - this.accounts.anyone, - ).viewConsumed(this.hashOrder(requestOrder)) + await IexecAccessors__factory.connect(this.proxyAddress, ethers.provider).viewConsumed( + this.hashOrder(requestOrder), + ) ).toNumber(); const dealId = getDealId(this.domain, requestOrder, taskIndex); const taskId = getTaskId(dealId, taskIndex); diff --git a/utils/poco-tools.ts b/utils/poco-tools.ts index 6b284a5c4..a076ebc78 100644 --- a/utils/poco-tools.ts +++ b/utils/poco-tools.ts @@ -83,11 +83,11 @@ export async function getIexecAccounts(): Promise { export function getDealId( domain: TypedDataDomain, requestOrder: IexecLibOrders_v5.RequestOrderStruct, - taskIndex: number = 0, + firstTaskIndex: number = 0, ): string { return ethers.utils.solidityKeccak256( ['bytes32', 'uint256'], - [hashOrder(domain, requestOrder), taskIndex], + [hashOrder(domain, requestOrder), firstTaskIndex], ); } From 05154f981001ee87452db8cc1d9c9669cbe890a6 Mon Sep 17 00:00:00 2001 From: Zied <26070035+zguesmi@users.noreply.github.com> Date: Thu, 12 Dec 2024 16:13:23 +0100 Subject: [PATCH 04/16] Migrate dual pool test file --- test/201_fullchain-bot-dual-pool.test.ts | 242 +++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 test/201_fullchain-bot-dual-pool.test.ts diff --git a/test/201_fullchain-bot-dual-pool.test.ts b/test/201_fullchain-bot-dual-pool.test.ts new file mode 100644 index 000000000..b3d504c72 --- /dev/null +++ b/test/201_fullchain-bot-dual-pool.test.ts @@ -0,0 +1,242 @@ +// SPDX-FileCopyrightText: 2024 IEXEC BLOCKCHAIN TECH +// SPDX-License-Identifier: Apache-2.0 + +import { loadFixture } from '@nomicfoundation/hardhat-network-helpers'; +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; +import { expect } from 'hardhat'; +import { loadHardhatFixtureDeployment } from '../scripts/hardhat-fixture-deployer'; +import { IexecInterfaceNative, IexecInterfaceNative__factory } from '../typechain'; +import { OrdersActors, OrdersAssets, OrdersPrices, buildOrders } from '../utils/createOrders'; +import { + PocoMode, + TaskStatusEnum, + buildUtf8ResultAndDigest, + getIexecAccounts, +} from '../utils/poco-tools'; +import { IexecWrapper } from './utils/IexecWrapper'; + +// TODO use a better file name. + +const standardDealTag = '0x0000000000000000000000000000000000000000000000000000000000000000'; +const appPrice = 1000; +const datasetPrice = 1_000_000; +const workerpoolPrice = 1_000_000_000; +const { results, resultDigest } = buildUtf8ResultAndDigest('result'); + +let proxyAddress: string; +let iexecPoco: IexecInterfaceNative; +let iexecWrapper: IexecWrapper; +let [appAddress, workerpoolAddress, datasetAddress]: string[] = []; +let [requester, appProvider, datasetProvider, scheduler, anyone, worker1]: SignerWithAddress[] = []; +let ordersActors: OrdersActors; +let ordersAssets: OrdersAssets; +let ordersPrices: OrdersPrices; + +describe('Integration tests', function () { + beforeEach('Deploy', async () => { + // Deploy all contracts + proxyAddress = await loadHardhatFixtureDeployment(); + // Initialize test environment + await loadFixture(initFixture); + }); + + async function initFixture() { + const accounts = await getIexecAccounts(); + ({ requester, appProvider, datasetProvider, scheduler, anyone, worker1 } = accounts); + iexecWrapper = new IexecWrapper(proxyAddress, accounts); + ({ appAddress, datasetAddress, workerpoolAddress } = await iexecWrapper.createAssets()); + iexecPoco = IexecInterfaceNative__factory.connect(proxyAddress, anyone); + ordersActors = { + appOwner: appProvider, + datasetOwner: datasetProvider, + workerpoolOwner: scheduler, + requester: requester, + }; + ordersAssets = { + app: appAddress, + dataset: datasetAddress, + workerpool: workerpoolAddress, + }; + ordersPrices = { + app: appPrice, + dataset: datasetPrice, + workerpool: workerpoolPrice, + }; + } + + /** + * A test to run full workflow (matchOrder..finalize) with 2 orders having 2 different volumes + * for the same workerpool and only 1 request order. + */ + it('[1] No sponsorship, no beneficiary, no callback, BoT, no replication, 2 workerpool orders', async function () { + const volume = 3; + const workerpoolOrderVolume1 = 2; + const workerpoolOrderVolume2 = 10; + const dealVolume1 = volume - workerpoolOrderVolume1; // 2 + console.log('🚀 ~ dealVolume1:', dealVolume1); + const dealVolume2 = Math.min(volume - dealVolume1, workerpoolOrderVolume2); // min(1, 10) + // console.log("🚀 ~ dealVolume2:", dealVolume2) + const workerpoolPrice1 = workerpoolPrice + 15; + console.log('🚀 ~ workerpoolPrice1:', workerpoolPrice1); + const workerpoolPrice2 = workerpoolPrice + 25; + const taskPrice1 = appPrice + datasetPrice + workerpoolPrice1; + console.log('🚀 ~ taskPrice1:', taskPrice1); + const taskPrice2 = appPrice + datasetPrice + workerpoolPrice2; + // Create default orders. + const { + appOrder, + datasetOrder, + workerpoolOrder, + requesterOrder: requestOrder, + } = buildOrders({ + assets: ordersAssets, + prices: ordersPrices, + requester: requester.address, + tag: standardDealTag, + volume, + }).toObject(); + // Create 2 different orders for the same workerpool. + const workerpoolOrder1 = workerpoolOrder; + const workerpoolOrder2 = { ...workerpoolOrder }; // Shallow cloning is fine here. + workerpoolOrder1.volume = workerpoolOrderVolume1; + workerpoolOrder1.workerpoolprice = workerpoolPrice1; + workerpoolOrder2.volume = workerpoolOrderVolume2; + workerpoolOrder2.workerpoolprice = workerpoolPrice2; + requestOrder.workerpoolmaxprice = Math.max(workerpoolPrice1, workerpoolPrice2); + // Match both workerpool orders with the same request order. + const { + dealId: dealId1, + taskIndex: taskIndex1, + schedulerStakePerDeal: schedulerStakeForDeal1, + dealPrice: dealPrice1, + } = await iexecWrapper.signAndMatchOrders( + appOrder, + datasetOrder, + workerpoolOrder1, + requestOrder, + ); // First task index is 0. + console.log('🚀 ~ dealPrice1:', dealPrice1); + const { + dealId: dealId2, + taskIndex: taskIndex2, + schedulerStakePerDeal: schedulerStakeForDeal2, + } = await iexecWrapper.signAndMatchOrders( + appOrder, + datasetOrder, + workerpoolOrder2, + requestOrder, + ); // First task index is 2. + const deal1 = await iexecPoco.viewDeal(dealId1); + expect(deal1.botFirst).to.equal(0); + expect(deal1.botSize).to.equal(dealVolume1); + const deal2 = await iexecPoco.viewDeal(dealId2); + expect(deal2.botFirst).to.equal(dealVolume1); + expect(deal2.botSize).to.equal(dealVolume2); + // Compute stakes and rewards for each deal. + const schedulerStakePerTaskOfDeal1 = schedulerStakeForDeal1 / dealVolume1; + console.log('🚀 ~ schedulerStakePerTaskOfDeal1:', schedulerStakePerTaskOfDeal1); + const schedulerStakePerTaskOfDeal2 = schedulerStakeForDeal2 / dealVolume2; + // console.log("🚀 ~ schedulerStakePerTaskOfDeal2:", schedulerStakePerTaskOfDeal2) + const workersRewardPerTaskOfDeal1 = await iexecWrapper.computeWorkersRewardPerTask( + dealId1, + PocoMode.CLASSIC, + ); + console.log('🚀 ~ workersRewardPerTaskOfDeal1:', workersRewardPerTaskOfDeal1); + const workersRewardPerTaskOfDeal2 = await iexecWrapper.computeWorkersRewardPerTask( + dealId2, + PocoMode.CLASSIC, + ); + // console.log("🚀 ~ workersRewardPerTaskOfDeal2:", workersRewardPerTaskOfDeal2) + + const schedulerRewardPerTaskOfDeal1 = workerpoolPrice1 - workersRewardPerTaskOfDeal1; + console.log('🚀 ~ schedulerRewardPerTaskOfDeal1:', schedulerRewardPerTaskOfDeal1); + const schedulerRewardPerTaskOfDeal2 = workerpoolPrice2 - workersRewardPerTaskOfDeal2; + // console.log("🚀 ~ schedulerRewardPerTaskOfDeal2:", schedulerRewardPerTaskOfDeal2) + + // Finalize each task and run checks. + await runTaskThenCheckBalancesAndVolumes( + dealId1, + taskIndex1, + taskPrice1, + schedulerStakePerTaskOfDeal1, + schedulerRewardPerTaskOfDeal1, + workersRewardPerTaskOfDeal1, + ); + await runTaskThenCheckBalancesAndVolumes( + dealId1, + taskIndex1 + 1, + taskPrice1, + schedulerStakePerTaskOfDeal1, + schedulerRewardPerTaskOfDeal1, + workersRewardPerTaskOfDeal1, + ); + await runTaskThenCheckBalancesAndVolumes( + dealId2, + taskIndex2, + taskPrice2, + schedulerStakePerTaskOfDeal2, + schedulerRewardPerTaskOfDeal2, + workersRewardPerTaskOfDeal2, + ); + }); + + async function runTaskThenCheckBalancesAndVolumes( + dealId: string, + taskIndex: number, + taskPrice: number, + schedulerStake: number, + schedulerReward: number, + workerReward: number, + ) { + // Save frozens. + const accounts = [requester, scheduler, appProvider, datasetProvider, worker1]; + const accountsInitialFrozens = await iexecWrapper.getInitialFrozens(accounts); + // Run task. + const taskId = await iexecWrapper.initializeTask(dealId, taskIndex); + const { workerStakePerTask: workerStake } = await iexecWrapper.contributeToTask( + dealId, + taskIndex, + resultDigest, + worker1, + ); + console.log('🚀 ~ taskPrice:', taskPrice); + console.log('🚀 ~ schedulerStake:', schedulerStake); + console.log('🚀 ~ schedulerReward:', schedulerReward); + console.log('🚀 ~ workerStake:', workerStake); + console.log('🚀 ~ workerReward:', workerReward); + await iexecPoco + .connect(worker1) + .reveal(taskId, resultDigest) + .then((tx) => tx.wait()); + const finalizeTx = await iexecPoco.connect(scheduler).finalize(taskId, results, '0x'); + await finalizeTx.wait(); + // Check task. + const task = await iexecPoco.viewTask(taskId); + expect(task.status).to.equal(TaskStatusEnum.COMPLETED); + expect(task.idx).to.equal(taskIndex); + // Verify token balance changes. + const expectedProxyBalanceChange = -(taskPrice + schedulerStake + workerStake); + await expect(finalizeTx).to.changeTokenBalances( + iexecPoco, + [proxyAddress, requester, scheduler, appProvider, datasetProvider, worker1], + [ + expectedProxyBalanceChange, // Proxy + 0, // Requester + schedulerStake + schedulerReward, // Scheduler + appPrice, // AppProvider + datasetPrice, // DatasetProvider + workerStake + workerReward, // Worker + ], + ); + // Calculate expected frozen changes + const expectedFrozenChanges = [ + 0, // Proxy + -taskPrice, // Requester + -schedulerStake, // Scheduler + 0, // AppProvider + 0, // DatasetProvider + 0, // Worker + ]; + await iexecWrapper.checkFrozenChanges(accountsInitialFrozens, expectedFrozenChanges); + } +}); From 1172c01548e5e23d1b214d576d202b25d1ea8cdb Mon Sep 17 00:00:00 2001 From: Zied <26070035+zguesmi@users.noreply.github.com> Date: Thu, 12 Dec 2024 16:36:31 +0100 Subject: [PATCH 05/16] Fix volume calculation --- test/201_fullchain-bot-dual-pool.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/201_fullchain-bot-dual-pool.test.ts b/test/201_fullchain-bot-dual-pool.test.ts index b3d504c72..af09d5f0c 100644 --- a/test/201_fullchain-bot-dual-pool.test.ts +++ b/test/201_fullchain-bot-dual-pool.test.ts @@ -72,9 +72,9 @@ describe('Integration tests', function () { const volume = 3; const workerpoolOrderVolume1 = 2; const workerpoolOrderVolume2 = 10; - const dealVolume1 = volume - workerpoolOrderVolume1; // 2 + const dealVolume1 = Math.min(workerpoolOrderVolume1, volume); // min(2, 3); console.log('🚀 ~ dealVolume1:', dealVolume1); - const dealVolume2 = Math.min(volume - dealVolume1, workerpoolOrderVolume2); // min(1, 10) + const dealVolume2 = Math.min(workerpoolOrderVolume2, volume - dealVolume1); // min(10, 1) // console.log("🚀 ~ dealVolume2:", dealVolume2) const workerpoolPrice1 = workerpoolPrice + 15; console.log('🚀 ~ workerpoolPrice1:', workerpoolPrice1); From 51f648df84d7aaf212b46d3c896e4ff6248a7105 Mon Sep 17 00:00:00 2001 From: Zied <26070035+zguesmi@users.noreply.github.com> Date: Thu, 12 Dec 2024 17:16:13 +0100 Subject: [PATCH 06/16] Fix test deal volume calculation in _signAndMatchOrders function --- test/utils/IexecWrapper.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/utils/IexecWrapper.ts b/test/utils/IexecWrapper.ts index c4537a4c0..5c98e6cc0 100644 --- a/test/utils/IexecWrapper.ts +++ b/test/utils/IexecWrapper.ts @@ -17,6 +17,7 @@ import { IexecLibOrders_v5, IexecMaintenanceDelegate__factory, IexecPoco2__factory, + IexecPocoAccessors__factory, IexecPocoBoostAccessors__factory, RLC__factory, WorkerpoolRegistry, @@ -262,7 +263,13 @@ export class IexecWrapper { ).toNumber(); const dealId = getDealId(this.domain, requestOrder, taskIndex); const taskId = getTaskId(dealId, taskIndex); - const volume = Number(requestOrder.volume); + // const volume = Number(requestOrder.volume); + const volume = ( + await IexecPocoAccessors__factory.connect( + this.proxyAddress, + ethers.provider, + ).computeDealVolume(appOrder, datasetOrder, workerpoolOrder, requestOrder) + ).toNumber(); const taskPrice = Number(appOrder.appprice) + Number(datasetOrder.datasetprice) + From 5106516da7cf137d934feab0408693398e615c90 Mon Sep 17 00:00:00 2001 From: Zied <26070035+zguesmi@users.noreply.github.com> Date: Thu, 12 Dec 2024 17:17:14 +0100 Subject: [PATCH 07/16] Debug dual pool IT --- test/201_fullchain-bot-dual-pool.test.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/201_fullchain-bot-dual-pool.test.ts b/test/201_fullchain-bot-dual-pool.test.ts index af09d5f0c..f079be14f 100644 --- a/test/201_fullchain-bot-dual-pool.test.ts +++ b/test/201_fullchain-bot-dual-pool.test.ts @@ -107,18 +107,20 @@ describe('Integration tests', function () { const { dealId: dealId1, taskIndex: taskIndex1, - schedulerStakePerDeal: schedulerStakeForDeal1, dealPrice: dealPrice1, + schedulerStakePerDeal: schedulerStakeForDeal1, } = await iexecWrapper.signAndMatchOrders( appOrder, datasetOrder, workerpoolOrder1, requestOrder, ); // First task index is 0. + console.log('🚀 ~ schedulerStakeForDeal1:', schedulerStakeForDeal1); console.log('🚀 ~ dealPrice1:', dealPrice1); const { dealId: dealId2, taskIndex: taskIndex2, + dealPrice: dealPrice2, schedulerStakePerDeal: schedulerStakeForDeal2, } = await iexecWrapper.signAndMatchOrders( appOrder, @@ -126,6 +128,7 @@ describe('Integration tests', function () { workerpoolOrder2, requestOrder, ); // First task index is 2. + // console.log('🚀 ~ dealPrice2:', dealPrice2); const deal1 = await iexecPoco.viewDeal(dealId1); expect(deal1.botFirst).to.equal(0); expect(deal1.botSize).to.equal(dealVolume1); @@ -154,6 +157,7 @@ describe('Integration tests', function () { // console.log("🚀 ~ schedulerRewardPerTaskOfDeal2:", schedulerRewardPerTaskOfDeal2) // Finalize each task and run checks. + console.log('🚀 ~ run1'); await runTaskThenCheckBalancesAndVolumes( dealId1, taskIndex1, @@ -162,6 +166,7 @@ describe('Integration tests', function () { schedulerRewardPerTaskOfDeal1, workersRewardPerTaskOfDeal1, ); + console.log('🚀 ~ run2'); await runTaskThenCheckBalancesAndVolumes( dealId1, taskIndex1 + 1, @@ -170,6 +175,7 @@ describe('Integration tests', function () { schedulerRewardPerTaskOfDeal1, workersRewardPerTaskOfDeal1, ); + console.log('🚀 ~ run1'); await runTaskThenCheckBalancesAndVolumes( dealId2, taskIndex2, @@ -215,7 +221,10 @@ describe('Integration tests', function () { expect(task.status).to.equal(TaskStatusEnum.COMPLETED); expect(task.idx).to.equal(taskIndex); // Verify token balance changes. + const proxyBalance = await iexecPoco.balanceOf(proxyAddress); + console.log('🚀 ~ proxyBalance:', proxyBalance); const expectedProxyBalanceChange = -(taskPrice + schedulerStake + workerStake); + console.log('🚀 ~ expectedProxyBalanceChange:', expectedProxyBalanceChange); await expect(finalizeTx).to.changeTokenBalances( iexecPoco, [proxyAddress, requester, scheduler, appProvider, datasetProvider, worker1], From 691567fe7fb5c9a983df6f1d080b4dabbd15258c Mon Sep 17 00:00:00 2001 From: Zied <26070035+zguesmi@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:52:47 +0100 Subject: [PATCH 08/16] Fix workers reward calculation issue --- test/utils/IexecWrapper.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/utils/IexecWrapper.ts b/test/utils/IexecWrapper.ts index 5c98e6cc0..88951b173 100644 --- a/test/utils/IexecWrapper.ts +++ b/test/utils/IexecWrapper.ts @@ -136,7 +136,7 @@ export class IexecWrapper { this.accounts.anyone, ).m_workerStakeRatioPolicy() ).toNumber(); - return (workerpoolPrice * workerStakeRatio) / 100; + return Math.floor((workerpoolPrice * workerStakeRatio) / 100); } /** @@ -174,10 +174,9 @@ export class IexecWrapper { this.proxyAddress, ethers.provider, ).viewDeal(dealId); - // (workerpoolPrice * workerRatio) / 100 - return ( - (deal.workerpool.price.toNumber() * (100 - deal.schedulerRewardRatio.toNumber())) / 100 - ); + // reward = (workerpoolPrice * workersRatio) / 100 + const workersRewardRatio = 100 - deal.schedulerRewardRatio.toNumber(); + return Math.floor((deal.workerpool.price.toNumber() * workersRewardRatio) / 100); } async setTeeBroker(brokerAddress: string) { From 7c2161ad8bb74b1577c7993a2127855b071a4775 Mon Sep 17 00:00:00 2001 From: Zied <26070035+zguesmi@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:28:35 +0100 Subject: [PATCH 09/16] Clean test file --- test/201_fullchain-bot-dual-pool.test.ts | 61 ++++++++++++------------ 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/test/201_fullchain-bot-dual-pool.test.ts b/test/201_fullchain-bot-dual-pool.test.ts index f079be14f..3312f0ad5 100644 --- a/test/201_fullchain-bot-dual-pool.test.ts +++ b/test/201_fullchain-bot-dual-pool.test.ts @@ -3,10 +3,21 @@ import { loadFixture } from '@nomicfoundation/hardhat-network-helpers'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; -import { expect } from 'hardhat'; +import { ethers, expect } from 'hardhat'; import { loadHardhatFixtureDeployment } from '../scripts/hardhat-fixture-deployer'; -import { IexecInterfaceNative, IexecInterfaceNative__factory } from '../typechain'; -import { OrdersActors, OrdersAssets, OrdersPrices, buildOrders } from '../utils/createOrders'; +import { + IexecInterfaceNative, + IexecInterfaceNative__factory, + IexecPocoAccessors, + IexecPocoAccessors__factory, +} from '../typechain'; +import { + IexecOrders, + OrdersActors, + OrdersAssets, + OrdersPrices, + buildOrders, +} from '../utils/createOrders'; import { PocoMode, TaskStatusEnum, @@ -25,6 +36,7 @@ const { results, resultDigest } = buildUtf8ResultAndDigest('result'); let proxyAddress: string; let iexecPoco: IexecInterfaceNative; +let iexecPocoAccessors: IexecPocoAccessors; // To use `computeDealVolume()` let iexecWrapper: IexecWrapper; let [appAddress, workerpoolAddress, datasetAddress]: string[] = []; let [requester, appProvider, datasetProvider, scheduler, anyone, worker1]: SignerWithAddress[] = []; @@ -46,6 +58,7 @@ describe('Integration tests', function () { iexecWrapper = new IexecWrapper(proxyAddress, accounts); ({ appAddress, datasetAddress, workerpoolAddress } = await iexecWrapper.createAssets()); iexecPoco = IexecInterfaceNative__factory.connect(proxyAddress, anyone); + iexecPocoAccessors = IexecPocoAccessors__factory.connect(proxyAddress, ethers.provider); ordersActors = { appOwner: appProvider, datasetOwner: datasetProvider, @@ -73,14 +86,10 @@ describe('Integration tests', function () { const workerpoolOrderVolume1 = 2; const workerpoolOrderVolume2 = 10; const dealVolume1 = Math.min(workerpoolOrderVolume1, volume); // min(2, 3); - console.log('🚀 ~ dealVolume1:', dealVolume1); const dealVolume2 = Math.min(workerpoolOrderVolume2, volume - dealVolume1); // min(10, 1) - // console.log("🚀 ~ dealVolume2:", dealVolume2) const workerpoolPrice1 = workerpoolPrice + 15; - console.log('🚀 ~ workerpoolPrice1:', workerpoolPrice1); const workerpoolPrice2 = workerpoolPrice + 25; const taskPrice1 = appPrice + datasetPrice + workerpoolPrice1; - console.log('🚀 ~ taskPrice1:', taskPrice1); const taskPrice2 = appPrice + datasetPrice + workerpoolPrice2; // Create default orders. const { @@ -104,10 +113,22 @@ describe('Integration tests', function () { workerpoolOrder2.workerpoolprice = workerpoolPrice2; requestOrder.workerpoolmaxprice = Math.max(workerpoolPrice1, workerpoolPrice2); // Match both workerpool orders with the same request order. + const dealOrders1 = new IexecOrders( + appOrder, + datasetOrder, + workerpoolOrder1, + requestOrder, + ).toArray(); + const dealOrders2 = new IexecOrders( + appOrder, + datasetOrder, + workerpoolOrder2, + requestOrder, + ).toArray(); + expect(await iexecPocoAccessors.computeDealVolume(...dealOrders1)).to.equal(dealVolume1); const { dealId: dealId1, taskIndex: taskIndex1, - dealPrice: dealPrice1, schedulerStakePerDeal: schedulerStakeForDeal1, } = await iexecWrapper.signAndMatchOrders( appOrder, @@ -115,12 +136,10 @@ describe('Integration tests', function () { workerpoolOrder1, requestOrder, ); // First task index is 0. - console.log('🚀 ~ schedulerStakeForDeal1:', schedulerStakeForDeal1); - console.log('🚀 ~ dealPrice1:', dealPrice1); + expect(await iexecPocoAccessors.computeDealVolume(...dealOrders2)).to.equal(dealVolume2); const { dealId: dealId2, taskIndex: taskIndex2, - dealPrice: dealPrice2, schedulerStakePerDeal: schedulerStakeForDeal2, } = await iexecWrapper.signAndMatchOrders( appOrder, @@ -128,7 +147,6 @@ describe('Integration tests', function () { workerpoolOrder2, requestOrder, ); // First task index is 2. - // console.log('🚀 ~ dealPrice2:', dealPrice2); const deal1 = await iexecPoco.viewDeal(dealId1); expect(deal1.botFirst).to.equal(0); expect(deal1.botSize).to.equal(dealVolume1); @@ -137,27 +155,18 @@ describe('Integration tests', function () { expect(deal2.botSize).to.equal(dealVolume2); // Compute stakes and rewards for each deal. const schedulerStakePerTaskOfDeal1 = schedulerStakeForDeal1 / dealVolume1; - console.log('🚀 ~ schedulerStakePerTaskOfDeal1:', schedulerStakePerTaskOfDeal1); const schedulerStakePerTaskOfDeal2 = schedulerStakeForDeal2 / dealVolume2; - // console.log("🚀 ~ schedulerStakePerTaskOfDeal2:", schedulerStakePerTaskOfDeal2) const workersRewardPerTaskOfDeal1 = await iexecWrapper.computeWorkersRewardPerTask( dealId1, PocoMode.CLASSIC, ); - console.log('🚀 ~ workersRewardPerTaskOfDeal1:', workersRewardPerTaskOfDeal1); const workersRewardPerTaskOfDeal2 = await iexecWrapper.computeWorkersRewardPerTask( dealId2, PocoMode.CLASSIC, ); - // console.log("🚀 ~ workersRewardPerTaskOfDeal2:", workersRewardPerTaskOfDeal2) - const schedulerRewardPerTaskOfDeal1 = workerpoolPrice1 - workersRewardPerTaskOfDeal1; - console.log('🚀 ~ schedulerRewardPerTaskOfDeal1:', schedulerRewardPerTaskOfDeal1); const schedulerRewardPerTaskOfDeal2 = workerpoolPrice2 - workersRewardPerTaskOfDeal2; - // console.log("🚀 ~ schedulerRewardPerTaskOfDeal2:", schedulerRewardPerTaskOfDeal2) - // Finalize each task and run checks. - console.log('🚀 ~ run1'); await runTaskThenCheckBalancesAndVolumes( dealId1, taskIndex1, @@ -166,7 +175,6 @@ describe('Integration tests', function () { schedulerRewardPerTaskOfDeal1, workersRewardPerTaskOfDeal1, ); - console.log('🚀 ~ run2'); await runTaskThenCheckBalancesAndVolumes( dealId1, taskIndex1 + 1, @@ -175,7 +183,6 @@ describe('Integration tests', function () { schedulerRewardPerTaskOfDeal1, workersRewardPerTaskOfDeal1, ); - console.log('🚀 ~ run1'); await runTaskThenCheckBalancesAndVolumes( dealId2, taskIndex2, @@ -205,11 +212,6 @@ describe('Integration tests', function () { resultDigest, worker1, ); - console.log('🚀 ~ taskPrice:', taskPrice); - console.log('🚀 ~ schedulerStake:', schedulerStake); - console.log('🚀 ~ schedulerReward:', schedulerReward); - console.log('🚀 ~ workerStake:', workerStake); - console.log('🚀 ~ workerReward:', workerReward); await iexecPoco .connect(worker1) .reveal(taskId, resultDigest) @@ -221,10 +223,7 @@ describe('Integration tests', function () { expect(task.status).to.equal(TaskStatusEnum.COMPLETED); expect(task.idx).to.equal(taskIndex); // Verify token balance changes. - const proxyBalance = await iexecPoco.balanceOf(proxyAddress); - console.log('🚀 ~ proxyBalance:', proxyBalance); const expectedProxyBalanceChange = -(taskPrice + schedulerStake + workerStake); - console.log('🚀 ~ expectedProxyBalanceChange:', expectedProxyBalanceChange); await expect(finalizeTx).to.changeTokenBalances( iexecPoco, [proxyAddress, requester, scheduler, appProvider, datasetProvider, worker1], From 414f1098d5554689eccc7e7b5351d145b8938a1a Mon Sep 17 00:00:00 2001 From: Zied <26070035+zguesmi@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:32:39 +0100 Subject: [PATCH 10/16] Check remaining volumes --- test/201_fullchain-bot-dual-pool.test.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/201_fullchain-bot-dual-pool.test.ts b/test/201_fullchain-bot-dual-pool.test.ts index 3312f0ad5..9af08ad13 100644 --- a/test/201_fullchain-bot-dual-pool.test.ts +++ b/test/201_fullchain-bot-dual-pool.test.ts @@ -191,6 +191,13 @@ describe('Integration tests', function () { schedulerRewardPerTaskOfDeal2, workersRewardPerTaskOfDeal2, ); + // Check remaining volumes. + expect(await iexecPoco.viewConsumed(iexecWrapper.hashOrder(workerpoolOrder1))).to.equal( + dealVolume1, + ); + expect(await iexecPoco.viewConsumed(iexecWrapper.hashOrder(workerpoolOrder2))).to.equal( + dealVolume2, + ); }); async function runTaskThenCheckBalancesAndVolumes( From 8c8dbc5c225df0b5c464765e9857c1b3618344ba Mon Sep 17 00:00:00 2001 From: Zied <26070035+zguesmi@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:34:59 +0100 Subject: [PATCH 11/16] Rename file --- ...bot-dual-pool.test.ts => 201_fullchain-multi-orders.test.ts} | 2 -- 1 file changed, 2 deletions(-) rename test/{201_fullchain-bot-dual-pool.test.ts => 201_fullchain-multi-orders.test.ts} (99%) diff --git a/test/201_fullchain-bot-dual-pool.test.ts b/test/201_fullchain-multi-orders.test.ts similarity index 99% rename from test/201_fullchain-bot-dual-pool.test.ts rename to test/201_fullchain-multi-orders.test.ts index 9af08ad13..42e9a5b05 100644 --- a/test/201_fullchain-bot-dual-pool.test.ts +++ b/test/201_fullchain-multi-orders.test.ts @@ -26,8 +26,6 @@ import { } from '../utils/poco-tools'; import { IexecWrapper } from './utils/IexecWrapper'; -// TODO use a better file name. - const standardDealTag = '0x0000000000000000000000000000000000000000000000000000000000000000'; const appPrice = 1000; const datasetPrice = 1_000_000; From 4ac18c54e8e719cae584f09073f2e9f777210419 Mon Sep 17 00:00:00 2001 From: Zied <26070035+zguesmi@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:37:56 +0100 Subject: [PATCH 12/16] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 440e61ca7..b8c239ef7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - 000_fullchain-5workers-1error.js (#160, #162) - Clean ToDo (#163) - 200_fullchain-bot.js (#164, #166) + - 201_fullchain-bot-dualPool.js (#171) - Fix balance checks in integration tests (#165) - Remove `smock` from unit tests: - IexecEscrow.v8 (#154, #155) From 09970c2236d85461efa5c0d2aa83ed6956690f79 Mon Sep 17 00:00:00 2001 From: Zied <26070035+zguesmi@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:45:59 +0100 Subject: [PATCH 13/16] Clean --- test/201_fullchain-multi-orders.test.ts | 2 +- test/utils/IexecWrapper.ts | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/test/201_fullchain-multi-orders.test.ts b/test/201_fullchain-multi-orders.test.ts index 42e9a5b05..d375dc04a 100644 --- a/test/201_fullchain-multi-orders.test.ts +++ b/test/201_fullchain-multi-orders.test.ts @@ -76,7 +76,7 @@ describe('Integration tests', function () { } /** - * A test to run full workflow (matchOrder..finalize) with 2 orders having 2 different volumes + * A test to run full workflow (matchOrders..finalize) with 2 orders having 2 different volumes * for the same workerpool and only 1 request order. */ it('[1] No sponsorship, no beneficiary, no callback, BoT, no replication, 2 workerpool orders', async function () { diff --git a/test/utils/IexecWrapper.ts b/test/utils/IexecWrapper.ts index 88951b173..124636828 100644 --- a/test/utils/IexecWrapper.ts +++ b/test/utils/IexecWrapper.ts @@ -154,8 +154,8 @@ export class IexecWrapper { } /** - * Compute the amount of RLC tokens that all contributing workers receive - * when a task is finalized. + * Compute the amount of RLC tokens that are rewarded to workers when + * a task is finalized. * @param dealId * @param mode * @returns @@ -262,7 +262,6 @@ export class IexecWrapper { ).toNumber(); const dealId = getDealId(this.domain, requestOrder, taskIndex); const taskId = getTaskId(dealId, taskIndex); - // const volume = Number(requestOrder.volume); const volume = ( await IexecPocoAccessors__factory.connect( this.proxyAddress, From 5b7c9c2d5eb7b365916750716527075d9df17b4f Mon Sep 17 00:00:00 2001 From: Zied <26070035+zguesmi@users.noreply.github.com> Date: Fri, 20 Dec 2024 10:57:36 +0100 Subject: [PATCH 14/16] Use plain prices for workerpool orders and check request order consumed --- test/201_fullchain-multi-orders.test.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/201_fullchain-multi-orders.test.ts b/test/201_fullchain-multi-orders.test.ts index d375dc04a..3213da730 100644 --- a/test/201_fullchain-multi-orders.test.ts +++ b/test/201_fullchain-multi-orders.test.ts @@ -29,7 +29,8 @@ import { IexecWrapper } from './utils/IexecWrapper'; const standardDealTag = '0x0000000000000000000000000000000000000000000000000000000000000000'; const appPrice = 1000; const datasetPrice = 1_000_000; -const workerpoolPrice = 1_000_000_000; +const workerpoolPrice1 = 1_000_000_015; +const workerpoolPrice2 = 1_000_000_025; const { results, resultDigest } = buildUtf8ResultAndDigest('result'); let proxyAddress: string; @@ -71,7 +72,7 @@ describe('Integration tests', function () { ordersPrices = { app: appPrice, dataset: datasetPrice, - workerpool: workerpoolPrice, + workerpool: 0, // Overridden below. }; } @@ -85,8 +86,6 @@ describe('Integration tests', function () { const workerpoolOrderVolume2 = 10; const dealVolume1 = Math.min(workerpoolOrderVolume1, volume); // min(2, 3); const dealVolume2 = Math.min(workerpoolOrderVolume2, volume - dealVolume1); // min(10, 1) - const workerpoolPrice1 = workerpoolPrice + 15; - const workerpoolPrice2 = workerpoolPrice + 25; const taskPrice1 = appPrice + datasetPrice + workerpoolPrice1; const taskPrice2 = appPrice + datasetPrice + workerpoolPrice2; // Create default orders. @@ -103,8 +102,8 @@ describe('Integration tests', function () { volume, }).toObject(); // Create 2 different orders for the same workerpool. - const workerpoolOrder1 = workerpoolOrder; - const workerpoolOrder2 = { ...workerpoolOrder }; // Shallow cloning is fine here. + const workerpoolOrder1 = { ...workerpoolOrder }; // Shallow cloning is fine here. + const workerpoolOrder2 = { ...workerpoolOrder }; workerpoolOrder1.volume = workerpoolOrderVolume1; workerpoolOrder1.workerpoolprice = workerpoolPrice1; workerpoolOrder2.volume = workerpoolOrderVolume2; @@ -190,6 +189,7 @@ describe('Integration tests', function () { workersRewardPerTaskOfDeal2, ); // Check remaining volumes. + expect(await iexecPoco.viewConsumed(iexecWrapper.hashOrder(requestOrder))).to.equal(volume); expect(await iexecPoco.viewConsumed(iexecWrapper.hashOrder(workerpoolOrder1))).to.equal( dealVolume1, ); @@ -206,7 +206,7 @@ describe('Integration tests', function () { schedulerReward: number, workerReward: number, ) { - // Save frozens. + // Save frozens before task execution. const accounts = [requester, scheduler, appProvider, datasetProvider, worker1]; const accountsInitialFrozens = await iexecWrapper.getInitialFrozens(accounts); // Run task. From b2c9e6b48551a79cc92e1388cd3598878234cc0a Mon Sep 17 00:00:00 2001 From: Zied <26070035+zguesmi@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:41:25 +0100 Subject: [PATCH 15/16] Create a new dummy commit to unblock CI --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8c239ef7..f6e2c9932 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ - 000_fullchain-5workers-1error.js (#160, #162) - Clean ToDo (#163) - 200_fullchain-bot.js (#164, #166) - - 201_fullchain-bot-dualPool.js (#171) + - 201_fullchain-bot-dualPool.js (#171). - Fix balance checks in integration tests (#165) - Remove `smock` from unit tests: - IexecEscrow.v8 (#154, #155) From b2cb3a3a282caaee01e8e6377a2b82cb8e2c0abc Mon Sep 17 00:00:00 2001 From: Zied <26070035+zguesmi@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:41:32 +0100 Subject: [PATCH 16/16] Revert "Create a new dummy commit to unblock CI" This reverts commit b2c9e6b48551a79cc92e1388cd3598878234cc0a. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6e2c9932..b8c239ef7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ - 000_fullchain-5workers-1error.js (#160, #162) - Clean ToDo (#163) - 200_fullchain-bot.js (#164, #166) - - 201_fullchain-bot-dualPool.js (#171). + - 201_fullchain-bot-dualPool.js (#171) - Fix balance checks in integration tests (#165) - Remove `smock` from unit tests: - IexecEscrow.v8 (#154, #155)