routing: update 3d party channel verification to use new chanvalidate package

In the process of moving to use the new package, we no longer need to
fetch the outpoint directly, and instead only need to pass the funding
transaction into the new verification logic.
This commit is contained in:
Olaoluwa Osuntokun 2019-09-30 19:55:03 -07:00
parent c199ad30ac
commit 6ebada112f
No known key found for this signature in database
GPG Key ID: BC13F65E2DC84465

@ -21,6 +21,7 @@ import (
"github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwallet/chanvalidate"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/multimutex" "github.com/lightningnetwork/lnd/multimutex"
"github.com/lightningnetwork/lnd/routing/chainview" "github.com/lightningnetwork/lnd/routing/chainview"
@ -1174,9 +1175,9 @@ func (r *ChannelRouter) processUpdate(msg interface{}) error {
// to obtain the full funding outpoint that's encoded within // to obtain the full funding outpoint that's encoded within
// the channel ID. // the channel ID.
channelID := lnwire.NewShortChanIDFromInt(msg.ChannelID) channelID := lnwire.NewShortChanIDFromInt(msg.ChannelID)
fundingPoint, _, err := r.fetchChanPoint(&channelID) fundingTx, err := r.fetchFundingTx(&channelID)
if err != nil { if err != nil {
return errors.Errorf("unable to fetch chan point for "+ return errors.Errorf("unable to fetch funding tx for "+
"chan_id=%v: %v", msg.ChannelID, err) "chan_id=%v: %v", msg.ChannelID, err)
} }
@ -1189,7 +1190,22 @@ func (r *ChannelRouter) processUpdate(msg interface{}) error {
if err != nil { if err != nil {
return err return err
} }
fundingPkScript, err := input.WitnessScriptHash(witnessScript) pkScript, err := input.WitnessScriptHash(witnessScript)
if err != nil {
return err
}
// Next we'll validate that this channel is actually well
// formed. If this check fails, then this channel either
// doesn't exist, or isn't the one that was meant to be created
// according to the passed channel proofs.
fundingPoint, err := chanvalidate.Validate(&chanvalidate.Context{
Locator: &chanvalidate.ShortChanIDChanLocator{
ID: channelID,
},
MultiSigPkScript: pkScript,
FundingTx: fundingTx,
})
if err != nil { if err != nil {
return err return err
} }
@ -1197,6 +1213,10 @@ func (r *ChannelRouter) processUpdate(msg interface{}) error {
// Now that we have the funding outpoint of the channel, ensure // Now that we have the funding outpoint of the channel, ensure
// that it hasn't yet been spent. If so, then this channel has // that it hasn't yet been spent. If so, then this channel has
// been closed so we'll ignore it. // been closed so we'll ignore it.
fundingPkScript, err := input.WitnessScriptHash(witnessScript)
if err != nil {
return err
}
chanUtxo, err := r.cfg.Chain.GetUtxo( chanUtxo, err := r.cfg.Chain.GetUtxo(
fundingPoint, fundingPkScript, channelID.BlockHeight, fundingPoint, fundingPkScript, channelID.BlockHeight,
r.quit, r.quit,
@ -1207,16 +1227,6 @@ func (r *ChannelRouter) processUpdate(msg interface{}) error {
msg.ChannelID, fundingPoint, err) msg.ChannelID, fundingPoint, err)
} }
// By checking the equality of witness pkscripts we checks that
// funding witness script is multisignature lock which contains
// both local and remote public keys which was declared in
// channel edge and also that the announced channel value is
// right.
if !bytes.Equal(fundingPkScript, chanUtxo.PkScript) {
return errors.Errorf("pkScript mismatch: expected %x, "+
"got %x", fundingPkScript, chanUtxo.PkScript)
}
// TODO(roasbeef): this is a hack, needs to be removed // TODO(roasbeef): this is a hack, needs to be removed
// after commitment fees are dynamic. // after commitment fees are dynamic.
msg.Capacity = btcutil.Amount(chanUtxo.Value) msg.Capacity = btcutil.Amount(chanUtxo.Value)
@ -1339,25 +1349,24 @@ func (r *ChannelRouter) processUpdate(msg interface{}) error {
return nil return nil
} }
// fetchChanPoint retrieves the original outpoint which is encoded within the // fetchFundingTx returns the funding transaction identified by the passed
// channelID. This method also return the public key script for the target // short channel ID.
// transaction.
// //
// TODO(roasbeef): replace with call to GetBlockTransaction? (would allow to // TODO(roasbeef): replace with call to GetBlockTransaction? (would allow to
// later use getblocktxn) // later use getblocktxn)
func (r *ChannelRouter) fetchChanPoint( func (r *ChannelRouter) fetchFundingTx(
chanID *lnwire.ShortChannelID) (*wire.OutPoint, *wire.TxOut, error) { chanID *lnwire.ShortChannelID) (*wire.MsgTx, error) {
// First fetch the block hash by the block number encoded, then use // First fetch the block hash by the block number encoded, then use
// that hash to fetch the block itself. // that hash to fetch the block itself.
blockNum := int64(chanID.BlockHeight) blockNum := int64(chanID.BlockHeight)
blockHash, err := r.cfg.Chain.GetBlockHash(blockNum) blockHash, err := r.cfg.Chain.GetBlockHash(blockNum)
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
fundingBlock, err := r.cfg.Chain.GetBlock(blockHash) fundingBlock, err := r.cfg.Chain.GetBlock(blockHash)
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
// As a sanity check, ensure that the advertised transaction index is // As a sanity check, ensure that the advertised transaction index is
@ -1365,21 +1374,12 @@ func (r *ChannelRouter) fetchChanPoint(
// block. // block.
numTxns := uint32(len(fundingBlock.Transactions)) numTxns := uint32(len(fundingBlock.Transactions))
if chanID.TxIndex > numTxns-1 { if chanID.TxIndex > numTxns-1 {
return nil, nil, fmt.Errorf("tx_index=#%v is out of range "+ return nil, fmt.Errorf("tx_index=#%v is out of range "+
"(max_index=%v), network_chan_id=%v\n", chanID.TxIndex, "(max_index=%v), network_chan_id=%v", chanID.TxIndex,
numTxns-1, spew.Sdump(chanID)) numTxns-1, chanID)
} }
// Finally once we have the block itself, we seek to the targeted return fundingBlock.Transactions[chanID.TxIndex], nil
// transaction index to obtain the funding output and txout.
fundingTx := fundingBlock.Transactions[chanID.TxIndex]
outPoint := &wire.OutPoint{
Hash: fundingTx.TxHash(),
Index: uint32(chanID.TxPosition),
}
txOut := fundingTx.TxOut[chanID.TxPosition]
return outPoint, txOut, nil
} }
// routingMsg couples a routing related routing topology update to the // routingMsg couples a routing related routing topology update to the