parent
28929ff429
commit
cb1f3cf48c
3 changed files with 32 additions and 3 deletions
|
@ -37,6 +37,7 @@ const (
|
|||
defaultMaxRPCWebsockets = 25
|
||||
defaultVerifyEnabled = false
|
||||
defaultDbType = "leveldb"
|
||||
defaultFreeTxRelayLimit = 15.0
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -93,6 +94,7 @@ type config struct {
|
|||
CpuProfile string `long:"cpuprofile" description:"Write CPU profile to the specified file"`
|
||||
DebugLevel string `short:"d" long:"debuglevel" description:"Logging level for all subsystems {trace, debug, info, warn, error, critical} -- You may also specify <subsystem>=<level>,<subsystem2>=<level>,... to set the log level for individual subsystems -- Use show to list available subsystems"`
|
||||
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"`
|
||||
onionlookup func(string) ([]net.IP, error)
|
||||
lookup func(string) ([]net.IP, error)
|
||||
oniondial func(string, string) (net.Conn, error)
|
||||
|
@ -293,6 +295,7 @@ func loadConfig() (*config, []string, error) {
|
|||
DbType: defaultDbType,
|
||||
RPCKey: defaultRPCKeyFile,
|
||||
RPCCert: defaultRPCCertFile,
|
||||
FreeTxRelayLimit: defaultFreeTxRelayLimit,
|
||||
}
|
||||
|
||||
// Service options which are only added on Windows.
|
||||
|
|
3
doc.go
3
doc.go
|
@ -74,6 +74,9 @@ Application Options:
|
|||
the log level for individual subsystems -- Use show
|
||||
to list available subsystems (info)
|
||||
--upnp Use UPnP to map our listening port outside of NAT
|
||||
--limitfreerelay= Limit relay of transactions with no transaction fee
|
||||
to the given amount in thousands of bytes per minute
|
||||
(15)
|
||||
|
||||
Help Options:
|
||||
-h, --help Show this help message
|
||||
|
|
29
mempool.go
29
mempool.go
|
@ -97,6 +97,9 @@ type txMemPool struct {
|
|||
orphans map[btcwire.ShaHash]*btcutil.Tx
|
||||
orphansByPrev map[btcwire.ShaHash]*list.List
|
||||
outpoints map[btcwire.OutPoint]*btcutil.Tx
|
||||
pennyTotal float64 // exponentially decaying total for penny spends.
|
||||
lastPennyUnix int64 // unix time of last ``penny spend''
|
||||
|
||||
}
|
||||
|
||||
// isDust returns whether or not the passed transaction output amount is
|
||||
|
@ -858,9 +861,29 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isOrphan *bool, isNe
|
|||
return TxRuleError(str)
|
||||
}
|
||||
|
||||
// TODO(davec): Rate-limit 'free' transactions. That is to say
|
||||
// transactions which are less than the minimum relay fee and are
|
||||
// therefore considered free.
|
||||
// Free-to-relay transactions are rate limited here to prevent
|
||||
// penny-flooding with tiny transactions as a form of attack.
|
||||
if minRequiredFee == 0 {
|
||||
nowUnix := time.Now().Unix()
|
||||
// we decay passed data with an exponentially decaying ~10
|
||||
// minutes window - matches bitcoind handling.
|
||||
mp.pennyTotal *= math.Pow(1.0-1.0/600.0,
|
||||
float64(nowUnix-mp.lastPennyUnix))
|
||||
mp.lastPennyUnix = nowUnix
|
||||
|
||||
// Are we still over the limit?
|
||||
if mp.pennyTotal >= cfg.FreeTxRelayLimit*10*1000 {
|
||||
str := fmt.Sprintf("transaction %v has 0 fees and has "+
|
||||
"been rejected by the rate limiter", txHash)
|
||||
return TxRuleError(str)
|
||||
}
|
||||
oldTotal := mp.pennyTotal
|
||||
|
||||
mp.pennyTotal += float64(tx.MsgTx().SerializeSize())
|
||||
txmpLog.Debugf("rate limit: curTotal %v, nextTotal: %v, "+
|
||||
"limit %v", oldTotal, mp.pennyTotal,
|
||||
cfg.FreeTxRelayLimit*10*1000)
|
||||
}
|
||||
|
||||
// Verify crypto signatures for each input and reject the transaction if
|
||||
// any don't verify.
|
||||
|
|
Loading…
Add table
Reference in a new issue