github.com/decred/dcrlnd@v0.7.6/lntest/itest/dcrlnd_assertions.go (about) 1 package itest 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 "github.com/decred/dcrd/chaincfg/chainhash" 9 "github.com/decred/dcrd/wire" 10 "github.com/decred/dcrlnd/lnrpc" 11 "github.com/decred/dcrlnd/lntest" 12 "github.com/decred/dcrlnd/lntest/wait" 13 ) 14 15 // assertCleanStateAliceBob ensures the state of the passed test nodes and the 16 // mempool are in a clean state (no open channels, no txs in the mempool, etc). 17 func assertCleanStateAliceBob(h *harnessTest, alice, bob *lntest.HarnessNode, net *lntest.NetworkHarness) { 18 _, minerHeight, err := net.Miner.Node.GetBestBlock(context.TODO()) 19 if err != nil { 20 h.Fatalf("unable to get best height: %v", err) 21 } 22 23 net.EnsureConnected(h.t, alice, bob) 24 assertNodeBlockHeight(h, alice, int32(minerHeight)) 25 assertNodeBlockHeight(h, bob, int32(minerHeight)) 26 assertNodeNumChannels(h, alice, 0) 27 assertNumPendingChannels(h, alice, 0, 0, 0, 0) 28 assertNodeNumChannels(h, bob, 0) 29 assertNumPendingChannels(h, bob, 0, 0, 0, 0) 30 assertNumUnminedUnspent(h, alice, 0) 31 assertNumUnminedUnspent(h, bob, 0) 32 waitForNTxsInMempool(net.Miner.Node, 0, minerMempoolTimeout) 33 } 34 35 // assertCleanState ensures the state of the main test nodes and the mempool 36 // are in a clean state (no open channels, no txs in the mempool, etc). 37 func assertCleanState(h *harnessTest, net *lntest.NetworkHarness) { 38 assertCleanStateAliceBob(h, net.Alice, net.Bob, net) 39 } 40 41 func assertNodeBlockHeight(t *harnessTest, node *lntest.HarnessNode, height int32) { 42 t.t.Helper() 43 44 err := wait.NoError(func() error { 45 ctxt, cancel := context.WithTimeout(context.Background(), defaultTimeout) 46 defer cancel() 47 getInfoReq := &lnrpc.GetInfoRequest{} 48 getInfoResp, err := node.GetInfo(ctxt, getInfoReq) 49 if err != nil { 50 return err 51 } 52 if int32(getInfoResp.BlockHeight) != height { 53 return fmt.Errorf("unexpected block height for node %s: "+ 54 "want=%d got=%d", node.Name(), 55 height, getInfoResp.BlockHeight) 56 } 57 58 return nil 59 }, defaultTimeout) 60 if err != nil { 61 t.Fatalf("failed to assert node block height: %v", err) 62 } 63 } 64 65 // recordedTxFee returns the tx fee recorded in the transaction itself (that 66 // is, sum(TxOut[].Value) - sum(TxIn[].ValueIn)). While this is not currently 67 // enforced by consensus rules and cannot be relied upon for validation 68 // purposes, it's sufficient for testing purposes, assuming the procedure that 69 // generated the transaction correctly fills the ValueIn (which should be true 70 // for transactions produced by dcrlnd). 71 func recordedTxFee(tx *wire.MsgTx) int64 { 72 var amountIn, amountOut int64 73 for _, in := range tx.TxIn { 74 amountIn += in.ValueIn 75 } 76 for _, out := range tx.TxOut { 77 amountOut += out.Value 78 } 79 return amountIn - amountOut 80 } 81 82 // waitForPendingHtlcs waits for up to 15 seconds for the given channel in the 83 // given node to show the specified number of pending HTLCs. 84 func waitForPendingHtlcs(node *lntest.HarnessNode, 85 chanPoint *lnrpc.ChannelPoint, pendingHtlcs int) error { 86 87 fundingTxID, err := chainhash.NewHash(chanPoint.GetFundingTxidBytes()) 88 if err != nil { 89 return fmt.Errorf("unable to convert funding txid into "+ 90 "chainhash.Hash: %v", err) 91 } 92 outPoint := wire.OutPoint{ 93 Hash: *fundingTxID, 94 Index: chanPoint.OutputIndex, 95 } 96 targetChan := outPoint.String() 97 98 req := &lnrpc.ListChannelsRequest{} 99 ctxb := context.Background() 100 101 var predErr error 102 wait.Predicate(func() bool { 103 ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) 104 channelInfo, err := node.ListChannels(ctxt, req) 105 if err != nil { 106 predErr = err 107 return false 108 } 109 110 for _, channel := range channelInfo.Channels { 111 if channel.ChannelPoint != targetChan { 112 continue 113 } 114 115 foundHtlcs := len(channel.PendingHtlcs) 116 if foundHtlcs == pendingHtlcs { 117 predErr = nil 118 return true 119 } 120 121 predErr = fmt.Errorf("found only %d htlcs (wanted %d)", 122 foundHtlcs, pendingHtlcs) 123 return false 124 } 125 126 predErr = fmt.Errorf("could not find channel %s", targetChan) 127 return false 128 }, time.Second*15) 129 return predErr 130 } 131 132 func assertNumUnminedUnspent(t *harnessTest, node *lntest.HarnessNode, expected int) { 133 err := wait.NoError(func() error { 134 ctxb := context.Background() 135 ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) 136 utxoReq := &lnrpc.ListUnspentRequest{} 137 utxoResp, err := node.ListUnspent(ctxt, utxoReq) 138 if err != nil { 139 return fmt.Errorf("unable to query utxos: %v", err) 140 } 141 142 actual := len(utxoResp.Utxos) 143 if actual != expected { 144 return fmt.Errorf("node %s has wrong number of unmined utxos ("+ 145 "expected %d actual %d)", node.Name(), expected, actual) 146 } 147 148 return nil 149 150 }, defaultTimeout) 151 if err != nil { 152 t.Fatalf("failed asserting nb of unmined unspent: %v", err) 153 } 154 } 155 156 func chanPointFundingToOutpoint(cp *lnrpc.ChannelPoint) wire.OutPoint { 157 txId, err := lnrpc.GetChanPointFundingTxid(cp) 158 if err != nil { 159 panic(err) 160 } 161 return wire.OutPoint{Hash: *txId, Index: cp.OutputIndex} 162 }