mempool: export isDust for use in other projects
This changes isDust to IsDust so other golang projects (btcwallet or lnd) can use the precise dust calculation used by btcd.
This commit is contained in:
parent
9d3279f215
commit
3c4900275c
2 changed files with 515 additions and 3 deletions
|
@ -172,12 +172,12 @@ func checkPkScriptStandard(pkScript []byte, scriptClass txscript.ScriptClass) er
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// isDust returns whether or not the passed transaction output amount is
|
// IsDust returns whether or not the passed transaction output amount is
|
||||||
// considered dust or not based on the passed minimum transaction relay fee.
|
// considered dust or not based on the passed minimum transaction relay fee.
|
||||||
// Dust is defined in terms of the minimum transaction relay fee. In
|
// Dust is defined in terms of the minimum transaction relay fee. In
|
||||||
// particular, if the cost to the network to spend coins is more than 1/3 of the
|
// particular, if the cost to the network to spend coins is more than 1/3 of the
|
||||||
// minimum transaction relay fee, it is considered dust.
|
// minimum transaction relay fee, it is considered dust.
|
||||||
func isDust(txOut *wire.TxOut, minRelayTxFee btcutil.Amount) bool {
|
func IsDust(txOut *wire.TxOut, minRelayTxFee btcutil.Amount) bool {
|
||||||
// Unspendable outputs are considered dust.
|
// Unspendable outputs are considered dust.
|
||||||
if txscript.IsUnspendable(txOut.PkScript) {
|
if txscript.IsUnspendable(txOut.PkScript) {
|
||||||
return true
|
return true
|
||||||
|
@ -352,7 +352,7 @@ func checkTransactionStandard(tx *btcutil.Tx, height int32,
|
||||||
// "dust".
|
// "dust".
|
||||||
if scriptClass == txscript.NullDataTy {
|
if scriptClass == txscript.NullDataTy {
|
||||||
numNullDataOutputs++
|
numNullDataOutputs++
|
||||||
} else if isDust(txOut, minRelayTxFee) {
|
} else if IsDust(txOut, minRelayTxFee) {
|
||||||
str := fmt.Sprintf("transaction output %d: payment "+
|
str := fmt.Sprintf("transaction output %d: payment "+
|
||||||
"of %d is dust", i, txOut.Value)
|
"of %d is dust", i, txOut.Value)
|
||||||
return txRuleError(wire.RejectDust, str)
|
return txRuleError(wire.RejectDust, str)
|
||||||
|
|
512
mempool/policy_test.go
Normal file
512
mempool/policy_test.go
Normal file
|
@ -0,0 +1,512 @@
|
||||||
|
// Copyright (c) 2013-2016 The btcsuite developers
|
||||||
|
// Use of this source code is governed by an ISC
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package mempool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/btcec"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
|
"github.com/btcsuite/btcd/txscript"
|
||||||
|
"github.com/btcsuite/btcd/wire"
|
||||||
|
"github.com/btcsuite/btcutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestCalcMinRequiredTxRelayFee tests the calcMinRequiredTxRelayFee API.
|
||||||
|
func TestCalcMinRequiredTxRelayFee(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string // test description.
|
||||||
|
size int64 // Transaction size in bytes.
|
||||||
|
relayFee btcutil.Amount // minimum relay transaction fee.
|
||||||
|
want int64 // Expected fee.
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
// Ensure combination of size and fee that are less than 1000
|
||||||
|
// produce a non-zero fee.
|
||||||
|
"250 bytes with relay fee of 3",
|
||||||
|
250,
|
||||||
|
3,
|
||||||
|
3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"100 bytes with default minimum relay fee",
|
||||||
|
100,
|
||||||
|
DefaultMinRelayTxFee,
|
||||||
|
100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"max standard tx size with default minimum relay fee",
|
||||||
|
maxStandardTxWeight / 4,
|
||||||
|
DefaultMinRelayTxFee,
|
||||||
|
100000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"max standard tx size with max satoshi relay fee",
|
||||||
|
maxStandardTxWeight / 4,
|
||||||
|
btcutil.MaxSatoshi,
|
||||||
|
btcutil.MaxSatoshi,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"1500 bytes with 5000 relay fee",
|
||||||
|
1500,
|
||||||
|
5000,
|
||||||
|
7500,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"1500 bytes with 3000 relay fee",
|
||||||
|
1500,
|
||||||
|
3000,
|
||||||
|
4500,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"782 bytes with 5000 relay fee",
|
||||||
|
782,
|
||||||
|
5000,
|
||||||
|
3910,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"782 bytes with 3000 relay fee",
|
||||||
|
782,
|
||||||
|
3000,
|
||||||
|
2346,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"782 bytes with 2550 relay fee",
|
||||||
|
782,
|
||||||
|
2550,
|
||||||
|
1994,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
got := calcMinRequiredTxRelayFee(test.size, test.relayFee)
|
||||||
|
if got != test.want {
|
||||||
|
t.Errorf("TestCalcMinRequiredTxRelayFee test '%s' "+
|
||||||
|
"failed: got %v want %v", test.name, got,
|
||||||
|
test.want)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestCheckPkScriptStandard tests the checkPkScriptStandard API.
|
||||||
|
func TestCheckPkScriptStandard(t *testing.T) {
|
||||||
|
var pubKeys [][]byte
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
pk, err := btcec.NewPrivateKey(btcec.S256())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("TestCheckPkScriptStandard NewPrivateKey failed: %v",
|
||||||
|
err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pubKeys = append(pubKeys, pk.PubKey().SerializeCompressed())
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string // test description.
|
||||||
|
script *txscript.ScriptBuilder
|
||||||
|
isStandard bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"key1 and key2",
|
||||||
|
txscript.NewScriptBuilder().AddOp(txscript.OP_2).
|
||||||
|
AddData(pubKeys[0]).AddData(pubKeys[1]).
|
||||||
|
AddOp(txscript.OP_2).AddOp(txscript.OP_CHECKMULTISIG),
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key1 or key2",
|
||||||
|
txscript.NewScriptBuilder().AddOp(txscript.OP_1).
|
||||||
|
AddData(pubKeys[0]).AddData(pubKeys[1]).
|
||||||
|
AddOp(txscript.OP_2).AddOp(txscript.OP_CHECKMULTISIG),
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"escrow",
|
||||||
|
txscript.NewScriptBuilder().AddOp(txscript.OP_2).
|
||||||
|
AddData(pubKeys[0]).AddData(pubKeys[1]).
|
||||||
|
AddData(pubKeys[2]).
|
||||||
|
AddOp(txscript.OP_3).AddOp(txscript.OP_CHECKMULTISIG),
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"one of four",
|
||||||
|
txscript.NewScriptBuilder().AddOp(txscript.OP_1).
|
||||||
|
AddData(pubKeys[0]).AddData(pubKeys[1]).
|
||||||
|
AddData(pubKeys[2]).AddData(pubKeys[3]).
|
||||||
|
AddOp(txscript.OP_4).AddOp(txscript.OP_CHECKMULTISIG),
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"malformed1",
|
||||||
|
txscript.NewScriptBuilder().AddOp(txscript.OP_3).
|
||||||
|
AddData(pubKeys[0]).AddData(pubKeys[1]).
|
||||||
|
AddOp(txscript.OP_2).AddOp(txscript.OP_CHECKMULTISIG),
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"malformed2",
|
||||||
|
txscript.NewScriptBuilder().AddOp(txscript.OP_2).
|
||||||
|
AddData(pubKeys[0]).AddData(pubKeys[1]).
|
||||||
|
AddOp(txscript.OP_3).AddOp(txscript.OP_CHECKMULTISIG),
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"malformed3",
|
||||||
|
txscript.NewScriptBuilder().AddOp(txscript.OP_0).
|
||||||
|
AddData(pubKeys[0]).AddData(pubKeys[1]).
|
||||||
|
AddOp(txscript.OP_2).AddOp(txscript.OP_CHECKMULTISIG),
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"malformed4",
|
||||||
|
txscript.NewScriptBuilder().AddOp(txscript.OP_1).
|
||||||
|
AddData(pubKeys[0]).AddData(pubKeys[1]).
|
||||||
|
AddOp(txscript.OP_0).AddOp(txscript.OP_CHECKMULTISIG),
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"malformed5",
|
||||||
|
txscript.NewScriptBuilder().AddOp(txscript.OP_1).
|
||||||
|
AddData(pubKeys[0]).AddData(pubKeys[1]).
|
||||||
|
AddOp(txscript.OP_CHECKMULTISIG),
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"malformed6",
|
||||||
|
txscript.NewScriptBuilder().AddOp(txscript.OP_1).
|
||||||
|
AddData(pubKeys[0]).AddData(pubKeys[1]),
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
script, err := test.script.Script()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("TestCheckPkScriptStandard test '%s' "+
|
||||||
|
"failed: %v", test.name, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
scriptClass := txscript.GetScriptClass(script)
|
||||||
|
got := checkPkScriptStandard(script, scriptClass)
|
||||||
|
if (test.isStandard && got != nil) ||
|
||||||
|
(!test.isStandard && got == nil) {
|
||||||
|
|
||||||
|
t.Fatalf("TestCheckPkScriptStandard test '%s' failed",
|
||||||
|
test.name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestDust tests the IsDust API.
|
||||||
|
func TestDust(t *testing.T) {
|
||||||
|
pkScript := []byte{0x76, 0xa9, 0x21, 0x03, 0x2f, 0x7e, 0x43,
|
||||||
|
0x0a, 0xa4, 0xc9, 0xd1, 0x59, 0x43, 0x7e, 0x84, 0xb9,
|
||||||
|
0x75, 0xdc, 0x76, 0xd9, 0x00, 0x3b, 0xf0, 0x92, 0x2c,
|
||||||
|
0xf3, 0xaa, 0x45, 0x28, 0x46, 0x4b, 0xab, 0x78, 0x0d,
|
||||||
|
0xba, 0x5e, 0x88, 0xac}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string // test description
|
||||||
|
txOut wire.TxOut
|
||||||
|
relayFee btcutil.Amount // minimum relay transaction fee.
|
||||||
|
isDust bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
// Any value is allowed with a zero relay fee.
|
||||||
|
"zero value with zero relay fee",
|
||||||
|
wire.TxOut{Value: 0, PkScript: pkScript},
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Zero value is dust with any relay fee"
|
||||||
|
"zero value with very small tx fee",
|
||||||
|
wire.TxOut{Value: 0, PkScript: pkScript},
|
||||||
|
1,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"38 byte public key script with value 584",
|
||||||
|
wire.TxOut{Value: 584, PkScript: pkScript},
|
||||||
|
1000,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"38 byte public key script with value 585",
|
||||||
|
wire.TxOut{Value: 585, PkScript: pkScript},
|
||||||
|
1000,
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Maximum allowed value is never dust.
|
||||||
|
"max satoshi amount is never dust",
|
||||||
|
wire.TxOut{Value: btcutil.MaxSatoshi, PkScript: pkScript},
|
||||||
|
btcutil.MaxSatoshi,
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Maximum int64 value causes overflow.
|
||||||
|
"maximum int64 value",
|
||||||
|
wire.TxOut{Value: 1<<63 - 1, PkScript: pkScript},
|
||||||
|
1<<63 - 1,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Unspendable pkScript due to an invalid public key
|
||||||
|
// script.
|
||||||
|
"unspendable pkScript",
|
||||||
|
wire.TxOut{Value: 5000, PkScript: []byte{0x01}},
|
||||||
|
0, // no relay fee
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
res := IsDust(&test.txOut, test.relayFee)
|
||||||
|
if res != test.isDust {
|
||||||
|
t.Fatalf("Dust test '%s' failed: want %v got %v",
|
||||||
|
test.name, test.isDust, res)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestCheckTransactionStandard tests the checkTransactionStandard API.
|
||||||
|
func TestCheckTransactionStandard(t *testing.T) {
|
||||||
|
// Create some dummy, but otherwise standard, data for transactions.
|
||||||
|
prevOutHash, err := chainhash.NewHashFromStr("01")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewShaHashFromStr: unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
dummyPrevOut := wire.OutPoint{Hash: *prevOutHash, Index: 1}
|
||||||
|
dummySigScript := bytes.Repeat([]byte{0x00}, 65)
|
||||||
|
dummyTxIn := wire.TxIn{
|
||||||
|
PreviousOutPoint: dummyPrevOut,
|
||||||
|
SignatureScript: dummySigScript,
|
||||||
|
Sequence: wire.MaxTxInSequenceNum,
|
||||||
|
}
|
||||||
|
addrHash := [20]byte{0x01}
|
||||||
|
addr, err := btcutil.NewAddressPubKeyHash(addrHash[:],
|
||||||
|
&chaincfg.TestNet3Params)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewAddressPubKeyHash: unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
dummyPkScript, err := txscript.PayToAddrScript(addr)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("PayToAddrScript: unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
dummyTxOut := wire.TxOut{
|
||||||
|
Value: 100000000, // 1 BTC
|
||||||
|
PkScript: dummyPkScript,
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
tx wire.MsgTx
|
||||||
|
height int32
|
||||||
|
isStandard bool
|
||||||
|
code wire.RejectCode
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Typical pay-to-pubkey-hash transaction",
|
||||||
|
tx: wire.MsgTx{
|
||||||
|
Version: 1,
|
||||||
|
TxIn: []*wire.TxIn{&dummyTxIn},
|
||||||
|
TxOut: []*wire.TxOut{&dummyTxOut},
|
||||||
|
LockTime: 0,
|
||||||
|
},
|
||||||
|
height: 300000,
|
||||||
|
isStandard: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Transaction version too high",
|
||||||
|
tx: wire.MsgTx{
|
||||||
|
Version: wire.TxVersion + 1,
|
||||||
|
TxIn: []*wire.TxIn{&dummyTxIn},
|
||||||
|
TxOut: []*wire.TxOut{&dummyTxOut},
|
||||||
|
LockTime: 0,
|
||||||
|
},
|
||||||
|
height: 300000,
|
||||||
|
isStandard: false,
|
||||||
|
code: wire.RejectNonstandard,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Transaction is not finalized",
|
||||||
|
tx: wire.MsgTx{
|
||||||
|
Version: 1,
|
||||||
|
TxIn: []*wire.TxIn{{
|
||||||
|
PreviousOutPoint: dummyPrevOut,
|
||||||
|
SignatureScript: dummySigScript,
|
||||||
|
Sequence: 0,
|
||||||
|
}},
|
||||||
|
TxOut: []*wire.TxOut{&dummyTxOut},
|
||||||
|
LockTime: 300001,
|
||||||
|
},
|
||||||
|
height: 300000,
|
||||||
|
isStandard: false,
|
||||||
|
code: wire.RejectNonstandard,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Transaction size is too large",
|
||||||
|
tx: wire.MsgTx{
|
||||||
|
Version: 1,
|
||||||
|
TxIn: []*wire.TxIn{&dummyTxIn},
|
||||||
|
TxOut: []*wire.TxOut{{
|
||||||
|
Value: 0,
|
||||||
|
PkScript: bytes.Repeat([]byte{0x00},
|
||||||
|
(maxStandardTxWeight/4)+1),
|
||||||
|
}},
|
||||||
|
LockTime: 0,
|
||||||
|
},
|
||||||
|
height: 300000,
|
||||||
|
isStandard: false,
|
||||||
|
code: wire.RejectNonstandard,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Signature script size is too large",
|
||||||
|
tx: wire.MsgTx{
|
||||||
|
Version: 1,
|
||||||
|
TxIn: []*wire.TxIn{{
|
||||||
|
PreviousOutPoint: dummyPrevOut,
|
||||||
|
SignatureScript: bytes.Repeat([]byte{0x00},
|
||||||
|
maxStandardSigScriptSize+1),
|
||||||
|
Sequence: wire.MaxTxInSequenceNum,
|
||||||
|
}},
|
||||||
|
TxOut: []*wire.TxOut{&dummyTxOut},
|
||||||
|
LockTime: 0,
|
||||||
|
},
|
||||||
|
height: 300000,
|
||||||
|
isStandard: false,
|
||||||
|
code: wire.RejectNonstandard,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Signature script that does more than push data",
|
||||||
|
tx: wire.MsgTx{
|
||||||
|
Version: 1,
|
||||||
|
TxIn: []*wire.TxIn{{
|
||||||
|
PreviousOutPoint: dummyPrevOut,
|
||||||
|
SignatureScript: []byte{
|
||||||
|
txscript.OP_CHECKSIGVERIFY},
|
||||||
|
Sequence: wire.MaxTxInSequenceNum,
|
||||||
|
}},
|
||||||
|
TxOut: []*wire.TxOut{&dummyTxOut},
|
||||||
|
LockTime: 0,
|
||||||
|
},
|
||||||
|
height: 300000,
|
||||||
|
isStandard: false,
|
||||||
|
code: wire.RejectNonstandard,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Valid but non standard public key script",
|
||||||
|
tx: wire.MsgTx{
|
||||||
|
Version: 1,
|
||||||
|
TxIn: []*wire.TxIn{&dummyTxIn},
|
||||||
|
TxOut: []*wire.TxOut{{
|
||||||
|
Value: 100000000,
|
||||||
|
PkScript: []byte{txscript.OP_TRUE},
|
||||||
|
}},
|
||||||
|
LockTime: 0,
|
||||||
|
},
|
||||||
|
height: 300000,
|
||||||
|
isStandard: false,
|
||||||
|
code: wire.RejectNonstandard,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "More than one nulldata output",
|
||||||
|
tx: wire.MsgTx{
|
||||||
|
Version: 1,
|
||||||
|
TxIn: []*wire.TxIn{&dummyTxIn},
|
||||||
|
TxOut: []*wire.TxOut{{
|
||||||
|
Value: 0,
|
||||||
|
PkScript: []byte{txscript.OP_RETURN},
|
||||||
|
}, {
|
||||||
|
Value: 0,
|
||||||
|
PkScript: []byte{txscript.OP_RETURN},
|
||||||
|
}},
|
||||||
|
LockTime: 0,
|
||||||
|
},
|
||||||
|
height: 300000,
|
||||||
|
isStandard: false,
|
||||||
|
code: wire.RejectNonstandard,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Dust output",
|
||||||
|
tx: wire.MsgTx{
|
||||||
|
Version: 1,
|
||||||
|
TxIn: []*wire.TxIn{&dummyTxIn},
|
||||||
|
TxOut: []*wire.TxOut{{
|
||||||
|
Value: 0,
|
||||||
|
PkScript: dummyPkScript,
|
||||||
|
}},
|
||||||
|
LockTime: 0,
|
||||||
|
},
|
||||||
|
height: 300000,
|
||||||
|
isStandard: false,
|
||||||
|
code: wire.RejectDust,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "One nulldata output with 0 amount (standard)",
|
||||||
|
tx: wire.MsgTx{
|
||||||
|
Version: 1,
|
||||||
|
TxIn: []*wire.TxIn{&dummyTxIn},
|
||||||
|
TxOut: []*wire.TxOut{{
|
||||||
|
Value: 0,
|
||||||
|
PkScript: []byte{txscript.OP_RETURN},
|
||||||
|
}},
|
||||||
|
LockTime: 0,
|
||||||
|
},
|
||||||
|
height: 300000,
|
||||||
|
isStandard: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
pastMedianTime := time.Now()
|
||||||
|
for _, test := range tests {
|
||||||
|
// Ensure standardness is as expected.
|
||||||
|
err := checkTransactionStandard(btcutil.NewTx(&test.tx),
|
||||||
|
test.height, pastMedianTime, DefaultMinRelayTxFee, 1)
|
||||||
|
if err == nil && test.isStandard {
|
||||||
|
// Test passes since function returned standard for a
|
||||||
|
// transaction which is intended to be standard.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err == nil && !test.isStandard {
|
||||||
|
t.Errorf("checkTransactionStandard (%s): standard when "+
|
||||||
|
"it should not be", test.name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err != nil && test.isStandard {
|
||||||
|
t.Errorf("checkTransactionStandard (%s): nonstandard "+
|
||||||
|
"when it should not be: %v", test.name, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure error type is a TxRuleError inside of a RuleError.
|
||||||
|
rerr, ok := err.(RuleError)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("checkTransactionStandard (%s): unexpected "+
|
||||||
|
"error type - got %T", test.name, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
txrerr, ok := rerr.Err.(TxRuleError)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("checkTransactionStandard (%s): unexpected "+
|
||||||
|
"error type - got %T", test.name, rerr.Err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the reject code is the expected one.
|
||||||
|
if txrerr.RejectCode != test.code {
|
||||||
|
t.Errorf("checkTransactionStandard (%s): unexpected "+
|
||||||
|
"error code - got %v, want %v", test.name,
|
||||||
|
txrerr.RejectCode, test.code)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue