@@ -360,6 +360,17 @@ type App struct {
360360
361361 // Instrumentation: store wall-clock when BeginBlock starts for execution duration metrics.
362362 beginBlockStartTime time.Time
363+ // Instrumentation: proposal phase timings (non-validating full nodes may skip PrepareProposal; we still measure if invoked).
364+ prepareProposalStart time.Time
365+ prepareProposalEnd time.Time
366+ processProposalStart time.Time
367+ processProposalEnd time.Time
368+ finalizeBlockStart time.Time
369+ commitStart time.Time
370+ commitEnd time.Time
371+ precommitterStart time.Time
372+ precommitterEnd time.Time
373+ prepareCheckStateStart time.Time
363374
364375 ModuleManager * module.Manager
365376 ModuleBasics module.BasicManager
@@ -1644,14 +1655,35 @@ func (app *App) createProposalHandlers(
16441655 if app .oracleMetrics == nil {
16451656 app .oracleMetrics = servicemetrics .NewNopMetrics ()
16461657 }
1647- return prepare .FullNodePrepareProposalHandler (), process .FullNodeProcessProposalHandler (
1658+ basePrepare := prepare .FullNodePrepareProposalHandler ()
1659+ wrappedPrepare := func (ctx sdk.Context , req * abci.RequestPrepareProposal ) (* abci.ResponsePrepareProposal , error ) {
1660+ app .prepareProposalStart = time .Now ()
1661+ resp , err := basePrepare (ctx , req )
1662+ app .prepareProposalEnd = time .Now ()
1663+ dur := app .prepareProposalEnd .Sub (app .prepareProposalStart )
1664+ lag := app .prepareProposalEnd .Sub (ctx .BlockTime ())
1665+ applog .InfoLog (ctx , "PIERRICK: PrepareProposal timing" , "height" , ctx .BlockHeight (), "duration_ms" , dur .Milliseconds (), "lag_ms" , lag .Milliseconds ())
1666+ return resp , err
1667+ }
1668+ baseProcess := process .FullNodeProcessProposalHandler (
16481669 txConfig ,
16491670 app .BridgeKeeper ,
16501671 app .ClobKeeper ,
16511672 app .StakingKeeper ,
16521673 app .PerpetualsKeeper ,
16531674 priceUpdateDecoder ,
16541675 )
1676+ wrappedProcess := func (ctx sdk.Context , req * abci.RequestProcessProposal ) (* abci.ResponseProcessProposal , error ) {
1677+ app .processProposalStart = time .Now ()
1678+ resp , err := baseProcess (ctx , req )
1679+ app .processProposalEnd = time .Now ()
1680+ dur := app .processProposalEnd .Sub (app .processProposalStart )
1681+ lag := app .processProposalEnd .Sub (ctx .BlockTime ())
1682+ accepted := resp != nil && resp .Status == abci .ResponseProcessProposal_ACCEPT
1683+ applog .InfoLog (ctx , "PIERRICK: ProcessProposal timing" , "height" , ctx .BlockHeight (), "duration_ms" , dur .Milliseconds (), "lag_ms" , lag .Milliseconds (), "accepted" , accepted )
1684+ return resp , err
1685+ }
1686+ return wrappedPrepare , wrappedProcess
16551687 }
16561688 strategy := currencypair .NewDefaultCurrencyPairStrategy (app .PricesKeeper )
16571689 var priceUpdateGenerator prices.PriceUpdateGenerator = prices .NewDefaultPriceUpdateGenerator (app .PricesKeeper )
@@ -1722,7 +1754,27 @@ func (app *App) createProposalHandlers(
17221754 )
17231755 return proposalHandler .PrepareProposalHandler (), proposalHandler .ProcessProposalHandler ()
17241756 }
1725- return dydxPrepareProposalHandler , dydxProcessProposalHandler
1757+ // Wrap dydx handlers for instrumentation on validating nodes.
1758+ wrappedPrepare := func (ctx sdk.Context , req * abci.RequestPrepareProposal ) (* abci.ResponsePrepareProposal , error ) {
1759+ app .prepareProposalStart = time .Now ()
1760+ resp , err := dydxPrepareProposalHandler (ctx , req )
1761+ app .prepareProposalEnd = time .Now ()
1762+ dur := app .prepareProposalEnd .Sub (app .prepareProposalStart )
1763+ lag := app .prepareProposalEnd .Sub (ctx .BlockTime ())
1764+ applog .InfoLog (ctx , "PIERRICK: PrepareProposal timing" , "height" , ctx .BlockHeight (), "duration_ms" , dur .Milliseconds (), "lag_ms" , lag .Milliseconds ())
1765+ return resp , err
1766+ }
1767+ wrappedProcess := func (ctx sdk.Context , req * abci.RequestProcessProposal ) (* abci.ResponseProcessProposal , error ) {
1768+ app .processProposalStart = time .Now ()
1769+ resp , err := dydxProcessProposalHandler (ctx , req )
1770+ app .processProposalEnd = time .Now ()
1771+ dur := app .processProposalEnd .Sub (app .processProposalStart )
1772+ lag := app .processProposalEnd .Sub (ctx .BlockTime ())
1773+ accepted := resp != nil && resp .Status == abci .ResponseProcessProposal_ACCEPT
1774+ applog .InfoLog (ctx , "PIERRICK: ProcessProposal timing" , "height" , ctx .BlockHeight (), "duration_ms" , dur .Milliseconds (), "lag_ms" , lag .Milliseconds (), "accepted" , accepted )
1775+ return resp , err
1776+ }
1777+ return wrappedPrepare , wrappedProcess
17261778}
17271779
17281780func (app * App ) initOracle (pricesTxDecoder process.UpdateMarketPriceTxDecoder ) {
@@ -1804,6 +1856,21 @@ func (app *App) GetBaseApp() *baseapp.BaseApp { return app.BaseApp }
18041856func (app * App ) PreBlocker (ctx sdk.Context , _ * abci.RequestFinalizeBlock ) (* sdk.ResponsePreBlock , error ) {
18051857 app .scheduleForkUpgrade (ctx )
18061858
1859+ // Record FinalizeBlock entry timing.
1860+ app .finalizeBlockStart = time .Now ()
1861+ lag := app .finalizeBlockStart .Sub (ctx .BlockTime ())
1862+ processDurMs := int64 (0 )
1863+ if ! app .processProposalStart .IsZero () && ! app .processProposalEnd .IsZero () {
1864+ processDurMs = app .processProposalEnd .Sub (app .processProposalStart ).Milliseconds ()
1865+ }
1866+ applog .InfoLog (
1867+ ctx ,
1868+ "PIERRICK: FinalizeBlock start timing" ,
1869+ "height" , ctx .BlockHeight (),
1870+ "lag_ms" , lag .Milliseconds (),
1871+ "process_proposal_duration_ms" , processDurMs ,
1872+ )
1873+
18071874 // Set gas meter to the free gas meter.
18081875 // This is because there is currently non-deterministic gas usage in the
18091876 // pre-blocker, e.g. due to hydration of in-memory data structures.
@@ -1869,25 +1936,31 @@ func (app *App) EndBlocker(ctx sdk.Context) (sdk.EndBlock, error) {
18691936 if err != nil {
18701937 return response , err
18711938 }
1939+ // Mark precommitter start; actual commit follows later.
1940+ app .precommitterStart = time .Now ()
18721941 return response , err
18731942}
18741943
18751944// Precommitter application updates before the commital of a block after all transactions have been delivered.
18761945func (app * App ) Precommitter (ctx sdk.Context ) {
1946+ start := time .Now ()
18771947 if err := app .ModuleManager .Precommit (ctx ); err != nil {
18781948 panic (err )
18791949 }
18801950 block := app .IndexerEventManager .ProduceBlock (ctx )
18811951 app .IndexerEventManager .SendOnchainData (block )
1952+ app .precommitterEnd = time .Now ()
1953+ applog .InfoLog (ctx , "PIERRICK: Precommit timing" , "height" , ctx .BlockHeight (), "duration_ms" , app .precommitterEnd .Sub (start ).Milliseconds ())
18821954}
18831955
18841956// PrepareCheckStater application updates after commit and before any check state is invoked.
18851957func (app * App ) PrepareCheckStater (ctx sdk.Context ) {
18861958 ctx = ctx .WithExecMode (lib .ExecModePrepareCheckState )
1887-
1959+ app . prepareCheckStateStart = time . Now ()
18881960 if err := app .ModuleManager .PrepareCheckState (ctx ); err != nil {
18891961 panic (err )
18901962 }
1963+ applog .InfoLog (ctx , "PIERRICK: PrepareCheckState timing" , "height" , ctx .BlockHeight (), "lag_ms" , time .Since (ctx .BlockTime ()).Milliseconds ())
18911964}
18921965
18931966// InitChainer application update at chain initialization.
0 commit comments