mempool: add closure to compute median time past to config

This commit adds an additional closure function to the mempool’s config
which computes the median time past from the point of view of the best
node in the chain. The mempool test harness has also been updated to allow
setting a mock median time past for testing purposes.

In addition to increasing the testability of the mempool, this commit
should also speed up transaction and block validation for BIP 113 as
the MTP no longer needs to be re-calculated each time from scratch.
This commit is contained in:
Olaoluwa Osuntokun 2016-08-23 11:48:03 -07:00
parent a6bf1d9850
commit a82f67b538
No known key found for this signature in database
GPG key ID: 9CC5B105D03521A2
3 changed files with 38 additions and 14 deletions

View file

@ -59,6 +59,11 @@ type Config struct {
// the current best chain.
BestHeight func() int32
// MedianTimePast defines the function to use in order to access the
// median time past calculated from the point-of-view of the current
// chain tip within the best chain.
MedianTimePast func() time.Time
// SigCache defines a signature cache to use.
SigCache *txscript.SigCache

View file

@ -9,6 +9,7 @@ import (
"reflect"
"sync"
"testing"
"time"
"github.com/btcsuite/btcd/blockchain"
"github.com/btcsuite/btcd/btcec"
@ -24,8 +25,9 @@ import (
// transations to be appear as though they are spending completely valid utxos.
type fakeChain struct {
sync.RWMutex
utxos *blockchain.UtxoViewpoint
currentHeight int32
utxos *blockchain.UtxoViewpoint
currentHeight int32
medianTimePast time.Time
}
// FetchUtxoView loads utxo details about the input transactions referenced by
@ -72,6 +74,23 @@ func (s *fakeChain) SetHeight(height int32) {
s.Unlock()
}
// MedianTimePast returns the current median time past associated with the fake
// chain instance.
func (s *fakeChain) MedianTimePast() time.Time {
s.RLock()
mtp := s.medianTimePast
s.RUnlock()
return mtp
}
// SetMedianTimePast sets the current median time past associated with the fake
// chain instance.
func (s *fakeChain) SetMedianTimePast(mtp time.Time) {
s.Lock()
s.medianTimePast = mtp
s.Unlock()
}
// spendableOutput is a convenience type that houses a particular utxo and the
// amount associated with it.
type spendableOutput struct {
@ -282,12 +301,12 @@ func newPoolHarness(chainParams *chaincfg.Params) (*poolHarness, []spendableOutp
MaxSigOpsPerTx: blockchain.MaxSigOpsPerBlock / 5,
MinRelayTxFee: 1000, // 1 Satoshi per byte
},
ChainParams: chainParams,
FetchUtxoView: chain.FetchUtxoView,
BestHeight: chain.BestHeight,
SigCache: nil,
TimeSource: blockchain.NewMedianTime(),
AddrIndex: nil,
ChainParams: chainParams,
FetchUtxoView: chain.FetchUtxoView,
BestHeight: chain.BestHeight,
MedianTimePast: chain.MedianTimePast,
SigCache: nil,
AddrIndex: nil,
}),
}

View file

@ -2582,12 +2582,12 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
MaxSigOpsPerTx: blockchain.MaxSigOpsPerBlock / 5,
MinRelayTxFee: cfg.minRelayTxFee,
},
ChainParams: chainParams,
FetchUtxoView: s.blockManager.chain.FetchUtxoView,
BestHeight: func() int32 { return bm.chain.BestSnapshot().Height },
SigCache: s.sigCache,
TimeSource: s.timeSource,
AddrIndex: s.addrIndex,
ChainParams: chainParams,
FetchUtxoView: s.blockManager.chain.FetchUtxoView,
BestHeight: func() int32 { return bm.chain.BestSnapshot().Height },
MedianTimePast: func() time.Time { return bm.chain.BestSnapshot().MedianTime },
SigCache: s.sigCache,
AddrIndex: s.addrIndex,
}
s.txMemPool = mempool.New(&txC)