Skip to content

Commit 89b1f2a

Browse files
authored
feat(entropy): Add gas tracking for the callback recovery flow (#2666)
* log gas usage * track gas usage in the recovery flow
1 parent 0ce6061 commit 89b1f2a

File tree

2 files changed

+27
-31
lines changed

2 files changed

+27
-31
lines changed

target_chains/ethereum/contracts/contracts/entropy/Entropy.sol

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -669,38 +669,43 @@ abstract contract Entropy is IEntropy, EntropyState {
669669
}
670670
} else {
671671
// This case uses the checks-effects-interactions pattern to avoid reentry attacks
672-
emit RevealedWithCallback(
673-
EntropyStructConverter.toV1Request(req),
674-
userRandomNumber,
675-
providerRevelation,
676-
randomNumber
677-
);
678-
emit EntropyEventsV2.Revealed(
679-
provider,
680-
req.requester,
681-
req.sequenceNumber,
682-
randomNumber,
683-
false,
684-
bytes(""),
685-
0, // gas usage not tracked in the old no-gas-limit flow.
686-
bytes("")
687-
);
688-
672+
address callAddress = req.requester;
673+
EntropyStructs.Request memory reqV1 = EntropyStructConverter
674+
.toV1Request(req);
689675
clearRequest(provider, sequenceNumber);
676+
// WARNING: DO NOT USE req BELOW HERE AS ITS CONTENTS HAS BEEN CLEARED
690677

691678
// Check if the requester is a contract account.
692679
uint len;
693-
address callAddress = req.requester;
694680
assembly {
695681
len := extcodesize(callAddress)
696682
}
683+
uint256 startingGas = gasleft();
697684
if (len != 0) {
698685
IEntropyConsumer(callAddress)._entropyCallback(
699686
sequenceNumber,
700687
provider,
701688
randomNumber
702689
);
703690
}
691+
uint32 gasUsed = SafeCast.toUint32(startingGas - gasleft());
692+
693+
emit RevealedWithCallback(
694+
reqV1,
695+
userRandomNumber,
696+
providerRevelation,
697+
randomNumber
698+
);
699+
emit EntropyEventsV2.Revealed(
700+
provider,
701+
callAddress,
702+
sequenceNumber,
703+
randomNumber,
704+
false,
705+
bytes(""),
706+
gasUsed,
707+
bytes("")
708+
);
704709
}
705710
}
706711

target_chains/ethereum/contracts/forge-test/Entropy.t.sol

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1778,7 +1778,6 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents, EntropyEventsV2 {
17781778
// can never cause a callback to fail because it runs out of gas.
17791779
vm.prank(provider1);
17801780
random.setDefaultGasLimit(0);
1781-
17821781
assertCallbackResult(0, 190000, true);
17831782
assertCallbackResult(0, 210000, true);
17841783
assertCallbackResult(300000, 290000, true);
@@ -1864,8 +1863,7 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents, EntropyEventsV2 {
18641863
assertEq(callbackFailed, true);
18651864
assertEq(callbackErrorCode, bytes(""));
18661865

1867-
// callback gas usage is approximate and only triggered when the provider has set a gas limit.
1868-
// Note: this condition is somewhat janky, but we hit the stack limit so can't put in any more local variables :(
1866+
// callback gas usage is approximate
18691867
assertTrue(
18701868
random.getProviderInfoV2(provider1).defaultGasLimit == 0 ||
18711869
((callbackGasUsage * 90) / 100 < callbackGasUsed)
@@ -1941,16 +1939,9 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents, EntropyEventsV2 {
19411939
);
19421940
assertEq(callbackFailed, false);
19431941
assertEq(callbackErrorCode, bytes(""));
1944-
// callback gas usage is approximate and only triggered when the provider has set a gas limit
1945-
// Note: this condition is somewhat janky, but we hit the stack limit so can't put in any more local variables :(
1946-
assertTrue(
1947-
random.getProviderInfoV2(provider1).defaultGasLimit == 0 ||
1948-
((callbackGasUsage * 90) / 100 < callbackGasUsed)
1949-
);
1950-
assertTrue(
1951-
random.getProviderInfoV2(provider1).defaultGasLimit == 0 ||
1952-
(callbackGasUsed < (callbackGasUsage * 110) / 100)
1953-
);
1942+
// callback gas usage is approximate
1943+
assertTrue((callbackGasUsage * 90) / 100 < callbackGasUsed);
1944+
assertTrue(callbackGasUsed < (callbackGasUsage * 110) / 100);
19541945
assertEq(extraArgs, bytes(""));
19551946

19561947
// Verify request is cleared after successful callback

0 commit comments

Comments
 (0)