Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Much quieter replays #1713

Merged
merged 13 commits into from
Aug 3, 2023
1 change: 0 additions & 1 deletion src/Chainweb/Chainweb.hs
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,6 @@ withChainwebInternal conf logger peer serviceSock rocksDb pactDbDir backupDir re
pactConfig maxGasLimit = PactServiceConfig
{ _pactReorgLimit = _configReorgLimit conf
, _pactLocalRewindDepthLimit = _configLocalRewindDepthLimit conf
, _pactRevalidate = True
, _pactQueueSize = _configPactQueueSize conf
, _pactResetDb = resetDb
, _pactAllowReadsInLocal = _configAllowReadsInLocal conf
Expand Down
2 changes: 1 addition & 1 deletion src/Chainweb/Pact/PactService.hs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ withPactService ver cid chainwebLogger bhDb pdb sqlenv config act =
, _psLocalRewindDepthLimit = _pactLocalRewindDepthLimit config
, _psOnFatalError = defaultOnFatalError (logFunctionText chainwebLogger)
, _psVersion = ver
, _psValidateHashesOnReplay = _pactRevalidate config
, _psReplaying = False
, _psAllowReadsInLocal = _pactAllowReadsInLocal config
, _psIsBatch = False
, _psCheckpointerDepth = 0
Expand Down
7 changes: 3 additions & 4 deletions src/Chainweb/Pact/PactService/Checkpointer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -400,8 +400,7 @@ rewindTo rewindLimit (Just (ParentHeader parent)) = do
withAsync (heightProgress (_blockHeight commonAncestor) heightRef (logInfo_ logger)) $ \_ ->
s
& S.scanM
-- no need to re-validate hashes, because these blocks have already been validated
(\ !p !c -> runPact (local (psValidateHashesOnReplay .~ False) $ fastForward (ParentHeader p, c)) >> writeIORef heightRef (_blockHeight c) >> return c)
(\ !p !c -> runPact (fastForward (ParentHeader p, c)) >> writeIORef heightRef (_blockHeight c) >> return c)
(return h) -- initial parent
return
& S.length_
Expand All @@ -416,7 +415,7 @@ fastForward
. (HasCallStack, CanReadablePayloadCas tbl, Logger logger)
=> (ParentHeader, BlockHeader)
-> PactServiceM logger tbl ()
fastForward (target, block) =
fastForward (target, block) = do
-- This does a restore, i.e. it rewinds the checkpointer back in
-- history, if needed.
withCheckpointerWithoutRewind (Just target) "fastForward" $ \pdbenv -> do
Expand Down Expand Up @@ -609,7 +608,7 @@ rewindToIncremental rewindLimit (Just (ParentHeader parent)) = do
-- transactions (withBatchIO).
let playChunk :: IORef BlockHeight -> BlockHeader -> Stream (Of BlockHeader) IO r -> IO (Of BlockHeader r)
playChunk heightRef cur s = withBatchIO runPact $ \runPactLocal -> S.foldM
(\c x -> x <$ (runPactLocal (fastForward (ParentHeader c, x)) >> writeIORef heightRef (_blockHeight c)))
(\c x -> x <$ (runPactLocal (local (psReplaying .~ True) $ fastForward (ParentHeader c, x)) >> writeIORef heightRef (_blockHeight c)))
(return cur)
return
s
Expand Down
22 changes: 16 additions & 6 deletions src/Chainweb/Pact/PactService/ExecBlock.hs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import Data.Vector (Vector)
import qualified Data.Vector as V

import System.IO
import qualified System.Logger as L
import System.Timeout

import Prelude hiding (lookup)
Expand Down Expand Up @@ -151,8 +152,9 @@ execBlock currHeader plData pdbenv = do

modify' $ set psStateValidated $ Just currHeader

-- Validate hashes if requested
asks _psValidateHashesOnReplay >>= \x -> when x $
-- Validate hashes if not doing a replay. no need to re-validate hashes
-- during a replay, because these blocks have already been validated
view psReplaying >>= \x -> unless x $
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this correct? During replay we need to compare the payload hash from the pact validation with the payload hash that is stored in the block header.

I guess the best would be to always check. IIRC it means to do one additional rocksdb lookup (which most likely is cached already). During replay we have to do it anyways. And in normal consensus operation the overhead would be minimal. So, it should be fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm probably just confused here. I'll just make it always check.

either throwM (void . return) $!
validateHashes currHeader plData miner results

Expand Down Expand Up @@ -347,7 +349,6 @@ runCoinbase
-> PactServiceM logger tbl (P.CommandResult [P.TxLogJson])
runCoinbase True _ _ _ _ _ = return noCoinbase
runCoinbase False dbEnv miner enfCBFail usePrecomp mc = do
logger <- view psLogger
rs <- view psMinerRewards
v <- view chainwebVersion
txCtx <- getTxContext def
Expand All @@ -357,7 +358,8 @@ runCoinbase False dbEnv miner enfCBFail usePrecomp mc = do
reward <- liftIO $! minerReward v rs bh

(T2 cr upgradedCacheM) <-
liftIO $! applyCoinbase v logger dbEnv miner reward txCtx enfCBFail usePrecomp mc
withSilentLoggerForReplays $ \logger ->
liftIO $ applyCoinbase v logger dbEnv miner reward txCtx enfCBFail usePrecomp mc
mapM_ upgradeInitCache upgradedCacheM
debugResult "runCoinbase" (P.crLogs %~ fmap J.Array $ cr)
return $! cr
Expand Down Expand Up @@ -388,6 +390,14 @@ applyPactCmds isGenesis env cmds miner mc blockGas txTimeLimit = do
evalStateT (V.mapM (applyPactCmd isGenesis env miner txTimeLimit) cmds) (T2 mc blockGas)
return txs

-- we don't want pact tx failure or unknown exception messages when we're doing a replay.
withSilentLoggerForReplays :: Logger logger => (logger -> PactServiceM logger tbl a) -> PactServiceM logger tbl a
withSilentLoggerForReplays f = do
replaying <- view psReplaying
logger <- view psLogger
if replaying then L.withLoggerLevel L.Error logger f
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is too broad. This would also suppress unrelated legitimate warnings logs -- assuming that those could exist.

Copy link
Contributor Author

@edmundnoble edmundnoble Aug 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible. Not sure. I think with replays we only end up actually caring about errors. We haven't even really seen warnings, if they are there, because they're buried by the Pact warnings.

else f logger

applyPactCmd
:: (Logger logger)
=> Bool
Expand Down Expand Up @@ -434,9 +444,9 @@ applyPactCmd isGenesis env miner txTimeLimit cmd = StateT $ \(T2 mcache maybeBlo
Just limit ->
maybe (throwM timeoutError) return <=< timeout (fromIntegral limit)
let txGas (T3 r _ _) = fromIntegral $ P._crGas r
T3 r c _warns <-
T3 r c _warns <- withSilentLoggerForReplays $ \cmdLogger ->
tracePactServiceM' "applyCmd" (J.toJsonViaEncode (P._cmdHash cmd)) txGas $
liftIO $ txTimeout $ applyCmd v logger gasLogger env miner (gasModel txCtx) txCtx spv gasLimitedCmd initialGas mcache ApplySend
liftIO $ txTimeout $ applyCmd v cmdLogger gasLogger env miner (gasModel txCtx) txCtx spv gasLimitedCmd initialGas mcache ApplySend
pure $ T2 r c

if isGenesis
Expand Down
2 changes: 0 additions & 2 deletions src/Chainweb/Pact/Service/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,6 @@ data PactServiceConfig = PactServiceConfig
-- hardcodes this to 8 currently.
, _pactLocalRewindDepthLimit :: !RewindLimit
-- ^ Maximum allowed rewind depth in the local command.
, _pactRevalidate :: !Bool
-- ^ Re-validate payload hashes during transaction replay
, _pactAllowReadsInLocal :: !Bool
-- ^ Allow direct database reads in local mode
, _pactQueueSize :: !Natural
Expand Down
10 changes: 5 additions & 5 deletions src/Chainweb/Pact/TransactionExec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ applyGenesisCmd logger dbEnv spv txCtx cmd =

go = do
-- TODO: fix with version recordification so that this matches the flags at genesis heights.
cr <- catchesPactError logger PrintsUnexpectedError $! runGenesis cmd permissiveNamespacePolicy interp
cr <- catchesPactError logger (onChainErrorPrintingFor txCtx) $! runGenesis cmd permissiveNamespacePolicy interp
case cr of
Left e -> fatal $ "Genesis command failed: " <> sshow e
Right r -> r <$ debug "successful genesis tx for request key"
Expand Down Expand Up @@ -635,7 +635,7 @@ jsonErrorResult err msg = do
l <- view txLogger

logInfo_ l
$! msg
$ msg
<> ": " <> sshow rk
<> ": " <> sshow err

Expand Down Expand Up @@ -1136,15 +1136,15 @@ gasLog m = do
l <- view txGasLogger
rk <- view txRequestKey
for_ l $ \logger ->
logInfo_ logger $! m <> ": " <> sshow rk
logInfo_ logger $ m <> ": " <> sshow rk

-- | Log request keys at DEBUG when successful
--
debug :: (Logger logger) => Text -> TransactionM logger db ()
debug s = do
l <- view txLogger
rk <- view txRequestKey
logDebug_ l $! s <> ": " <> sshow rk
logDebug_ l $ s <> ": " <> sshow rk


-- | Denotes fatal failure points in the tx exec process
Expand All @@ -1155,7 +1155,7 @@ fatal e = do
rk <- view txRequestKey

logError_ l
$! "critical transaction failure: "
$ "critical transaction failure: "
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for undoing the bangs

Copy link
Contributor Author

@edmundnoble edmundnoble Aug 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loggers are always strict, so the bangs aren't necessary... except that they're lazy when they're filtered such that the log message never makes it to the queue. I've seen some pretty big log messages here, so I'd like those not constructed in case that can raise throughput.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, log messages are deep forced before added to the queue.

Avoiding construction when their log level is disabled is a good point.

<> sshow rk <> ": " <> e

throwM $ PactTransactionExecError (fromUntypedHash $ unRequestKey rk) e
Expand Down
28 changes: 19 additions & 9 deletions src/Chainweb/Pact/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ module Chainweb.Pact.Types
, GasId(..)
, EnforceCoinbaseFailure(..)
, CoinbaseUsePrecompiled(..)
, cleanModuleCache

-- * Transaction State
, TransactionState(..)
Expand Down Expand Up @@ -80,7 +81,7 @@ module Chainweb.Pact.Types
, psLocalRewindDepthLimit
, psOnFatalError
, psVersion
, psValidateHashesOnReplay
, psReplaying
, psLogger
, psGasLogger
, psAllowReadsInLocal
Expand Down Expand Up @@ -215,7 +216,6 @@ import Chainweb.Time
import Chainweb.Transaction
import Chainweb.Utils
import Chainweb.Version
import Chainweb.Version.Guards
import Utils.Logging.Trace


Expand Down Expand Up @@ -286,6 +286,15 @@ moduleCacheKeys :: ModuleCache -> [ModuleName]
moduleCacheKeys (ModuleCache a) = fst <$> LHM.toList a
{-# INLINE moduleCacheKeys #-}

-- this can't go in Chainweb.Version.Guards because it causes an import cycle
-- it uses genesisHeight which is from BlockHeader which imports Guards
Comment on lines +291 to +292
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to move genesisHeight to a different place instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably would cause a cycle. I tried it during recordification.

cleanModuleCache :: ChainwebVersion -> ChainId -> BlockHeight -> Bool
cleanModuleCache v cid bh =
case v ^?! versionForks . at Chainweb217Pact . _Just . onChain cid of
ForkAtBlockHeight bh' -> bh == bh'
ForkAtGenesis -> bh == genesisHeight v cid
ForkNever -> False

-- -------------------------------------------------------------------- --
-- Local vs. Send execution context flag

Expand Down Expand Up @@ -410,7 +419,7 @@ data PactServiceEnv logger tbl = PactServiceEnv
-- ^ The limit of checkpointer's rewind in the `execValidationBlock` command.
, _psOnFatalError :: !(forall a. PactException -> Text -> IO a)
, _psVersion :: !ChainwebVersion
, _psValidateHashesOnReplay :: !Bool
, _psReplaying :: !Bool
, _psAllowReadsInLocal :: !Bool
, _psLogger :: !logger
, _psGasLogger :: !(Maybe logger)
Expand Down Expand Up @@ -456,7 +465,6 @@ testPactServiceConfig :: PactServiceConfig
testPactServiceConfig = PactServiceConfig
{ _pactReorgLimit = defaultReorgLimit
, _pactLocalRewindDepthLimit = defaultLocalRewindDepthLimit
, _pactRevalidate = True
, _pactQueueSize = 1000
, _pactResetDb = True
, _pactAllowReadsInLocal = False
Expand Down Expand Up @@ -720,9 +728,11 @@ catchesPactError :: (MonadCatch m, MonadIO m, Logger logger) => logger -> Unexpe
catchesPactError logger exnPrinting action = catches (Right <$> action)
[ Handler $ \(e :: PactError) -> return $ Left e
, Handler $ \(e :: SomeException) -> do
liftIO $ logWarn_ logger ("catchesPactError: unknown error: " <> sshow e)
return $ Left $ PactError EvalError def def $
case exnPrinting of
PrintsUnexpectedError -> viaShow e
CensorsUnexpectedError -> "unknown error"
!err <- case exnPrinting of
PrintsUnexpectedError ->
return (viaShow e)
CensorsUnexpectedError -> do
liftIO $ logWarn_ logger ("catchesPactError: unknown error: " <> sshow e)
return "unknown error"
return $ Left $ PactError EvalError def def err
]
4 changes: 0 additions & 4 deletions src/Chainweb/Version/Guards.hs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ module Chainweb.Version.Guards
, chainweb215Pact
, chainweb216Pact
, chainweb217Pact
, cleanModuleCache
, chainweb218Pact
, chainweb219Pact
, chainweb220Pact
Expand Down Expand Up @@ -223,9 +222,6 @@ chainweb216Pact = checkFork after Chainweb216Pact
chainweb217Pact :: ChainwebVersion -> ChainId -> BlockHeight -> Bool
chainweb217Pact = checkFork after Chainweb217Pact

cleanModuleCache :: ChainwebVersion -> ChainId -> BlockHeight -> Bool
cleanModuleCache = checkFork atOrAfter Chainweb217Pact

chainweb218Pact :: ChainwebVersion -> ChainId -> BlockHeight -> Bool
chainweb218Pact = checkFork atOrAfter Chainweb218Pact

Expand Down
2 changes: 1 addition & 1 deletion test/Chainweb/Test/Pact/Utils.hs
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ testPactCtxSQLite logger v cid bhdb pdb sqlenv conf gasmodel = do
, _psLocalRewindDepthLimit = _pactLocalRewindDepthLimit conf
, _psOnFatalError = defaultOnFatalError mempty
, _psVersion = v
, _psValidateHashesOnReplay = _pactRevalidate conf
, _psReplaying = False
, _psAllowReadsInLocal = _pactAllowReadsInLocal conf
, _psIsBatch = False
, _psCheckpointerDepth = 0
Expand Down
2 changes: 1 addition & 1 deletion tools/cwtool/TxSimulator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ simulate sc@(SimConfig dbDir txIdx' _ _ cid ver gasLog doTypecheck) = do
, _psReorgLimit = RewindLimit 0
, _psOnFatalError = ferr
, _psVersion = ver
, _psValidateHashesOnReplay = True
, _psReplaying = False
, _psAllowReadsInLocal = False
, _psLogger = logger
, _psGasLogger = gasLogger
Expand Down
Loading