-
Notifications
You must be signed in to change notification settings - Fork 93
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
Much quieter replays #1713
Changes from 6 commits
3961e13
5e33306
3081d53
b3857cd
166adac
3ef7fc1
12529c9
f95511f
6951213
0380363
55df614
f80cecf
3e4f71d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) | ||
|
@@ -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 $ | ||
either throwM (void . return) $! | ||
validateHashes currHeader plData miner results | ||
|
||
|
@@ -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 | ||
|
@@ -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 | ||
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
|
@@ -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 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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" | ||
|
@@ -635,7 +635,7 @@ jsonErrorResult err msg = do | |
l <- view txLogger | ||
|
||
logInfo_ l | ||
$! msg | ||
$ msg | ||
<> ": " <> sshow rk | ||
<> ": " <> sshow err | ||
|
||
|
@@ -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 | ||
|
@@ -1155,7 +1155,7 @@ fatal e = do | |
rk <- view txRequestKey | ||
|
||
logError_ l | ||
$! "critical transaction failure: " | ||
$ "critical transaction failure: " | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the reason for undoing the bangs There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,6 +38,7 @@ module Chainweb.Pact.Types | |
, GasId(..) | ||
, EnforceCoinbaseFailure(..) | ||
, CoinbaseUsePrecompiled(..) | ||
, cleanModuleCache | ||
|
||
-- * Transaction State | ||
, TransactionState(..) | ||
|
@@ -80,7 +81,7 @@ module Chainweb.Pact.Types | |
, psLocalRewindDepthLimit | ||
, psOnFatalError | ||
, psVersion | ||
, psValidateHashesOnReplay | ||
, psReplaying | ||
, psLogger | ||
, psGasLogger | ||
, psAllowReadsInLocal | ||
|
@@ -215,7 +216,6 @@ import Chainweb.Time | |
import Chainweb.Transaction | ||
import Chainweb.Utils | ||
import Chainweb.Version | ||
import Chainweb.Version.Guards | ||
import Utils.Logging.Trace | ||
|
||
|
||
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it make sense to move There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
|
||
|
@@ -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) | ||
|
@@ -456,7 +465,6 @@ testPactServiceConfig :: PactServiceConfig | |
testPactServiceConfig = PactServiceConfig | ||
{ _pactReorgLimit = defaultReorgLimit | ||
, _pactLocalRewindDepthLimit = defaultLocalRewindDepthLimit | ||
, _pactRevalidate = True | ||
, _pactQueueSize = 1000 | ||
, _pactResetDb = True | ||
, _pactAllowReadsInLocal = False | ||
|
@@ -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 | ||
] |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.