example_test.go_ raw

   1  // Copyright (c) 2015 The btcsuite developers
   2  package wtxmgr_test
   3  
   4  import (
   5  	"fmt"
   6  
   7  	"github.com/p9c/p9/pkg/chain/config/netparams"
   8  	chainhash "github.com/p9c/p9/pkg/chain/hash"
   9  	wtxmgr "github.com/p9c/p9/pkg/chain/tx/mgr"
  10  	"github.com/p9c/p9/pkg/chain/wire"
  11  	"github.com/p9c/p9/pkg/db/walletdb"
  12  )
  13  
  14  var (
  15  	// Spends: bogus
  16  	// Outputs: 10 DUO
  17  	exampleTxRecordA *wtxmgr.TxRecord
  18  	// Spends: A:0
  19  	// Outputs: 5 DUO, 5 DUO
  20  	exampleTxRecordB *wtxmgr.TxRecord
  21  )
  22  
  23  func init() {
  24  	tx := spendOutput(&chainhash.Hash{}, 0, 10e8)
  25  	rec, e := wtxmgr.NewTxRecordFromMsgTx(tx, timeNow())
  26  	if e != nil  {
  27  		panic(err)
  28  	}
  29  	exampleTxRecordA = rec
  30  	tx = spendOutput(&exampleTxRecordA.Hash, 0, 5e8, 5e8)
  31  	rec, e = wtxmgr.NewTxRecordFromMsgTx(tx, timeNow())
  32  	if e != nil  {
  33  		panic(err)
  34  	}
  35  	exampleTxRecordB = rec
  36  }
  37  
  38  var exampleBlock100 = makeBlockMeta(100)
  39  
  40  // This example demonstrates reporting the Store balance given an unmined and mined transaction given 0, 1, and 6 block
  41  // confirmations.
  42  func ExampleStore_Balance() {
  43  	s, db, teardown, e := testStore()
  44  	defer teardown()
  45  	if e != nil  {
  46  				return
  47  	}
  48  	// Prints balances for 0 block confirmations, 1 confirmation, and 6
  49  	// confirmations.
  50  	printBalances := func(syncHeight int32) {
  51  		dbtx, e := db.BeginReadTx()
  52  		if e != nil  {
  53  						return
  54  		}
  55  		defer func() {
  56  			e := dbtx.Rollback()
  57  			if e != nil  {
  58  							}
  59  		}()
  60  		ns := dbtx.ReadBucket(namespaceKey)
  61  		zeroConfBal, e := s.Balance(ns, 0, syncHeight)
  62  		if e != nil  {
  63  						return
  64  		}
  65  		oneConfBal, e := s.Balance(ns, 1, syncHeight)
  66  		if e != nil  {
  67  						return
  68  		}
  69  		sixConfBal, e := s.Balance(ns, 6, syncHeight)
  70  		if e != nil  {
  71  						return
  72  		}
  73  		fmt.Printf("%v, %v, %v\n", zeroConfBal, oneConfBal, sixConfBal)
  74  	}
  75  	// Insert a transaction which outputs 10 DUO unmined and mark the output
  76  	// as a credit.
  77  	e = walletdb.Update(db, func(tx walletdb.ReadWriteTx) (e error) {
  78  		ns := tx.ReadWriteBucket(namespaceKey)
  79  		e := s.InsertTx(ns, exampleTxRecordA, nil)
  80  		if e != nil  {
  81  			return err
  82  		}
  83  		return s.AddCredit(ns, exampleTxRecordA, nil, 0, false)
  84  	})
  85  	if e != nil  {
  86  				return
  87  	}
  88  	printBalances(100)
  89  	// Mine the transaction in block 100 and print balances again with a
  90  	// sync height of 100 and 105 blocks.
  91  	e = walletdb.Update(db, func(tx walletdb.ReadWriteTx) (e error) {
  92  		ns := tx.ReadWriteBucket(namespaceKey)
  93  		return s.InsertTx(ns, exampleTxRecordA, &exampleBlock100)
  94  	})
  95  	if e != nil  {
  96  				return
  97  	}
  98  	printBalances(100)
  99  	printBalances(105)
 100  	// Output:
 101  	// 10 DUO, 0 DUO, 0 DUO
 102  	// 10 DUO, 10 DUO, 0 DUO
 103  	// 10 DUO, 10 DUO, 10 DUO
 104  }
 105  func ExampleStore_Rollback() {
 106  	s, db, teardown, e := testStore()
 107  	defer teardown()
 108  	if e != nil  {
 109  				return
 110  	}
 111  	e = walletdb.Update(db, func(tx walletdb.ReadWriteTx) (e error) {
 112  		ns := tx.ReadWriteBucket(namespaceKey)
 113  		// Insert a transaction which outputs 10 DUO in a block at height 100.
 114  		e := s.InsertTx(ns, exampleTxRecordA, &exampleBlock100)
 115  		if e != nil  {
 116  			return err
 117  		}
 118  		// Rollback everything from block 100 onwards.
 119  		e = s.Rollback(ns, 100)
 120  		if e != nil  {
 121  			return err
 122  		}
 123  		// Assert that the transaction is now unmined.
 124  		details, e := s.TxDetails(ns, &exampleTxRecordA.Hash)
 125  		if e != nil  {
 126  			return err
 127  		}
 128  		if details == nil {
 129  			return fmt.Errorf("no details found")
 130  		}
 131  		fmt.Println(details.Block.Height)
 132  		return nil
 133  	})
 134  	if e != nil  {
 135  				return
 136  	}
 137  	// Output:
 138  	// -1
 139  }
 140  func Example_basicUsage() {
 141  	// Open the database.
 142  	db, dbTeardown, e := testDB()
 143  	defer dbTeardown()
 144  	if e != nil  {
 145  				return
 146  	}
 147  	// Open a read-write transaction to operate on the database.
 148  	dbtx, e := db.BeginReadWriteTx()
 149  	if e != nil  {
 150  				return
 151  	}
 152  	defer func() {
 153  		e := dbtx.Commit()
 154  		if e != nil  {
 155  					}
 156  	}()
 157  	// Create a bucket for the transaction store.
 158  	b, e := dbtx.CreateTopLevelBucket([]byte("txstore"))
 159  	if e != nil  {
 160  				return
 161  	}
 162  	// Create and open the transaction store in the provided namespace.
 163  	e = wtxmgr.Create(b)
 164  	if e != nil  {
 165  				return
 166  	}
 167  	s, e := wtxmgr.Open(b, &netparams.TestNet3Params)
 168  	if e != nil  {
 169  				return
 170  	}
 171  	// Insert an unmined transaction that outputs 10 DUO to a wallet address
 172  	// at output 0.
 173  	e = s.InsertTx(b, exampleTxRecordA, nil)
 174  	if e != nil  {
 175  				return
 176  	}
 177  	e = s.AddCredit(b, exampleTxRecordA, nil, 0, false)
 178  	if e != nil  {
 179  				return
 180  	}
 181  	// Insert a second transaction which spends the output, and creates two
 182  	// outputs.  Mark the second one (5 DUO) as wallet change.
 183  	e = s.InsertTx(b, exampleTxRecordB, nil)
 184  	if e != nil  {
 185  				return
 186  	}
 187  	e = s.AddCredit(b, exampleTxRecordB, nil, 1, true)
 188  	if e != nil  {
 189  				return
 190  	}
 191  	// Mine each transaction in a block at height 100.
 192  	e = s.InsertTx(b, exampleTxRecordA, &exampleBlock100)
 193  	if e != nil  {
 194  				return
 195  	}
 196  	e = s.InsertTx(b, exampleTxRecordB, &exampleBlock100)
 197  	if e != nil  {
 198  				return
 199  	}
 200  	// Print the one confirmation balance.
 201  	bal, e := s.Balance(b, 1, 100)
 202  	if e != nil  {
 203  				return
 204  	}
 205  	fmt.Println(bal)
 206  	// Fetch unspent outputs.
 207  	utxos, e := s.UnspentOutputs(b)
 208  	if e != nil  {
 209  			}
 210  	expectedOutPoint := wire.OutPoint{Hash: exampleTxRecordB.Hash, Index: 1}
 211  	for _, utxo := range utxos {
 212  		fmt.Println(utxo.OutPoint == expectedOutPoint)
 213  	}
 214  	// Output:
 215  	// 5 DUO
 216  	// true
 217  }
 218