Skip to content

Commit

Permalink
Fix broken verifier gassing in Pact 5
Browse files Browse the repository at this point in the history
This is a tricky thing to get right. The tests betrayed that we had it
wrong, but the correct thing to do here was hard to find in the
presence of both saturating unsigned arithmetic (which doesn't seem to
fully work, I got overflow errors when subtraction went below 0) and
milligas/gas conversion/rounding.

Change-Id: Id00000006858d16ed26102355a3fe9b80e6c8b3a
  • Loading branch information
edmundnoble committed Jan 10, 2025
1 parent aff18ad commit f7bea69
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 4 deletions.
15 changes: 13 additions & 2 deletions src/Chainweb/Pact5/TransactionExec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,19 @@ runVerifiers txCtx cmd = do
let verifierGasRemaining = fromIntegral @Int64 @SatWord pact4VerifierGasRemaining
-- NB: this is not nice.
-- TODO: better gas info here
chargeGas noInfo $ GAConstant $ gasToMilliGas $ Gas $
verifierGasRemaining - min (_gas (milliGasToGas initGasRemaining)) verifierGasRemaining
-- Explanation by cases:
-- Case 1:
-- gasToMilliGas verifierGasRemaining is less than initGasRemaining,
-- in which case the verifier charges gas.
-- In that case we can subtract it from initGasRemaining and charge that safely.
-- Case 2:
-- gasToMilliGas verifierGasRemaining is greater than or equal to initGasRemaining,
-- in which case the verifier has not charged gas, or has charged less than
-- rounding error.
-- In that case we do not charge gas at all.
--
when (gasToMilliGas (Gas verifierGasRemaining) < initGasRemaining) $
chargeGas noInfo $ GAConstant $ MilliGas $ coerce initGasRemaining - coerce (gasToMilliGas (Gas verifierGasRemaining))

applyLocal
:: (Logger logger)
Expand Down
4 changes: 2 additions & 2 deletions test/unit/Chainweb/Test/Pact5/TransactionExecTest.hs
Original file line number Diff line number Diff line change
Expand Up @@ -534,12 +534,12 @@ applyCmdVerifierSpec rdb = readFromAfterGenesis v rdb $
[ P.fun _crEvents ? P.list
[ event
(P.equals "TRANSFER")
(P.equals [PString "sender00", PString "NoMiner", PDecimal 162])
(P.equals [PString "sender00", PString "NoMiner", PDecimal 362])
(P.equals coinModuleName)
]
, P.fun _crResult ? P.equals ? PactResultOk (PInteger 1)
-- reflects buyGas gas usage, as well as that of the payload
, P.fun _crGas ? P.equals ? Gas 81
, P.fun _crGas ? P.equals ? Gas 181
, P.fun _crContinuation ? P.equals ? Nothing
, P.fun _crMetaData ? P.equals ? Nothing
]
Expand Down

0 comments on commit f7bea69

Please sign in to comment.