Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

config: New option --minrelaytxfee #194

Merged
merged 2 commits into from
May 19, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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