Add new option -maxorphantx

The option -maxorphantx allows the user to specify the number of
orphan transactions to keep in memory.

Also, lower the default max orphan count from 10000 to 1000.
This commit is contained in:
David Hill 2015-05-05 10:53:15 -04:00
parent 19eae8d8a1
commit 5f8dbab47a
5 changed files with 29 additions and 10 deletions

View file

@ -463,7 +463,7 @@ func (b *blockManager) handleTxMsg(tmsg *txMsg) {
// NOTE: BitcoinJ, and possibly other wallets, don't follow the spec of // NOTE: BitcoinJ, and possibly other wallets, don't follow the spec of
// sending an inventory message and allowing the remote peer to decide // sending an inventory message and allowing the remote peer to decide
// whether or not they want to request the transaction via a getdata // whether or not they want to request the transaction via a getdata
// message. Unfortuantely the reference implementation permits // message. Unfortunately, the reference implementation permits
// unrequested data, so it has allowed wallets that don't follow the // unrequested data, so it has allowed wallets that don't follow the
// spec to proliferate. While this is not ideal, there is no check here // spec to proliferate. While this is not ideal, there is no check here
// to disconnect peers for sending unsolicited transactions to provide // to disconnect peers for sending unsolicited transactions to provide
@ -471,7 +471,9 @@ func (b *blockManager) handleTxMsg(tmsg *txMsg) {
// Process the transaction to include validation, insertion in the // Process the transaction to include validation, insertion in the
// memory pool, orphan handling, etc. // memory pool, orphan handling, etc.
err := tmsg.peer.server.txMemPool.ProcessTransaction(tmsg.tx, true, true) allowOrphans := cfg.MaxOrphanTxs > 0
err := tmsg.peer.server.txMemPool.ProcessTransaction(tmsg.tx,
allowOrphans, true)
// Remove transaction from request maps. Either the mempool/chain // Remove transaction from request maps. Either the mempool/chain
// already knows about it and as such we shouldn't have any more // already knows about it and as such we shouldn't have any more

View file

@ -106,6 +106,7 @@ type config struct {
Upnp bool `long:"upnp" description:"Use UPnP to map our listening port outside of NAT"` Upnp bool `long:"upnp" description:"Use UPnP to map our listening port outside of NAT"`
FreeTxRelayLimit float64 `long:"limitfreerelay" description:"Limit relay of transactions with no transaction fee to the given amount in thousands of bytes per minute"` FreeTxRelayLimit float64 `long:"limitfreerelay" description:"Limit relay of transactions with no transaction fee to the given amount in thousands of bytes per minute"`
NoRelayPriority bool `long:"norelaypriority" description:"Do not require free or low-fee transactions to have high priority for relaying"` NoRelayPriority bool `long:"norelaypriority" description:"Do not require free or low-fee transactions to have high priority for relaying"`
MaxOrphanTxs int `long:"maxorphantx" description:"Max number of orphan transactions to keep in memory"`
Generate bool `long:"generate" description:"Generate (mine) bitcoins using the CPU"` Generate bool `long:"generate" description:"Generate (mine) bitcoins using the CPU"`
MiningAddrs []string `long:"miningaddr" description:"Add the specified payment address to the list of addresses to use for generated blocks -- At least one address is required if the generate option is set"` MiningAddrs []string `long:"miningaddr" description:"Add the specified payment address to the list of addresses to use for generated blocks -- At least one address is required if the generate option is set"`
BlockMinSize uint32 `long:"blockminsize" description:"Mininum block size in bytes to be used when creating a block"` BlockMinSize uint32 `long:"blockminsize" description:"Mininum block size in bytes to be used when creating a block"`
@ -319,6 +320,7 @@ func loadConfig() (*config, []string, error) {
BlockMinSize: defaultBlockMinSize, BlockMinSize: defaultBlockMinSize,
BlockMaxSize: defaultBlockMaxSize, BlockMaxSize: defaultBlockMaxSize,
BlockPrioritySize: defaultBlockPrioritySize, BlockPrioritySize: defaultBlockPrioritySize,
MaxOrphanTxs: maxOrphanTransactions,
Generate: defaultGenerate, Generate: defaultGenerate,
AddrIndex: defaultAddrIndex, AddrIndex: defaultAddrIndex,
} }
@ -600,6 +602,16 @@ func loadConfig() (*config, []string, error) {
return nil, nil, err return nil, nil, err
} }
// Limit the max orphan count to a sane vlue.
if cfg.MaxOrphanTxs < 0 {
str := "%s: The maxorphantx option may not be less than 0 " +
"-- parsed [%d]"
err := fmt.Errorf(str, funcName, cfg.MaxOrphanTxs)
fmt.Fprintln(os.Stderr, err)
fmt.Fprintln(os.Stderr, usageMessage)
return nil, nil, err
}
// Limit the block priority and minimum block sizes to max block size. // Limit the block priority and minimum block sizes to max block size.
cfg.BlockPrioritySize = minUint32(cfg.BlockPrioritySize, cfg.BlockMaxSize) cfg.BlockPrioritySize = minUint32(cfg.BlockPrioritySize, cfg.BlockMaxSize)
cfg.BlockMinSize = minUint32(cfg.BlockMinSize, cfg.BlockMaxSize) cfg.BlockMinSize = minUint32(cfg.BlockMinSize, cfg.BlockMaxSize)

3
doc.go
View file

@ -81,7 +81,8 @@ Application Options:
--limitfreerelay= Limit relay of transactions with no transaction fee --limitfreerelay= Limit relay of transactions with no transaction fee
to the given amount in thousands of bytes per minute to the given amount in thousands of bytes per minute
(15) (15)
--maxorphantx= Max number of orphan transactions to keep in memory
(1000)
--generate= Generate (mine) bitcoins using the CPU --generate= Generate (mine) bitcoins using the CPU
--miningaddr= Add the specified payment address to the list of --miningaddr= Add the specified payment address to the list of
addresses to use for generated blocks -- At least addresses to use for generated blocks -- At least

View file

@ -26,10 +26,8 @@ const (
mempoolHeight = 0x7fffffff mempoolHeight = 0x7fffffff
// maxOrphanTransactions is the maximum number of orphan transactions // maxOrphanTransactions is the maximum number of orphan transactions
// that can be queued. At the time this comment was written, this // that can be queued.
// equates to 10,000 transactions, but will increase if the max allowed maxOrphanTransactions = 1000
// block payload increases.
maxOrphanTransactions = wire.MaxBlockPayload / 100
// maxOrphanTxSize is the maximum size allowed for orphan transactions. // maxOrphanTxSize is the maximum size allowed for orphan transactions.
// This helps prevent memory exhaustion attacks from sending a lot of // This helps prevent memory exhaustion attacks from sending a lot of
@ -438,7 +436,7 @@ func (mp *txMemPool) RemoveOrphan(txHash *wire.ShaHash) {
// //
// 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 *txMemPool) limitNumOrphans() error {
if len(mp.orphans)+1 > maxOrphanTransactions { if len(mp.orphans)+1 > cfg.MaxOrphanTxs && cfg.MaxOrphanTxs > 0 {
// Generate a cryptographically random hash. // Generate a cryptographically random hash.
randHashBytes := make([]byte, wire.HashSize) randHashBytes := make([]byte, wire.HashSize)
_, err := rand.Read(randHashBytes) _, err := rand.Read(randHashBytes)
@ -503,8 +501,8 @@ func (mp *txMemPool) maybeAddOrphan(tx *btcutil.Tx) error {
// //
// Note that the number of orphan transactions in the orphan pool is // Note that the number of orphan transactions in the orphan pool is
// also limited, so this equates to a maximum memory used of // also limited, so this equates to a maximum memory used of
// maxOrphanTxSize * maxOrphanTransactions (which is 500MB as of the // maxOrphanTxSize * cfg.MaxOrphanTxs (which is ~5MB using the default
// time this comment was written). // values at the time this comment was written).
serializedLen := tx.MsgTx().SerializeSize() serializedLen := tx.MsgTx().SerializeSize()
if serializedLen > maxOrphanTxSize { if serializedLen > maxOrphanTxSize {
str := fmt.Sprintf("orphan transaction size of %d bytes is "+ str := fmt.Sprintf("orphan transaction size of %d bytes is "+

View file

@ -203,6 +203,12 @@
; the default). ; the default).
; notls=1 ; notls=1
; ------------------------------------------------------------------------------
; Mempool Settings - The following options
; ------------------------------------------------------------------------------
; Limit orphan transaction pool to 1000 transactions.
; maxorphantx=1000
; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------
; Optional Transaction Indexes ; Optional Transaction Indexes
; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------