Skip to content

Conversation

wjmelements
Copy link
Collaborator

Reviewer @aarshkshah1992
Solidity memory arrays cannot increase in size once allocated, but it safe to truncate them.
Because memory gas is quadratic, the cost of this copy grows quickly with the size of the array.
By truncating the array we can avoid the copy step.

Changes

  • replace array copy with array truncation

Test plan

  • verified that without truncation at least one test fails

@wjmelements wjmelements changed the title View: Remove Copy View: Truncate instead of Copy Jul 28, 2025
@wjmelements
Copy link
Collaborator Author

This change's diff to the .gas-snapshot, using #193:

diff --git a/.gas-snapshot b/.gas-snapshot
index 7ec0148..bd1394b 100644
--- a/.gas-snapshot
+++ b/.gas-snapshot
@@ -58,9 +58,9 @@ DepositWithPermitAndOperatorApproval:testDepositWithPermitAndOperatorApproval_Mu
 DepositWithPermitAndOperatorApproval:testDepositWithPermitAndOperatorApproval_ZeroAmount() (gas: 314923)
 ERC1967ProxyTest:testInitialSetup() (gas: 21033)
 ERC1967ProxyTest:testOwnershipTransfer() (gas: 39095)
-ERC1967ProxyTest:testUpgradeImplementation() (gas: 7603080)
+ERC1967ProxyTest:testUpgradeImplementation() (gas: 7576386)
 ERC1967ProxyTest:test_RevertWhen_TransferFromNonOwner() (gas: 37166)
-ERC1967ProxyTest:test_RevertWhen_UpgradeFromNonOwner() (gas: 7600044)
+ERC1967ProxyTest:test_RevertWhen_UpgradeFromNonOwner() (gas: 7573350)
 FeeOnTransferVulnerabilityTest:testFeeOnTransferVulnerabilityBasic() (gas: 189206)
 FeeOnTransferVulnerabilityTest:testFeeOnTransferWithDepositWithPermit() (gas: 247245)
 FeeOnTransferVulnerabilityTest:testFeeOnTransferWithDepositWithPermitAndApproveOperator() (gas: 365288)
@@ -94,10 +94,10 @@ OperatorApprovalUsageLeakTest:testOperatorLockupUsageLeakOnRailFinalization() (g
 PayeeFaultArbitrationBugTest:testLockupReturnedWithFault() (gas: 910072)
 PayeeFaultArbitrationBugTest:testLockupReturnedWithFaultReducedDuration() (gas: 2059695)
 PayeeFaultArbitrationBugTest:testLockupReturnedWithFaultTermination() (gas: 888076)
-PayeeRailsTest:testEmptyResult() (gas: 57771)
-PayeeRailsTest:testGetRailsForPayeeAndToken() (gas: 149980)
-PayeeRailsTest:testGetRailsForPayerAndToken() (gas: 146086)
-PayeeRailsTest:testRailsBeyondEndEpoch() (gas: 346932)
+PayeeRailsTest:testEmptyResult() (gas: 55199)
+PayeeRailsTest:testGetRailsForPayeeAndToken() (gas: 142479)
+PayeeRailsTest:testGetRailsForPayerAndToken() (gas: 139457)
+PayeeRailsTest:testRailsBeyondEndEpoch() (gas: 331722)
 PaymentsEventsTest:testAccountLockupSettledEvent() (gas: 615226)
 PaymentsEventsTest:testDepositRecordedEvent() (gas: 317742)
 PaymentsEventsTest:testOperatorApprovalUpdatedEvent() (gas: 128062)

It's a small improvement for small arrays but it would be larger for large arrays. There is a also a small reduction in codesize.

While these view methods are unlikely to be used during execution, if their gas usage is too large, eth_call node RPC could revert with out-of-gas. This is also a reason to avoid unbounded looping, even in view methods.

@wjmelements
Copy link
Collaborator Author

wjmelements commented Jul 29, 2025

memory gas is quadratic

I'm not sure that this is the case for Filecoin but I still think this is a good change.

For Ethereum, here is the gas savings by number of results:

Results Savings
0 643
300 310600
600 654079
900 1031309
1200 1442287
1500 1887016
1800 2365495
2100 2877724

Copy link
Contributor

@rvagg rvagg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

@wjmelements wjmelements merged commit 47e807a into FilOzone:main Jul 29, 2025
3 checks passed
@github-project-automation github-project-automation bot moved this to 🎉 Done in Payments Jul 29, 2025
@aarshkshah1992
Copy link
Contributor

Learnt something new here ! Thanks @wjmelements

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 🎉 Done

Development

Successfully merging this pull request may close these issues.

3 participants