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.
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
btcPerSatoshi = 1E-8

View file

@ -89,6 +89,10 @@ type Config struct {
// indexing the unconfirmed transactions in the memory pool.
// This can be nil if the address index is not enabled.
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
@ -527,8 +531,8 @@ func (mp *TxPool) addTransaction(utxoView *blockchain.UtxoViewpoint, tx *btcutil
},
StartingPriority: mining.CalcPriority(tx.MsgTx(), utxoView, height),
}
mp.pool[*tx.Hash()] = txD
mp.pool[*tx.Hash()] = txD
for _, txIn := range tx.MsgTx().TxIn {
mp.outpoints[txIn.PreviousOutPoint] = tx
}
@ -540,6 +544,11 @@ func (mp *TxPool) addTransaction(utxoView *blockchain.UtxoViewpoint, tx *btcutil
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
}

View file

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

View file

@ -167,6 +167,9 @@ type SyncManager struct {
headerList *list.List
startHeader *list.Element
nextCheckpoint *chaincfg.Checkpoint
// An optional fee estimator.
feeEstimator *mempool.FeeEstimator
}
// 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)
}
// 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.
case blockchain.NTBlockDisconnected:
block, ok := notification.Data.(*btcutil.Block)
@ -1269,6 +1286,11 @@ func (sm *SyncManager) handleBlockchainNotification(notification *blockchain.Not
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),
headerList: list.New(),
quit: make(chan struct{}),
feeEstimator: config.FeeEstimator,
}
best := sm.chain.BestSnapshot()

View file

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