Skip to content

Commit 7d77dc9

Browse files
authored
feat(SPRegistry): pick SP with lowest pendingBytes instead of committedBytes (#41)
1 parent 7456835 commit 7d77dc9

File tree

3 files changed

+18
-15
lines changed

3 files changed

+18
-15
lines changed

src/SPRegistry.sol

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ contract SPRegistry is Initializable, AccessControlUpgradeable, UUPSUpgradeable,
384384

385385
/**
386386
* @notice Find a provider matching requirements and reserve pending capacity
387-
* @dev Selects the least-committed eligible provider. Reserves `pendingBytes` atomically
387+
* @dev Selects the least-pending eligible provider. Reserves `pendingBytes` atomically
388388
* so capacity is held between matching and commitment.
389389
* Returns FilActorId(0) if no provider matches.
390390
* @param requirements SLI thresholds the client needs
@@ -401,7 +401,7 @@ contract SPRegistry is Initializable, AccessControlUpgradeable, UUPSUpgradeable,
401401
uint256 length = $._providerIds.length();
402402

403403
CommonTypes.FilActorId bestProvider;
404-
uint256 lowestCommitted = type(uint256).max;
404+
uint256 lowestPending = type(uint256).max;
405405
uint256 bestProviderPrice;
406406

407407
for (uint256 i = 0; i < length; i++) {
@@ -418,11 +418,11 @@ contract SPRegistry is Initializable, AccessControlUpgradeable, UUPSUpgradeable,
418418

419419
if (!_meetsRequirements(p.capabilities, requirements)) continue;
420420

421-
if (p.committedBytes < lowestCommitted) {
422-
lowestCommitted = p.committedBytes;
421+
if (p.pendingBytes < lowestPending) {
422+
lowestPending = p.pendingBytes;
423423
bestProvider = CommonTypes.FilActorId.wrap(id);
424424
bestProviderPrice = p.pricePerSectorPerMonth;
425-
if (lowestCommitted == 0) break;
425+
if (lowestPending == 0) break;
426426
}
427427
}
428428

src/interfaces/ISPRegistry.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ interface ISPRegistry {
5757

5858
/**
5959
* @notice Find a provider matching requirements and reserve pending capacity
60-
* @dev Selects the least-committed eligible provider. Reserves `pendingBytes` atomically
60+
* @dev Selects the least-pending eligible provider. Reserves `pendingBytes` atomically
6161
* so capacity is held between matching and commitment.
6262
* Returns FilActorId(0) if no provider matches.
6363
* @param requirements SLI thresholds the client needs

test/SPRegistry.t.sol

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -744,21 +744,24 @@ contract SPRegistryTest is Test {
744744
assertEq(CommonTypes.FilActorId.unwrap(result), 0);
745745
}
746746

747-
function testGetProviderForDealPicksLeastCommitted() public {
747+
function testGetProviderForDealPicksLeastPending() public {
748748
vm.startPrank(adminAddress);
749749
spRegistry.registerProviderFor(provider1, owner1, defaultCapabilities, defaultAvailableBytes, 0, address(0));
750750
spRegistry.registerProviderFor(provider2, owner2, defaultCapabilities, defaultAvailableBytes, 0, address(0));
751751
vm.stopPrank();
752752

753-
// Commit some capacity to provider1 so provider2 has less committed
754-
vm.prank(poRepMarketAddress);
755-
spRegistry.commitCapacity(provider1, 5000, 5000);
756-
757753
SLITypes.SLIThresholds memory req =
758754
SLITypes.SLIThresholds({retrievabilityBps: 8000, bandwidthMbps: 500, latencyMs: 200, indexingPct: 50});
755+
756+
// First call routes to provider1 (insertion order tiebreak), giving it pending bytes
759757
vm.prank(poRepMarketAddress);
760-
(CommonTypes.FilActorId result,) = spRegistry.getProviderForDeal(req, defaultTerms);
761-
assertEq(CommonTypes.FilActorId.unwrap(result), CommonTypes.FilActorId.unwrap(provider2));
758+
(CommonTypes.FilActorId first,) = spRegistry.getProviderForDeal(req, defaultTerms);
759+
assertEq(CommonTypes.FilActorId.unwrap(first), CommonTypes.FilActorId.unwrap(provider1));
760+
761+
// Second call must route to provider2 — it has 0 pending vs provider1's dealSizeBytes
762+
vm.prank(poRepMarketAddress);
763+
(CommonTypes.FilActorId second,) = spRegistry.getProviderForDeal(req, defaultTerms);
764+
assertEq(CommonTypes.FilActorId.unwrap(second), CommonTypes.FilActorId.unwrap(provider2));
762765
}
763766

764767
function testGetProviderForDealZeroRequirementSkipsDimension() public {
@@ -920,7 +923,7 @@ contract SPRegistryTest is Test {
920923
spRegistry.releaseCapacity(provider1, 1000);
921924
}
922925

923-
function testGetProviderForDealTiebreakEqualCommitted() public {
926+
function testGetProviderForDealTiebreakEqualPending() public {
924927
vm.startPrank(adminAddress);
925928
spRegistry.registerProviderFor(provider1, owner1, defaultCapabilities, defaultAvailableBytes, 0, address(0));
926929
spRegistry.registerProviderFor(provider2, owner2, defaultCapabilities, defaultAvailableBytes, 0, address(0));
@@ -931,7 +934,7 @@ contract SPRegistryTest is Test {
931934
vm.prank(poRepMarketAddress);
932935
(CommonTypes.FilActorId result,) = spRegistry.getProviderForDeal(req, defaultTerms);
933936

934-
// Both have 0 committed bytes; first registered wins (EnumerableSet insertion order)
937+
// Both have 0 pending bytes; first registered wins (EnumerableSet insertion order)
935938
assertEq(CommonTypes.FilActorId.unwrap(result), CommonTypes.FilActorId.unwrap(provider1));
936939
}
937940

0 commit comments

Comments
 (0)