2016-02-28 05:30:56 +01:00
|
|
|
// Copyright (c) 2016 The btcsuite developers
|
|
|
|
// Use of this source code is governed by an ISC
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
// Package txrules provides transaction rules that should be followed by
|
|
|
|
// transaction authors for wide mempool acceptance and quick mining.
|
|
|
|
package txrules
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
|
2021-08-03 22:40:17 +02:00
|
|
|
"github.com/btcsuite/btcd/mempool"
|
2018-05-15 07:11:11 +02:00
|
|
|
"github.com/btcsuite/btcd/txscript"
|
|
|
|
"github.com/btcsuite/btcd/wire"
|
|
|
|
"github.com/btcsuite/btcutil"
|
2016-02-28 05:30:56 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// DefaultRelayFeePerKb is the default minimum relay fee policy for a mempool.
|
|
|
|
const DefaultRelayFeePerKb btcutil.Amount = 1e3
|
|
|
|
|
|
|
|
// IsDustOutput determines whether a transaction output is considered dust.
|
|
|
|
// Transactions with dust outputs are not standard and are rejected by mempools
|
|
|
|
// with default policies.
|
|
|
|
func IsDustOutput(output *wire.TxOut, relayFeePerKb btcutil.Amount) bool {
|
|
|
|
// Unspendable outputs which solely carry data are not checked for dust.
|
|
|
|
if txscript.GetScriptClass(output.PkScript) == txscript.NullDataTy {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2021-08-03 22:40:17 +02:00
|
|
|
return mempool.IsDust(output, relayFeePerKb)
|
2016-02-28 05:30:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Transaction rule violations
|
|
|
|
var (
|
|
|
|
ErrAmountNegative = errors.New("transaction output amount is negative")
|
|
|
|
ErrAmountExceedsMax = errors.New("transaction output amount exceeds maximum value")
|
|
|
|
ErrOutputIsDust = errors.New("transaction output is dust")
|
|
|
|
)
|
|
|
|
|
|
|
|
// CheckOutput performs simple consensus and policy tests on a transaction
|
|
|
|
// output.
|
|
|
|
func CheckOutput(output *wire.TxOut, relayFeePerKb btcutil.Amount) error {
|
|
|
|
if output.Value < 0 {
|
|
|
|
return ErrAmountNegative
|
|
|
|
}
|
|
|
|
if output.Value > btcutil.MaxSatoshi {
|
|
|
|
return ErrAmountExceedsMax
|
|
|
|
}
|
|
|
|
if IsDustOutput(output, relayFeePerKb) {
|
|
|
|
return ErrOutputIsDust
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// FeeForSerializeSize calculates the required fee for a transaction of some
|
|
|
|
// arbitrary size given a mempool's relay fee policy.
|
|
|
|
func FeeForSerializeSize(relayFeePerKb btcutil.Amount, txSerializeSize int) btcutil.Amount {
|
|
|
|
fee := relayFeePerKb * btcutil.Amount(txSerializeSize) / 1000
|
|
|
|
|
|
|
|
if fee == 0 && relayFeePerKb > 0 {
|
|
|
|
fee = relayFeePerKb
|
|
|
|
}
|
|
|
|
|
|
|
|
if fee < 0 || fee > btcutil.MaxSatoshi {
|
|
|
|
fee = btcutil.MaxSatoshi
|
|
|
|
}
|
|
|
|
|
|
|
|
return fee
|
|
|
|
}
|