mirror of
https://github.com/LBRYFoundation/lbcd.git
synced 2025-08-23 17:47:24 +00:00
mempool: Refactor mempool code to its own package. (#737)
This does the minimum work necessary to refactor the mempool code into its own package. The idea is that separating this code into its own package will greatly improve its testability, allow independent benchmarking and profiling, and open up some interesting opportunities for future development related to the memory pool. There are likely some areas related to policy that could be further refactored, however it is better to do that in future commits in order to keep the changeset as small as possible during this refactor. Overview of the major changes: - Create the new package - Move several files into the new package: - mempool.go -> mempool/mempool.go - mempoolerror.go -> mempool/error.go - policy.go -> mempool/policy.go - policy_test.go -> mempool/policy_test.go - Update mempool logging to use the new mempool package logger - Rename mempoolPolicy to Policy (so it's now mempool.Policy) - Rename mempoolConfig to Config (so it's now mempool.Config) - Rename mempoolTxDesc to TxDesc (so it's now mempool.TxDesc) - Rename txMemPool to TxPool (so it's now mempool.TxPool) - Move defaultBlockPrioritySize to the new package and export it - Export DefaultMinRelayTxFee from the mempool package - Export the CalcPriority function from the mempool package - Introduce a new RawMempoolVerbose function on the TxPool and update the RPC server to use it - Update all references to the mempool to use the package. - Add a skeleton README.md
This commit is contained in:
parent
87b3756c8c
commit
7fac099bee
12 changed files with 229 additions and 149 deletions
|
@ -17,6 +17,7 @@ import (
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
|
"github.com/btcsuite/btcd/mempool"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
)
|
)
|
||||||
|
@ -475,7 +476,7 @@ func (b *blockManager) handleTxMsg(tmsg *txMsg) {
|
||||||
// simply rejected as opposed to something actually going wrong,
|
// simply rejected as opposed to something actually going wrong,
|
||||||
// so log it as such. Otherwise, something really did go wrong,
|
// so log it as such. Otherwise, something really did go wrong,
|
||||||
// so log it as an actual error.
|
// so log it as an actual error.
|
||||||
if _, ok := err.(RuleError); ok {
|
if _, ok := err.(mempool.RuleError); ok {
|
||||||
bmgrLog.Debugf("Rejected transaction %v from %s: %v",
|
bmgrLog.Debugf("Rejected transaction %v from %s: %v",
|
||||||
txHash, tmsg.peer, err)
|
txHash, tmsg.peer, err)
|
||||||
} else {
|
} else {
|
||||||
|
@ -485,7 +486,7 @@ func (b *blockManager) handleTxMsg(tmsg *txMsg) {
|
||||||
|
|
||||||
// Convert the error into an appropriate reject message and
|
// Convert the error into an appropriate reject message and
|
||||||
// send it.
|
// send it.
|
||||||
code, reason := errToRejectErr(err)
|
code, reason := mempool.ErrToRejectErr(err)
|
||||||
tmsg.peer.PushRejectMsg(wire.CmdTx, code, reason, txHash,
|
tmsg.peer.PushRejectMsg(wire.CmdTx, code, reason, txHash,
|
||||||
false)
|
false)
|
||||||
return
|
return
|
||||||
|
@ -585,7 +586,7 @@ func (b *blockManager) handleBlockMsg(bmsg *blockMsg) {
|
||||||
|
|
||||||
// Convert the error into an appropriate reject message and
|
// Convert the error into an appropriate reject message and
|
||||||
// send it.
|
// send it.
|
||||||
code, reason := errToRejectErr(err)
|
code, reason := mempool.ErrToRejectErr(err)
|
||||||
bmsg.peer.PushRejectMsg(wire.CmdBlock, code, reason,
|
bmsg.peer.PushRejectMsg(wire.CmdBlock, code, reason,
|
||||||
blockHash, false)
|
blockHash, false)
|
||||||
return
|
return
|
||||||
|
|
|
@ -22,6 +22,7 @@ import (
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
_ "github.com/btcsuite/btcd/database/ffldb"
|
_ "github.com/btcsuite/btcd/database/ffldb"
|
||||||
|
"github.com/btcsuite/btcd/mempool"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
flags "github.com/btcsuite/go-flags"
|
flags "github.com/btcsuite/go-flags"
|
||||||
|
@ -46,7 +47,6 @@ const (
|
||||||
defaultBlockMaxSize = 750000
|
defaultBlockMaxSize = 750000
|
||||||
blockMaxSizeMin = 1000
|
blockMaxSizeMin = 1000
|
||||||
blockMaxSizeMax = wire.MaxBlockPayload - 1000
|
blockMaxSizeMax = wire.MaxBlockPayload - 1000
|
||||||
defaultBlockPrioritySize = 50000
|
|
||||||
defaultGenerate = false
|
defaultGenerate = false
|
||||||
defaultMaxOrphanTransactions = 1000
|
defaultMaxOrphanTransactions = 1000
|
||||||
defaultMaxOrphanTxSize = 5000
|
defaultMaxOrphanTxSize = 5000
|
||||||
|
@ -344,11 +344,11 @@ func loadConfig() (*config, []string, error) {
|
||||||
DbType: defaultDbType,
|
DbType: defaultDbType,
|
||||||
RPCKey: defaultRPCKeyFile,
|
RPCKey: defaultRPCKeyFile,
|
||||||
RPCCert: defaultRPCCertFile,
|
RPCCert: defaultRPCCertFile,
|
||||||
MinRelayTxFee: defaultMinRelayTxFee.ToBTC(),
|
MinRelayTxFee: mempool.DefaultMinRelayTxFee.ToBTC(),
|
||||||
FreeTxRelayLimit: defaultFreeTxRelayLimit,
|
FreeTxRelayLimit: defaultFreeTxRelayLimit,
|
||||||
BlockMinSize: defaultBlockMinSize,
|
BlockMinSize: defaultBlockMinSize,
|
||||||
BlockMaxSize: defaultBlockMaxSize,
|
BlockMaxSize: defaultBlockMaxSize,
|
||||||
BlockPrioritySize: defaultBlockPrioritySize,
|
BlockPrioritySize: mempool.DefaultBlockPrioritySize,
|
||||||
MaxOrphanTxs: defaultMaxOrphanTransactions,
|
MaxOrphanTxs: defaultMaxOrphanTransactions,
|
||||||
SigCacheMaxSize: defaultSigCacheMaxSize,
|
SigCacheMaxSize: defaultSigCacheMaxSize,
|
||||||
Generate: defaultGenerate,
|
Generate: defaultGenerate,
|
||||||
|
|
2
log.go
2
log.go
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
"github.com/btcsuite/btcd/blockchain/indexers"
|
"github.com/btcsuite/btcd/blockchain/indexers"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
|
"github.com/btcsuite/btcd/mempool"
|
||||||
"github.com/btcsuite/btcd/peer"
|
"github.com/btcsuite/btcd/peer"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btclog"
|
"github.com/btcsuite/btclog"
|
||||||
|
@ -136,6 +137,7 @@ func useLogger(subsystemID string, logger btclog.Logger) {
|
||||||
|
|
||||||
case "TXMP":
|
case "TXMP":
|
||||||
txmpLog = logger
|
txmpLog = logger
|
||||||
|
mempool.UseLogger(logger)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
23
mempool/README.md
Normal file
23
mempool/README.md
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
mempool
|
||||||
|
=======
|
||||||
|
|
||||||
|
[]
|
||||||
|
(https://travis-ci.org/btcsuite/btcd) [![ISC License]
|
||||||
|
(http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org)
|
||||||
|
[]
|
||||||
|
(http://godoc.org/github.com/btcsuite/btcd/mempool)
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This package is currently a work in progress.
|
||||||
|
|
||||||
|
## Installation and Updating
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ go get -u github.com/btcsuite/btcd/mempool
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Package mempool is licensed under the [copyfree](http://copyfree.org) ISC
|
||||||
|
License.
|
|
@ -1,8 +1,8 @@
|
||||||
// Copyright (c) 2014 The btcsuite developers
|
// Copyright (c) 2014-2016 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package main
|
package mempool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
|
@ -109,9 +109,9 @@ func extractRejectCode(err error) (wire.RejectCode, bool) {
|
||||||
return wire.RejectInvalid, false
|
return wire.RejectInvalid, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// errToRejectErr examines the underlying type of the error and returns a reject
|
// ErrToRejectErr examines the underlying type of the error and returns a reject
|
||||||
// code and string appropriate to be sent in a wire.MsgReject message.
|
// code and string appropriate to be sent in a wire.MsgReject message.
|
||||||
func errToRejectErr(err error) (wire.RejectCode, string) {
|
func ErrToRejectErr(err error) (wire.RejectCode, string) {
|
||||||
// Return the reject code along with the error text if it can be
|
// Return the reject code along with the error text if it can be
|
||||||
// extracted from the error.
|
// extracted from the error.
|
||||||
rejectCode, found := extractRejectCode(err)
|
rejectCode, found := extractRejectCode(err)
|
32
mempool/log.go
Normal file
32
mempool/log.go
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright (c) 2013-2016 The btcsuite developers
|
||||||
|
// Use of this source code is governed by an ISC
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package mempool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/btcsuite/btclog"
|
||||||
|
)
|
||||||
|
|
||||||
|
// log is a logger that is initialized with no output filters. This
|
||||||
|
// means the package will not perform any logging by default until the caller
|
||||||
|
// requests it.
|
||||||
|
var log btclog.Logger
|
||||||
|
|
||||||
|
// The default amount of logging is none.
|
||||||
|
func init() {
|
||||||
|
DisableLog()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisableLog disables all library log output. Logging output is disabled
|
||||||
|
// by default until either UseLogger or SetLogWriter are called.
|
||||||
|
func DisableLog() {
|
||||||
|
log = btclog.Disabled
|
||||||
|
}
|
||||||
|
|
||||||
|
// UseLogger uses a specified Logger to output package logging info.
|
||||||
|
// This should be used in preference to SetLogWriter if the caller is also
|
||||||
|
// using btclog.
|
||||||
|
func UseLogger(logger btclog.Logger) {
|
||||||
|
log = logger
|
||||||
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package main
|
package mempool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"container/list"
|
"container/list"
|
||||||
|
@ -16,6 +16,8 @@ import (
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
"github.com/btcsuite/btcd/blockchain/indexers"
|
"github.com/btcsuite/btcd/blockchain/indexers"
|
||||||
|
"github.com/btcsuite/btcd/btcjson"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/mining"
|
"github.com/btcsuite/btcd/mining"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
|
@ -24,26 +26,30 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// DefaultBlockPrioritySize is the default size in bytes for high-
|
||||||
|
// priority / low-fee transactions. It is used to help determine which
|
||||||
|
// are allowed into the mempool and consequently affects their relay and
|
||||||
|
// inclusion when generating block templates.
|
||||||
|
DefaultBlockPrioritySize = 50000
|
||||||
|
|
||||||
|
// MinHighPriority is the minimum priority value that allows a
|
||||||
|
// transaction to be considered high priority.
|
||||||
|
MinHighPriority = btcutil.SatoshiPerBitcoin * 144.0 / 250
|
||||||
|
|
||||||
// mempoolHeight is the height used for the "block" height field of the
|
// mempoolHeight is the height used for the "block" height field of the
|
||||||
// contextual transaction information provided in a transaction view.
|
// contextual transaction information provided in a transaction view.
|
||||||
mempoolHeight = 0x7fffffff
|
mempoolHeight = 0x7fffffff
|
||||||
)
|
)
|
||||||
|
|
||||||
// mempoolTxDesc is a descriptor containing a transaction in the mempool along
|
// Config is a descriptor containing the memory pool configuration.
|
||||||
// with additional metadata.
|
type Config struct {
|
||||||
type mempoolTxDesc struct {
|
|
||||||
mining.TxDesc
|
|
||||||
|
|
||||||
// StartingPriority is the priority of the transaction when it was added
|
|
||||||
// to the pool.
|
|
||||||
StartingPriority float64
|
|
||||||
}
|
|
||||||
|
|
||||||
// mempoolConfig is a descriptor containing the memory pool configuration.
|
|
||||||
type mempoolConfig struct {
|
|
||||||
// Policy defines the various mempool configuration options related
|
// Policy defines the various mempool configuration options related
|
||||||
// to policy.
|
// to policy.
|
||||||
Policy mempoolPolicy
|
Policy Policy
|
||||||
|
|
||||||
|
// ChainParams identifies which chain parameters the txpool is
|
||||||
|
// associated with.
|
||||||
|
ChainParams *chaincfg.Params
|
||||||
|
|
||||||
// FetchUtxoView defines the function to use to fetch unspent
|
// FetchUtxoView defines the function to use to fetch unspent
|
||||||
// transaction output information.
|
// transaction output information.
|
||||||
|
@ -65,9 +71,9 @@ type mempoolConfig struct {
|
||||||
AddrIndex *indexers.AddrIndex
|
AddrIndex *indexers.AddrIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
// mempoolPolicy houses the policy (configuration parameters) which is used to
|
// Policy houses the policy (configuration parameters) which is used to
|
||||||
// control the mempool.
|
// control the mempool.
|
||||||
type mempoolPolicy struct {
|
type Policy struct {
|
||||||
// DisableRelayPriority defines whether to relay free or low-fee
|
// DisableRelayPriority defines whether to relay free or low-fee
|
||||||
// transactions that do not have enough priority to be relayed.
|
// transactions that do not have enough priority to be relayed.
|
||||||
DisableRelayPriority bool
|
DisableRelayPriority bool
|
||||||
|
@ -95,16 +101,26 @@ type mempoolPolicy struct {
|
||||||
MinRelayTxFee btcutil.Amount
|
MinRelayTxFee btcutil.Amount
|
||||||
}
|
}
|
||||||
|
|
||||||
// txMemPool is used as a source of transactions that need to be mined into
|
// TxDesc is a descriptor containing a transaction in the mempool along with
|
||||||
// blocks and relayed to other peers. It is safe for concurrent access from
|
// additional metadata.
|
||||||
// multiple peers.
|
type TxDesc struct {
|
||||||
type txMemPool struct {
|
mining.TxDesc
|
||||||
|
|
||||||
|
// StartingPriority is the priority of the transaction when it was added
|
||||||
|
// to the pool.
|
||||||
|
StartingPriority float64
|
||||||
|
}
|
||||||
|
|
||||||
|
// TxPool is used as a source of transactions that need to be mined into blocks
|
||||||
|
// and relayed to other peers. It is safe for concurrent access from multiple
|
||||||
|
// peers.
|
||||||
|
type TxPool struct {
|
||||||
// The following variables must only be used atomically.
|
// The following variables must only be used atomically.
|
||||||
lastUpdated int64 // last time pool was updated
|
lastUpdated int64 // last time pool was updated
|
||||||
|
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
cfg mempoolConfig
|
cfg Config
|
||||||
pool map[chainhash.Hash]*mempoolTxDesc
|
pool map[chainhash.Hash]*TxDesc
|
||||||
orphans map[chainhash.Hash]*btcutil.Tx
|
orphans map[chainhash.Hash]*btcutil.Tx
|
||||||
orphansByPrev map[chainhash.Hash]map[chainhash.Hash]*btcutil.Tx
|
orphansByPrev map[chainhash.Hash]map[chainhash.Hash]*btcutil.Tx
|
||||||
outpoints map[wire.OutPoint]*btcutil.Tx
|
outpoints map[wire.OutPoint]*btcutil.Tx
|
||||||
|
@ -112,14 +128,14 @@ type txMemPool struct {
|
||||||
lastPennyUnix int64 // unix time of last ``penny spend''
|
lastPennyUnix int64 // unix time of last ``penny spend''
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the txMemPool type implements the mining.TxSource interface.
|
// Ensure the TxPool type implements the mining.TxSource interface.
|
||||||
var _ mining.TxSource = (*txMemPool)(nil)
|
var _ mining.TxSource = (*TxPool)(nil)
|
||||||
|
|
||||||
// removeOrphan is the internal function which implements the public
|
// removeOrphan is the internal function which implements the public
|
||||||
// RemoveOrphan. See the comment for RemoveOrphan for more details.
|
// RemoveOrphan. See the comment for RemoveOrphan for more details.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for writes).
|
// This function MUST be called with the mempool lock held (for writes).
|
||||||
func (mp *txMemPool) removeOrphan(txHash *chainhash.Hash) {
|
func (mp *TxPool) removeOrphan(txHash *chainhash.Hash) {
|
||||||
// Nothing to do if passed tx is not an orphan.
|
// Nothing to do if passed tx is not an orphan.
|
||||||
tx, exists := mp.orphans[*txHash]
|
tx, exists := mp.orphans[*txHash]
|
||||||
if !exists {
|
if !exists {
|
||||||
|
@ -148,7 +164,7 @@ func (mp *txMemPool) removeOrphan(txHash *chainhash.Hash) {
|
||||||
// previous orphan index.
|
// previous orphan index.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) RemoveOrphan(txHash *chainhash.Hash) {
|
func (mp *TxPool) RemoveOrphan(txHash *chainhash.Hash) {
|
||||||
mp.Lock()
|
mp.Lock()
|
||||||
mp.removeOrphan(txHash)
|
mp.removeOrphan(txHash)
|
||||||
mp.Unlock()
|
mp.Unlock()
|
||||||
|
@ -158,7 +174,7 @@ func (mp *txMemPool) RemoveOrphan(txHash *chainhash.Hash) {
|
||||||
// orphan if adding a new one would cause it to overflow the max allowed.
|
// orphan if adding a new one would cause it to overflow the max allowed.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for writes).
|
// This function MUST be called with the mempool lock held (for writes).
|
||||||
func (mp *txMemPool) limitNumOrphans() error {
|
func (mp *TxPool) limitNumOrphans() error {
|
||||||
if len(mp.orphans)+1 > mp.cfg.Policy.MaxOrphanTxs &&
|
if len(mp.orphans)+1 > mp.cfg.Policy.MaxOrphanTxs &&
|
||||||
mp.cfg.Policy.MaxOrphanTxs > 0 {
|
mp.cfg.Policy.MaxOrphanTxs > 0 {
|
||||||
|
|
||||||
|
@ -196,7 +212,7 @@ func (mp *txMemPool) limitNumOrphans() error {
|
||||||
// addOrphan adds an orphan transaction to the orphan pool.
|
// addOrphan adds an orphan transaction to the orphan pool.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for writes).
|
// This function MUST be called with the mempool lock held (for writes).
|
||||||
func (mp *txMemPool) addOrphan(tx *btcutil.Tx) {
|
func (mp *TxPool) addOrphan(tx *btcutil.Tx) {
|
||||||
// Limit the number orphan transactions to prevent memory exhaustion. A
|
// Limit the number orphan transactions to prevent memory exhaustion. A
|
||||||
// random orphan is evicted to make room if needed.
|
// random orphan is evicted to make room if needed.
|
||||||
mp.limitNumOrphans()
|
mp.limitNumOrphans()
|
||||||
|
@ -211,14 +227,14 @@ func (mp *txMemPool) addOrphan(tx *btcutil.Tx) {
|
||||||
mp.orphansByPrev[originTxHash][*tx.Hash()] = tx
|
mp.orphansByPrev[originTxHash][*tx.Hash()] = tx
|
||||||
}
|
}
|
||||||
|
|
||||||
txmpLog.Debugf("Stored orphan transaction %v (total: %d)", tx.Hash(),
|
log.Debugf("Stored orphan transaction %v (total: %d)", tx.Hash(),
|
||||||
len(mp.orphans))
|
len(mp.orphans))
|
||||||
}
|
}
|
||||||
|
|
||||||
// maybeAddOrphan potentially adds an orphan to the orphan pool.
|
// maybeAddOrphan potentially adds an orphan to the orphan pool.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for writes).
|
// This function MUST be called with the mempool lock held (for writes).
|
||||||
func (mp *txMemPool) maybeAddOrphan(tx *btcutil.Tx) error {
|
func (mp *TxPool) maybeAddOrphan(tx *btcutil.Tx) error {
|
||||||
// Ignore orphan transactions that are too large. This helps avoid
|
// Ignore orphan transactions that are too large. This helps avoid
|
||||||
// a memory exhaustion attack based on sending a lot of really large
|
// a memory exhaustion attack based on sending a lot of really large
|
||||||
// orphans. In the case there is a valid transaction larger than this,
|
// orphans. In the case there is a valid transaction larger than this,
|
||||||
|
@ -247,7 +263,7 @@ func (mp *txMemPool) maybeAddOrphan(tx *btcutil.Tx) error {
|
||||||
// exists in the main pool.
|
// exists in the main pool.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for reads).
|
// This function MUST be called with the mempool lock held (for reads).
|
||||||
func (mp *txMemPool) isTransactionInPool(hash *chainhash.Hash) bool {
|
func (mp *TxPool) isTransactionInPool(hash *chainhash.Hash) bool {
|
||||||
if _, exists := mp.pool[*hash]; exists {
|
if _, exists := mp.pool[*hash]; exists {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -259,7 +275,7 @@ func (mp *txMemPool) isTransactionInPool(hash *chainhash.Hash) bool {
|
||||||
// exists in the main pool.
|
// exists in the main pool.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) IsTransactionInPool(hash *chainhash.Hash) bool {
|
func (mp *TxPool) IsTransactionInPool(hash *chainhash.Hash) bool {
|
||||||
// Protect concurrent access.
|
// Protect concurrent access.
|
||||||
mp.RLock()
|
mp.RLock()
|
||||||
defer mp.RUnlock()
|
defer mp.RUnlock()
|
||||||
|
@ -271,7 +287,7 @@ func (mp *txMemPool) IsTransactionInPool(hash *chainhash.Hash) bool {
|
||||||
// in the orphan pool.
|
// in the orphan pool.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for reads).
|
// This function MUST be called with the mempool lock held (for reads).
|
||||||
func (mp *txMemPool) isOrphanInPool(hash *chainhash.Hash) bool {
|
func (mp *TxPool) isOrphanInPool(hash *chainhash.Hash) bool {
|
||||||
if _, exists := mp.orphans[*hash]; exists {
|
if _, exists := mp.orphans[*hash]; exists {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -283,7 +299,7 @@ func (mp *txMemPool) isOrphanInPool(hash *chainhash.Hash) bool {
|
||||||
// in the orphan pool.
|
// in the orphan pool.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) IsOrphanInPool(hash *chainhash.Hash) bool {
|
func (mp *TxPool) IsOrphanInPool(hash *chainhash.Hash) bool {
|
||||||
// Protect concurrent access.
|
// Protect concurrent access.
|
||||||
mp.RLock()
|
mp.RLock()
|
||||||
defer mp.RUnlock()
|
defer mp.RUnlock()
|
||||||
|
@ -295,7 +311,7 @@ func (mp *txMemPool) IsOrphanInPool(hash *chainhash.Hash) bool {
|
||||||
// in the main pool or in the orphan pool.
|
// in the main pool or in the orphan pool.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for reads).
|
// This function MUST be called with the mempool lock held (for reads).
|
||||||
func (mp *txMemPool) haveTransaction(hash *chainhash.Hash) bool {
|
func (mp *TxPool) haveTransaction(hash *chainhash.Hash) bool {
|
||||||
return mp.isTransactionInPool(hash) || mp.isOrphanInPool(hash)
|
return mp.isTransactionInPool(hash) || mp.isOrphanInPool(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +319,7 @@ func (mp *txMemPool) haveTransaction(hash *chainhash.Hash) bool {
|
||||||
// in the main pool or in the orphan pool.
|
// in the main pool or in the orphan pool.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) HaveTransaction(hash *chainhash.Hash) bool {
|
func (mp *TxPool) HaveTransaction(hash *chainhash.Hash) bool {
|
||||||
// Protect concurrent access.
|
// Protect concurrent access.
|
||||||
mp.RLock()
|
mp.RLock()
|
||||||
defer mp.RUnlock()
|
defer mp.RUnlock()
|
||||||
|
@ -315,7 +331,7 @@ func (mp *txMemPool) HaveTransaction(hash *chainhash.Hash) bool {
|
||||||
// RemoveTransaction. See the comment for RemoveTransaction for more details.
|
// RemoveTransaction. See the comment for RemoveTransaction for more details.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for writes).
|
// This function MUST be called with the mempool lock held (for writes).
|
||||||
func (mp *txMemPool) removeTransaction(tx *btcutil.Tx, removeRedeemers bool) {
|
func (mp *TxPool) removeTransaction(tx *btcutil.Tx, removeRedeemers bool) {
|
||||||
txHash := tx.Hash()
|
txHash := tx.Hash()
|
||||||
if removeRedeemers {
|
if removeRedeemers {
|
||||||
// Remove any transactions which rely on this one.
|
// Remove any transactions which rely on this one.
|
||||||
|
@ -350,7 +366,7 @@ func (mp *txMemPool) removeTransaction(tx *btcutil.Tx, removeRedeemers bool) {
|
||||||
// they would otherwise become orphans.
|
// they would otherwise become orphans.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) RemoveTransaction(tx *btcutil.Tx, removeRedeemers bool) {
|
func (mp *TxPool) RemoveTransaction(tx *btcutil.Tx, removeRedeemers bool) {
|
||||||
// Protect concurrent access.
|
// Protect concurrent access.
|
||||||
mp.Lock()
|
mp.Lock()
|
||||||
defer mp.Unlock()
|
defer mp.Unlock()
|
||||||
|
@ -365,7 +381,7 @@ func (mp *txMemPool) RemoveTransaction(tx *btcutil.Tx, removeRedeemers bool) {
|
||||||
// contain transactions which were previously unknown to the memory pool.
|
// contain transactions which were previously unknown to the memory pool.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) RemoveDoubleSpends(tx *btcutil.Tx) {
|
func (mp *TxPool) RemoveDoubleSpends(tx *btcutil.Tx) {
|
||||||
// Protect concurrent access.
|
// Protect concurrent access.
|
||||||
mp.Lock()
|
mp.Lock()
|
||||||
defer mp.Unlock()
|
defer mp.Unlock()
|
||||||
|
@ -384,17 +400,17 @@ func (mp *txMemPool) RemoveDoubleSpends(tx *btcutil.Tx) {
|
||||||
// helper for maybeAcceptTransaction.
|
// helper for maybeAcceptTransaction.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for writes).
|
// This function MUST be called with the mempool lock held (for writes).
|
||||||
func (mp *txMemPool) addTransaction(utxoView *blockchain.UtxoViewpoint, tx *btcutil.Tx, height int32, fee int64) {
|
func (mp *TxPool) addTransaction(utxoView *blockchain.UtxoViewpoint, tx *btcutil.Tx, height int32, fee int64) {
|
||||||
// Add the transaction to the pool and mark the referenced outpoints
|
// Add the transaction to the pool and mark the referenced outpoints
|
||||||
// as spent by the pool.
|
// as spent by the pool.
|
||||||
mp.pool[*tx.Hash()] = &mempoolTxDesc{
|
mp.pool[*tx.Hash()] = &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,
|
||||||
},
|
},
|
||||||
StartingPriority: calcPriority(tx.MsgTx(), utxoView, height),
|
StartingPriority: CalcPriority(tx.MsgTx(), utxoView, height),
|
||||||
}
|
}
|
||||||
for _, txIn := range tx.MsgTx().TxIn {
|
for _, txIn := range tx.MsgTx().TxIn {
|
||||||
mp.outpoints[txIn.PreviousOutPoint] = tx
|
mp.outpoints[txIn.PreviousOutPoint] = tx
|
||||||
|
@ -414,7 +430,7 @@ func (mp *txMemPool) addTransaction(utxoView *blockchain.UtxoViewpoint, tx *btcu
|
||||||
// main chain.
|
// main chain.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for reads).
|
// This function MUST be called with the mempool lock held (for reads).
|
||||||
func (mp *txMemPool) checkPoolDoubleSpend(tx *btcutil.Tx) error {
|
func (mp *TxPool) checkPoolDoubleSpend(tx *btcutil.Tx) error {
|
||||||
for _, txIn := range tx.MsgTx().TxIn {
|
for _, txIn := range tx.MsgTx().TxIn {
|
||||||
if txR, exists := mp.outpoints[txIn.PreviousOutPoint]; exists {
|
if txR, exists := mp.outpoints[txIn.PreviousOutPoint]; exists {
|
||||||
str := fmt.Sprintf("output %v already spent by "+
|
str := fmt.Sprintf("output %v already spent by "+
|
||||||
|
@ -433,7 +449,7 @@ func (mp *txMemPool) checkPoolDoubleSpend(tx *btcutil.Tx) error {
|
||||||
// transaction pool.
|
// transaction pool.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for reads).
|
// This function MUST be called with the mempool lock held (for reads).
|
||||||
func (mp *txMemPool) fetchInputUtxos(tx *btcutil.Tx) (*blockchain.UtxoViewpoint, error) {
|
func (mp *TxPool) fetchInputUtxos(tx *btcutil.Tx) (*blockchain.UtxoViewpoint, error) {
|
||||||
utxoView, err := mp.cfg.FetchUtxoView(tx)
|
utxoView, err := mp.cfg.FetchUtxoView(tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -457,7 +473,7 @@ func (mp *txMemPool) fetchInputUtxos(tx *btcutil.Tx) (*blockchain.UtxoViewpoint,
|
||||||
// orphans.
|
// orphans.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) FetchTransaction(txHash *chainhash.Hash) (*btcutil.Tx, error) {
|
func (mp *TxPool) FetchTransaction(txHash *chainhash.Hash) (*btcutil.Tx, error) {
|
||||||
// Protect concurrent access.
|
// Protect concurrent access.
|
||||||
mp.RLock()
|
mp.RLock()
|
||||||
defer mp.RUnlock()
|
defer mp.RUnlock()
|
||||||
|
@ -474,7 +490,7 @@ func (mp *txMemPool) FetchTransaction(txHash *chainhash.Hash) (*btcutil.Tx, erro
|
||||||
// more details.
|
// more details.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for writes).
|
// This function MUST be called with the mempool lock held (for writes).
|
||||||
func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit bool) ([]*chainhash.Hash, error) {
|
func (mp *TxPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit bool) ([]*chainhash.Hash, error) {
|
||||||
txHash := tx.Hash()
|
txHash := tx.Hash()
|
||||||
|
|
||||||
// Don't accept the transaction if it already exists in the pool. This
|
// Don't accept the transaction if it already exists in the pool. This
|
||||||
|
@ -521,7 +537,7 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit boo
|
||||||
|
|
||||||
// Don't allow non-standard transactions if the network parameters
|
// Don't allow non-standard transactions if the network parameters
|
||||||
// forbid their relaying.
|
// forbid their relaying.
|
||||||
if !activeNetParams.RelayNonStdTxs {
|
if !mp.cfg.ChainParams.RelayNonStdTxs {
|
||||||
err := checkTransactionStandard(tx, nextBlockHeight,
|
err := checkTransactionStandard(tx, nextBlockHeight,
|
||||||
mp.cfg.TimeSource, mp.cfg.Policy.MinRelayTxFee)
|
mp.cfg.TimeSource, mp.cfg.Policy.MinRelayTxFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -596,7 +612,7 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit boo
|
||||||
// Also returns the fees associated with the transaction which will be
|
// Also returns the fees associated with the transaction which will be
|
||||||
// used later.
|
// used later.
|
||||||
txFee, err := blockchain.CheckTransactionInputs(tx, nextBlockHeight,
|
txFee, err := blockchain.CheckTransactionInputs(tx, nextBlockHeight,
|
||||||
utxoView, activeNetParams.Params)
|
utxoView, mp.cfg.ChainParams)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if cerr, ok := err.(blockchain.RuleError); ok {
|
if cerr, ok := err.(blockchain.RuleError); ok {
|
||||||
return nil, chainRuleError(cerr)
|
return nil, chainRuleError(cerr)
|
||||||
|
@ -606,7 +622,7 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit boo
|
||||||
|
|
||||||
// Don't allow transactions with non-standard inputs if the network
|
// Don't allow transactions with non-standard inputs if the network
|
||||||
// parameters forbid their relaying.
|
// parameters forbid their relaying.
|
||||||
if !activeNetParams.RelayNonStdTxs {
|
if !mp.cfg.ChainParams.RelayNonStdTxs {
|
||||||
err := checkInputsStandard(tx, utxoView)
|
err := checkInputsStandard(tx, utxoView)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Attempt to extract a reject code from the error so
|
// Attempt to extract a reject code from the error so
|
||||||
|
@ -659,7 +675,7 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit boo
|
||||||
serializedSize := int64(tx.MsgTx().SerializeSize())
|
serializedSize := int64(tx.MsgTx().SerializeSize())
|
||||||
minFee := calcMinRequiredTxRelayFee(serializedSize,
|
minFee := calcMinRequiredTxRelayFee(serializedSize,
|
||||||
mp.cfg.Policy.MinRelayTxFee)
|
mp.cfg.Policy.MinRelayTxFee)
|
||||||
if serializedSize >= (defaultBlockPrioritySize-1000) && txFee < minFee {
|
if serializedSize >= (DefaultBlockPrioritySize-1000) && txFee < minFee {
|
||||||
str := fmt.Sprintf("transaction %v has %d fees which is under "+
|
str := fmt.Sprintf("transaction %v has %d fees which is under "+
|
||||||
"the required amount of %d", txHash, txFee,
|
"the required amount of %d", txHash, txFee,
|
||||||
minFee)
|
minFee)
|
||||||
|
@ -671,12 +687,12 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit boo
|
||||||
// memory pool from blocks that have been disconnected during a reorg
|
// memory pool from blocks that have been disconnected during a reorg
|
||||||
// are exempted.
|
// are exempted.
|
||||||
if isNew && !mp.cfg.Policy.DisableRelayPriority && txFee < minFee {
|
if isNew && !mp.cfg.Policy.DisableRelayPriority && txFee < minFee {
|
||||||
currentPriority := calcPriority(tx.MsgTx(), utxoView,
|
currentPriority := CalcPriority(tx.MsgTx(), utxoView,
|
||||||
nextBlockHeight)
|
nextBlockHeight)
|
||||||
if currentPriority <= minHighPriority {
|
if currentPriority <= MinHighPriority {
|
||||||
str := fmt.Sprintf("transaction %v has insufficient "+
|
str := fmt.Sprintf("transaction %v has insufficient "+
|
||||||
"priority (%g <= %g)", txHash,
|
"priority (%g <= %g)", txHash,
|
||||||
currentPriority, minHighPriority)
|
currentPriority, MinHighPriority)
|
||||||
return nil, txRuleError(wire.RejectInsufficientFee, str)
|
return nil, txRuleError(wire.RejectInsufficientFee, str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -685,8 +701,8 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit boo
|
||||||
// penny-flooding with tiny transactions as a form of attack.
|
// penny-flooding with tiny transactions as a form of attack.
|
||||||
if rateLimit && txFee < minFee {
|
if rateLimit && txFee < minFee {
|
||||||
nowUnix := time.Now().Unix()
|
nowUnix := time.Now().Unix()
|
||||||
// we decay passed data with an exponentially decaying ~10
|
// Decay passed data with an exponentially decaying ~10 minute
|
||||||
// minutes window - matches bitcoind handling.
|
// window - matches bitcoind handling.
|
||||||
mp.pennyTotal *= math.Pow(1.0-1.0/600.0,
|
mp.pennyTotal *= math.Pow(1.0-1.0/600.0,
|
||||||
float64(nowUnix-mp.lastPennyUnix))
|
float64(nowUnix-mp.lastPennyUnix))
|
||||||
mp.lastPennyUnix = nowUnix
|
mp.lastPennyUnix = nowUnix
|
||||||
|
@ -700,7 +716,7 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit boo
|
||||||
oldTotal := mp.pennyTotal
|
oldTotal := mp.pennyTotal
|
||||||
|
|
||||||
mp.pennyTotal += float64(serializedSize)
|
mp.pennyTotal += float64(serializedSize)
|
||||||
txmpLog.Tracef("rate limit: curTotal %v, nextTotal: %v, "+
|
log.Tracef("rate limit: curTotal %v, nextTotal: %v, "+
|
||||||
"limit %v", oldTotal, mp.pennyTotal,
|
"limit %v", oldTotal, mp.pennyTotal,
|
||||||
mp.cfg.Policy.FreeTxRelayLimit*10*1000)
|
mp.cfg.Policy.FreeTxRelayLimit*10*1000)
|
||||||
}
|
}
|
||||||
|
@ -719,7 +735,7 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit boo
|
||||||
// Add to transaction pool.
|
// Add to transaction pool.
|
||||||
mp.addTransaction(utxoView, tx, best.Height, txFee)
|
mp.addTransaction(utxoView, tx, best.Height, txFee)
|
||||||
|
|
||||||
txmpLog.Debugf("Accepted transaction %v (pool size: %v)", txHash,
|
log.Debugf("Accepted transaction %v (pool size: %v)", txHash,
|
||||||
len(mp.pool))
|
len(mp.pool))
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -736,7 +752,7 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit boo
|
||||||
// be added to the orphan pool.
|
// be added to the orphan pool.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) MaybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit bool) ([]*chainhash.Hash, error) {
|
func (mp *TxPool) MaybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit bool) ([]*chainhash.Hash, error) {
|
||||||
// Protect concurrent access.
|
// Protect concurrent access.
|
||||||
mp.Lock()
|
mp.Lock()
|
||||||
defer mp.Unlock()
|
defer mp.Unlock()
|
||||||
|
@ -748,7 +764,7 @@ func (mp *txMemPool) MaybeAcceptTransaction(tx *btcutil.Tx, isNew, rateLimit boo
|
||||||
// ProcessOrphans. See the comment for ProcessOrphans for more details.
|
// ProcessOrphans. See the comment for ProcessOrphans for more details.
|
||||||
//
|
//
|
||||||
// This function MUST be called with the mempool lock held (for writes).
|
// This function MUST be called with the mempool lock held (for writes).
|
||||||
func (mp *txMemPool) processOrphans(hash *chainhash.Hash) []*btcutil.Tx {
|
func (mp *TxPool) processOrphans(hash *chainhash.Hash) []*btcutil.Tx {
|
||||||
var acceptedTxns []*btcutil.Tx
|
var acceptedTxns []*btcutil.Tx
|
||||||
|
|
||||||
// Start with processing at least the passed hash.
|
// Start with processing at least the passed hash.
|
||||||
|
@ -793,9 +809,8 @@ func (mp *txMemPool) processOrphans(hash *chainhash.Hash) []*btcutil.Tx {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: Remove orphans that depend on this
|
// TODO: Remove orphans that depend on this
|
||||||
// failed transaction.
|
// failed transaction.
|
||||||
txmpLog.Debugf("Unable to move "+
|
log.Debugf("Unable to move orphan transaction "+
|
||||||
"orphan transaction %v to mempool: %v",
|
"%v to mempool: %v", tx.Hash(), err)
|
||||||
tx.Hash(), err)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -840,7 +855,7 @@ func (mp *txMemPool) processOrphans(hash *chainhash.Hash) []*btcutil.Tx {
|
||||||
// no transactions were moved from the orphan pool to the mempool.
|
// no transactions were moved from the orphan pool to the mempool.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) ProcessOrphans(hash *chainhash.Hash) []*btcutil.Tx {
|
func (mp *TxPool) ProcessOrphans(hash *chainhash.Hash) []*btcutil.Tx {
|
||||||
mp.Lock()
|
mp.Lock()
|
||||||
acceptedTxns := mp.processOrphans(hash)
|
acceptedTxns := mp.processOrphans(hash)
|
||||||
mp.Unlock()
|
mp.Unlock()
|
||||||
|
@ -859,12 +874,12 @@ func (mp *txMemPool) ProcessOrphans(hash *chainhash.Hash) []*btcutil.Tx {
|
||||||
// the passed one being accepted.
|
// the passed one being accepted.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) ProcessTransaction(tx *btcutil.Tx, allowOrphan, rateLimit bool) ([]*btcutil.Tx, error) {
|
func (mp *TxPool) ProcessTransaction(tx *btcutil.Tx, allowOrphan, rateLimit bool) ([]*btcutil.Tx, error) {
|
||||||
// Protect concurrent access.
|
// Protect concurrent access.
|
||||||
mp.Lock()
|
mp.Lock()
|
||||||
defer mp.Unlock()
|
defer mp.Unlock()
|
||||||
|
|
||||||
txmpLog.Tracef("Processing transaction %v", tx.Hash())
|
log.Tracef("Processing transaction %v", tx.Hash())
|
||||||
|
|
||||||
// Potentially accept the transaction to the memory pool.
|
// Potentially accept the transaction to the memory pool.
|
||||||
missingParents, err := mp.maybeAcceptTransaction(tx, true, rateLimit)
|
missingParents, err := mp.maybeAcceptTransaction(tx, true, rateLimit)
|
||||||
|
@ -919,7 +934,7 @@ func (mp *txMemPool) ProcessTransaction(tx *btcutil.Tx, allowOrphan, rateLimit b
|
||||||
// include the orphan pool.
|
// include the orphan pool.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) Count() int {
|
func (mp *TxPool) Count() int {
|
||||||
mp.RLock()
|
mp.RLock()
|
||||||
defer mp.RUnlock()
|
defer mp.RUnlock()
|
||||||
|
|
||||||
|
@ -930,7 +945,7 @@ func (mp *txMemPool) Count() int {
|
||||||
// pool.
|
// pool.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) TxHashes() []*chainhash.Hash {
|
func (mp *TxPool) TxHashes() []*chainhash.Hash {
|
||||||
mp.RLock()
|
mp.RLock()
|
||||||
defer mp.RUnlock()
|
defer mp.RUnlock()
|
||||||
|
|
||||||
|
@ -949,11 +964,11 @@ func (mp *txMemPool) TxHashes() []*chainhash.Hash {
|
||||||
// The descriptors are to be treated as read only.
|
// The descriptors are to be treated as read only.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) TxDescs() []*mempoolTxDesc {
|
func (mp *TxPool) TxDescs() []*TxDesc {
|
||||||
mp.RLock()
|
mp.RLock()
|
||||||
defer mp.RUnlock()
|
defer mp.RUnlock()
|
||||||
|
|
||||||
descs := make([]*mempoolTxDesc, len(mp.pool))
|
descs := make([]*TxDesc, len(mp.pool))
|
||||||
i := 0
|
i := 0
|
||||||
for _, desc := range mp.pool {
|
for _, desc := range mp.pool {
|
||||||
descs[i] = desc
|
descs[i] = desc
|
||||||
|
@ -968,7 +983,7 @@ func (mp *txMemPool) TxDescs() []*mempoolTxDesc {
|
||||||
//
|
//
|
||||||
// This is part of the mining.TxSource interface implementation and is safe for
|
// This is part of the mining.TxSource interface implementation and is safe for
|
||||||
// concurrent access as required by the interface contract.
|
// concurrent access as required by the interface contract.
|
||||||
func (mp *txMemPool) MiningDescs() []*mining.TxDesc {
|
func (mp *TxPool) MiningDescs() []*mining.TxDesc {
|
||||||
mp.RLock()
|
mp.RLock()
|
||||||
defer mp.RUnlock()
|
defer mp.RUnlock()
|
||||||
|
|
||||||
|
@ -982,23 +997,69 @@ func (mp *txMemPool) MiningDescs() []*mining.TxDesc {
|
||||||
return descs
|
return descs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RawMempoolVerbose returns all of the entries in the mempool as a fully
|
||||||
|
// populated btcjson result.
|
||||||
|
//
|
||||||
|
// This function is safe for concurrent access.
|
||||||
|
func (mp *TxPool) RawMempoolVerbose() map[string]*btcjson.GetRawMempoolVerboseResult {
|
||||||
|
mp.RLock()
|
||||||
|
defer mp.RUnlock()
|
||||||
|
|
||||||
|
result := make(map[string]*btcjson.GetRawMempoolVerboseResult,
|
||||||
|
len(mp.pool))
|
||||||
|
best := mp.cfg.Chain.BestSnapshot()
|
||||||
|
|
||||||
|
for _, desc := range mp.pool {
|
||||||
|
// Calculate the current priority based on the inputs to
|
||||||
|
// the transaction. Use zero if one or more of the
|
||||||
|
// input transactions can't be found for some reason.
|
||||||
|
tx := desc.Tx
|
||||||
|
var currentPriority float64
|
||||||
|
utxos, err := mp.fetchInputUtxos(tx)
|
||||||
|
if err == nil {
|
||||||
|
currentPriority = CalcPriority(tx.MsgTx(), utxos,
|
||||||
|
best.Height+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
mpd := &btcjson.GetRawMempoolVerboseResult{
|
||||||
|
Size: int32(tx.MsgTx().SerializeSize()),
|
||||||
|
Fee: btcutil.Amount(desc.Fee).ToBTC(),
|
||||||
|
Time: desc.Added.Unix(),
|
||||||
|
Height: int64(desc.Height),
|
||||||
|
StartingPriority: desc.StartingPriority,
|
||||||
|
CurrentPriority: currentPriority,
|
||||||
|
Depends: make([]string, 0),
|
||||||
|
}
|
||||||
|
for _, txIn := range tx.MsgTx().TxIn {
|
||||||
|
hash := &txIn.PreviousOutPoint.Hash
|
||||||
|
if mp.haveTransaction(hash) {
|
||||||
|
mpd.Depends = append(mpd.Depends,
|
||||||
|
hash.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result[tx.Hash().String()] = mpd
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// LastUpdated returns the last time a transaction was added to or removed from
|
// LastUpdated returns the last time a transaction was added to or removed from
|
||||||
// the main pool. It does not include the orphan pool.
|
// the main pool. It does not include the orphan pool.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (mp *txMemPool) LastUpdated() time.Time {
|
func (mp *TxPool) LastUpdated() time.Time {
|
||||||
return time.Unix(atomic.LoadInt64(&mp.lastUpdated), 0)
|
return time.Unix(atomic.LoadInt64(&mp.lastUpdated), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// newTxMemPool returns a new memory pool for validating and storing standalone
|
// New returns a new memory pool for validating and storing standalone
|
||||||
// transactions until they are mined into a block.
|
// transactions until they are mined into a block.
|
||||||
func newTxMemPool(cfg *mempoolConfig) *txMemPool {
|
func New(cfg *Config) *TxPool {
|
||||||
memPool := &txMemPool{
|
return &TxPool{
|
||||||
cfg: *cfg,
|
cfg: *cfg,
|
||||||
pool: make(map[chainhash.Hash]*mempoolTxDesc),
|
pool: make(map[chainhash.Hash]*TxDesc),
|
||||||
orphans: make(map[chainhash.Hash]*btcutil.Tx),
|
orphans: make(map[chainhash.Hash]*btcutil.Tx),
|
||||||
orphansByPrev: make(map[chainhash.Hash]map[chainhash.Hash]*btcutil.Tx),
|
orphansByPrev: make(map[chainhash.Hash]map[chainhash.Hash]*btcutil.Tx),
|
||||||
outpoints: make(map[wire.OutPoint]*btcutil.Tx),
|
outpoints: make(map[wire.OutPoint]*btcutil.Tx),
|
||||||
}
|
}
|
||||||
return memPool
|
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package main
|
package mempool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -38,12 +38,12 @@ const (
|
||||||
// (1 + 15*74 + 3) + (15*34 + 3) + 23 = 1650
|
// (1 + 15*74 + 3) + (15*34 + 3) + 23 = 1650
|
||||||
maxStandardSigScriptSize = 1650
|
maxStandardSigScriptSize = 1650
|
||||||
|
|
||||||
// defaultMinRelayTxFee is the minimum fee in satoshi that is required
|
// DefaultMinRelayTxFee is the minimum fee in satoshi that is required
|
||||||
// for a transaction to be treated as free for relay and mining
|
// for a transaction to be treated as free for relay and mining
|
||||||
// purposes. It is also used to help determine if a transaction is
|
// purposes. It is also used to help determine if a transaction is
|
||||||
// considered dust and as a base for calculating minimum required fees
|
// considered dust and as a base for calculating minimum required fees
|
||||||
// for larger transactions. This value is in Satoshi/1000 bytes.
|
// for larger transactions. This value is in Satoshi/1000 bytes.
|
||||||
defaultMinRelayTxFee = btcutil.Amount(1000)
|
DefaultMinRelayTxFee = btcutil.Amount(1000)
|
||||||
|
|
||||||
// maxStandardMultiSigKeys is the maximum number of public keys allowed
|
// maxStandardMultiSigKeys is the maximum number of public keys allowed
|
||||||
// in a multi-signature transaction output script for it to be
|
// in a multi-signature transaction output script for it to be
|
||||||
|
@ -75,11 +75,11 @@ func calcMinRequiredTxRelayFee(serializedSize int64, minRelayTxFee btcutil.Amoun
|
||||||
return minFee
|
return minFee
|
||||||
}
|
}
|
||||||
|
|
||||||
// calcPriority returns a transaction priority given a transaction and the sum
|
// CalcPriority returns a transaction priority given a transaction and the sum
|
||||||
// of each of its input values multiplied by their age (# of confirmations).
|
// of each of its input values multiplied by their age (# of confirmations).
|
||||||
// Thus, the final formula for the priority is:
|
// Thus, the final formula for the priority is:
|
||||||
// sum(inputValue * inputAge) / adjustedTxSize
|
// sum(inputValue * inputAge) / adjustedTxSize
|
||||||
func calcPriority(tx *wire.MsgTx, utxoView *blockchain.UtxoViewpoint, nextBlockHeight int32) float64 {
|
func CalcPriority(tx *wire.MsgTx, utxoView *blockchain.UtxoViewpoint, nextBlockHeight int32) float64 {
|
||||||
// In order to encourage spending multiple old unspent transaction
|
// In order to encourage spending multiple old unspent transaction
|
||||||
// outputs thereby reducing the total set, don't count the constant
|
// outputs thereby reducing the total set, don't count the constant
|
||||||
// overhead for each input as well as enough bytes of the signature
|
// overhead for each input as well as enough bytes of the signature
|
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package main
|
package mempool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -36,13 +36,13 @@ func TestCalcMinRequiredTxRelayFee(t *testing.T) {
|
||||||
{
|
{
|
||||||
"100 bytes with default minimum relay fee",
|
"100 bytes with default minimum relay fee",
|
||||||
100,
|
100,
|
||||||
defaultMinRelayTxFee,
|
DefaultMinRelayTxFee,
|
||||||
100,
|
100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"max standard tx size with default minimum relay fee",
|
"max standard tx size with default minimum relay fee",
|
||||||
maxStandardTxSize,
|
maxStandardTxSize,
|
||||||
defaultMinRelayTxFee,
|
DefaultMinRelayTxFee,
|
||||||
100000,
|
100000,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -470,7 +470,7 @@ func TestCheckTransactionStandard(t *testing.T) {
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
// Ensure standardness is as expected.
|
// Ensure standardness is as expected.
|
||||||
err := checkTransactionStandard(btcutil.NewTx(&test.tx),
|
err := checkTransactionStandard(btcutil.NewTx(&test.tx),
|
||||||
test.height, timeSource, defaultMinRelayTxFee)
|
test.height, timeSource, DefaultMinRelayTxFee)
|
||||||
if err == nil && test.isStandard {
|
if err == nil && test.isStandard {
|
||||||
// Test passes since function returned standard for a
|
// Test passes since function returned standard for a
|
||||||
// transaction which is intended to be standard.
|
// transaction which is intended to be standard.
|
13
mining.go
13
mining.go
|
@ -12,6 +12,7 @@ import (
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
|
"github.com/btcsuite/btcd/mempool"
|
||||||
"github.com/btcsuite/btcd/mining"
|
"github.com/btcsuite/btcd/mining"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
|
@ -27,10 +28,6 @@ const (
|
||||||
// for the updated version.
|
// for the updated version.
|
||||||
generatedBlockVersion = 4
|
generatedBlockVersion = 4
|
||||||
|
|
||||||
// minHighPriority is the minimum priority value that allows a
|
|
||||||
// transaction to be considered high priority.
|
|
||||||
minHighPriority = btcutil.SatoshiPerBitcoin * 144.0 / 250
|
|
||||||
|
|
||||||
// blockHeaderOverhead is the max number of bytes it takes to serialize
|
// blockHeaderOverhead is the max number of bytes it takes to serialize
|
||||||
// a block header and max possible transaction count.
|
// a block header and max possible transaction count.
|
||||||
blockHeaderOverhead = wire.MaxBlockHeaderPayload + wire.MaxVarIntPayload
|
blockHeaderOverhead = wire.MaxBlockHeaderPayload + wire.MaxVarIntPayload
|
||||||
|
@ -522,7 +519,7 @@ mempoolLoop:
|
||||||
// Calculate the final transaction priority using the input
|
// Calculate the final transaction priority using the input
|
||||||
// value age sum as well as the adjusted transaction size. The
|
// value age sum as well as the adjusted transaction size. The
|
||||||
// formula is: sum(inputValue * inputAge) / adjustedTxSize
|
// formula is: sum(inputValue * inputAge) / adjustedTxSize
|
||||||
prioItem.priority = calcPriority(tx.MsgTx(), utxos,
|
prioItem.priority = mempool.CalcPriority(tx.MsgTx(), utxos,
|
||||||
nextBlockHeight)
|
nextBlockHeight)
|
||||||
|
|
||||||
// Calculate the fee in Satoshi/kB.
|
// Calculate the fee in Satoshi/kB.
|
||||||
|
@ -623,13 +620,13 @@ mempoolLoop:
|
||||||
// the priority size or there are no more high-priority
|
// the priority size or there are no more high-priority
|
||||||
// transactions.
|
// transactions.
|
||||||
if !sortedByFee && (blockPlusTxSize >= policy.BlockPrioritySize ||
|
if !sortedByFee && (blockPlusTxSize >= policy.BlockPrioritySize ||
|
||||||
prioItem.priority <= minHighPriority) {
|
prioItem.priority <= mempool.MinHighPriority) {
|
||||||
|
|
||||||
minrLog.Tracef("Switching to sort by fees per "+
|
minrLog.Tracef("Switching to sort by fees per "+
|
||||||
"kilobyte blockSize %d >= BlockPrioritySize "+
|
"kilobyte blockSize %d >= BlockPrioritySize "+
|
||||||
"%d || priority %.2f <= minHighPriority %.2f",
|
"%d || priority %.2f <= minHighPriority %.2f",
|
||||||
blockPlusTxSize, policy.BlockPrioritySize,
|
blockPlusTxSize, policy.BlockPrioritySize,
|
||||||
prioItem.priority, minHighPriority)
|
prioItem.priority, mempool.MinHighPriority)
|
||||||
|
|
||||||
sortedByFee = true
|
sortedByFee = true
|
||||||
priorityQueue.SetLessFunc(txPQByFee)
|
priorityQueue.SetLessFunc(txPQByFee)
|
||||||
|
@ -641,7 +638,7 @@ mempoolLoop:
|
||||||
// final one in the high-priority section, so just fall
|
// final one in the high-priority section, so just fall
|
||||||
// though to the code below so it is added now.
|
// though to the code below so it is added now.
|
||||||
if blockPlusTxSize > policy.BlockPrioritySize ||
|
if blockPlusTxSize > policy.BlockPrioritySize ||
|
||||||
prioItem.priority < minHighPriority {
|
prioItem.priority < mempool.MinHighPriority {
|
||||||
|
|
||||||
heap.Push(priorityQueue, prioItem)
|
heap.Push(priorityQueue, prioItem)
|
||||||
continue
|
continue
|
||||||
|
|
46
rpcserver.go
46
rpcserver.go
|
@ -33,6 +33,7 @@ import (
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
|
"github.com/btcsuite/btcd/mempool"
|
||||||
"github.com/btcsuite/btcd/mining"
|
"github.com/btcsuite/btcd/mining"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
|
@ -2227,53 +2228,14 @@ func handleGetPeerInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{})
|
||||||
func handleGetRawMempool(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
func handleGetRawMempool(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||||
c := cmd.(*btcjson.GetRawMempoolCmd)
|
c := cmd.(*btcjson.GetRawMempoolCmd)
|
||||||
mp := s.server.txMemPool
|
mp := s.server.txMemPool
|
||||||
descs := mp.TxDescs()
|
|
||||||
|
|
||||||
if c.Verbose != nil && *c.Verbose {
|
if c.Verbose != nil && *c.Verbose {
|
||||||
result := make(map[string]*btcjson.GetRawMempoolVerboseResult,
|
return mp.RawMempoolVerbose(), nil
|
||||||
len(descs))
|
|
||||||
|
|
||||||
best := s.chain.BestSnapshot()
|
|
||||||
|
|
||||||
mp.RLock()
|
|
||||||
defer mp.RUnlock()
|
|
||||||
for _, desc := range descs {
|
|
||||||
// Calculate the current priority based on the inputs to
|
|
||||||
// the transaction. Use zero if one or more of the
|
|
||||||
// input transactions can't be found for some reason.
|
|
||||||
tx := desc.Tx
|
|
||||||
var currentPriority float64
|
|
||||||
utxos, err := mp.fetchInputUtxos(tx)
|
|
||||||
if err == nil {
|
|
||||||
currentPriority = calcPriority(tx.MsgTx(),
|
|
||||||
utxos, best.Height+1)
|
|
||||||
}
|
|
||||||
|
|
||||||
mpd := &btcjson.GetRawMempoolVerboseResult{
|
|
||||||
Size: int32(tx.MsgTx().SerializeSize()),
|
|
||||||
Fee: btcutil.Amount(desc.Fee).ToBTC(),
|
|
||||||
Time: desc.Added.Unix(),
|
|
||||||
Height: int64(desc.Height),
|
|
||||||
StartingPriority: desc.StartingPriority,
|
|
||||||
CurrentPriority: currentPriority,
|
|
||||||
Depends: make([]string, 0),
|
|
||||||
}
|
|
||||||
for _, txIn := range tx.MsgTx().TxIn {
|
|
||||||
hash := &txIn.PreviousOutPoint.Hash
|
|
||||||
if s.server.txMemPool.haveTransaction(hash) {
|
|
||||||
mpd.Depends = append(mpd.Depends,
|
|
||||||
hash.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result[tx.Hash().String()] = mpd
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The response is simply an array of the transaction hashes if the
|
// The response is simply an array of the transaction hashes if the
|
||||||
// verbose flag is not set.
|
// verbose flag is not set.
|
||||||
|
descs := mp.TxDescs()
|
||||||
hashStrings := make([]string, len(descs))
|
hashStrings := make([]string, len(descs))
|
||||||
for i := range hashStrings {
|
for i := range hashStrings {
|
||||||
hashStrings[i] = descs[i].Tx.Hash().String()
|
hashStrings[i] = descs[i].Tx.Hash().String()
|
||||||
|
@ -3452,7 +3414,7 @@ func handleSendRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan st
|
||||||
// so log it as an actual error. In both cases, a JSON-RPC
|
// so log it as an actual error. In both cases, a JSON-RPC
|
||||||
// error is returned to the client with the deserialization
|
// error is returned to the client with the deserialization
|
||||||
// error code (to match bitcoind behavior).
|
// error code (to match bitcoind behavior).
|
||||||
if _, ok := err.(RuleError); ok {
|
if _, ok := err.(mempool.RuleError); ok {
|
||||||
rpcsLog.Debugf("Rejected transaction %v: %v", tx.Hash(),
|
rpcsLog.Debugf("Rejected transaction %v: %v", tx.Hash(),
|
||||||
err)
|
err)
|
||||||
} else {
|
} else {
|
||||||
|
|
10
server.go
10
server.go
|
@ -26,6 +26,7 @@ import (
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/database"
|
"github.com/btcsuite/btcd/database"
|
||||||
|
"github.com/btcsuite/btcd/mempool"
|
||||||
"github.com/btcsuite/btcd/mining"
|
"github.com/btcsuite/btcd/mining"
|
||||||
"github.com/btcsuite/btcd/peer"
|
"github.com/btcsuite/btcd/peer"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
|
@ -184,7 +185,7 @@ type server struct {
|
||||||
sigCache *txscript.SigCache
|
sigCache *txscript.SigCache
|
||||||
rpcServer *rpcServer
|
rpcServer *rpcServer
|
||||||
blockManager *blockManager
|
blockManager *blockManager
|
||||||
txMemPool *txMemPool
|
txMemPool *mempool.TxPool
|
||||||
cpuMiner *CPUMiner
|
cpuMiner *CPUMiner
|
||||||
modifyRebroadcastInv chan interface{}
|
modifyRebroadcastInv chan interface{}
|
||||||
pendingPeers chan *serverPeer
|
pendingPeers chan *serverPeer
|
||||||
|
@ -2515,8 +2516,8 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
|
||||||
}
|
}
|
||||||
s.blockManager = bm
|
s.blockManager = bm
|
||||||
|
|
||||||
txC := mempoolConfig{
|
txC := mempool.Config{
|
||||||
Policy: mempoolPolicy{
|
Policy: mempool.Policy{
|
||||||
DisableRelayPriority: cfg.NoRelayPriority,
|
DisableRelayPriority: cfg.NoRelayPriority,
|
||||||
FreeTxRelayLimit: cfg.FreeTxRelayLimit,
|
FreeTxRelayLimit: cfg.FreeTxRelayLimit,
|
||||||
MaxOrphanTxs: cfg.MaxOrphanTxs,
|
MaxOrphanTxs: cfg.MaxOrphanTxs,
|
||||||
|
@ -2524,13 +2525,14 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
|
||||||
MaxSigOpsPerTx: blockchain.MaxSigOpsPerBlock / 5,
|
MaxSigOpsPerTx: blockchain.MaxSigOpsPerBlock / 5,
|
||||||
MinRelayTxFee: cfg.minRelayTxFee,
|
MinRelayTxFee: cfg.minRelayTxFee,
|
||||||
},
|
},
|
||||||
|
ChainParams: chainParams,
|
||||||
FetchUtxoView: s.blockManager.chain.FetchUtxoView,
|
FetchUtxoView: s.blockManager.chain.FetchUtxoView,
|
||||||
Chain: s.blockManager.chain,
|
Chain: s.blockManager.chain,
|
||||||
SigCache: s.sigCache,
|
SigCache: s.sigCache,
|
||||||
TimeSource: s.timeSource,
|
TimeSource: s.timeSource,
|
||||||
AddrIndex: s.addrIndex,
|
AddrIndex: s.addrIndex,
|
||||||
}
|
}
|
||||||
s.txMemPool = newTxMemPool(&txC)
|
s.txMemPool = mempool.New(&txC)
|
||||||
|
|
||||||
// Create the mining policy based on the configuration options.
|
// Create the mining policy based on the configuration options.
|
||||||
// NOTE: The CPU miner relies on the mempool, so the mempool has to be
|
// NOTE: The CPU miner relies on the mempool, so the mempool has to be
|
||||||
|
|
Loading…
Add table
Reference in a new issue