// Copyright (c) 2015 The btcsuite developers // // Permission to use, copy, modify, and distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. package wtxmgr_test import ( "fmt" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcwallet/wtxmgr" ) var ( // Spends: bogus // Outputs: 10 BTC exampleTxRecordA *wtxmgr.TxRecord // Spends: A:0 // Outputs: 5 BTC, 5 BTC exampleTxRecordB *wtxmgr.TxRecord ) func init() { tx := spendOutput(&wire.ShaHash{}, 0, 10e8) rec, err := wtxmgr.NewTxRecordFromMsgTx(tx, timeNow()) if err != nil { panic(err) } exampleTxRecordA = rec tx = spendOutput(&exampleTxRecordA.Hash, 0, 5e8, 5e8) rec, err = wtxmgr.NewTxRecordFromMsgTx(tx, timeNow()) if err != nil { panic(err) } exampleTxRecordB = rec } var exampleBlock100 = makeBlockMeta(100) // This example demonstrates reporting the Store balance given an unmined and // mined transaction given 0, 1, and 6 block confirmations. func ExampleStore_Balance() { s, teardown, err := testStore() defer teardown() if err != nil { fmt.Println(err) return } // Prints balances for 0 block confirmations, 1 confirmation, and 6 // confirmations. printBalances := func(syncHeight int32) { zeroConfBal, err := s.Balance(0, syncHeight) if err != nil { fmt.Println(err) return } oneConfBal, err := s.Balance(1, syncHeight) if err != nil { fmt.Println(err) return } sixConfBal, err := s.Balance(6, syncHeight) if err != nil { fmt.Println(err) return } fmt.Printf("%v, %v, %v\n", zeroConfBal, oneConfBal, sixConfBal) } // Insert a transaction which outputs 10 BTC unmined and mark the output // as a credit. err = s.InsertTx(exampleTxRecordA, nil) if err != nil { fmt.Println(err) return } err = s.AddCredit(exampleTxRecordA, nil, 0, false) if err != nil { fmt.Println(err) return } printBalances(100) // Mine the transaction in block 100 and print balances again with a // sync height of 100 and 105 blocks. err = s.InsertTx(exampleTxRecordA, &exampleBlock100) if err != nil { fmt.Println(err) return } printBalances(100) printBalances(105) // Output: // 10 BTC, 0 BTC, 0 BTC // 10 BTC, 10 BTC, 0 BTC // 10 BTC, 10 BTC, 10 BTC } func ExampleStore_Rollback() { s, teardown, err := testStore() defer teardown() if err != nil { fmt.Println(err) return } // Insert a transaction which outputs 10 BTC in a block at height 100. err = s.InsertTx(exampleTxRecordA, &exampleBlock100) if err != nil { fmt.Println(err) return } // Rollback everything from block 100 onwards. err = s.Rollback(100) if err != nil { fmt.Println(err) return } // Assert that the transaction is now unmined. details, err := s.TxDetails(&exampleTxRecordA.Hash) if err != nil { fmt.Println(err) return } if details == nil { fmt.Println("No details found") return } fmt.Println(details.Block.Height) // Output: // -1 } func Example_basicUsage() { // Open the database. db, dbTeardown, err := testDB() defer dbTeardown() if err != nil { fmt.Println(err) return } // Create or open a db namespace for the transaction store. ns, err := db.Namespace([]byte("txstore")) if err != nil { fmt.Println(err) return } // Create (or open) the transaction store in the provided namespace. s, err := wtxmgr.Create(ns) if err != nil { fmt.Println(err) return } // Insert an unmined transaction that outputs 10 BTC to a wallet address // at output 0. err = s.InsertTx(exampleTxRecordA, nil) if err != nil { fmt.Println(err) return } err = s.AddCredit(exampleTxRecordA, nil, 0, false) if err != nil { fmt.Println(err) return } // Insert a second transaction which spends the output, and creates two // outputs. Mark the second one (5 BTC) as wallet change. err = s.InsertTx(exampleTxRecordB, nil) if err != nil { fmt.Println(err) return } err = s.AddCredit(exampleTxRecordB, nil, 1, true) if err != nil { fmt.Println(err) return } // Mine each transaction in a block at height 100. err = s.InsertTx(exampleTxRecordA, &exampleBlock100) if err != nil { fmt.Println(err) return } err = s.InsertTx(exampleTxRecordB, &exampleBlock100) if err != nil { fmt.Println(err) return } // Print the one confirmation balance. bal, err := s.Balance(1, 100) if err != nil { fmt.Println(err) return } fmt.Println(bal) // Fetch unspent outputs. utxos, err := s.UnspentOutputs() if err != nil { fmt.Println(err) } expectedOutPoint := wire.OutPoint{Hash: exampleTxRecordB.Hash, Index: 1} for _, utxo := range utxos { fmt.Println(utxo.OutPoint == expectedOutPoint) } // Output: // 5 BTC // true }