Skip to content

Commit 550e707

Browse files
Le-CaignecCopilotgfournierProzguesmi
authored
feat: implement dataset compatibility check with a deal in IexecPoco1Facet (#266)
Co-authored-by: Copilot <[email protected]> Co-authored-by: gfournieriExec <[email protected]> Co-authored-by: Zied Guesmi <[email protected]>
1 parent ccfe6e5 commit 550e707

File tree

5 files changed

+307
-27
lines changed

5 files changed

+307
-27
lines changed

contracts/facets/IexecPoco1Facet.sol

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,7 @@ struct Matching {
2626
bool hasDataset;
2727
}
2828

29-
contract IexecPoco1Facet is
30-
IexecPoco1,
31-
FacetBase,
32-
IexecEscrow,
33-
SignatureVerifier,
34-
IexecPocoCommon
35-
{
29+
contract IexecPoco1Facet is IexecPoco1, FacetBase, IexecEscrow, SignatureVerifier, IexecPocoCommon {
3630
using Math for uint256;
3731
using IexecLibOrders_v5 for IexecLibOrders_v5.AppOrder;
3832
using IexecLibOrders_v5 for IexecLibOrders_v5.DatasetOrder;
@@ -65,6 +59,65 @@ contract IexecPoco1Facet is
6559
return _verifySignatureOrPresignature(_identity, _hash, _signature);
6660
}
6761

62+
/**
63+
* @notice Public view function to check if a dataset order is compatible with a deal.
64+
* This function performs all the necessary checks to verify dataset order compatibility with a deal.
65+
*
66+
* @dev This function is mainly consumed by offchain clients. It should be carefully inspected if used inside on-chain code.
67+
* This function should not be used in matchOrders as it does not check the same requirements.
68+
*
69+
* @param datasetOrder The dataset order to verify
70+
* @param dealid The deal ID to check against
71+
* @return true if the dataset order is compatible with the deal, false otherwise
72+
*/
73+
function isDatasetCompatibleWithDeal(
74+
IexecLibOrders_v5.DatasetOrder calldata datasetOrder,
75+
bytes32 dealid
76+
) external view override returns (bool) {
77+
PocoStorageLib.PocoStorage storage $ = PocoStorageLib.getPocoStorage();
78+
// Check if deal exists
79+
IexecLibCore_v5.Deal storage deal = $.m_deals[dealid];
80+
if (deal.requester == address(0)) {
81+
return false;
82+
}
83+
// The specified deal should not have a dataset.
84+
if (deal.dataset.pointer != address(0)) {
85+
return false;
86+
}
87+
// Check dataset order owner signature (including presign and EIP1271)
88+
bytes32 datasetOrderHash = _toTypedDataHash(datasetOrder.hash());
89+
address datasetOwner = IERC5313(datasetOrder.dataset).owner();
90+
if (!_verifySignatureOrPresignature(datasetOwner, datasetOrderHash, datasetOrder.sign)) {
91+
return false;
92+
}
93+
// Check if dataset order is not fully consumed
94+
if ($.m_consumed[datasetOrderHash] >= datasetOrder.volume) {
95+
return false;
96+
}
97+
// Check if deal app is allowed by dataset order apprestrict (including whitelist)
98+
if (!_isAccountAuthorizedByRestriction(datasetOrder.apprestrict, deal.app.pointer)) {
99+
return false;
100+
}
101+
// Check if deal workerpool is allowed by dataset order workerpoolrestrict (including whitelist)
102+
if (
103+
!_isAccountAuthorizedByRestriction(
104+
datasetOrder.workerpoolrestrict,
105+
deal.workerpool.pointer
106+
)
107+
) {
108+
return false;
109+
}
110+
// Check if deal requester is allowed by dataset order requesterrestrict (including whitelist)
111+
if (!_isAccountAuthorizedByRestriction(datasetOrder.requesterrestrict, deal.requester)) {
112+
return false;
113+
}
114+
// Check if deal tag fulfills all the tag bits of the dataset order
115+
if ((deal.tag & datasetOrder.tag) != datasetOrder.tag) {
116+
return false;
117+
}
118+
return true;
119+
}
120+
68121
/***************************************************************************
69122
* ODB order matching *
70123
***************************************************************************/

contracts/interfaces/IexecPoco1.sol

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,9 @@ interface IexecPoco1 {
4646
IexecLibOrders_v5.WorkerpoolOrder calldata,
4747
IexecLibOrders_v5.RequestOrder calldata
4848
) external returns (bytes32);
49+
50+
function isDatasetCompatibleWithDeal(
51+
IexecLibOrders_v5.DatasetOrder calldata datasetOrder,
52+
bytes32 dealid
53+
) external view returns (bool);
4954
}

contracts/interfaces/IexecPoco1.v8.sol

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,9 @@ interface IexecPoco1 {
4040
IexecLibOrders_v5.WorkerpoolOrder calldata,
4141
IexecLibOrders_v5.RequestOrder calldata
4242
) external returns (bytes32);
43+
44+
function isDatasetCompatibleWithDeal(
45+
IexecLibOrders_v5.DatasetOrder calldata datasetOrder,
46+
bytes32 dealid
47+
) external view returns (bool);
4348
}

