Эх сурвалжийг харах

feat(entropy): Add gas tracking for the callback recovery flow (#2666)

* log gas usage

* track gas usage in the recovery flow
Jayant Krishnamurthy 6 сар өмнө
parent
commit
89b1f2a11e

+ 23 - 18
target_chains/ethereum/contracts/contracts/entropy/Entropy.sol

@@ -669,31 +669,18 @@ abstract contract Entropy is IEntropy, EntropyState {
             }
         } else {
             // This case uses the checks-effects-interactions pattern to avoid reentry attacks
-            emit RevealedWithCallback(
-                EntropyStructConverter.toV1Request(req),
-                userRandomNumber,
-                providerRevelation,
-                randomNumber
-            );
-            emit EntropyEventsV2.Revealed(
-                provider,
-                req.requester,
-                req.sequenceNumber,
-                randomNumber,
-                false,
-                bytes(""),
-                0, // gas usage not tracked in the old no-gas-limit flow.
-                bytes("")
-            );
-
+            address callAddress = req.requester;
+            EntropyStructs.Request memory reqV1 = EntropyStructConverter
+                .toV1Request(req);
             clearRequest(provider, sequenceNumber);
+            // WARNING: DO NOT USE req BELOW HERE AS ITS CONTENTS HAS BEEN CLEARED
 
             // Check if the requester is a contract account.
             uint len;
-            address callAddress = req.requester;
             assembly {
                 len := extcodesize(callAddress)
             }
+            uint256 startingGas = gasleft();
             if (len != 0) {
                 IEntropyConsumer(callAddress)._entropyCallback(
                     sequenceNumber,
@@ -701,6 +688,24 @@ abstract contract Entropy is IEntropy, EntropyState {
                     randomNumber
                 );
             }
+            uint32 gasUsed = SafeCast.toUint32(startingGas - gasleft());
+
+            emit RevealedWithCallback(
+                reqV1,
+                userRandomNumber,
+                providerRevelation,
+                randomNumber
+            );
+            emit EntropyEventsV2.Revealed(
+                provider,
+                callAddress,
+                sequenceNumber,
+                randomNumber,
+                false,
+                bytes(""),
+                gasUsed,
+                bytes("")
+            );
         }
     }
 

+ 4 - 13
target_chains/ethereum/contracts/forge-test/Entropy.t.sol

@@ -1778,7 +1778,6 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents, EntropyEventsV2 {
         // can never cause a callback to fail because it runs out of gas.
         vm.prank(provider1);
         random.setDefaultGasLimit(0);
-
         assertCallbackResult(0, 190000, true);
         assertCallbackResult(0, 210000, true);
         assertCallbackResult(300000, 290000, true);
@@ -1864,8 +1863,7 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents, EntropyEventsV2 {
             assertEq(callbackFailed, true);
             assertEq(callbackErrorCode, bytes(""));
 
-            // callback gas usage is approximate and only triggered when the provider has set a gas limit.
-            // Note: this condition is somewhat janky, but we hit the stack limit so can't put in any more local variables :(
+            // callback gas usage is approximate
             assertTrue(
                 random.getProviderInfoV2(provider1).defaultGasLimit == 0 ||
                     ((callbackGasUsage * 90) / 100 < callbackGasUsed)
@@ -1941,16 +1939,9 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents, EntropyEventsV2 {
             );
             assertEq(callbackFailed, false);
             assertEq(callbackErrorCode, bytes(""));
-            // callback gas usage is approximate and only triggered when the provider has set a gas limit
-            // Note: this condition is somewhat janky, but we hit the stack limit so can't put in any more local variables :(
-            assertTrue(
-                random.getProviderInfoV2(provider1).defaultGasLimit == 0 ||
-                    ((callbackGasUsage * 90) / 100 < callbackGasUsed)
-            );
-            assertTrue(
-                random.getProviderInfoV2(provider1).defaultGasLimit == 0 ||
-                    (callbackGasUsed < (callbackGasUsage * 110) / 100)
-            );
+            // callback gas usage is approximate
+            assertTrue((callbackGasUsage * 90) / 100 < callbackGasUsed);
+            assertTrue(callbackGasUsed < (callbackGasUsage * 110) / 100);
             assertEq(extraArgs, bytes(""));
 
             // Verify request is cleared after successful callback