Skip to content

Commit d02ce06

Browse files
committed
refactor: update isDatasetCompatibleWithDeal function to return detailed results
1 parent 14f454e commit d02ce06

File tree

4 files changed

+96
-131
lines changed

4 files changed

+96
-131
lines changed

contracts/facets/IexecPoco1Facet.sol

Lines changed: 32 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -57,99 +57,55 @@ contract IexecPoco1Facet is IexecPoco1, FacetBase, IexecEscrow, SignatureVerifie
5757
*
5858
* @param datasetOrder The dataset order to verify
5959
* @param dealid The deal ID to check against
60-
* @return true if the dataset order is compatible with the deal, false otherwise
60+
* @return result true if the dataset order is compatible with the deal, false otherwise
61+
* @return reason the specific reason why the compatibility check failed, empty string if successful
6162
*/
6263
function isDatasetCompatibleWithDeal(
6364
IexecLibOrders_v5.DatasetOrder calldata datasetOrder,
6465
bytes32 dealid
65-
) external view override returns (bool) {
66+
) external view override returns (bool result, string memory reason) {
6667
PocoStorageLib.PocoStorage storage $ = PocoStorageLib.getPocoStorage();
67-
68-
// Track status of all checks
69-
bool dealExists;
70-
bool dealHasNoDataset;
71-
bool signatureValid;
72-
bool notFullyConsumed;
73-
bool appRestrictionValid;
74-
bool workerpoolRestrictionValid;
75-
bool requesterRestrictionValid;
76-
bool tagCompatible;
77-
7868
// Check if deal exists
7969
IexecLibCore_v5.Deal storage deal = $.m_deals[dealid];
80-
dealExists = (deal.requester != address(0));
81-
70+
if (deal.requester == address(0)) {
71+
return (false, "Deal does not exist");
72+
}
8273
// The specified deal should not have a dataset.
83-
dealHasNoDataset = (deal.dataset.pointer == address(0));
84-
74+
if (deal.dataset.pointer != address(0)) {
75+
return (false, "Deal already has a dataset");
76+
}
8577
// Check dataset order owner signature (including presign and EIP1271)
8678
bytes32 datasetOrderHash = _toTypedDataHash(datasetOrder.hash());
8779
address datasetOwner = IERC5313(datasetOrder.dataset).owner();
88-
signatureValid = _verifySignatureOrPresignature(
89-
datasetOwner,
90-
datasetOrderHash,
91-
datasetOrder.sign
92-
);
93-
80+
if (!_verifySignatureOrPresignature(datasetOwner, datasetOrderHash, datasetOrder.sign)) {
81+
return (false, "Invalid dataset order signature");
82+
}
9483
// Check if dataset order is not fully consumed
95-
notFullyConsumed = ($.m_consumed[datasetOrderHash] < datasetOrder.volume);
96-
84+
if ($.m_consumed[datasetOrderHash] >= datasetOrder.volume) {
85+
return (false, "Dataset order is fully consumed");
86+
}
9787
// Check if deal app is allowed by dataset order apprestrict (including whitelist)
98-
appRestrictionValid = _isAccountAuthorizedByRestriction(
99-
datasetOrder.apprestrict,
100-
deal.app.pointer
101-
);
102-
88+
if (!_isAccountAuthorizedByRestriction(datasetOrder.apprestrict, deal.app.pointer)) {
89+
return (false, "App restriction not satisfied");
90+
}
10391
// Check if deal workerpool is allowed by dataset order workerpoolrestrict (including whitelist)
104-
workerpoolRestrictionValid = _isAccountAuthorizedByRestriction(
105-
datasetOrder.workerpoolrestrict,
106-
deal.workerpool.pointer
107-
);
108-
92+
if (
93+
!_isAccountAuthorizedByRestriction(
94+
datasetOrder.workerpoolrestrict,
95+
deal.workerpool.pointer
96+
)
97+
) {
98+
return (false, "Workerpool restriction not satisfied");
99+
}
109100
// Check if deal requester is allowed by dataset order requesterrestrict (including whitelist)
110-
requesterRestrictionValid = _isAccountAuthorizedByRestriction(
111-
datasetOrder.requesterrestrict,
112-
deal.requester
113-
);
114-
101+
if (!_isAccountAuthorizedByRestriction(datasetOrder.requesterrestrict, deal.requester)) {
102+
return (false, "Requester restriction not satisfied");
103+
}
115104
// Check if deal tag fulfills all the tag bits of the dataset order
116-
tagCompatible = ((deal.tag & datasetOrder.tag) == datasetOrder.tag);
117-
118-
// Check if all conditions are met
119-
bool allChecksPassed = dealExists &&
120-
dealHasNoDataset &&
121-
signatureValid &&
122-
notFullyConsumed &&
123-
appRestrictionValid &&
124-
workerpoolRestrictionValid &&
125-
requesterRestrictionValid &&
126-
tagCompatible;
127-
128-
if (!allChecksPassed) {
129-
string memory status = string(
130-
abi.encodePacked(
131-
"DatasetCompatibilityCheck: ",
132-
dealExists ? "1" : "0",
133-
"-",
134-
dealHasNoDataset ? "1" : "0",
135-
"-",
136-
signatureValid ? "1" : "0",
137-
"-",
138-
notFullyConsumed ? "1" : "0",
139-
"-",
140-
appRestrictionValid ? "1" : "0",
141-
"-",
142-
workerpoolRestrictionValid ? "1" : "0",
143-
"-",
144-
requesterRestrictionValid ? "1" : "0",
145-
"-",
146-
tagCompatible ? "1" : "0"
147-
)
148-
);
149-
revert(status);
105+
if ((deal.tag & datasetOrder.tag) != datasetOrder.tag) {
106+
return (false, "Tag compatibility not satisfied");
150107
}
151-
152-
return true;
108+
return (true, "");
153109
}
154110

155111
/***************************************************************************

contracts/interfaces/IexecPoco1.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,5 @@ interface IexecPoco1 {
5050
function isDatasetCompatibleWithDeal(
5151
IexecLibOrders_v5.DatasetOrder calldata datasetOrder,
5252
bytes32 dealid
53-
) external view returns (bool);
53+
) external view returns (bool result, string memory reason);
5454
}

contracts/interfaces/IexecPoco1.v8.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,5 @@ interface IexecPoco1 {
5555
function isDatasetCompatibleWithDeal(
5656
IexecLibOrders_v5.DatasetOrder calldata datasetOrder,
5757
bytes32 dealid
58-
) external view returns (bool);
58+
) external view returns (bool result, string memory reason);
5959
}

test/byContract/IexecPoco/IexecPoco1.test.ts

Lines changed: 62 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,22 +1112,25 @@ describe('IexecPoco1', () => {
11121112
});
11131113

11141114
it('Should return true for compatible dataset order', async () => {
1115-
expect(
1116-
await iexecPoco.isDatasetCompatibleWithDeal(
1117-
compatibleDatasetOrder,
1118-
dealIdWithoutDataset,
1119-
),
1120-
).to.be.true;
1115+
const [result, reason] = await iexecPoco.isDatasetCompatibleWithDeal(
1116+
compatibleDatasetOrder,
1117+
dealIdWithoutDataset,
1118+
);
1119+
expect(result).to.be.true;
1120+
expect(reason).to.equal('');
11211121
});
11221122

1123-
it('Should revert with status for non-existent deal', async () => {
1123+
it('Should return false with reason for non-existent deal', async () => {
11241124
const nonExistentDealId = ethers.keccak256(ethers.toUtf8Bytes('non-existent-deal'));
1125-
await expect(
1126-
iexecPoco.isDatasetCompatibleWithDeal(compatibleDatasetOrder, nonExistentDealId),
1127-
).to.be.revertedWith('DatasetCompatibilityCheck: 0-1-1-1-0-0-0-0');
1125+
const [result, reason] = await iexecPoco.isDatasetCompatibleWithDeal(
1126+
compatibleDatasetOrder,
1127+
nonExistentDealId,
1128+
);
1129+
expect(result).to.be.false;
1130+
expect(reason).to.equal('Deal does not exist');
11281131
});
11291132

1130-
it('Should revert with status for deal with a dataset', async () => {
1133+
it('Should return false with reason for deal with a dataset', async () => {
11311134
// Use the original orders that include a dataset to create a deal with dataset
11321135
const ordersWithDataset = buildOrders({
11331136
assets: ordersAssets, // This includes the dataset
@@ -1157,56 +1160,62 @@ describe('IexecPoco1', () => {
11571160
);
11581161
await iexecPocoAsRequester.matchOrders(...ordersWithDataset.toArray());
11591162

1160-
await expect(
1161-
iexecPoco.isDatasetCompatibleWithDeal(compatibleDatasetOrder, dealIdWithDataset),
1162-
).to.be.revertedWith('DatasetCompatibilityCheck: 1-0-1-1-1-1-1-1');
1163+
const [result, reason] = await iexecPoco.isDatasetCompatibleWithDeal(
1164+
compatibleDatasetOrder,
1165+
dealIdWithDataset,
1166+
);
1167+
expect(result).to.be.false;
1168+
expect(reason).to.equal('Deal already has a dataset');
11631169
});
11641170

1165-
it('Should revert with status for dataset order with invalid signature', async () => {
1171+
it('Should return false with reason for dataset order with invalid signature', async () => {
11661172
// Create dataset order with invalid signature
11671173
const invalidSignatureDatasetOrder = {
11681174
...compatibleDatasetOrder,
11691175
sign: randomSignature, // Invalid signature
11701176
};
11711177

1172-
await expect(
1173-
iexecPoco.isDatasetCompatibleWithDeal(
1174-
invalidSignatureDatasetOrder,
1175-
dealIdWithoutDataset,
1176-
),
1177-
).to.be.revertedWith('DatasetCompatibilityCheck: 1-1-0-1-1-1-1-1');
1178+
const [result, reason] = await iexecPoco.isDatasetCompatibleWithDeal(
1179+
invalidSignatureDatasetOrder,
1180+
dealIdWithoutDataset,
1181+
);
1182+
expect(result).to.be.false;
1183+
expect(reason).to.equal('Invalid dataset order signature');
11781184
});
11791185

1180-
it('Should revert with status for fully consumed dataset order', async () => {
1186+
it('Should return false with reason for fully consumed dataset order', async () => {
11811187
// Create dataset order with volume 0 (fully consumed)
11821188
const consumedDatasetOrder = {
11831189
...compatibleDatasetOrder,
11841190
volume: 0n,
11851191
};
11861192
await signOrder(iexecWrapper.getDomain(), consumedDatasetOrder, datasetProvider);
11871193

1188-
await expect(
1189-
iexecPoco.isDatasetCompatibleWithDeal(consumedDatasetOrder, dealIdWithoutDataset),
1190-
).to.be.revertedWith('DatasetCompatibilityCheck: 1-1-1-0-1-1-1-1');
1194+
const [result, reason] = await iexecPoco.isDatasetCompatibleWithDeal(
1195+
consumedDatasetOrder,
1196+
dealIdWithoutDataset,
1197+
);
1198+
expect(result).to.be.false;
1199+
expect(reason).to.equal('Dataset order is fully consumed');
11911200
});
11921201

1193-
it('Should revert with status for dataset order with incompatible app restriction', async () => {
1202+
it('Should return false with reason for dataset order with incompatible app restriction', async () => {
11941203
// Create dataset order with incompatible app restriction
11951204
const incompatibleAppDatasetOrder = {
11961205
...compatibleDatasetOrder,
11971206
apprestrict: randomAddress, // Different app restriction
11981207
};
11991208
await signOrder(iexecWrapper.getDomain(), incompatibleAppDatasetOrder, datasetProvider);
12001209

1201-
await expect(
1202-
iexecPoco.isDatasetCompatibleWithDeal(
1203-
incompatibleAppDatasetOrder,
1204-
dealIdWithoutDataset,
1205-
),
1206-
).to.be.revertedWith('DatasetCompatibilityCheck: 1-1-1-1-0-1-1-1');
1210+
const [result, reason] = await iexecPoco.isDatasetCompatibleWithDeal(
1211+
incompatibleAppDatasetOrder,
1212+
dealIdWithoutDataset,
1213+
);
1214+
expect(result).to.be.false;
1215+
expect(reason).to.equal('App restriction not satisfied');
12071216
});
12081217

1209-
it('Should revert with status for dataset order with incompatible workerpool restriction', async () => {
1218+
it('Should return false with reason for dataset order with incompatible workerpool restriction', async () => {
12101219
// Create dataset order with incompatible workerpool restriction
12111220
const incompatibleWorkerpoolDatasetOrder = {
12121221
...compatibleDatasetOrder,
@@ -1218,15 +1227,15 @@ describe('IexecPoco1', () => {
12181227
datasetProvider,
12191228
);
12201229

1221-
await expect(
1222-
iexecPoco.isDatasetCompatibleWithDeal(
1223-
incompatibleWorkerpoolDatasetOrder,
1224-
dealIdWithoutDataset,
1225-
),
1226-
).to.be.revertedWith('DatasetCompatibilityCheck: 1-1-1-1-1-0-1-1');
1230+
const [result, reason] = await iexecPoco.isDatasetCompatibleWithDeal(
1231+
incompatibleWorkerpoolDatasetOrder,
1232+
dealIdWithoutDataset,
1233+
);
1234+
expect(result).to.be.false;
1235+
expect(reason).to.equal('Workerpool restriction not satisfied');
12271236
});
12281237

1229-
it('Should revert with status for dataset order with incompatible requester restriction', async () => {
1238+
it('Should return false with reason for dataset order with incompatible requester restriction', async () => {
12301239
// Create dataset order with incompatible requester restriction
12311240
const incompatibleRequesterDatasetOrder = {
12321241
...compatibleDatasetOrder,
@@ -1238,28 +1247,28 @@ describe('IexecPoco1', () => {
12381247
datasetProvider,
12391248
);
12401249

1241-
await expect(
1242-
iexecPoco.isDatasetCompatibleWithDeal(
1243-
incompatibleRequesterDatasetOrder,
1244-
dealIdWithoutDataset,
1245-
),
1246-
).to.be.revertedWith('DatasetCompatibilityCheck: 1-1-1-1-1-1-0-1');
1250+
const [result, reason] = await iexecPoco.isDatasetCompatibleWithDeal(
1251+
incompatibleRequesterDatasetOrder,
1252+
dealIdWithoutDataset,
1253+
);
1254+
expect(result).to.be.false;
1255+
expect(reason).to.equal('Requester restriction not satisfied');
12471256
});
12481257

1249-
it('Should revert with status for dataset order with incompatible tag', async () => {
1258+
it('Should return false with reason for dataset order with incompatible tag', async () => {
12501259
// Create dataset order with incompatible tag
12511260
const incompatibleTagDatasetOrder = {
12521261
...compatibleDatasetOrder,
12531262
tag: '0x0000000000000000000000000000000000000000000000000000000000000002', // Different tag
12541263
};
12551264
await signOrder(iexecWrapper.getDomain(), incompatibleTagDatasetOrder, datasetProvider);
12561265

1257-
await expect(
1258-
iexecPoco.isDatasetCompatibleWithDeal(
1259-
incompatibleTagDatasetOrder,
1260-
dealIdWithoutDataset,
1261-
),
1262-
).to.be.revertedWith('DatasetCompatibilityCheck: 1-1-1-1-1-1-1-0');
1266+
const [result, reason] = await iexecPoco.isDatasetCompatibleWithDeal(
1267+
incompatibleTagDatasetOrder,
1268+
dealIdWithoutDataset,
1269+
);
1270+
expect(result).to.be.false;
1271+
expect(reason).to.equal('Tag compatibility not satisfied');
12631272
});
12641273
});
12651274

0 commit comments

Comments
 (0)