Skip to content

Commit 6460d36

Browse files
feature/fix-processProtectedData-price-handling (#422)
Co-authored-by: Pierre Jeanjacquot <[email protected]>
1 parent 4a9f66d commit 6460d36

File tree

8 files changed

+79
-167
lines changed

8 files changed

+79
-167
lines changed

packages/sdk/package-lock.json

Lines changed: 13 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/sdk/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
"@ethersproject/random": "^5.7.0",
5757
"@multiformats/multiaddr": "^12.1.3",
5858
"@typechain/ethers-v6": "^0.5.1",
59+
"@types/bn.js": "^5.1.6",
5960
"borsh": "^2.0.0",
6061
"debug": "^4.3.4",
6162
"ethers": "^6.13.2",
@@ -75,6 +76,7 @@
7576
"@types/jest": "^29.5.12",
7677
"@typescript-eslint/eslint-plugin": "^6.7.5",
7778
"@typescript-eslint/parser": "^6.7.5",
79+
"bn.js": "^5.2.1",
7880
"eslint": "^8.51.0",
7981
"eslint-config-airbnb-typescript": "^17.1.0",
8082
"eslint-config-prettier": "^9.0.0",

packages/sdk/src/lib/dataProtectorCore/processProtectedData.ts

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ import {
99
processProtectedDataErrorMessage,
1010
handleIfProtocolError,
1111
} from '../../utils/errors.js';
12-
import { fetchOrdersUnderMaxPrice } from '../../utils/fetchOrdersUnderMaxPrice.js';
12+
import {
13+
checkUserVoucher,
14+
findWorkerpoolOrders,
15+
} from '../../utils/processProtectedData.models.js';
1316
import { pushRequesterSecret } from '../../utils/pushRequesterSecret.js';
1417
import {
1518
addressOrEnsSchema,
@@ -23,7 +26,6 @@ import {
2326
validateOnStatusUpdateCallback,
2427
} from '../../utils/validators.js';
2528
import { isERC734 } from '../../utils/whitelist.js';
26-
import { getResultFromCompletedTask } from './getResultFromCompletedTask.js';
2729
import {
2830
MatchOptions,
2931
OnStatusUpdateFn,
@@ -32,12 +34,9 @@ import {
3234
ProcessProtectedDataStatuses,
3335
} from '../types/index.js';
3436
import { IExecConsumer } from '../types/internalTypes.js';
37+
import { getResultFromCompletedTask } from './getResultFromCompletedTask.js';
3538
import { getWhitelistContract } from './smartContract/getWhitelistContract.js';
3639
import { isAddressInWhitelist } from './smartContract/whitelistContract.read.js';
37-
import {
38-
checkUserVoucher,
39-
filterWorkerpoolOrders,
40-
} from '../../utils/processProtectedData.models.js';
4140

4241
export type ProcessProtectedData = typeof processProtectedData;
4342

@@ -146,6 +145,10 @@ export const processProtectedData = async ({
146145
requester,
147146
}
148147
);
148+
const datasetorder = datasetOrderbook.orders[0]?.order; //The first order is the cheapest one
149+
if (!datasetorder) {
150+
throw new Error(`No dataset orders found`);
151+
}
149152
vOnStatusUpdate({
150153
title: 'FETCH_PROTECTED_DATA_ORDERBOOK',
151154
isDone: true,
@@ -162,6 +165,10 @@ export const processProtectedData = async ({
162165
maxTag: SCONE_TAG,
163166
workerpool: vWorkerpool,
164167
});
168+
const apporder = appOrderbook.orders[0]?.order; //The first order is the cheapest one
169+
if (!apporder) {
170+
throw new Error(`No app orders found`);
171+
}
165172
vOnStatusUpdate({
166173
title: 'FETCH_APP_ORDERBOOK',
167174
isDone: true,
@@ -181,24 +188,18 @@ export const processProtectedData = async ({
181188
maxTag: SCONE_TAG,
182189
category: 0,
183190
});
184-
vOnStatusUpdate({
185-
title: 'FETCH_WORKERPOOL_ORDERBOOK',
186-
isDone: true,
187-
});
188-
const desiredPriceWorkerpoolOrder = filterWorkerpoolOrders({
191+
const workerpoolOrder = findWorkerpoolOrders({
189192
workerpoolOrders: [...workerpoolOrderbook.orders],
190193
useVoucher: vUseVoucher,
191194
userVoucher,
192195
});
193-
if (!desiredPriceWorkerpoolOrder) {
196+
if (!workerpoolOrder) {
194197
throw new Error('No Workerpool order found.');
195198
}
196-
197-
const underMaxPriceOrders = fetchOrdersUnderMaxPrice(
198-
datasetOrderbook,
199-
appOrderbook,
200-
vMaxPrice
201-
);
199+
vOnStatusUpdate({
200+
title: 'FETCH_WORKERPOOL_ORDERBOOK',
201+
isDone: true,
202+
});
202203

203204
vOnStatusUpdate({
204205
title: 'PUSH_REQUESTER_SECRET',
@@ -216,30 +217,48 @@ export const processProtectedData = async ({
216217
});
217218
const requestorderToSign = await iexec.order.createRequestorder({
218219
app: vApp,
219-
category: desiredPriceWorkerpoolOrder.category,
220+
category: workerpoolOrder.category,
220221
dataset: vProtectedData,
221-
appmaxprice: underMaxPriceOrders.apporder.appprice,
222-
datasetmaxprice: underMaxPriceOrders.datasetorder.datasetprice,
223-
workerpoolmaxprice: desiredPriceWorkerpoolOrder.workerpoolprice,
222+
appmaxprice: apporder.appprice,
223+
datasetmaxprice: datasetorder.datasetprice,
224+
workerpoolmaxprice: workerpoolOrder.workerpoolprice,
224225
tag: SCONE_TAG,
225-
workerpool: desiredPriceWorkerpoolOrder.workerpool,
226+
workerpool: workerpoolOrder.workerpool,
226227
params: {
227228
iexec_input_files: vInputFiles,
228229
iexec_secrets: secretsId,
229230
iexec_args: vArgs,
230231
},
231232
});
232233
const requestorder = await iexec.order.signRequestorder(requestorderToSign);
234+
235+
const orders = {
236+
requestorder,
237+
workerpoolorder: workerpoolOrder,
238+
apporder: apporder,
239+
datasetorder: datasetorder,
240+
};
233241
const matchOptions: MatchOptions = {
234242
useVoucher: vUseVoucher,
235243
...(vVoucherAddress ? { voucherAddress: vVoucherAddress } : {}),
236244
};
245+
246+
const estimatedMatchOrderPrice = await iexec.order.estimateMatchOrders(
247+
orders,
248+
matchOptions
249+
);
250+
if (
251+
estimatedMatchOrderPrice.total
252+
.sub(estimatedMatchOrderPrice.sponsored)
253+
.ltn(vMaxPrice)
254+
) {
255+
throw new Error(
256+
`No orders found within the specified price limit ${vMaxPrice} nRLC.`
257+
);
258+
}
259+
237260
const { dealid, txHash } = await iexec.order.matchOrders(
238-
{
239-
requestorder,
240-
workerpoolorder: desiredPriceWorkerpoolOrder,
241-
...underMaxPriceOrders,
242-
},
261+
orders,
243262
matchOptions
244263
);
245264
const taskId = await iexec.deal.computeTaskId(dealid, 0);

packages/sdk/src/utils/fetchOrdersUnderMaxPrice.ts

Lines changed: 0 additions & 34 deletions
This file was deleted.

packages/sdk/src/utils/processProtectedData.models.ts

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export function checkUserVoucher({
3636
}
3737
}
3838

39-
export function filterWorkerpoolOrders({
39+
export function findWorkerpoolOrders({
4040
workerpoolOrders,
4141
useVoucher,
4242
userVoucher,
@@ -49,9 +49,7 @@ export function filterWorkerpoolOrders({
4949
return null;
5050
}
5151

52-
let eligibleWorkerpoolOrders = [...workerpoolOrders];
53-
let maxVoucherSponsoredAmount = 0; // may be safer to use bigint
54-
52+
let eligibleWorkerpoolOrders = workerpoolOrders;
5553
if (useVoucher) {
5654
if (!userVoucher) {
5755
throw new Error(
@@ -67,19 +65,11 @@ export function filterWorkerpoolOrders({
6765
'Found some workerpool orders but none can be sponsored by your voucher.'
6866
);
6967
}
70-
maxVoucherSponsoredAmount = bnToNumber(userVoucher.balance);
7168
}
7269

7370
const [cheapestOrder] = eligibleWorkerpoolOrders.sort(
7471
(order1, order2) =>
7572
order1.order.workerpoolprice - order2.order.workerpoolprice
7673
);
77-
78-
if (
79-
!cheapestOrder ||
80-
cheapestOrder.order.workerpoolprice > maxVoucherSponsoredAmount
81-
) {
82-
return null;
83-
}
8474
return cheapestOrder.order;
8575
}

packages/sdk/tests/unit/dataProtectorCore/processProtectedData/fetchOrdersUnderMaxPrice.test.ts

Lines changed: 0 additions & 89 deletions
This file was deleted.

packages/sdk/tests/unit/dataProtectorCore/processProtectedData/processProtectedData.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jest.unstable_mockModule(
4040
jest.unstable_mockModule(
4141
'../../../../src/utils/processProtectedData.models.js',
4242
() => ({
43-
filterWorkerpoolOrders: jest.fn(
43+
findWorkerpoolOrders: jest.fn(
4444
() => mockWorkerpoolOrderbook.orders[0].order
4545
),
4646
checkUserVoucher: jest.fn(),
@@ -524,11 +524,11 @@ describe('processProtectedData', () => {
524524

525525
describe('When there is NO workerpool orders', () => {
526526
it('should throw a WorkflowError with the correct message', async () => {
527-
const { filterWorkerpoolOrders } = await import(
527+
const { findWorkerpoolOrders } = await import(
528528
'../../../../src/utils/processProtectedData.models.js'
529529
);
530530

531-
(filterWorkerpoolOrders as jest.Mock).mockReturnValue(null);
531+
(findWorkerpoolOrders as jest.Mock).mockReturnValue(null);
532532
// --- GIVEN
533533
const iexec = {
534534
wallet: {

0 commit comments

Comments
 (0)