Skip to content

Commit

Permalink
Add checks to regenerate fee estimator if an invalid state is detecte…
Browse files Browse the repository at this point in the history
…d. Change default minimum registered blocks from 5 to 3.
  • Loading branch information
Daniel Krawisz committed Nov 25, 2016
1 parent e19de46 commit 7a31a98
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 30 deletions.
11 changes: 10 additions & 1 deletion blockmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -1158,7 +1158,16 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {

// Register block with the fee estimator if enabled.
if b.server.feeEstimator != nil {
b.server.feeEstimator.RegisterBlock(block)
err := b.server.feeEstimator.RegisterBlock(block)

// If an error is somehow generated then the fee estimator
// has entered an invalid state. Since it doesn't know how
// to recover, create a new one.
if err != nil {
b.server.feeEstimator = mempool.NewFeeEstimator(
mempool.DefaultEstimateFeeMaxRollback,
mempool.DefaultEstimateFeeMinRegisteredBlocks)
}
}

if r := b.server.rpcServer; r != nil {
Expand Down
10 changes: 9 additions & 1 deletion mempool/estimatefee.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const (
// DefaultEstimateFeeMinRegisteredBlocks is the default minimum
// number of blocks which must be observed by the fee estimator before
// it will provide fee estimations.
DefaultEstimateFeeMinRegisteredBlocks = 5
DefaultEstimateFeeMinRegisteredBlocks = 3

bytePerKb = 1024

Expand Down Expand Up @@ -327,6 +327,14 @@ func (ef *FeeEstimator) RegisterBlock(block *btcutil.Block) error {
return nil
}

// LastKnownHeight returns the height of the last block which was registered.
func (ef *FeeEstimator) LastKnownHeight() int32 {
ef.mtx.Lock()
defer ef.mtx.Unlock()

return ef.lastKnownHeight
}

// Rollback unregisters a recently registered block from the FeeEstimator.
// This can be used to reverse the effect of an orphaned block on the fee
// estimator. The maximum number of rollbacks allowed is given by
Expand Down
58 changes: 30 additions & 28 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2329,34 +2329,6 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
sigCache: txscript.NewSigCache(cfg.SigCacheMaxSize),
}

// Search for a FeeEstimator state in the database. If none can be found
// or if it cannot be loaded, create a new one.
db.Update(func(tx database.Tx) error {
metadata := tx.Metadata()
feeEstimationData := metadata.Get(mempool.EstimateFeeDatabaseKey)
if feeEstimationData != nil {
// delete it from the database so that we don't try to restore the
// same thing again somehow.
metadata.Delete(mempool.EstimateFeeDatabaseKey)

// If there is an error, log it and make a new fee estimator.
var err error
s.feeEstimator, err = mempool.RestoreFeeEstimator(feeEstimationData)

if err != nil {
peerLog.Errorf("Failed restore fee estimator %v", err)
}
}

return nil
})

if s.feeEstimator == nil {
s.feeEstimator = mempool.NewFeeEstimator(
mempool.DefaultEstimateFeeMaxRollback,
mempool.DefaultEstimateFeeMinRegisteredBlocks)
}

// Create the transaction and address indexes if needed.
//
// CAUTION: the txindex needs to be first in the indexes array because
Expand Down Expand Up @@ -2395,6 +2367,36 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
}
s.blockManager = bm

// Search for a FeeEstimator state in the database. If none can be found
// or if it cannot be loaded, create a new one.
db.Update(func(tx database.Tx) error {
metadata := tx.Metadata()
feeEstimationData := metadata.Get(mempool.EstimateFeeDatabaseKey)
if feeEstimationData != nil {
// delete it from the database so that we don't try to restore the
// same thing again somehow.
metadata.Delete(mempool.EstimateFeeDatabaseKey)

// If there is an error, log it and make a new fee estimator.
var err error
s.feeEstimator, err = mempool.RestoreFeeEstimator(feeEstimationData)

if err != nil {
peerLog.Errorf("Failed restore fee estimator %v", err)
}
}

return nil
})

// If no feeEstimator has been found, or if the one that has been found
// is behind somehow, create a new one and start over.
if s.feeEstimator == nil || s.feeEstimator.LastKnownHeight() != s.blockManager.chain.BestSnapshot().Height {
s.feeEstimator = mempool.NewFeeEstimator(
mempool.DefaultEstimateFeeMaxRollback,
mempool.DefaultEstimateFeeMinRegisteredBlocks)
}

txC := mempool.Config{
Policy: mempool.Policy{
DisableRelayPriority: cfg.NoRelayPriority,
Expand Down

0 comments on commit 7a31a98

Please sign in to comment.