btcd: support feefilter requests.

This only adds support for handling remote peer requests.
This commit is contained in:
David Hill 2016-10-28 12:50:08 -04:00
parent fbb49ae349
commit 2510baac35
6 changed files with 44 additions and 14 deletions

View file

@ -179,6 +179,7 @@ type GetPeerInfoResult struct {
StartingHeight int32 `json:"startingheight"` StartingHeight int32 `json:"startingheight"`
CurrentHeight int32 `json:"currentheight,omitempty"` CurrentHeight int32 `json:"currentheight,omitempty"`
BanScore int32 `json:"banscore"` BanScore int32 `json:"banscore"`
FeeFilter int64 `json:"feefilter"`
SyncNode bool `json:"syncnode"` SyncNode bool `json:"syncnode"`
} }

View file

@ -510,10 +510,11 @@ func (mp *TxPool) addTransaction(utxoView *blockchain.UtxoViewpoint, tx *btcutil
// as spent by the pool. // as spent by the pool.
txD := &TxDesc{ txD := &TxDesc{
TxDesc: mining.TxDesc{ TxDesc: mining.TxDesc{
Tx: tx, Tx: tx,
Added: time.Now(), Added: time.Now(),
Height: height, Height: height,
Fee: fee, Fee: fee,
FeePerKB: fee * 1000 / int64(tx.MsgTx().SerializeSize()),
}, },
StartingPriority: mining.CalcPriority(tx.MsgTx(), utxoView, height), StartingPriority: mining.CalcPriority(tx.MsgTx(), utxoView, height),
} }

View file

@ -55,6 +55,9 @@ type TxDesc struct {
// Fee is the total fee the transaction associated with the entry pays. // Fee is the total fee the transaction associated with the entry pays.
Fee int64 Fee int64
// FeePerKB is the fee the transaction pays in Satoshi per 1000 bytes.
FeePerKB int64
} }
// TxSource represents a source of transactions to consider for inclusion in // TxSource represents a source of transactions to consider for inclusion in
@ -575,8 +578,7 @@ mempoolLoop:
nextBlockHeight) nextBlockHeight)
// Calculate the fee in Satoshi/kB. // Calculate the fee in Satoshi/kB.
txSize := tx.MsgTx().SerializeSize() prioItem.feePerKB = txDesc.FeePerKB
prioItem.feePerKB = (txDesc.Fee * 1000) / int64(txSize)
prioItem.fee = txDesc.Fee prioItem.fee = txDesc.Fee
// Add the transaction to the priority queue to mark it ready // Add the transaction to the priority queue to mark it ready

View file

