FeeEstimator added to server. Mempool alerts the fee estimator of

new txs that it observes. The block manager alerts the fee estimator
of new and orphaned blocks.

Check for invalid state and recreate FeeEstimator if necessary.
This commit is contained in:
Daniel Krawisz 2017-11-13 22:37:35 -06:00 committed by Olaoluwa Osuntokun
parent e6d8b869aa
commit 1333ad7f78
5 changed files with 49 additions and 1 deletions

View file

@ -34,6 +34,15 @@ const (
// can be made by the txs found in a given block. // can be made by the txs found in a given block.
estimateFeeMaxReplacements = 10 estimateFeeMaxReplacements = 10
// DefaultEstimateFeeMaxRollback is the default number of rollbacks
// allowed by the fee estimator for orphaned blocks.
DefaultEstimateFeeMaxRollback = 2
// DefaultEstimateFeeMinRegisteredBlocks is the default minimum
// number of blocks which must be observed by the fee estimator before
// it will provide fee estimations.
DefaultEstimateFeeMinRegisteredBlocks = 3
bytePerKb = 1024 bytePerKb = 1024
btcPerSatoshi = 1E-8 btcPerSatoshi = 1E-8

View file

@ -89,6 +89,10 @@ type Config struct {
// indexing the unconfirmed transactions in the memory pool. // indexing the unconfirmed transactions in the memory pool.
// This can be nil if the address index is not enabled. // This can be nil if the address index is not enabled.
AddrIndex *indexers.AddrIndex AddrIndex *indexers.AddrIndex
// FeeEstimatator provides a feeEstimator. If it is not nil, the mempool
// records all new transactions it observes into the feeEstimator.
FeeEstimator *FeeEstimator
} }
// Policy houses the policy (configuration parameters) which is used to // Policy houses the policy (configuration parameters) which is used to
@ -527,8 +531,8 @@ func (mp *TxPool) addTransaction(utxoView *blockchain.UtxoViewpoint, tx *btcutil
}, },
StartingPriority: mining.CalcPriority(tx.MsgTx(), utxoView, height), StartingPriority: mining.CalcPriority(tx.MsgTx(), utxoView, height),
} }
mp.pool[*tx.Hash()] = txD
mp.pool[*tx.Hash()] = txD
for _, txIn := range tx.MsgTx().TxIn { for _, txIn := range tx.MsgTx().TxIn {
mp.outpoints[txIn.PreviousOutPoint] = tx mp.outpoints[txIn.PreviousOutPoint] = tx
} }
@ -540,6 +544,11 @@ func (mp *TxPool) addTransaction(utxoView *blockchain.UtxoViewpoint, tx *btcutil
mp.cfg.AddrIndex.AddUnconfirmedTx(tx, utxoView) mp.cfg.AddrIndex.AddUnconfirmedTx(tx, utxoView)
} }
// Record this tx for fee estimation if enabled.
if mp.cfg.FeeEstimator != nil {
mp.cfg.FeeEstimator.ObserveTransaction(txD)
}
return txD return txD
} }

View file

@ -36,4 +36,6 @@ type Config struct {
DisableCheckpoints bool DisableCheckpoints bool
MaxPeers int MaxPeers int
FeeEstimator *mempool.FeeEstimator
} }

View file

@ -167,6 +167,9 @@ type SyncManager struct {
headerList *list.List headerList *list.List
startHeader *list.Element startHeader *list.Element
nextCheckpoint *chaincfg.Checkpoint nextCheckpoint *chaincfg.Checkpoint
// An optional fee estimator.
feeEstimator *mempool.FeeEstimator
} }
// resetHeaderState sets the headers-first mode state to values appropriate for // resetHeaderState sets the headers-first mode state to values appropriate for
@ -1249,6 +1252,20 @@ func (sm *SyncManager) handleBlockchainNotification(notification *blockchain.Not
sm.peerNotifier.AnnounceNewTransactions(acceptedTxs) sm.peerNotifier.AnnounceNewTransactions(acceptedTxs)
} }
// Register block with the fee estimator, if it exists.
if sm.feeEstimator != nil {
err := sm.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 {
sm.feeEstimator = mempool.NewFeeEstimator(
mempool.DefaultEstimateFeeMaxRollback,
mempool.DefaultEstimateFeeMinRegisteredBlocks)
}
}
// A block has been disconnected from the main block chain. // A block has been disconnected from the main block chain.
case blockchain.NTBlockDisconnected: case blockchain.NTBlockDisconnected:
block, ok := notification.Data.(*btcutil.Block) block, ok := notification.Data.(*btcutil.Block)
@ -1269,6 +1286,11 @@ func (sm *SyncManager) handleBlockchainNotification(notification *blockchain.Not
sm.txMemPool.RemoveTransaction(tx, true) sm.txMemPool.RemoveTransaction(tx, true)
} }
} }
// Rollback previous block recorded by the fee estimator.
if sm.feeEstimator != nil {
sm.feeEstimator.Rollback(block.Hash())
}
} }
} }
@ -1417,6 +1439,7 @@ func New(config *Config) (*SyncManager, error) {
msgChan: make(chan interface{}, config.MaxPeers*3), msgChan: make(chan interface{}, config.MaxPeers*3),
headerList: list.New(), headerList: list.New(),
quit: make(chan struct{}), quit: make(chan struct{}),
feeEstimator: config.FeeEstimator,
} }
best := sm.chain.BestSnapshot() best := sm.chain.BestSnapshot()

View file

@ -2411,6 +2411,10 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
return nil, err return nil, err
} }
feeEstimator := mempool.NewFeeEstimator(
mempool.DefaultEstimateFeeMaxRollback,
mempool.DefaultEstimateFeeMinRegisteredBlocks)
txC := mempool.Config{ txC := mempool.Config{
Policy: mempool.Policy{ Policy: mempool.Policy{
DisableRelayPriority: cfg.NoRelayPriority, DisableRelayPriority: cfg.NoRelayPriority,
@ -2433,6 +2437,7 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
SigCache: s.sigCache, SigCache: s.sigCache,
HashCache: s.hashCache, HashCache: s.hashCache,
AddrIndex: s.addrIndex, AddrIndex: s.addrIndex,
FeeEstimator: feeEstimator,
} }
s.txMemPool = mempool.New(&txC) s.txMemPool = mempool.New(&txC)