@@ -185,24 +185,20 @@ func (bk NibiruBankKeeper) ForceGasInvariant(
185185 // Assign vars for the tx gas meter
186186 gasMeterBefore := ctx .GasMeter () // Tx gas meter MUST be defined
187187 gasConsumedBefore := gasMeterBefore .GasConsumed ()
188- // Don't modify the "ctx.BlockGasMeter()" directly because this is
189- // handled in "BaseApp.runTx"
190-
191- // Start baseGasConsumed at 0 in case we panic before BaseOp completes and
192- // baseGasConsumed gets a value assignment
193188 baseOpGasConsumed := uint64 (0 )
194189
195190 defer func () {
191+ // NOTE: we have to refund the entire gasMeterBefore because it's modified by AfterOp
192+ // stateDB.getStateObject() reads from state using the local root ctx which affects the gas meter
196193 gasMeterBefore .RefundGas (gasMeterBefore .GasConsumed (), "" )
197194 gasMeterBefore .ConsumeGas (gasConsumedBefore + baseOpGasConsumed , "NibiruBankKeeper invariant" )
198195 }()
199196
200- // Note that because the ctx gas meter uses private variables to track gas,
201- // we have to branch off with a new gas meter instance to avoid mutating the
202- // "true" gas meter (called GasMeterBefore here).
203- // We use an infinite gas meter because we consume gas in the deferred function
204- // and gasMeterBefore will panic if we consume too much gas.
205- ctx = ctx .WithGasMeter (sdk .NewInfiniteGasMeter ())
197+ // We keep the same gas meter type but reset the gas consumed prior to measuring the base op
198+ // We need the same gas meter type because we use a custom FixedGasMeter for oracle votes in the AnteHandler
199+ // In the defer function, we reset the gas meter again and then add the gasConsumedBefore to baseOpGasConsumed,
200+ // so any modifications to the gasMeterBefore after this point will be inconsequential.
201+ ctx .GasMeter ().RefundGas (gasConsumedBefore , "reset gas meter before measuring base op" )
206202
207203 err := BaseOp (ctx )
208204 baseOpGasConsumed = ctx .GasMeter ().GasConsumed ()
0 commit comments