2013-09-09 20:14:57 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/conformal/btcscript"
|
|
|
|
"github.com/conformal/btcutil"
|
|
|
|
"github.com/conformal/btcwallet/tx"
|
|
|
|
"github.com/conformal/btcwallet/wallet"
|
|
|
|
"github.com/conformal/btcwire"
|
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
2014-01-16 18:04:47 +01:00
|
|
|
func init() {
|
|
|
|
cfg = &config{
|
|
|
|
KeypoolSize: 100,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-04 01:22:47 +01:00
|
|
|
type allowFreeTest struct {
|
|
|
|
name string
|
|
|
|
inputs []*tx.Utxo
|
|
|
|
curHeight int32
|
|
|
|
txSize int
|
|
|
|
free bool
|
|
|
|
}
|
|
|
|
|
|
|
|
var allowFreeTests = []allowFreeTest{
|
|
|
|
allowFreeTest{
|
|
|
|
name: "priority < 57,600,000",
|
|
|
|
inputs: []*tx.Utxo{
|
|
|
|
&tx.Utxo{
|
|
|
|
Amt: uint64(btcutil.SatoshiPerBitcoin),
|
|
|
|
Height: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
curHeight: 142, // 143 confirmations
|
|
|
|
txSize: 250,
|
|
|
|
free: false,
|
|
|
|
},
|
|
|
|
allowFreeTest{
|
|
|
|
name: "priority == 57,600,000",
|
|
|
|
inputs: []*tx.Utxo{
|
|
|
|
&tx.Utxo{
|
|
|
|
Amt: uint64(btcutil.SatoshiPerBitcoin),
|
|
|
|
Height: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
curHeight: 143, // 144 confirmations
|
|
|
|
txSize: 250,
|
|
|
|
free: false,
|
|
|
|
},
|
|
|
|
allowFreeTest{
|
|
|
|
name: "priority > 57,600,000",
|
|
|
|
inputs: []*tx.Utxo{
|
|
|
|
&tx.Utxo{
|
|
|
|
Amt: uint64(btcutil.SatoshiPerBitcoin),
|
|
|
|
Height: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
curHeight: 144, // 145 confirmations
|
|
|
|
txSize: 250,
|
|
|
|
free: true,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAllowFree(t *testing.T) {
|
|
|
|
for _, test := range allowFreeTests {
|
|
|
|
calcFree := allowFree(test.curHeight, test.inputs, test.txSize)
|
|
|
|
if calcFree != test.free {
|
|
|
|
t.Errorf("Allow free test '%v' failed.", test.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-09 20:14:57 +02:00
|
|
|
func TestFakeTxs(t *testing.T) {
|
|
|
|
// First we need a wallet.
|
Implement address rescanning.
When a wallet is opened, a rescan request will be sent to btcd with
all active addresses from the wallet, to rescan from the last synced
block (now saved to the wallet file) and the current best block.
As multi-account support is further explored, rescan requests should
be batched together to send a single request for all addresses from
all wallets.
This change introduces several changes to the wallet, tx, and utxo
files. Wallet files are still compatible, however, a rescan will try
to start at the genesis block since no correct "last synced to" or
"created at block X" was saved. The tx and utxo files, however, are
not compatible and should be deleted (or an error will occur on read).
If any errors occur opening the utxo file, a rescan will start
beginning at the creation block saved in the wallet.
2013-10-30 02:22:14 +01:00
|
|
|
w, err := wallet.NewWallet("banana wallet", "", []byte("banana"),
|
2014-01-16 18:04:47 +01:00
|
|
|
btcwire.MainNet, &wallet.BlockStamp{}, 100)
|
2013-09-09 20:14:57 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Can not create encrypted wallet: %s", err)
|
|
|
|
return
|
|
|
|
}
|
2013-12-04 01:22:47 +01:00
|
|
|
a := &Account{
|
2013-09-09 20:14:57 +02:00
|
|
|
Wallet: w,
|
|
|
|
}
|
|
|
|
|
|
|
|
w.Unlock([]byte("banana"))
|
|
|
|
|
|
|
|
// Create and add a fake Utxo so we have some funds to spend.
|
|
|
|
//
|
|
|
|
// This will pass validation because btcscript is unaware of invalid
|
|
|
|
// tx inputs, however, this example would fail in btcd.
|
|
|
|
utxo := &tx.Utxo{}
|
2014-01-16 18:04:47 +01:00
|
|
|
addr, err := w.NextChainedAddress(&wallet.BlockStamp{}, 100)
|
2013-09-09 20:14:57 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Cannot get next address: %s", err)
|
|
|
|
return
|
|
|
|
}
|
2014-01-06 18:24:29 +01:00
|
|
|
copy(utxo.AddrHash[:], addr.ScriptAddress())
|
2013-09-09 20:14:57 +02:00
|
|
|
ophash := (btcwire.ShaHash)([...]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
|
|
|
|
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
|
|
|
|
28, 29, 30, 31, 32})
|
|
|
|
out := btcwire.NewOutPoint(&ophash, 0)
|
|
|
|
utxo.Out = tx.OutPoint(*out)
|
2014-01-06 18:24:29 +01:00
|
|
|
ss, err := btcscript.PayToAddrScript(addr)
|
2013-09-09 20:14:57 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Could not create utxo PkScript: %s", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
utxo.Subscript = tx.PkScript(ss)
|
2013-12-04 01:22:47 +01:00
|
|
|
utxo.Amt = 1000000
|
2013-09-09 20:14:57 +02:00
|
|
|
utxo.Height = 12345
|
2014-01-30 16:14:02 +01:00
|
|
|
a.UtxoStore = append(a.UtxoStore, utxo)
|
2013-09-09 20:14:57 +02:00
|
|
|
|
|
|
|
// Fake our current block height so btcd doesn't need to be queried.
|
Implement address rescanning.
When a wallet is opened, a rescan request will be sent to btcd with
all active addresses from the wallet, to rescan from the last synced
block (now saved to the wallet file) and the current best block.
As multi-account support is further explored, rescan requests should
be batched together to send a single request for all addresses from
all wallets.
This change introduces several changes to the wallet, tx, and utxo
files. Wallet files are still compatible, however, a rescan will try
to start at the genesis block since no correct "last synced to" or
"created at block X" was saved. The tx and utxo files, however, are
not compatible and should be deleted (or an error will occur on read).
If any errors occur opening the utxo file, a rescan will start
beginning at the creation block saved in the wallet.
2013-10-30 02:22:14 +01:00
|
|
|
curBlock.BlockStamp.Height = 12346
|
2013-09-09 20:14:57 +02:00
|
|
|
|
|
|
|
// Create the transaction.
|
2013-11-12 18:08:10 +01:00
|
|
|
pairs := map[string]int64{
|
2013-09-09 20:14:57 +02:00
|
|
|
"17XhEvq9Nahdj7Xe1nv6oRe1tEmaHUuynH": 5000,
|
|
|
|
}
|
2013-12-04 01:22:47 +01:00
|
|
|
_, err = a.txToPairs(pairs, 0)
|
2013-09-09 20:14:57 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Tx creation failed: %s", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|