Skip to content

Commit b5f3d16

Browse files
use promise.all to accelerate orders retrieval and add dataMaxPrice & appMaxPrice & workerpoolMaxPrice as parameters
1 parent c7f70ac commit b5f3d16

File tree

3 files changed

+145
-90
lines changed

3 files changed

+145
-90
lines changed

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

Lines changed: 116 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { ethers } from 'ethers';
21
import {
3-
DEFAULT_MAX_PRICE,
2+
MAX_DESIRED_APP_ORDER_PRICE,
3+
MAX_DESIRED_DATA_ORDER_PRICE,
4+
MAX_DESIRED_WORKERPOOL_ORDER_PRICE,
45
SCONE_TAG,
56
WORKERPOOL_ADDRESS,
67
} from '../../config/config.js';
@@ -11,7 +12,7 @@ import {
1112
} from '../../utils/errors.js';
1213
import {
1314
checkUserVoucher,
14-
findWorkerpoolOrders,
15+
filterWorkerpoolOrders,
1516
} from '../../utils/processProtectedData.models.js';
1617
import { pushRequesterSecret } from '../../utils/pushRequesterSecret.js';
1718
import {
@@ -45,7 +46,9 @@ export const processProtectedData = async ({
4546
protectedData,
4647
app,
4748
userWhitelist,
48-
maxPrice = DEFAULT_MAX_PRICE,
49+
dataMaxPrice = MAX_DESIRED_DATA_ORDER_PRICE,
50+
appMaxPrice = MAX_DESIRED_APP_ORDER_PRICE,
51+
workerpoolMaxPrice = MAX_DESIRED_WORKERPOOL_ORDER_PRICE,
4952
path,
5053
args,
5154
inputFiles,
@@ -67,9 +70,15 @@ export const processProtectedData = async ({
6770
const vUserWhitelist = addressSchema()
6871
.label('userWhitelist')
6972
.validateSync(userWhitelist);
70-
const vMaxPrice = positiveNumberSchema()
71-
.label('maxPrice')
72-
.validateSync(maxPrice);
73+
const vDataMaxPrice = positiveNumberSchema()
74+
.label('dataMaxPrice')
75+
.validateSync(dataMaxPrice);
76+
const vAppMaxPrice = positiveNumberSchema()
77+
.label('appMaxPrice')
78+
.validateSync(appMaxPrice);
79+
const vWorkerpoolMaxPrice = positiveNumberSchema()
80+
.label('workerpoolMaxPrice')
81+
.validateSync(workerpoolMaxPrice);
7382
const vPath = stringSchema().label('path').validateSync(path);
7483
const vInputFiles = urlArraySchema()
7584
.label('inputFiles')
@@ -136,76 +145,111 @@ export const processProtectedData = async ({
136145
}
137146

138147
vOnStatusUpdate({
139-
title: 'FETCH_PROTECTED_DATA_ORDERBOOK',
148+
title: 'FETCH_ORDERS',
140149
isDone: false,
141150
});
142-
const datasetOrderbook = await iexec.orderbook.fetchDatasetOrderbook(
143-
vProtectedData,
144-
{
145-
app: vApp,
146-
workerpool: vWorkerpool,
147-
requester,
148-
}
149-
);
150-
const datasetorder = datasetOrderbook.orders[0]?.order; //The first order is the cheapest one
151-
if (!datasetorder) {
152-
throw new Error(`No dataset orders found`);
153-
}
154-
vOnStatusUpdate({
155-
title: 'FETCH_PROTECTED_DATA_ORDERBOOK',
156-
isDone: true,
157-
});
151+
const [
152+
datasetorderForApp,
153+
datasetorderForWhitelist,
154+
apporder,
155+
workerpoolorder,
156+
] = await Promise.all([
157+
// Fetch dataset order
158+
iexec.orderbook
159+
.fetchDatasetOrderbook(vProtectedData, {
160+
app: vApp,
161+
requester: requester,
162+
})
163+
.then((datasetOrderbook) => {
164+
const desiredPriceDataOrderbook = datasetOrderbook.orders.filter(
165+
(order) => order.order.datasetprice <= vDataMaxPrice
166+
);
167+
return desiredPriceDataOrderbook[0]?.order; // may be undefined
168+
}),
169+
// Fetch dataset order for whitelist
170+
iexec.orderbook
171+
.fetchDatasetOrderbook(vProtectedData, {
172+
app: vUserWhitelist,
173+
requester: requester,
174+
})
175+
.then((datasetOrderbook) => {
176+
const desiredPriceDataOrderbook = datasetOrderbook.orders.filter(
177+
(order) => order.order.datasetprice <= vDataMaxPrice
178+
);
179+
return desiredPriceDataOrderbook[0]?.order; // may be undefined
180+
}),
181+
// Fetch app order
182+
iexec.orderbook
183+
.fetchAppOrderbook(vApp, {
184+
minTag: ['tee', 'scone'],
185+
maxTag: ['tee', 'scone'],
186+
workerpool: vWorkerpool,
187+
})
188+
.then((appOrderbook) => {
189+
const desiredPriceAppOrderbook = appOrderbook.orders.filter(
190+
(order) => order.order.appprice <= vAppMaxPrice
191+
);
192+
const desiredPriceAppOrder = desiredPriceAppOrderbook[0]?.order;
193+
if (!desiredPriceAppOrder) {
194+
throw new Error('No App order found for the desired price');
195+
}
196+
return desiredPriceAppOrder;
197+
}),
198+
// Fetch workerpool order for App or AppWhitelist
199+
Promise.all([
200+
// for app
201+
iexec.orderbook.fetchWorkerpoolOrderbook({
202+
workerpool: vWorkerpool,
203+
app: vApp,
204+
dataset: vProtectedData,
205+
requester: requester, // public orders + user specific orders
206+
isRequesterStrict: useVoucher, // If voucher, we only want user specific orders
207+
minTag: ['tee', 'scone'],
208+
maxTag: ['tee', 'scone'],
209+
category: 0,
210+
}),
211+
// for app whitelist
212+
iexec.orderbook.fetchWorkerpoolOrderbook({
213+
workerpool: vWorkerpool,
214+
app: vUserWhitelist,
215+
dataset: vProtectedData,
216+
requester: requester, // public orders + user specific orders
217+
isRequesterStrict: useVoucher, // If voucher, we only want user specific orders
218+
minTag: ['tee', 'scone'],
219+
maxTag: ['tee', 'scone'],
220+
category: 0,
221+
}),
222+
]).then(
223+
([workerpoolOrderbookForApp, workerpoolOrderbookForAppWhitelist]) => {
224+
const desiredPriceWorkerpoolOrder = filterWorkerpoolOrders({
225+
workerpoolOrders: [
226+
...workerpoolOrderbookForApp.orders,
227+
...workerpoolOrderbookForAppWhitelist.orders,
228+
],
229+
workerpoolMaxPrice: vWorkerpoolMaxPrice,
230+
useVoucher: vUseVoucher,
231+
userVoucher,
232+
});
233+
if (!desiredPriceWorkerpoolOrder) {
234+
throw new Error('No Workerpool order found for the desired price');
235+
}
236+
return desiredPriceWorkerpoolOrder;
237+
}
238+
),
239+
]);
158240

159-
vOnStatusUpdate({
160-
title: 'FETCH_APP_ORDERBOOK',
161-
isDone: false,
162-
});
163-
const appOrderbook = await iexec.orderbook.fetchAppOrderbook(vApp, {
164-
dataset: protectedData,
165-
requester,
166-
minTag: SCONE_TAG,
167-
maxTag: SCONE_TAG,
168-
workerpool: vWorkerpool,
169-
});
170-
const apporder = appOrderbook.orders[0]?.order; //The first order is the cheapest one
171-
if (!apporder) {
172-
throw new Error(`No app orders found`);
241+
if (!workerpoolorder) {
242+
throw new Error('No Workerpool order found for the desired price');
173243
}
174-
vOnStatusUpdate({
175-
title: 'FETCH_APP_ORDERBOOK',
176-
isDone: true,
177-
});
178244

179-
vOnStatusUpdate({
180-
title: 'FETCH_WORKERPOOL_ORDERBOOK',
181-
isDone: false,
182-
});
183-
const workerpoolOrderbook = await iexec.orderbook.fetchWorkerpoolOrderbook({
184-
workerpool: vWorkerpool === ethers.ZeroAddress ? 'any' : vWorkerpool, // if address zero was chosen use any workerpool
185-
app: vApp,
186-
dataset: vProtectedData,
187-
requester: requester,
188-
isRequesterStrict:
189-
vVoucherOwner && vVoucherOwner.toLowerCase() !== requester.toLowerCase()
190-
? false
191-
: useVoucher,
192-
minTag: SCONE_TAG,
193-
maxTag: SCONE_TAG,
194-
category: 0,
195-
});
196-
const workerpoolOrder = findWorkerpoolOrders({
197-
workerpoolOrders: [...workerpoolOrderbook.orders],
198-
useVoucher: vUseVoucher,
199-
userVoucher,
200-
});
201-
if (!workerpoolOrder) {
202-
throw new Error('No Workerpool order found.');
245+
const datasetorder = datasetorderForApp || datasetorderForWhitelist;
246+
if (!datasetorder) {
247+
throw new Error('No Dataset order found for the desired price');
203248
}
204249
vOnStatusUpdate({
205-
title: 'FETCH_WORKERPOOL_ORDERBOOK',
250+
title: 'FETCH_ORDERS',
206251
isDone: true,
207252
});
208-
209253
vOnStatusUpdate({
210254
title: 'PUSH_REQUESTER_SECRET',
211255
isDone: false,
@@ -222,13 +266,13 @@ export const processProtectedData = async ({
222266
});
223267
const requestorderToSign = await iexec.order.createRequestorder({
224268
app: vApp,
225-
category: workerpoolOrder.category,
269+
category: workerpoolorder.category,
226270
dataset: vProtectedData,
227271
appmaxprice: apporder.appprice,
228272
datasetmaxprice: datasetorder.datasetprice,
229-
workerpoolmaxprice: workerpoolOrder.workerpoolprice,
273+
workerpoolmaxprice: workerpoolorder.workerpoolprice,
230274
tag: SCONE_TAG,
231-
workerpool: workerpoolOrder.workerpool,
275+
workerpool: workerpoolorder.workerpool,
232276
params: {
233277
iexec_input_files: vInputFiles,
234278
iexec_secrets: secretsId,
@@ -239,7 +283,7 @@ export const processProtectedData = async ({
239283

240284
const orders = {
241285
requestorder,
242-
workerpoolorder: workerpoolOrder,
286+
workerpoolorder: workerpoolorder,
243287
apporder: apporder,
244288
datasetorder: datasetorder,
245289
};
@@ -248,20 +292,6 @@ export const processProtectedData = async ({
248292
...(vVoucherOwner ? { voucherAddress: userVoucher?.address } : {}),
249293
};
250294

251-
const estimatedMatchOrderPrice = await iexec.order.estimateMatchOrders(
252-
orders,
253-
matchOptions
254-
);
255-
if (
256-
estimatedMatchOrderPrice.total
257-
.sub(estimatedMatchOrderPrice.sponsored)
258-
.ltn(vMaxPrice)
259-
) {
260-
throw new Error(
261-
`No orders found within the specified price limit ${vMaxPrice} nRLC.`
262-
);
263-
}
264-
265295
const { dealid, txHash } = await iexec.order.matchOrders(
266296
orders,
267297
matchOptions

packages/sdk/src/lib/types/coreTypes.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ export type TransferResponse = {
276276

277277
// ---------------------ProcessProtectedData Types------------------------------------
278278
export type ProcessProtectedDataStatuses =
279+
| 'FETCH_ORDERS'
279280
| 'FETCH_PROTECTED_DATA_ORDERBOOK'
280281
| 'FETCH_APP_ORDERBOOK'
281282
| 'FETCH_WORKERPOOL_ORDERBOOK'
@@ -302,11 +303,22 @@ export type ProcessProtectedDataParams = {
302303
userWhitelist?: Address;
303304

304305
/**
305-
* The maximum price per task for processing the protected data.
306-
* It is the sum of the application price, dataset price and workerpool price per task.
306+
* The maximum price of dataset per task for processing the protected data.
307307
@default = 0
308308
*/
309-
maxPrice?: number;
309+
dataMaxPrice?: number;
310+
311+
/**
312+
* The maximum price of application per task for processing the protected data.
313+
@default = 0
314+
*/
315+
appMaxPrice?: number;
316+
317+
/**
318+
* The maximum price of workerpool per task for processing the protected data.
319+
@default = 0
320+
*/
321+
workerpoolMaxPrice?: number;
310322

311323
/**
312324
* The file name of the desired file in the returned ZIP file.

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ export function checkUserVoucher({
2424
}
2525
}
2626

27-
export function findWorkerpoolOrders({
27+
export function filterWorkerpoolOrders({
2828
workerpoolOrders,
29+
workerpoolMaxPrice,
2930
useVoucher,
3031
userVoucher,
3132
}: {
3233
workerpoolOrders: PublishedWorkerpoolorder[];
34+
workerpoolMaxPrice: number;
3335
useVoucher: boolean;
3436
userVoucher?: VoucherInfo;
3537
}) {
@@ -38,6 +40,8 @@ export function findWorkerpoolOrders({
3840
}
3941

4042
let eligibleWorkerpoolOrders = workerpoolOrders;
43+
let maxVoucherSponsoredAmount = 0; // may be safer to use bigint
44+
4145
if (useVoucher) {
4246
if (!userVoucher) {
4347
throw new Error(
@@ -53,11 +57,20 @@ export function findWorkerpoolOrders({
5357
'Found some workerpool orders but none can be sponsored by your voucher.'
5458
);
5559
}
60+
maxVoucherSponsoredAmount = bnToNumber(userVoucher.balance);
5661
}
5762

5863
const [cheapestOrder] = eligibleWorkerpoolOrders.sort(
5964
(order1, order2) =>
6065
order1.order.workerpoolprice - order2.order.workerpoolprice
6166
);
67+
68+
if (
69+
!cheapestOrder ||
70+
cheapestOrder.order.workerpoolprice >
71+
workerpoolMaxPrice + maxVoucherSponsoredAmount
72+
) {
73+
return null;
74+
}
6275
return cheapestOrder.order;
6376
}

0 commit comments

Comments
 (0)