Skip to content

Commit 8afeda1

Browse files
perf(ServiceProviderRegistry): getProviderPayee helper for dataSetCreated (#249)
## Description Implements a helper function to fetch only the payee address for service providers, reducing the access footprint of `CreateDataSet`. ## Problem Currently, `FilecoinWarmStorageService.dataSetCreated()` calls `getProvider(providerId)` which reads the entire `ServiceProviderInfo` struct from storage, including expensive string fields (`name` and `description`), when only the `payee` address is needed. ## Solution - **Added `getProviderPayee(uint256 providerId)`** in `ServiceProviderRegistry.sol` - Returns only the payee address directly from storage - Uses `providerExists` modifier for safety - **Updated `FilecoinWarmStorageService.sol`** - Replaced `getProvider()` call with `getProviderPayee()` in `dataSetCreated()` - Eliminates intermediate struct creation and string reads - **Added unit tests** - `testGetProviderPayeeReturnsCorrectAddress()` - verifies correct payee returned - `testGetProviderPayeeRevertsForInvalidProviderId()` - verifies revert behavior Fixes #248
1 parent aa82318 commit 8afeda1

File tree

4 files changed

+78
-3
lines changed

4 files changed

+78
-3
lines changed

service_contracts/abi/ServiceProviderRegistry.abi.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,25 @@
824824
],
825825
"stateMutability": "view"
826826
},
827+
{
828+
"type": "function",
829+
"name": "getProviderPayee",
830+
"inputs": [
831+
{
832+
"name": "providerId",
833+
"type": "uint256",
834+
"internalType": "uint256"
835+
}
836+
],
837+
"outputs": [
838+
{
839+
"name": "payee",
840+
"type": "address",
841+
"internalType": "address"
842+
}
843+
],
844+
"stateMutability": "view"
845+
},
827846
{
828847
"type": "function",
829848
"name": "getProvidersByProductType",

service_contracts/src/FilecoinWarmStorageService.sol

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -489,9 +489,7 @@ contract FilecoinWarmStorageService is
489489
// Check if provider is approved
490490
require(approvedProviders[providerId], Errors.ProviderNotApproved(serviceProvider, providerId));
491491

492-
ServiceProviderRegistry.ServiceProviderInfoView memory providerInfo =
493-
serviceProviderRegistry.getProvider(providerId);
494-
address payee = providerInfo.info.payee;
492+
address payee = serviceProviderRegistry.getProviderPayee(providerId);
495493

496494
uint256 clientDataSetId = clientDataSetIds[createData.payer]++;
497495
clientDataSets[createData.payer].push(dataSetId);

service_contracts/src/ServiceProviderRegistry.sol

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,13 @@ contract ServiceProviderRegistry is
484484
return ServiceProviderInfoView({providerId: providerId, info: provider});
485485
}
486486

487+
/// @notice Get only the payee address for a provider
488+
/// @param providerId The ID of the provider
489+
/// @return payee The payee address
490+
function getProviderPayee(uint256 providerId) external view providerExists(providerId) returns (address payee) {
491+
return providers[providerId].payee;
492+
}
493+
487494
/// @notice Get product data for a specific product type
488495
/// @param providerId The ID of the provider
489496
/// @param productType The type of product to retrieve

service_contracts/test/ServiceProviderRegistry.t.sol

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,4 +308,55 @@ contract ServiceProviderRegistryTest is Test {
308308
registry.transferOwnership(user1);
309309
assertEq(registry.owner(), user1, "Service provider should be transferred");
310310
}
311+
312+
function testGetProviderPayeeReturnsCorrectAddress() public {
313+
// Give user1 some ETH for registration fee
314+
vm.deal(user1, 10 ether);
315+
316+
// Prepare PDP data
317+
ServiceProviderRegistryStorage.PDPOffering memory pdpData = ServiceProviderRegistryStorage.PDPOffering({
318+
serviceURL: "https://example.com",
319+
minPieceSizeInBytes: 1024,
320+
maxPieceSizeInBytes: 1024 * 1024,
321+
ipniPiece: true,
322+
ipniIpfs: false,
323+
storagePricePerTibPerMonth: 500000000000000000, // 0.5 FIL per TiB per month
324+
minProvingPeriodInEpochs: 2880,
325+
location: "US-East",
326+
paymentTokenAddress: IERC20(address(0)) // Payment in FIL
327+
});
328+
329+
// Encode PDP data
330+
bytes memory encodedData = abi.encode(pdpData);
331+
332+
// Empty capability arrays
333+
string[] memory emptyKeys = new string[](0);
334+
string[] memory emptyValues = new string[](0);
335+
336+
// Register provider with user2 as payee
337+
vm.prank(user1);
338+
uint256 providerId = registry.registerProvider{value: 5 ether}(
339+
user2,
340+
"Provider One",
341+
"Test provider description",
342+
ServiceProviderRegistryStorage.ProductType.PDP,
343+
encodedData,
344+
emptyKeys,
345+
emptyValues
346+
);
347+
348+
// Verify helper returns the payee address
349+
address payee = registry.getProviderPayee(providerId);
350+
assertEq(payee, user2, "getProviderPayee should return the registered payee");
351+
}
352+
353+
function testGetProviderPayeeRevertsForInvalidProviderId() public {
354+
// 0 is invalid provider ID; expect revert due to providerExists modifier
355+
vm.expectRevert("Provider does not exist");
356+
registry.getProviderPayee(0);
357+
358+
// Non-existent but non-zero ID should also revert
359+
vm.expectRevert("Provider does not exist");
360+
registry.getProviderPayee(1);
361+
}
311362
}

0 commit comments

Comments
 (0)