From f674e10a2be52bfbdc41dc042646c9b3a3812529 Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Wed, 10 Jan 2018 23:59:30 -0500 Subject: [PATCH] lnd+cmd/lncli: handle ChannelPoint funding txid proto update Since a ChannelPoint's funding txid can now be get/set as raw bytes or a string, we first need to check what type it's currently set to before accessing it. --- cmd/lncli/commands.go | 34 +++++++--- fundingmanager.go | 4 +- lnd_test.go | 143 ++++++++++++++++++++++++++++++++++-------- lntest/harness.go | 6 +- lntest/node.go | 41 ++++++++++-- rpcserver.go | 60 +++++++++++++++--- 6 files changed, 240 insertions(+), 48 deletions(-) diff --git a/cmd/lncli/commands.go b/cmd/lncli/commands.go index b21514c4..79925f48 100644 --- a/cmd/lncli/commands.go +++ b/cmd/lncli/commands.go @@ -543,7 +543,25 @@ func openChannel(ctx *cli.Context) error { case *lnrpc.OpenStatusUpdate_ChanOpen: channelPoint := update.ChanOpen.ChannelPoint - txid, err := chainhash.NewHash(channelPoint.FundingTxid) + + // A channel point's funding txid can be get/set as a + // byte slice or a string. In the case it is a string, + // decode it. + var txidHash []byte + switch channelPoint.GetFundingTxid().(type) { + case *lnrpc.ChannelPoint_FundingTxidBytes: + txidHash = channelPoint.GetFundingTxidBytes() + case *lnrpc.ChannelPoint_FundingTxidStr: + s := channelPoint.GetFundingTxidStr() + h, err := chainhash.NewHashFromStr(s) + if err != nil { + return err + } + + txidHash = h[:] + } + + txid, err := chainhash.NewHash(txidHash) if err != nil { return err } @@ -653,11 +671,9 @@ func closeChannel(ctx *cli.Context) error { return fmt.Errorf("funding txid argument missing") } - txidhash, err := chainhash.NewHashFromStr(txid) - if err != nil { - return err + req.ChannelPoint.FundingTxid = &lnrpc.ChannelPoint_FundingTxidStr{ + FundingTxidStr: txid, } - req.ChannelPoint.FundingTxid = txidhash[:] switch { case ctx.IsSet("output_index"): @@ -2147,17 +2163,15 @@ func updateChannelPolicy(ctx *cli.Context) error { "txid:index") } - txHash, err := chainhash.NewHashFromStr(split[0]) - if err != nil { - return err - } index, err := strconv.ParseInt(split[1], 10, 32) if err != nil { return fmt.Errorf("unable to decode output index: %v", err) } chanPoint = &lnrpc.ChannelPoint{ - FundingTxid: txHash[:], + FundingTxid: &lnrpc.ChannelPoint_FundingTxidStr{ + FundingTxidStr: split[0], + }, OutputIndex: uint32(index), } } diff --git a/fundingmanager.go b/fundingmanager.go index e3b5309f..0d84d39b 100644 --- a/fundingmanager.go +++ b/fundingmanager.go @@ -1436,7 +1436,9 @@ func (f *fundingManager) handleFundingSigned(fmsg *fundingSignedMsg) { Update: &lnrpc.OpenStatusUpdate_ChanOpen{ ChanOpen: &lnrpc.ChannelOpenUpdate{ ChannelPoint: &lnrpc.ChannelPoint{ - FundingTxid: fundingPoint.Hash[:], + FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{ + FundingTxidBytes: fundingPoint.Hash[:], + }, OutputIndex: fundingPoint.Index, }, }, diff --git a/lnd_test.go b/lnd_test.go index 6d1968de..13597c81 100644 --- a/lnd_test.go +++ b/lnd_test.go @@ -165,7 +165,11 @@ func openChannelAndAssert(ctx context.Context, t *harnessTest, if err != nil { t.Fatalf("error while waiting for channel open: %v", err) } - fundingTxID, err := chainhash.NewHash(fundingChanPoint.FundingTxid) + txidHash, err := getChanPointFundingTxid(fundingChanPoint) + if err != nil { + t.Fatalf("unable to get txid: %v", err) + } + fundingTxID, err := chainhash.NewHash(txidHash) if err != nil { t.Fatalf("unable to create sha hash: %v", err) } @@ -202,7 +206,11 @@ func closeChannelAndAssert(ctx context.Context, t *harnessTest, t.Fatalf("unable to close channel: %v", err) } - txid, err := chainhash.NewHash(fundingChanPoint.FundingTxid) + txidHash, err := getChanPointFundingTxid(fundingChanPoint) + if err != nil { + t.Fatalf("unable to get txid: %v", err) + } + txid, err := chainhash.NewHash(txidHash) if err != nil { t.Fatalf("unable to convert to chainhash: %v", err) } @@ -548,7 +556,11 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) { // txStr returns the string representation of the channel's // funding tx. txStr := func(chanPoint *lnrpc.ChannelPoint) string { - fundingTxID, err := chainhash.NewHash(chanPoint.FundingTxid) + txidHash, err := getChanPointFundingTxid(chanPoint) + if err != nil { + return "" + } + fundingTxID, err := chainhash.NewHash(txidHash) if err != nil { return "" } @@ -852,7 +864,9 @@ func testOpenChannelAfterReorg(net *lntest.NetworkHarness, t *harnessTest) { } chanPoint := &lnrpc.ChannelPoint{ - FundingTxid: pendingUpdate.Txid, + FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{ + FundingTxidBytes: pendingUpdate.Txid, + }, OutputIndex: pendingUpdate.OutputIndex, } @@ -1015,7 +1029,9 @@ func testDisconnectingTargetPeer(net *lntest.NetworkHarness, t *harnessTest) { // block until the channel is closed and will additionally assert the // relevant channel closing post conditions. chanPoint := &lnrpc.ChannelPoint{ - FundingTxid: pendingUpdate.Txid, + FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{ + FundingTxidBytes: pendingUpdate.Txid, + }, OutputIndex: pendingUpdate.OutputIndex, } @@ -1196,7 +1212,9 @@ peersPoll: // block until the channel is closed and will additionally assert the // relevant channel closing post conditions. chanPoint := &lnrpc.ChannelPoint{ - FundingTxid: pendingUpdate.Txid, + FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{ + FundingTxidBytes: pendingUpdate.Txid, + }, OutputIndex: pendingUpdate.OutputIndex, } ctxt, _ = context.WithTimeout(ctxb, timeout) @@ -1516,7 +1534,14 @@ func testChannelForceClosure(net *lntest.NetworkHarness, t *harnessTest) { // Compute the outpoint of the channel, which we will use repeatedly to // locate the pending channel information in the rpc responses. - txid, _ := chainhash.NewHash(chanPoint.FundingTxid[:]) + txidHash, err := getChanPointFundingTxid(chanPoint) + if err != nil { + t.Fatalf("unable to get txid: %v", err) + } + txid, err := chainhash.NewHash(txidHash) + if err != nil { + t.Fatalf("unable to create sha hash: %v", err) + } op := wire.OutPoint{ Hash: *txid, Index: chanPoint.OutputIndex, @@ -2298,7 +2323,11 @@ func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) { net.Bob, chanAmt, 0) networkChans = append(networkChans, chanPointAlice) - aliceChanTXID, err := chainhash.NewHash(chanPointAlice.FundingTxid) + txidHash, err := getChanPointFundingTxid(chanPointAlice) + if err != nil { + t.Fatalf("unable to get txid: %v", err) + } + aliceChanTXID, err := chainhash.NewHash(txidHash) if err != nil { t.Fatalf("unable to create sha hash: %v", err) } @@ -2329,7 +2358,11 @@ func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) { chanPointDave := openChannelAndAssert(ctxt, t, net, dave, net.Alice, chanAmt, 0) networkChans = append(networkChans, chanPointDave) - daveChanTXID, err := chainhash.NewHash(chanPointDave.FundingTxid) + txidHash, err = getChanPointFundingTxid(chanPointDave) + if err != nil { + t.Fatalf("unable to get txid: %v", err) + } + daveChanTXID, err := chainhash.NewHash(txidHash) if err != nil { t.Fatalf("unable to create sha hash: %v", err) } @@ -2356,7 +2389,11 @@ func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) { dave, chanAmt, 0) networkChans = append(networkChans, chanPointCarol) - carolChanTXID, err := chainhash.NewHash(chanPointCarol.FundingTxid) + txidHash, err = getChanPointFundingTxid(chanPointCarol) + if err != nil { + t.Fatalf("unable to get txid: %v", err) + } + carolChanTXID, err := chainhash.NewHash(txidHash) if err != nil { t.Fatalf("unable to create sha hash: %v", err) } @@ -2370,7 +2407,11 @@ func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) { nodeNames := []string{"Alice", "Bob", "Carol", "Dave"} for _, chanPoint := range networkChans { for i, node := range nodes { - txid, e := chainhash.NewHash(chanPoint.FundingTxid) + txidHash, err := getChanPointFundingTxid(chanPoint) + if err != nil { + t.Fatalf("unable to get txid: %v", err) + } + txid, e := chainhash.NewHash(txidHash) if e != nil { t.Fatalf("unable to create sha hash: %v", e) } @@ -2500,7 +2541,11 @@ func testPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) { net.Bob, chanAmt*2, 0) networkChans = append(networkChans, chanPointAlice) - aliceChanTXID, err := chainhash.NewHash(chanPointAlice.FundingTxid) + txidHash, err := getChanPointFundingTxid(chanPointAlice) + if err != nil { + t.Fatalf("unable to get txid: %v", err) + } + aliceChanTXID, err := chainhash.NewHash(txidHash) if err != nil { t.Fatalf("unable to create sha hash: %v", err) } @@ -2525,7 +2570,11 @@ func testPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) { chanPointDave := openChannelAndAssert(ctxt, t, net, dave, net.Alice, chanAmt, 0) networkChans = append(networkChans, chanPointDave) - daveChanTXID, err := chainhash.NewHash(chanPointDave.FundingTxid) + txidHash, err = getChanPointFundingTxid(chanPointDave) + if err != nil { + t.Fatalf("unable to get txid: %v", err) + } + daveChanTXID, err := chainhash.NewHash(txidHash) if err != nil { t.Fatalf("unable to create sha hash: %v", err) } @@ -2552,7 +2601,11 @@ func testPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) { dave, chanAmt, 0) networkChans = append(networkChans, chanPointCarol) - carolChanTXID, err := chainhash.NewHash(chanPointCarol.FundingTxid) + txidHash, err = getChanPointFundingTxid(chanPointCarol) + if err != nil { + t.Fatalf("unable to get txid: %v", err) + } + carolChanTXID, err := chainhash.NewHash(txidHash) if err != nil { t.Fatalf("unable to create sha hash: %v", err) } @@ -2567,7 +2620,11 @@ func testPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) { nodeNames := []string{"Alice", "Bob", "Carol", "Dave"} for _, chanPoint := range networkChans { for i, node := range nodes { - txid, e := chainhash.NewHash(chanPoint.FundingTxid) + txidHash, err := getChanPointFundingTxid(chanPoint) + if err != nil { + t.Fatalf("unable to get txid: %v", err) + } + txid, e := chainhash.NewHash(txidHash) if e != nil { t.Fatalf("unable to create sha hash: %v", e) } @@ -2603,7 +2660,11 @@ func testPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) { if err != nil { t.Fatalf("error while waiting for channel open: %v", err) } - fundingTxID, err := chainhash.NewHash(chanPointPrivate.FundingTxid) + txidHash, err = getChanPointFundingTxid(chanPointPrivate) + if err != nil { + t.Fatalf("unable to get txid: %v", err) + } + fundingTxID, err := chainhash.NewHash(txidHash) if err != nil { t.Fatalf("unable to create sha hash: %v", err) } @@ -2979,7 +3040,11 @@ func testMaxPendingChannels(net *lntest.NetworkHarness, t *harnessTest) { t.Fatalf("error while waiting for channel open: %v", err) } - fundingTxID, err := chainhash.NewHash(fundingChanPoint.FundingTxid) + txidHash, err := getChanPointFundingTxid(fundingChanPoint) + if err != nil { + t.Fatalf("unable to get txid: %v", err) + } + fundingTxID, err := chainhash.NewHash(txidHash) if err != nil { t.Fatalf("unable to create sha hash: %v", err) } @@ -4277,11 +4342,17 @@ func testGraphTopologyNotifications(net *lntest.NetworkHarness, t *harnessTest) t.Fatalf("close heights of channel mismatch: expected "+ "%v, got %v", blockHeight+1, closedChan.ClosedHeight) } - if !bytes.Equal(closedChan.ChanPoint.FundingTxid, - chanPoint.FundingTxid) { + chanPointTxid, err := getChanPointFundingTxid(chanPoint) + if err != nil { + t.Fatalf("unable to get txid: %v", err) + } + closedChanTxid, err := getChanPointFundingTxid(closedChan.ChanPoint) + if err != nil { + t.Fatalf("unable to get txid: %v", err) + } + if !bytes.Equal(closedChanTxid, chanPointTxid) { t.Fatalf("channel point hash mismatch: expected %v, "+ - "got %v", chanPoint.FundingTxid, - closedChan.ChanPoint.FundingTxid) + "got %v", chanPointTxid, closedChanTxid) } if closedChan.ChanPoint.OutputIndex != chanPoint.OutputIndex { t.Fatalf("output index mismatch: expected %v, got %v", @@ -5180,7 +5251,11 @@ func testMultiHopHtlcLocalTimeout(net *lntest.NetworkHarness, t *harnessTest) { } // Bob's force close transaction should now be found in the mempool. - bobFundingTxid, err := chainhash.NewHash(bobChanPoint.FundingTxid) + txidHash, err := getChanPointFundingTxid(bobChanPoint) + if err != nil { + t.Fatalf("unable to get txid: %v", err) + } + bobFundingTxid, err := chainhash.NewHash(txidHash) if err != nil { t.Fatalf("unable to create sha hash: %v", err) } @@ -5393,7 +5468,11 @@ func testMultiHopReceiverChainClaim(net *lntest.NetworkHarness, t *harnessTest) if err != nil { t.Fatalf("transactions not found in mempool: %v", err) } - bobFundingTxid, err := chainhash.NewHash(bobChanPoint.FundingTxid) + txidHash, err := getChanPointFundingTxid(bobChanPoint) + if err != nil { + t.Fatalf("unable to get txid: %v", err) + } + bobFundingTxid, err := chainhash.NewHash(txidHash) carolFundingPoint := wire.OutPoint{ Hash: *bobFundingTxid, Index: bobChanPoint.OutputIndex, @@ -6008,7 +6087,14 @@ func testMultiHopHtlcLocalChainClaim(net *lntest.NetworkHarness, t *harnessTest) if err != nil { t.Fatalf("transactions not found in mempool: %v", err) } - bobFundingTxid, err := chainhash.NewHash(bobChanPoint.FundingTxid) + txidHash, err := getChanPointFundingTxid(bobChanPoint) + if err != nil { + t.Fatalf("unable to get txid: %v", err) + } + bobFundingTxid, err := chainhash.NewHash(txidHash) + if err != nil { + t.Fatalf("unable to create sha hash: %v", err) + } carolFundingPoint := wire.OutPoint{ Hash: *bobFundingTxid, Index: bobChanPoint.OutputIndex, @@ -6218,7 +6304,14 @@ func testMultiHopHtlcRemoteChainClaim(net *lntest.NetworkHarness, t *harnessTest if err != nil { t.Fatalf("transactions not found in mempool: %v", err) } - bobFundingTxid, err := chainhash.NewHash(bobChanPoint.FundingTxid) + txidHash, err := getChanPointFundingTxid(bobChanPoint) + if err != nil { + t.Fatalf("unable to get txid: %v", err) + } + bobFundingTxid, err := chainhash.NewHash(txidHash) + if err != nil { + t.Fatalf("unable to create sha hash: %v", err) + } carolFundingPoint := wire.OutPoint{ Hash: *bobFundingTxid, Index: bobChanPoint.OutputIndex, diff --git a/lntest/harness.go b/lntest/harness.go index dfcfc022..c42d22d0 100644 --- a/lntest/harness.go +++ b/lntest/harness.go @@ -633,7 +633,11 @@ func (n *NetworkHarness) CloseChannel(ctx context.Context, // Create a channel outpoint that we can use to compare to channels // from the ListChannelsResponse. - fundingTxID, err := chainhash.NewHash(cp.FundingTxid) + txidHash, err := getChanPointFundingTxid(cp) + if err != nil { + return nil, nil, err + } + fundingTxID, err := chainhash.NewHash(txidHash) if err != nil { return nil, nil, err } diff --git a/lntest/node.go b/lntest/node.go index 1a7e4690..f18aacb9 100644 --- a/lntest/node.go +++ b/lntest/node.go @@ -450,6 +450,29 @@ type chanWatchRequest struct { eventChan chan struct{} } +// getChanPointFundingTxid returns the given channel point's funding txid in +// raw bytes. +func getChanPointFundingTxid(chanPoint *lnrpc.ChannelPoint) ([]byte, error) { + var txid []byte + + // A channel point's funding txid can be get/set as a byte slice or a + // string. In the case it is a string, decode it. + switch chanPoint.GetFundingTxid().(type) { + case *lnrpc.ChannelPoint_FundingTxidBytes: + txid = chanPoint.GetFundingTxidBytes() + case *lnrpc.ChannelPoint_FundingTxidStr: + s := chanPoint.GetFundingTxidStr() + h, err := chainhash.NewHashFromStr(s) + if err != nil { + return nil, err + } + + txid = h[:] + } + + return txid, nil +} + // lightningNetworkWatcher is a goroutine which is able to dispatch // notifications once it has been observed that a target channel has been // closed or opened within the network. In order to dispatch these @@ -510,7 +533,8 @@ func (hn *HarnessNode) lightningNetworkWatcher() { // For each new channel, we'll increment the number of // edges seen by one. for _, newChan := range graphUpdate.ChannelUpdates { - txid, _ := chainhash.NewHash(newChan.ChanPoint.FundingTxid) + txidHash, _ := getChanPointFundingTxid(newChan.ChanPoint) + txid, _ := chainhash.NewHash(txidHash) op := wire.OutPoint{ Hash: *txid, Index: newChan.ChanPoint.OutputIndex, @@ -536,7 +560,8 @@ func (hn *HarnessNode) lightningNetworkWatcher() { // detected a channel closure while lnd was pruning the // channel graph. for _, closedChan := range graphUpdate.ClosedChans { - txid, _ := chainhash.NewHash(closedChan.ChanPoint.FundingTxid) + txidHash, _ := getChanPointFundingTxid(closedChan.ChanPoint) + txid, _ := chainhash.NewHash(txidHash) op := wire.OutPoint{ Hash: *txid, Index: closedChan.ChanPoint.OutputIndex, @@ -603,7 +628,11 @@ func (hn *HarnessNode) WaitForNetworkChannelOpen(ctx context.Context, eventChan := make(chan struct{}) - txid, err := chainhash.NewHash(op.FundingTxid) + txidHash, err := getChanPointFundingTxid(op) + if err != nil { + return err + } + txid, err := chainhash.NewHash(txidHash) if err != nil { return err } @@ -634,7 +663,11 @@ func (hn *HarnessNode) WaitForNetworkChannelClose(ctx context.Context, eventChan := make(chan struct{}) - txid, err := chainhash.NewHash(op.FundingTxid) + txidHash, err := getChanPointFundingTxid(op) + if err != nil { + return err + } + txid, err := chainhash.NewHash(txidHash) if err != nil { return err } diff --git a/rpcserver.go b/rpcserver.go index 7e392ff3..5bb1dc19 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -653,7 +653,15 @@ out: switch update := fundingUpdate.Update.(type) { case *lnrpc.OpenStatusUpdate_ChanOpen: chanPoint := update.ChanOpen.ChannelPoint - h, _ := chainhash.NewHash(chanPoint.FundingTxid) + txidHash, err := getChanPointFundingTxid(chanPoint) + if err != nil { + return err + } + + h, err := chainhash.NewHash(txidHash) + if err != nil { + return err + } outpoint = wire.OutPoint{ Hash: *h, Index: chanPoint.OutputIndex, @@ -772,14 +780,39 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context, chanUpdate := openUpdate.ChanPending return &lnrpc.ChannelPoint{ - FundingTxid: chanUpdate.Txid, + FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{ + FundingTxidBytes: chanUpdate.Txid, + }, }, nil case <-r.quit: return nil, nil } } -// CloseLink attempts to close an active channel identified by its channel +// getChanPointFundingTxid returns the given channel point's funding txid in +// raw bytes. +func getChanPointFundingTxid(chanPoint *lnrpc.ChannelPoint) ([]byte, error) { + var txid []byte + + // A channel point's funding txid can be get/set as a byte slice or a + // string. In the case it is a string, decode it. + switch chanPoint.GetFundingTxid().(type) { + case *lnrpc.ChannelPoint_FundingTxidBytes: + txid = chanPoint.GetFundingTxidBytes() + case *lnrpc.ChannelPoint_FundingTxidStr: + s := chanPoint.GetFundingTxidStr() + h, err := chainhash.NewHashFromStr(s) + if err != nil { + return nil, err + } + + txid = h[:] + } + + return txid, nil +} + +// CloseChannel attempts to close an active channel identified by its channel // point. The actions of this method can additionally be augmented to attempt // a force close after a timeout period in the case of an inactive peer. func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest, @@ -795,7 +828,12 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest, force := in.Force index := in.ChannelPoint.OutputIndex - txid, err := chainhash.NewHash(in.ChannelPoint.FundingTxid) + txidHash, err := getChanPointFundingTxid(in.GetChannelPoint()) + if err != nil { + rpcsLog.Errorf("[closechannel] unable to get funding txid: %v", err) + return err + } + txid, err := chainhash.NewHash(txidHash) if err != nil { rpcsLog.Errorf("[closechannel] invalid txid: %v", err) return err @@ -2870,7 +2908,9 @@ func marshallTopologyChange(topChange *routing.TopologyChange) *lnrpc.GraphTopol channelUpdates[i] = &lnrpc.ChannelEdgeUpdate{ ChanId: channelUpdate.ChanID, ChanPoint: &lnrpc.ChannelPoint{ - FundingTxid: channelUpdate.ChanPoint.Hash[:], + FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{ + FundingTxidBytes: channelUpdate.ChanPoint.Hash[:], + }, OutputIndex: channelUpdate.ChanPoint.Index, }, Capacity: int64(channelUpdate.Capacity), @@ -2892,7 +2932,9 @@ func marshallTopologyChange(topChange *routing.TopologyChange) *lnrpc.GraphTopol Capacity: int64(closedChan.Capacity), ClosedHeight: closedChan.ClosedHeight, ChanPoint: &lnrpc.ChannelPoint{ - FundingTxid: closedChan.ChanPoint.Hash[:], + FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{ + FundingTxidBytes: closedChan.ChanPoint.Hash[:], + }, OutputIndex: closedChan.ChanPoint.Index, }, } @@ -3148,7 +3190,11 @@ func (r *rpcServer) UpdateChannelPolicy(ctx context.Context, // Otherwise, we're targeting an individual channel by its channel // point. case *lnrpc.PolicyUpdateRequest_ChanPoint: - txid, err := chainhash.NewHash(scope.ChanPoint.FundingTxid) + txidHash, err := getChanPointFundingTxid(scope.ChanPoint) + if err != nil { + return nil, err + } + txid, err := chainhash.NewHash(txidHash) if err != nil { return nil, err }