@ -2229,6 +2229,7 @@ func handleGetPeerInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{})
StartingHeight: statsSnap.StartingHeight, StartingHeight: statsSnap.StartingHeight,
CurrentHeight: statsSnap.LastBlock, CurrentHeight: statsSnap.LastBlock,
BanScore: int32(p.banScore.Int()), BanScore: int32(p.banScore.Int()),
FeeFilter: atomic.LoadInt64(&p.feeFilter),
SyncNode: p == syncPeer, SyncNode: p == syncPeer,
} }
if p.LastPingNonce() != 0 { if p.LastPingNonce() != 0 {

View file

@ -391,6 +391,7 @@ var helpDescsEnUS = map[string]string{
"getpeerinforesult-startingheight": "The latest block height the peer knew about when the connection was established", "getpeerinforesult-startingheight": "The latest block height the peer knew about when the connection was established",
"getpeerinforesult-currentheight": "The current height of the peer", "getpeerinforesult-currentheight": "The current height of the peer",
"getpeerinforesult-banscore": "The ban score", "getpeerinforesult-banscore": "The ban score",
"getpeerinforesult-feefilter": "The requested minimum fee a transaction must have to be announced to the peer",
"getpeerinforesult-syncnode": "Whether or not the peer is the sync peer", "getpeerinforesult-syncnode": "Whether or not the peer is the sync peer",
// GetPeerInfoCmd help. // GetPeerInfoCmd help.

View file

@ -181,6 +181,9 @@ type server struct {
// serverPeer extends the peer to maintain state shared by the server and // serverPeer extends the peer to maintain state shared by the server and
// the blockmanager. // the blockmanager.
type serverPeer struct { type serverPeer struct {
// The following variables must only be used atomically
feeFilter int64
*peer.Peer *peer.Peer
connReq *connmgr.ConnReq connReq *connmgr.ConnReq
@ -782,6 +785,18 @@ func (sp *serverPeer) enforceNodeBloomFlag(cmd string) bool {
return true return true
} }
func (sp *serverPeer) OnFeeFilter(p *peer.Peer, msg *wire.MsgFeeFilter) {
// Check that the passed minimum fee is a valid amount.
if msg.MinFee < 0 || msg.MinFee > btcutil.MaxSatoshi {
peerLog.Debugf("Peer %v sent an invalid feefilter '%v' -- "+
"disconnecting", sp, btcutil.Amount(msg.MinFee))
sp.Disconnect()
return
}
atomic.StoreInt64(&sp.feeFilter, msg.MinFee)
}
// OnFilterAdd is invoked when a peer receives a filteradd bitcoin // OnFilterAdd is invoked when a peer receives a filteradd bitcoin
// message and is used by remote peers to add data to an already loaded bloom // message and is used by remote peers to add data to an already loaded bloom
// filter. The peer will be disconnected if a filter is not loaded when this // filter. The peer will be disconnected if a filter is not loaded when this
@ -1316,16 +1331,24 @@ func (s *server) handleRelayInvMsg(state *peerState, msg relayMsg) {
if sp.relayTxDisabled() { if sp.relayTxDisabled() {
return return
} }
txD, ok := msg.data.(*mempool.TxDesc)
if !ok {
peerLog.Warnf("Underlying data for tx" +
" inv relay is not a *mempool.TxDesc")
return
}
// Don't relay the transaction if the transaction fee-per-kb
// is less than the peer's feefilter.
feeFilter := atomic.LoadInt64(&sp.feeFilter)
if feeFilter > 0 && txD.FeePerKB < feeFilter {
return
}
// Don't relay the transaction if there is a bloom // Don't relay the transaction if there is a bloom
// filter loaded and the transaction doesn't match it. // filter loaded and the transaction doesn't match it.
if sp.filter.IsLoaded() { if sp.filter.IsLoaded() {
txD, ok := msg.data.(*mempool.TxDesc)
if !ok {
peerLog.Warnf("Underlying data for tx" +
" inv relay is not a *mempool.TxDesc")
return
}
if !sp.filter.MatchTxAndUpdate(txD.Tx) { if !sp.filter.MatchTxAndUpdate(txD.Tx) {
return return
} }
@ -1528,6 +1551,7 @@ func newPeerConfig(sp *serverPeer) *peer.Config {
OnGetData: sp.OnGetData, OnGetData: sp.OnGetData,
OnGetBlocks: sp.OnGetBlocks, OnGetBlocks: sp.OnGetBlocks,
OnGetHeaders: sp.OnGetHeaders, OnGetHeaders: sp.OnGetHeaders,
OnFeeFilter: sp.OnFeeFilter,
OnFilterAdd: sp.OnFilterAdd, OnFilterAdd: sp.OnFilterAdd,
OnFilterClear: sp.OnFilterClear, OnFilterClear: sp.OnFilterClear,
OnFilterLoad: sp.OnFilterLoad, OnFilterLoad: sp.OnFilterLoad,
@ -1550,7 +1574,7 @@ func newPeerConfig(sp *serverPeer) *peer.Config {
ChainParams: sp.server.chainParams, ChainParams: sp.server.chainParams,
Services: sp.server.services, Services: sp.server.services,
DisableRelayTx: cfg.BlocksOnly, DisableRelayTx: cfg.BlocksOnly,
ProtocolVersion: wire.SendHeadersVersion, ProtocolVersion: wire.FeeFilterVersion,
} }
} }