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.
This commit is contained in:
Wilmer Paulino 2018-01-10 23:59:30 -05:00
parent 2cfd705a06
commit f674e10a2b
No known key found for this signature in database
GPG Key ID: 6DF57B9F9514972F
6 changed files with 240 additions and 48 deletions

@ -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),
}
}

@ -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,
},
},

@ -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,

@ -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
}

@ -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
}

@ -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
}