decred.org/dcrwallet/v3@v3.1.0/wallet/udb/txexample_test.go (about) 1 // Copyright (c) 2015 The btcsuite developers 2 // Copyright (c) 2015 The Decred developers 3 // Use of this source code is governed by an ISC 4 // license that can be found in the LICENSE file. 5 6 //go:build ignore 7 8 package udb 9 10 import ( 11 "testing" 12 "time" 13 14 "decred.org/dcrwallet/v3/wallet/walletdb" 15 "github.com/decred/dcrd/dcrutil/v4" 16 "github.com/decred/dcrd/wire" 17 ) 18 19 func ExampleStore_Rollback(t *testing.T) { 20 t.Parallel() 21 db, s, teardown, err := setup("store_rollback") 22 defer teardown() 23 if err != nil { 24 t.Fatal(err) 25 } 26 27 cb := newCoinBase(30e8) 28 cbRec, err := NewTxRecordFromMsgTx(cb, time.Time{}) 29 if err != nil { 30 t.Fatal(err) 31 } 32 33 defaultAccount := uint32(0) 34 g := makeBlockGenerator() 35 b1H := g.generate(dcrutil.BlockValid) 36 b1Hash := b1H.BlockHash() 37 b1Meta := makeBlockMeta(b1H) 38 headers := []*wire.BlockHeader{b1H} 39 headerData := makeHeaderDataSlice(headers...) 40 filters := emptyFilters(1) 41 42 err = walletdb.Update(db, func(tx walletdb.ReadWriteTx) error { 43 ns := tx.ReadWriteBucket(wtxmgrBucketKey) 44 addrmgrNs := tx.ReadBucket(waddrmgrBucketKey) 45 46 err = insertMainChainHeaders(s, ns, addrmgrNs, headerData[0:1], filters[0:1]) 47 if err != nil { 48 t.Fatal(err) 49 } 50 51 // Insert coinbase and mark outputs 0 as credits. 52 err = s.InsertMemPoolTx(ns, cbRec) 53 if err != nil { 54 t.Fatal(err) 55 } 56 57 err = s.InsertMinedTx(ns, addrmgrNs, cbRec, &b1Hash) 58 if err != nil { 59 t.Fatal(err) 60 } 61 62 s.AddCredit(ns, cbRec, b1Meta, 0, false, defaultAccount) 63 if err != nil { 64 t.Fatal(err) 65 } 66 67 // Spends: b1H coinbase 68 // Outputs: 10 Coin 69 aTx := spendOutput(&b1Hash, 0, 0, 10e8) 70 txRecordA, err := NewTxRecordFromMsgTx(aTx, time.Now()) 71 if err != nil { 72 t.Fatal(err) 73 } 74 75 err = s.InsertMemPoolTx(ns, txRecordA) 76 if err != nil { 77 t.Fatal(err) 78 } 79 80 err = s.InsertMinedTx(ns, addrmgrNs, txRecordA, &b1Hash) 81 if err != nil { 82 t.Fatal(err) 83 } 84 85 // Rollback everything. 86 err = s.Rollback(ns, addrmgrNs, int32(b1H.Height)) 87 if err != nil { 88 t.Fatal(err) 89 } 90 91 // Assert that the transaction is now unmined. 92 details, err := s.TxDetails(ns, &txRecordA.Hash) 93 if err != nil { 94 t.Fatal(err) 95 } 96 if details == nil { 97 t.Fatal("no tx details found") 98 } 99 100 return nil 101 }) 102 if err != nil { 103 t.Fatal(err) 104 } 105 } 106 107 func Example_basicUsage(t *testing.T) { 108 t.Parallel() 109 db, s, teardown, err := setup("basic_usage") 110 defer teardown() 111 if err != nil { 112 t.Fatal(err) 113 } 114 115 cb := newCoinBase(10e8, 5e8) 116 cbRec, err := NewTxRecordFromMsgTx(cb, time.Time{}) 117 if err != nil { 118 t.Fatal(err) 119 } 120 121 defaultAccount := uint32(0) 122 g := makeBlockGenerator() 123 b1H := g.generate(dcrutil.BlockValid) 124 b1Hash := b1H.BlockHash() 125 b1Meta := makeBlockMeta(b1H) 126 headers := []*wire.BlockHeader{b1H} 127 b2H := g.generate(dcrutil.BlockValid) 128 b2Hash := b2H.BlockHash() 129 // b2Meta := makeBlockMeta(b2H) 130 headers = append(headers, b2H) 131 headerData := makeHeaderDataSlice(headers...) 132 filters := emptyFilters(2) 133 134 err = walletdb.Update(db, func(tx walletdb.ReadWriteTx) error { 135 ns := tx.ReadWriteBucket(wtxmgrBucketKey) 136 addrmgrNs := tx.ReadBucket(waddrmgrBucketKey) 137 138 err = insertMainChainHeaders(s, ns, addrmgrNs, headerData[0:1], filters[0:1]) 139 if err != nil { 140 t.Fatal(err) 141 } 142 143 // Insert coinbase and mark outputs 0 as credits. 144 err = s.InsertMemPoolTx(ns, cbRec) 145 if err != nil { 146 t.Fatal(err) 147 } 148 149 err = s.InsertMinedTx(ns, addrmgrNs, cbRec, &b1Hash) 150 if err != nil { 151 t.Fatal(err) 152 } 153 154 s.AddCredit(ns, cbRec, b1Meta, 0, false, defaultAccount) 155 if err != nil { 156 t.Fatal(err) 157 } 158 159 err = insertMainChainHeaders(s, ns, addrmgrNs, headerData[1:2], filters[1:2]) 160 if err != nil { 161 t.Fatalf("t:%v", err) 162 } 163 164 // Mine spending transactions in the next block. 165 166 // Spends: b1H coinbase 167 // Outputs: 10 Coin 168 aTx := spendOutput(&b1Hash, 0, 0, 10e8) 169 txRecordA, err := NewTxRecordFromMsgTx(aTx, time.Now()) 170 if err != nil { 171 t.Fatal(err) 172 } 173 174 err = s.InsertMemPoolTx(ns, txRecordA) 175 if err != nil { 176 t.Fatal(err) 177 } 178 179 err = s.InsertMinedTx(ns, addrmgrNs, txRecordA, &b2Hash) 180 if err != nil { 181 t.Fatal(err) 182 } 183 184 // Spends: A:0 185 // Outputs: 5 Coin, 5 Coin 186 bTx := spendOutput(&txRecordA.Hash, 0, 0, 5e8, 5e8) 187 txRecordB, err := NewTxRecordFromMsgTx(bTx, time.Now()) 188 if err != nil { 189 t.Fatal(err) 190 } 191 192 err = s.InsertMemPoolTx(ns, txRecordB) 193 if err != nil { 194 t.Fatal(err) 195 } 196 197 err = s.InsertMinedTx(ns, addrmgrNs, txRecordB, &b2Hash) 198 if err != nil { 199 t.Fatal(err) 200 } 201 202 // Fetch unspent outputs. 203 utxos, err := s.UnspentOutputs(ns) 204 if err != nil { 205 t.Fatal(err) 206 } 207 208 expectedOutPoint := wire.OutPoint{Hash: cbRec.Hash, Index: 0} 209 match := false 210 for _, utxo := range utxos { 211 if utxo.OutPoint == expectedOutPoint { 212 match = true 213 } 214 } 215 216 if !match { 217 t.Fatal("expected an unspect coinbase output") 218 } 219 220 return nil 221 }) 222 if err != nil { 223 t.Fatal(err) 224 } 225 } 226 227 // // Output: 228 // // 5 Coin 229 // true