fc2e313a39
This change replaces the old transaction store file format and implementation. The most important change is how the full backing transactions for any received or sent transaction are now saved, rather than simply saving parsed-out details of the tx (tx shas, block height/hash, pkScripts, etc.). To support the change, notifications for received transaction outputs and txs spending watched outpoints have been updated to use the new redeemingtx and recvtx notifications as these contain the full tx, which is deserializead and inserted into the store. The old transaction store serialization code is completely removed, as updating to the new format automatically cannot be done. Old wallets first running past this change will error reading the file and start a full rescan to rebuild the data. Unlike previous rescan code, transactions spending outpoint managed by wallet are also included. This results in recovering not just received history, but history for sent transactions as well.
135 lines
3.2 KiB
Go
135 lines
3.2 KiB
Go
// TODO(jrick) Due to the extra encapsulation added during the switch
|
|
// to the new txstore, structures can no longer be mocked due to private
|
|
// members. Since all members for RecvTxOut and SignedTx are private, the
|
|
// simplist solution would be to make RecvTxOut an interface and create
|
|
// our own types satisifying the interface for this test package. Until
|
|
// then, disable this test.
|
|
//
|
|
// +build ignore
|
|
|
|
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"
|
|
)
|
|
|
|
func init() {
|
|
cfg = &config{
|
|
KeypoolSize: 100,
|
|
}
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestFakeTxs(t *testing.T) {
|
|
// First we need a wallet.
|
|
w, err := wallet.NewWallet("banana wallet", "", []byte("banana"),
|
|
btcwire.MainNet, &wallet.BlockStamp{}, 100)
|
|
if err != nil {
|
|
t.Errorf("Can not create encrypted wallet: %s", err)
|
|
return
|
|
}
|
|
a := &Account{
|
|
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{}
|
|
addr, err := w.NextChainedAddress(&wallet.BlockStamp{}, 100)
|
|
if err != nil {
|
|
t.Errorf("Cannot get next address: %s", err)
|
|
return
|
|
}
|
|
copy(utxo.AddrHash[:], addr.ScriptAddress())
|
|
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)
|
|
ss, err := btcscript.PayToAddrScript(addr)
|
|
if err != nil {
|
|
t.Errorf("Could not create utxo PkScript: %s", err)
|
|
return
|
|
}
|
|
utxo.Subscript = tx.PkScript(ss)
|
|
utxo.Amt = 1000000
|
|
utxo.Height = 12345
|
|
a.UtxoStore = append(a.UtxoStore, utxo)
|
|
|
|
// Fake our current block height so btcd doesn't need to be queried.
|
|
curBlock.BlockStamp.Height = 12346
|
|
|
|
// Create the transaction.
|
|
pairs := map[string]int64{
|
|
"17XhEvq9Nahdj7Xe1nv6oRe1tEmaHUuynH": 5000,
|
|
}
|
|
_, err = a.txToPairs(pairs, 1)
|
|
if err != nil {
|
|
t.Errorf("Tx creation failed: %s", err)
|
|
return
|
|
}
|
|
}
|