Skip to content

Commit

Permalink
config: New option --minrelaytxfee
Browse files Browse the repository at this point in the history
Upstream commit a56db22
  • Loading branch information
davecgh committed May 19, 2016
2 parents 0c883ff + a56db22 commit 096e77d
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 21 deletions.
13 changes: 13 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ type config struct {
MiningTimeOffset int `long:"miningtimeoffset" description:"Offset the mining timestamp of a block by this many seconds (positive values are in the past)"`
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"`
MinRelayTxFee float64 `long:"minrelaytxfee" description:"The minimum transaction fee in DCR/kB to be considered a non-zero fee."`
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"`
MaxOrphanTxs int `long:"maxorphantx" description:"Max number of orphan transactions to keep in memory"`
Expand All @@ -134,6 +135,7 @@ type config struct {
oniondial func(string, string) (net.Conn, error)
dial func(string, string) (net.Conn, error)
miningAddrs []dcrutil.Address
minRelayTxFee dcrutil.Amount
}

// serviceOptions defines the configuration options for the daemon as a service on
Expand Down Expand Up @@ -331,6 +333,7 @@ func loadConfig() (*config, []string, error) {
DbType: defaultDbType,
RPCKey: defaultRPCKeyFile,
RPCCert: defaultRPCCertFile,
MinRelayTxFee: defaultMinRelayTxFee.ToCoin(),
FreeTxRelayLimit: defaultFreeTxRelayLimit,
BlockMinSize: defaultBlockMinSize,
BlockMaxSize: defaultBlockMaxSize,
Expand Down Expand Up @@ -611,6 +614,16 @@ func loadConfig() (*config, []string, error) {
}
}

// Validate the the minrelaytxfee.
cfg.minRelayTxFee, err = dcrutil.NewAmount(cfg.MinRelayTxFee)
if err != nil {
str := "%s: invalid minrelaytxfee: %v"
err := fmt.Errorf(str, funcName, err)
fmt.Fprintln(os.Stderr, err)
fmt.Fprintln(os.Stderr, usageMessage)
return nil, nil, err
}

// Limit the max block size to a sane value.
if cfg.BlockMaxSize < blockMaxSizeMin || cfg.BlockMaxSize >
blockMaxSizeMax {
Expand Down
2 changes: 2 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ 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
--minrelaytxfee= The minimum transaction fee in DCR/kB to be
considered a non-zero fee.
--limitfreerelay= Limit relay of transactions with no transaction fee
to the given amount in thousands of bytes per
minute (15)
Expand Down
18 changes: 9 additions & 9 deletions mempool.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,12 @@ const (
// considered standard.
maxStandardMultiSigKeys = 3

// minTxRelayFee is the minimum fee in atoms that is required for a
// transaction to be treated as free for relay and mining purposes. It
// is also used to help determine if a transaction is considered dust
// and as a base for calculating minimum required fees per KB for larger
// transactions. This value is in Atom/1000 bytes.
minTxRelayFee = 1e6
// defaultMinRelayTxFee is the minimum fee in atoms that is required
// for a transaction to be treated as free for relay and mining
// purposes. It is also used to help determine if a transaction is
// considered dust and as a base for calculating minimum required fees
// for larger transactions. This value is in Atoms/1000 bytes.
defaultMinRelayTxFee = dcrutil.Amount(1e6)

// minTicketFeeMainNet is the minimum fee per KB in atoms that is
// required for a ticket to enter the mempool on MainNet.
Expand Down Expand Up @@ -478,7 +478,7 @@ func (mp *txMemPool) checkTransactionStandard(tx *dcrutil.Tx, txType stake.TxTyp
// "dust".
if scriptClass == txscript.NullDataTy {
numNullDataOutputs++
} else if isDust(txOut, minTxRelayFee) &&
} else if isDust(txOut, cfg.minRelayTxFee) &&
txType != stake.TxTypeSStx {
str := fmt.Sprintf("transaction output %d: payment "+
"of %d is dust", i, txOut.Value)
Expand Down Expand Up @@ -1406,7 +1406,7 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *dcrutil.Tx, isNew,
// high-priority transactions, don't require a fee for it.
// This applies to non-stake transactions only.
serializedSize := int64(tx.MsgTx().SerializeSize())
minFee := calcMinRequiredTxRelayFee(serializedSize, minTxRelayFee)
minFee := calcMinRequiredTxRelayFee(serializedSize, cfg.minRelayTxFee)
if txType == stake.TxTypeRegular { // Non-stake only
if serializedSize >= (defaultBlockPrioritySize-1000) && txFee < minFee {
str := fmt.Sprintf("transaction %v has %v fees which is under "+
Expand Down Expand Up @@ -1482,7 +1482,7 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *dcrutil.Tx, isNew,
// then they can AllowHighFees = true
if !allowHighFees {
maxFee := calcMinRequiredTxRelayFee(serializedSize*maxRelayFeeMultiplier,
minTxRelayFee)
cfg.minRelayTxFee)
if txFee > maxFee {
err = fmt.Errorf("transaction %v has %v fee which is above the "+
"allowHighFee check threshold amount of %v", txHash,
Expand Down
5 changes: 3 additions & 2 deletions mining.go
Original file line number Diff line number Diff line change
Expand Up @@ -1531,14 +1531,15 @@ mempoolLoop:

// Skip free transactions once the block is larger than the
// minimum block size, except for stake transactions.
if sortedByFee && (prioItem.feePerKB < minTxRelayFee) &&
if sortedByFee &&
(prioItem.feePerKB < float64(cfg.minRelayTxFee)) &&
(tx.Tree() != dcrutil.TxTreeStake) &&
(blockPlusTxSize >= cfg.BlockMinSize) {

minrLog.Tracef("Skipping tx %s with feePerKB %.2f "+
"< minTxRelayFee %d and block size %d >= "+
"minBlockSize %d", tx.Sha(), prioItem.feePerKB,
minTxRelayFee, blockPlusTxSize,
cfg.minRelayTxFee, blockPlusTxSize,
cfg.BlockMinSize)
logSkippedDeps(tx, deps)
continue
Expand Down
6 changes: 3 additions & 3 deletions policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ import (
// calcMinRequiredTxRelayFee returns the minimum transaction fee required for a
// transaction with the passed serialized size to be accepted into the memory
// pool and relayed.
func calcMinRequiredTxRelayFee(serializedSize, minRelayTxFee int64) int64 {
func calcMinRequiredTxRelayFee(serializedSize int64, minRelayTxFee dcrutil.Amount) int64 {
// Calculate the minimum fee for a transaction to be allowed into the
// mempool and relayed by scaling the base fee (which is the minimum
// free transaction relay fee). minTxRelayFee is in Atom/KB, so
// divide the transaction size by 1000 to convert to kilobytes. Also,
// integer division is used so fees only increase on full kilobyte
// boundaries.

minFee := (serializedSize * minRelayTxFee) / 1000
minFee := (serializedSize * int64(minRelayTxFee)) / 1000

if minFee == 0 && minRelayTxFee > 0 {
minFee = minRelayTxFee
minFee = int64(minRelayTxFee)
}

// Set the minimum fee to the maximum possible value if the calculated
Expand Down
12 changes: 6 additions & 6 deletions policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,19 @@ func TestCalcMinRequiredTxRelayFee(t *testing.T) {
{
"zero value with default minimum relay fee",
0,
minTxRelayFee,
int64(minTxRelayFee),
defaultMinRelayTxFee,
int64(defaultMinRelayTxFee),
},
{
"1000 bytes with default minimum relay fee",
1000,
minTxRelayFee,
int64(minTxRelayFee),
defaultMinRelayTxFee,
int64(defaultMinRelayTxFee),
},
{
"max standard tx size with default minimum relay fee",
maxStandardTxSize,
minTxRelayFee,
defaultMinRelayTxFee,
100000000,
},
{
Expand All @@ -49,7 +49,7 @@ func TestCalcMinRequiredTxRelayFee(t *testing.T) {
}

for _, test := range tests {
got := calcMinRequiredTxRelayFee(test.size, int64(test.relayFee))
got := calcMinRequiredTxRelayFee(test.size, test.relayFee)
if got != test.want {
t.Errorf("TestCalcMinRequiredTxRelayFee test '%s' "+
"failed: got %v want %v", test.name, got,
Expand Down
2 changes: 1 addition & 1 deletion rpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -3517,7 +3517,7 @@ func handleGetInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (in
Proxy: cfg.Proxy,
Difficulty: getDifficultyRatio(blkHeader.Bits),
TestNet: cfg.TestNet,
RelayFee: minTxRelayFee / dcrutil.AtomsPerCoin,
RelayFee: cfg.minRelayTxFee.ToCoin(),
}

return ret, nil
Expand Down
3 changes: 3 additions & 0 deletions sample-dcrd.conf
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@
; Mempool Settings - The following options
; ------------------------------------------------------------------------------

; Set the minimum transaction fee to be considered a non-zero fee,
; minrelaytxfee=0.01

; Rate-limit free transactions to the value 15 * 1000 bytes per
; minute.
; limitfreerelay=15
Expand Down

0 comments on commit 096e77d

Please sign in to comment.