Skip to content

Commit 5701658

Browse files
authored
perf: Optimize withCDN Metadata Key (#271)
Reviewers @rvagg @ZenGround0 We only check for the withCDN key We only use deleteMetadataKey to update storage metadata keys. This reduces codesize 24,533 -> 24,336 (-197). #### Changes * rename methods to deleteCDNMetadataKey and hasCDNMetadataKey and remove their key parameters * precompute withCDN hash and strlen * deleteCDNMetadataKey operates on storage * delete key by removing from the end of the list rather than by shifting * avoid duplicate find by returning found from deleteCDNMetadataKey * compare storage string to "withCDN" with inline assembly (`WITH_CDN_STRING_STORAGE_REPR`)
1 parent 1a71505 commit 5701658

File tree

1 file changed

+33
-48
lines changed

1 file changed

+33
-48
lines changed

service_contracts/src/FilecoinWarmStorageService.sol

Lines changed: 33 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@ contract FilecoinWarmStorageService is
177177

178178
// Metadata key constants
179179
string private constant METADATA_KEY_WITH_CDN = "withCDN";
180+
uint256 private constant METADATA_KEY_WITH_CDN_SIZE = 7;
181+
bytes32 private constant METADATA_KEY_WITH_CDN_HASH = keccak256("withCDN");
182+
// solidity storage representation of string "withCDN"
183+
bytes32 private constant WITH_CDN_STRING_STORAGE_REPR =
184+
0x7769746843444e0000000000000000000000000000000000000000000000000e;
180185

181186
// Pricing constants
182187
uint256 private immutable STORAGE_PRICE_PER_TIB_PER_MONTH; // 5 USDFC per TiB per month without CDN with correct decimals
@@ -608,7 +613,7 @@ contract FilecoinWarmStorageService is
608613
uint256 cacheMissRailId = 0;
609614
uint256 cdnRailId = 0;
610615

611-
if (hasMetadataKey(createData.metadataKeys, METADATA_KEY_WITH_CDN)) {
616+
if (hasCDNMetadataKey(createData.metadataKeys)) {
612617
cacheMissRailId = payments.createRail(
613618
usdfcTokenAddress, // token address
614619
createData.payer, // from (payer)
@@ -694,7 +699,7 @@ contract FilecoinWarmStorageService is
694699

695700
// Clean up rail mappings
696701
delete railToDataSet[info.pdpRailId];
697-
if (hasMetadataKey(dataSetMetadataKeys[dataSetId], METADATA_KEY_WITH_CDN)) {
702+
if (hasCDNMetadataKey(dataSetMetadataKeys[dataSetId])) {
698703
delete railToDataSet[info.cacheMissRailId];
699704
delete railToDataSet[info.cdnRailId];
700705
}
@@ -994,12 +999,11 @@ contract FilecoinWarmStorageService is
994999

9951000
payments.terminateRail(info.pdpRailId);
9961001

997-
if (hasMetadataKey(dataSetMetadataKeys[dataSetId], METADATA_KEY_WITH_CDN)) {
1002+
if (deleteCDNMetadataKey(dataSetMetadataKeys[dataSetId])) {
9981003
payments.terminateRail(info.cacheMissRailId);
9991004
payments.terminateRail(info.cdnRailId);
10001005

10011006
// Delete withCDN flag from metadata to prevent further CDN operations
1002-
dataSetMetadataKeys[dataSetId] = deleteMetadataKey(dataSetMetadataKeys[dataSetId], METADATA_KEY_WITH_CDN);
10031007
delete dataSetMetadata[dataSetId][METADATA_KEY_WITH_CDN];
10041008

10051009
emit CDNServiceTerminated(msg.sender, dataSetId, info.cacheMissRailId, info.cdnRailId);
@@ -1050,10 +1054,7 @@ contract FilecoinWarmStorageService is
10501054
require(msg.sender == info.payer, Errors.CallerNotPayer(dataSetId, info.payer, msg.sender));
10511055

10521056
// Check if CDN service is configured
1053-
require(
1054-
hasMetadataKey(dataSetMetadataKeys[dataSetId], METADATA_KEY_WITH_CDN),
1055-
Errors.FilBeamServiceNotConfigured(dataSetId)
1056-
);
1057+
require(hasCDNMetadataKey(dataSetMetadataKeys[dataSetId]), Errors.FilBeamServiceNotConfigured(dataSetId));
10571058

10581059
// Check if cache miss and CDN rails are configured
10591060
require(info.cacheMissRailId != 0 && info.cdnRailId != 0, Errors.InvalidDataSetId(dataSetId));
@@ -1085,10 +1086,7 @@ contract FilecoinWarmStorageService is
10851086

10861087
function terminateCDNService(uint256 dataSetId) external onlyFilBeamController {
10871088
// Check if CDN service is configured
1088-
require(
1089-
hasMetadataKey(dataSetMetadataKeys[dataSetId], METADATA_KEY_WITH_CDN),
1090-
Errors.FilBeamServiceNotConfigured(dataSetId)
1091-
);
1089+
require(deleteCDNMetadataKey(dataSetMetadataKeys[dataSetId]), Errors.FilBeamServiceNotConfigured(dataSetId));
10921090

10931091
// Check if cache miss and CDN rails are configured
10941092
DataSetInfo storage info = dataSetInfo[dataSetId];
@@ -1099,7 +1097,6 @@ contract FilecoinWarmStorageService is
10991097
payments.terminateRail(info.cdnRailId);
11001098

11011099
// Delete withCDN flag from metadata to prevent further CDN operations
1102-
dataSetMetadataKeys[dataSetId] = deleteMetadataKey(dataSetMetadataKeys[dataSetId], METADATA_KEY_WITH_CDN);
11031100
delete dataSetMetadata[dataSetId][METADATA_KEY_WITH_CDN];
11041101

11051102
emit CDNServiceTerminated(msg.sender, dataSetId, info.cacheMissRailId, info.cdnRailId);
@@ -1147,7 +1144,7 @@ contract FilecoinWarmStorageService is
11471144
emit RailRateUpdated(dataSetId, pdpRailId, newStorageRatePerEpoch);
11481145

11491146
// Update the CDN rail payment rates, if applicable
1150-
if (hasMetadataKey(dataSetMetadataKeys[dataSetId], METADATA_KEY_WITH_CDN)) {
1147+
if (hasCDNMetadataKey(dataSetMetadataKeys[dataSetId])) {
11511148
(uint256 newCacheMissRatePerEpoch, uint256 newCDNRatePerEpoch) = _calculateCDNRates(totalBytes);
11521149

11531150
uint256 cacheMissRailId = dataSetInfo[dataSetId].cacheMissRailId;
@@ -1308,19 +1305,17 @@ contract FilecoinWarmStorageService is
13081305
}
13091306

13101307
/**
1311-
* @notice Returns true if `key` exists in `metadataKeys`.
1308+
* @notice Returns true if key `withCDN` exists in `metadataKeys`.
13121309
* @param metadataKeys The array of metadata keys
1313-
* @param key The metadata key to look up
13141310
* @return True if key exists; false otherwise.
13151311
*/
1316-
function hasMetadataKey(string[] memory metadataKeys, string memory key) internal pure returns (bool) {
1317-
bytes memory keyBytes = bytes(key);
1318-
uint256 keyLength = keyBytes.length;
1319-
bytes32 keyHash = keccak256(keyBytes);
1320-
1312+
function hasCDNMetadataKey(string[] memory metadataKeys) internal pure returns (bool) {
13211313
for (uint256 i = 0; i < metadataKeys.length; i++) {
13221314
bytes memory currentKeyBytes = bytes(metadataKeys[i]);
1323-
if (currentKeyBytes.length == keyLength && keccak256(currentKeyBytes) == keyHash) {
1315+
if (
1316+
currentKeyBytes.length == METADATA_KEY_WITH_CDN_SIZE
1317+
&& keccak256(currentKeyBytes) == METADATA_KEY_WITH_CDN_HASH
1318+
) {
13241319
return true;
13251320
}
13261321
}
@@ -1330,37 +1325,27 @@ contract FilecoinWarmStorageService is
13301325
}
13311326

13321327
/**
1333-
* @notice Deletes `key` if it exists in `metadataKeys`.
1334-
* @param metadataKeys The array of metadata keys
1335-
* @param key The metadata key to delete
1336-
* @return Modified array of metadata keys
1328+
* @notice Deletes key `withCDN` if it exists in `metadataKeys`.
1329+
* @param metadataKeys The array of metadata keys to modify
1330+
* @return found Whether the withCDN key was deleted
13371331
*/
1338-
function deleteMetadataKey(string[] memory metadataKeys, string memory key)
1339-
internal
1340-
pure
1341-
returns (string[] memory)
1342-
{
1343-
bytes memory keyBytes = bytes(key);
1344-
uint256 keyLength = keyBytes.length;
1345-
bytes32 keyHash = keccak256(keyBytes);
1346-
1347-
uint256 len = metadataKeys.length;
1348-
for (uint256 i = 0; i < len; i++) {
1349-
bytes memory currentKeyBytes = bytes(metadataKeys[i]);
1350-
if (currentKeyBytes.length == keyLength && keccak256(currentKeyBytes) == keyHash) {
1351-
// Shift elements left to fill the gap
1352-
for (uint256 j = i; j < len - 1; j++) {
1353-
metadataKeys[j] = metadataKeys[j + 1];
1332+
function deleteCDNMetadataKey(string[] storage metadataKeys) internal returns (bool found) {
1333+
unchecked {
1334+
uint256 len = metadataKeys.length;
1335+
for (uint256 i = 0; i < len; i++) {
1336+
string storage metadataKey = metadataKeys[i];
1337+
bytes32 repr;
1338+
assembly ("memory-safe") {
1339+
repr := sload(metadataKey.slot)
13541340
}
1355-
1356-
delete metadataKeys[len - 1];
1357-
assembly {
1358-
mstore(metadataKeys, sub(len, 1))
1341+
if (repr == WITH_CDN_STRING_STORAGE_REPR) {
1342+
metadataKey = metadataKeys[len - 1];
1343+
metadataKeys.pop();
1344+
return true;
13591345
}
1360-
break;
13611346
}
13621347
}
1363-
return metadataKeys;
1348+
return false;
13641349
}
13651350

13661351
/**

0 commit comments

Comments
 (0)