Closed larskuhtz closed 4 years ago
The failure comes from this code
applyBuyGas =
catchesPactError (buyGas cmd miner) >>= \case
Left e -> fatal $ "tx failure for requestKey when buying gas: " <> sshow e
Right _ -> checkTooBigTx initialGas gasLimit applyPayload redeemAllGas
and fatal
is implemented as follows:
-- | Denotes fatal failure points in the tx exec process
--
fatal :: Text -> TransactionM db a
fatal e = do
l <- view txLogger
rk <- view txRequestKey
liftIO
$! logLog l "ERROR"
$! "critical transaction failure: "
<> sshow rk <> ": " <> T.unpack e
internalError e
It throws PactInternalError
.
The fact that the transaction id rk
is only available in the textual error message indicates that there is no handler that would extract the transaction id and remove it from the mempool.
I wonder if all those exception throw by fatal should be intercepted by an onException that remove the respective tx from the mempool? Or alternatively, all places where this is thrown should call some function that the removes the tx.
When a handler is used the tx id would have to be included as a constructor field (to avoid parsing the textual message).
Yes, I'm adding a constructor to PactException
so that we can badlist the offending tx when we call fatal
. Most of the rest of the work is plumbing
It seems that certain tx can cause
newBlock
to fail but are not removed from the mempool. Instead it seems that they get gossiped around and included in each new block, thus block creation of any new blocks on all nodes.PactInternalException
by callingfatal
is banned from the mempool.Some background: