Skip to content

getActivePieces runs out of gas with high offsets due to O(n) loop from index 0 #243

@nijoe1

Description

@nijoe1

Summary

The getActivePieces function becomes unusable at higher offsets because the loop always starts from i = 0, causing gas costs to scale linearly with offset.

Reproduction

Contract: 0xBADd0B92C1c71d02E7d520f64c0876538fa2557F

Dataset: setId = 64 (60,000+ pieces on Filecoin mainnet)

Call Result
getActivePieces(64, 10000, 100) ✅ Works
getActivePieces(64, 12000, 100) ❌ OutOfGas

Root Cause

for (uint256 i = 0; i < maxPieceId; i++) {  // Always starts from 0
    if (pieceLeafCounts[setId][i] > 0) {
        if (activeCount >= offset && resultIndex < limit) {
            // collect
        }
        activeCount++;
    }
}

With offset 12,000, the function performs ~12,000+ cold storage reads just to reach the starting point.

Suggested Fix

Switch from offset-based to cursor-based pagination using startPieceId:

function getActivePieces(uint256 setId, uint256 startPieceId, uint256 limit)

Callers use the last returned pieceId as startPieceId for the next page, making pagination O(limit) instead of O(offset).

cc: @rvagg @BigLep @rjan90

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

Status

🎉 Done

Status

🎉 Done

Relationships

None yet

Development

No branches or pull requests

Issue actions