From f7cce5cb39e239677675c199d15a167954b169cf Mon Sep 17 00:00:00 2001 From: Svarog Date: Sun, 4 Jul 2021 11:47:43 +0300 Subject: [PATCH] Cache virtual past median time (#1775) * Add cache for virtual pastMedianTime * Implement InvalidateVirtualPastMedianTimeCache for mocPastMedianTimeManager --- ...terface_processes_pastmediantimemanager.go | 1 + .../blockprocessor/validateandinsertblock.go | 2 ++ .../pastmediantimemanager.go | 20 ++++++++++++++++++- .../transactionvalidator_test.go | 4 ++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/domain/consensus/model/interface_processes_pastmediantimemanager.go b/domain/consensus/model/interface_processes_pastmediantimemanager.go index 096859215..35961fdcd 100644 --- a/domain/consensus/model/interface_processes_pastmediantimemanager.go +++ b/domain/consensus/model/interface_processes_pastmediantimemanager.go @@ -6,4 +6,5 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" // past median time of a block type PastMedianTimeManager interface { PastMedianTime(stagingArea *StagingArea, blockHash *externalapi.DomainHash) (int64, error) + InvalidateVirtualPastMedianTimeCache() } diff --git a/domain/consensus/processes/blockprocessor/validateandinsertblock.go b/domain/consensus/processes/blockprocessor/validateandinsertblock.go index fc207b9f0..45792d732 100644 --- a/domain/consensus/processes/blockprocessor/validateandinsertblock.go +++ b/domain/consensus/processes/blockprocessor/validateandinsertblock.go @@ -184,6 +184,8 @@ func (bp *blockProcessor) validateAndInsertBlock(stagingArea *model.StagingArea, return nil, err } + bp.pastMedianTimeManager.InvalidateVirtualPastMedianTimeCache() + bp.blockLogger.LogBlock(block) return &externalapi.BlockInsertionResult{ diff --git a/domain/consensus/processes/pastmediantimemanager/pastmediantimemanager.go b/domain/consensus/processes/pastmediantimemanager/pastmediantimemanager.go index d2d68a988..bfe65f1a3 100644 --- a/domain/consensus/processes/pastmediantimemanager/pastmediantimemanager.go +++ b/domain/consensus/processes/pastmediantimemanager/pastmediantimemanager.go @@ -23,6 +23,8 @@ type pastMedianTimeManager struct { ghostdagDataStore model.GHOSTDAGDataStore genesisHash *externalapi.DomainHash + + virtualPastMedianTimeCache int64 } // New instantiates a new PastMedianTimeManager @@ -47,6 +49,9 @@ func New(timestampDeviationTolerance int, // PastMedianTime returns the past median time for some block func (pmtm *pastMedianTimeManager) PastMedianTime(stagingArea *model.StagingArea, blockHash *externalapi.DomainHash) (int64, error) { + if blockHash == model.VirtualBlockHash && pmtm.virtualPastMedianTimeCache != 0 { + return pmtm.virtualPastMedianTimeCache, nil + } window, err := pmtm.dagTraversalManager.BlockWindow(stagingArea, blockHash, 2*pmtm.timestampDeviationTolerance-1) if err != nil { return 0, err @@ -59,7 +64,16 @@ func (pmtm *pastMedianTimeManager) PastMedianTime(stagingArea *model.StagingArea return header.TimeInMilliseconds(), nil } - return pmtm.windowMedianTimestamp(stagingArea, window) + pastMedianTime, err := pmtm.windowMedianTimestamp(stagingArea, window) + if err != nil { + return 0, err + } + + if blockHash == model.VirtualBlockHash { + pmtm.virtualPastMedianTimeCache = pastMedianTime + } + + return pastMedianTime, nil } func (pmtm *pastMedianTimeManager) windowMedianTimestamp( @@ -82,3 +96,7 @@ func (pmtm *pastMedianTimeManager) windowMedianTimestamp( return timestamps[len(timestamps)/2], nil } + +func (pmtm *pastMedianTimeManager) InvalidateVirtualPastMedianTimeCache() { + pmtm.virtualPastMedianTimeCache = 0 +} diff --git a/domain/consensus/processes/transactionvalidator/transactionvalidator_test.go b/domain/consensus/processes/transactionvalidator/transactionvalidator_test.go index 81c95e49c..28bcf0669 100644 --- a/domain/consensus/processes/transactionvalidator/transactionvalidator_test.go +++ b/domain/consensus/processes/transactionvalidator/transactionvalidator_test.go @@ -23,6 +23,10 @@ type mocPastMedianTimeManager struct { pastMedianTimeForTest int64 } +func (mdf *mocPastMedianTimeManager) InvalidateVirtualPastMedianTimeCache() { + // do nothing +} + // PastMedianTime returns the past median time for the test. func (mdf *mocPastMedianTimeManager) PastMedianTime(*model.StagingArea, *externalapi.DomainHash) (int64, error) { return mdf.pastMedianTimeForTest, nil