Exemple #1
0
// isDust returns whether or not the passed transaction output amount is
// considered dust or not based on the passed minimum transaction relay fee.
// 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
// minimum transaction relay fee, it is considered dust.
func isDust(txOut *wire.TxOut, minRelayTxFee dcrutil.Amount) bool {
	// Unspendable outputs are considered dust.
	if txscript.IsUnspendable(txOut.PkScript) {
		return true
	}

	// The total serialized size consists of the output and the associated
	// input script to redeem it.  Since there is no input script
	// to redeem it yet, use the minimum size of a typical input script.
	//
	// Pay-to-pubkey-hash bytes breakdown:
	//
	//  Output to hash (38 bytes):
	//   2 script version, 8 value, 1 script len, 25 script
	//   [1 OP_DUP, 1 OP_HASH_160, 1 OP_DATA_20, 20 hash,
	//   1 OP_EQUALVERIFY, 1 OP_CHECKSIG]
	//
	//  Input with compressed pubkey (165 bytes):
	//   37 prev outpoint, 16 fraud proof, 1 script len,
	//   107 script [1 OP_DATA_72, 72 sig, 1 OP_DATA_33,
	//   33 compressed pubkey], 4 sequence
	//
	//  Input with uncompressed pubkey (198 bytes):
	//   37 prev outpoint,  16 fraud proof, 1 script len,
	//   139 script [1 OP_DATA_72, 72 sig, 1 OP_DATA_65,
	//   65 compressed pubkey], 4 sequence, 1 witness
	//   append
	//
	// Pay-to-pubkey bytes breakdown:
	//
	//  Output to compressed pubkey (46 bytes):
	//   2 script version, 8 value, 1 script len, 35 script
	//   [1 OP_DATA_33, 33 compressed pubkey, 1 OP_CHECKSIG]
	//
	//  Output to uncompressed pubkey (76 bytes):
	//   2 script version, 8 value, 1 script len, 67 script
	//   [1 OP_DATA_65, 65 pubkey, 1 OP_CHECKSIG]
	//
	//  Input (133 bytes):
	//   37 prev outpoint, 16 fraud proof, 1 script len, 73
	//   script [1 OP_DATA_72, 72 sig], 4 sequence, 1 witness
	//   append
	//
	// Theoretically this could examine the script type of the output script
	// and use a different size for the typical input script size for
	// pay-to-pubkey vs pay-to-pubkey-hash inputs per the above breakdowns,
	// but the only combinination which is less than the value chosen is
	// a pay-to-pubkey script with a compressed pubkey, which is not very
	// common.
	//
	// The most common scripts are pay-to-pubkey-hash, and as per the above
	// breakdown, the minimum size of a p2pkh input script is 165 bytes.  So
	// that figure is used.
	totalSize := txOut.SerializeSize() + 165

	// The output is considered dust if the cost to the network to spend the
	// coins is more than 1/3 of the minimum free transaction relay fee.
	// minFreeTxRelayFee is in Atom/KB, so multiply by 1000 to
	// convert to bytes.
	//
	// Using the typical values for a pay-to-pubkey-hash transaction from
	// the breakdown above and the default minimum free transaction relay
	// fee of 5000000, this equates to values less than 546 atoms being
	// considered dust.
	//
	// The following is equivalent to (value/totalSize) * (1/3) * 1000
	// without needing to do floating point math.
	return txOut.Value*1000/(3*int64(totalSize)) < int64(minRelayTxFee)
}
Exemple #2
0
// TestCalcSignatureHash does some rudimentary testing of msg hash calculation.
func TestCalcSignatureHash(t *testing.T) {
	tx := new(wire.MsgTx)
	for i := 0; i < 3; i++ {
		txIn := new(wire.TxIn)
		txIn.Sequence = 0xFFFFFFFF
		txIn.PreviousOutPoint.Hash = chainhash.HashFuncH([]byte{byte(i)})
		txIn.PreviousOutPoint.Index = uint32(i)
		txIn.PreviousOutPoint.Tree = int8(0)
		tx.AddTxIn(txIn)
	}
	for i := 0; i < 2; i++ {
		txOut := new(wire.TxOut)
		txOut.PkScript = []byte{0x01, 0x01, 0x02, 0x03}
		txOut.Value = 0x0000FF00FF00FF00
		tx.AddTxOut(txOut)
	}

	want, _ := hex.DecodeString("d09285b6f60c71329323bc2e76c48" +
		"a462cde4e1032aa8f59c55823f1722c7f4a")
	pops, _ := txscript.TstParseScript([]byte{0x01, 0x01, 0x02, 0x03})

	// Test prefix caching.
	msg1, err := txscript.CalcSignatureHash(pops, txscript.SigHashAll, tx, 0, nil)
	if err != nil {
		t.Fatalf("unexpected error %v", err.Error())
	}

	prefixHash := tx.TxSha()
	msg2, err := txscript.CalcSignatureHash(pops, txscript.SigHashAll, tx, 0,
		&prefixHash)
	if err != nil {
		t.Fatalf("unexpected error %v", err.Error())
	}

	if !bytes.Equal(msg1, want) {
		t.Errorf("for sighash all sig noncached wrong msg %x given, want %x",
			msg1,
			want)
	}
	if !bytes.Equal(msg2, want) {
		t.Errorf("for sighash all sig cached wrong msg %x given, want %x",
			msg1,
			want)
	}
	if !bytes.Equal(msg1, msg2) {
		t.Errorf("for sighash all sig non-equivalent msgs %x and %x were "+
			"returned when using a cached prefix",
			msg1,
			msg2)
	}

	// Move the index and make sure that we get a whole new hash, despite
	// using the same TxOuts.
	msg3, err := txscript.CalcSignatureHash(pops, txscript.SigHashAll, tx, 1,
		&prefixHash)
	if err != nil {
		t.Fatalf("unexpected error %v", err.Error())
	}

	if bytes.Equal(msg1, msg3) {
		t.Errorf("for sighash all sig equivalent msgs %x and %x were "+
			"returned when using a cached prefix but different indices",
			msg1,
			msg3)
	}
}