scripts/upgrades/accessors/deploy-and-update-accessor-facet.ts renamed to scripts/upgrades/deploy-and-update-some-facet.ts

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,21 @@
44
import { ZeroAddress } from 'ethers';
55
import { ethers } from 'hardhat';
66
import { FacetCutAction } from 'hardhat-deploy/dist/types';
7-
import type { IDiamond } from '../../../typechain';
7+
import type { IDiamond } from '../../typechain';
88
import {
99
DiamondCutFacet__factory,
1010
DiamondLoupeFacet__factory,
11+
IexecPoco1Facet__factory,
1112
IexecPocoAccessorsFacet__factory,
12-
} from '../../../typechain';
13-
import { Ownable__factory } from '../../../typechain/factories/rlc-faucet-contract/contracts';
14-
import { FactoryDeployer } from '../../../utils/FactoryDeployer';
15-
import config from '../../../utils/config';
16-
import { linkContractToProxy } from '../../../utils/proxy-tools';
17-
import { printFunctions } from '../upgrade-helper';
13+
} from '../../typechain';
14+
import { Ownable__factory } from '../../typechain/factories/rlc-faucet-contract/contracts';
15+
import { FactoryDeployer } from '../../utils/FactoryDeployer';
16+
import config from '../../utils/config';
17+
import { linkContractToProxy } from '../../utils/proxy-tools';
18+
import { printFunctions } from './upgrade-helper';
1819

1920
(async () => {
20-
console.log('Deploying and updating IexecPocoAccessorsFacet...');
21+
console.log('Deploying and updating IexecPocoAccessorsFacet & IexecPoco1Facet...');
2122

2223
const [account] = await ethers.getSigners();
2324
const chainId = (await ethers.provider.getNetwork()).chainId;
@@ -47,18 +48,25 @@ import { printFunctions } from '../upgrade-helper';
4748
proxyOwnerSigner,
4849
);
4950

50-
console.log('\n=== Step 1: Deploying new IexecPocoAccessorsFacet ===');
51+
console.log('\n=== Step 1: Deploying all new facets ===');
5152
const factoryDeployer = new FactoryDeployer(account, chainId);
5253
const iexecLibOrders = {
5354
['contracts/libs/IexecLibOrders_v5.sol:IexecLibOrders_v5']:
5455
deploymentOptions.IexecLibOrders_v5,
5556
};
5657

57-
const newFacetFactory = new IexecPocoAccessorsFacet__factory(iexecLibOrders);
58-
const newFacetAddress = await factoryDeployer.deployContract(newFacetFactory);
58+
console.log('Deploying new IexecPocoAccessorsFacet...');
59+
const iexecPocoAccessorsFacetFactory = new IexecPocoAccessorsFacet__factory(iexecLibOrders);
60+
const iexecPocoAccessorsFacet = await factoryDeployer.deployContract(
61+
new IexecPocoAccessorsFacet__factory(iexecLibOrders),
62+
);
63+
64+
console.log('Deploying new IexecPoco1Facet...');
65+
const newIexecPoco1FacetFactory = new IexecPoco1Facet__factory(iexecLibOrders);
66+
const newIexecPoco1Facet = await factoryDeployer.deployContract(newIexecPoco1FacetFactory);
5967

6068
console.log(
61-
'\n=== Step 2: Remove old facets (remove all functions of old accessors facets) ===',
69+
'\n=== Step 2: Remove old facets (IexecAccessorsFacet & IexecPocoAccessorsFacet & IexecPoco1Facet) ===',
6270
);
6371

6472
const diamondLoupe = DiamondLoupeFacet__factory.connect(diamondProxyAddress, account);
@@ -99,16 +107,17 @@ import { printFunctions } from '../upgrade-helper';
99107
});
100108
}
101109

102-
const oldAccessorFacets = [
110+
const oldFacets = [
103111
'0xEa232be31ab0112916505Aeb7A2a94b5571DCc6b', //IexecAccessorsFacet
104112
'0xeb40697b275413241d9b31dE568C98B3EA12FFF0', //IexecPocoAccessorsFacet
113+
'0x46b555fE117DFd8D4eAC2470FA2d739c6c3a0152', //IexecPoco1Facet
105114
];
106-
// Remove ALL functions from the old accessor facets using diamondLoupe.facetFunctionSelectors() except of constant founctions
107-
for (const facetAddress of oldAccessorFacets) {
115+
// Remove ALL functions from the old facets using diamondLoupe.facetFunctionSelectors() except of constant founctions
116+
for (const facetAddress of oldFacets) {
108117
const selectors = await diamondLoupe.facetFunctionSelectors(facetAddress);
109118
if (selectors.length > 0) {
110119
console.log(
111-
`Removing old accessor facet ${facetAddress} with ${selectors.length} functions - will remove ALL`,
120+
`Removing old facet ${facetAddress} with ${selectors.length} functions - will remove ALL`,
112121
);
113122
removalCuts.push({
114123
facetAddress: ZeroAddress,
@@ -131,12 +140,23 @@ import { printFunctions } from '../upgrade-helper';
131140
console.log('Diamond functions after removing old facets:');
132141
await printFunctions(diamondProxyAddress);
133142
}
134-
console.log('\n=== Step 3: Updating diamond proxy with new facet ===');
135-
await linkContractToProxy(diamondProxyAsOwner, newFacetAddress, newFacetFactory);
136-
console.log('New functions added successfully');
143+
console.log('\n=== Step 3: Updating diamond proxy with all new facets ===');
144+
console.log('Adding new IexecPocoAccessorsFacet...');
145+
await linkContractToProxy(
146+
diamondProxyAsOwner,
147+
iexecPocoAccessorsFacet,
148+
iexecPocoAccessorsFacetFactory,
149+
);
150+
console.log('New IexecPocoAccessorsFacet added successfully');
151+
152+
console.log('Adding new IexecPoco1Facet ...');
153+
await linkContractToProxy(diamondProxyAsOwner, newIexecPoco1Facet, newIexecPoco1FacetFactory);
154+
console.log('New IexecPoco1Facet with isDatasetCompatibleWithDeal added successfully');
137155

138-
console.log('Diamond functions after adding new facet:');
156+
console.log('Diamond functions after adding new facets:');
139157
await printFunctions(diamondProxyAddress);
140158

141159
console.log('\nUpgrade completed successfully!');
160+
console.log(`New IexecPocoAccessorsFacet deployed at: ${iexecPocoAccessorsFacet}`);
161+
console.log(`New IexecPoco1Facet deployed at: ${newIexecPoco1Facet}`);
142162
})();

0 commit comments

Comments
 (0)