diff --git a/graph/builder.go b/graph/builder.go index 099725068..d629523f4 100644 --- a/graph/builder.go +++ b/graph/builder.go @@ -1231,7 +1231,9 @@ func (b *Builder) processUpdate(msg interface{}, // to obtain the full funding outpoint that's encoded within // the channel ID. channelID := lnwire.NewShortChanIDFromInt(msg.ChannelID) - fundingTx, err := b.fetchFundingTxWrapper(&channelID) + fundingTx, err := lnwallet.FetchFundingTxWrapper( + b.cfg.Chain, &channelID, b.quit, + ) if err != nil { //nolint:lll // @@ -1448,69 +1450,6 @@ func (b *Builder) processUpdate(msg interface{}, return nil } -// fetchFundingTxWrapper is a wrapper around fetchFundingTx, except that it -// will exit if the router has stopped. -func (b *Builder) fetchFundingTxWrapper(chanID *lnwire.ShortChannelID) ( - *wire.MsgTx, error) { - - txChan := make(chan *wire.MsgTx, 1) - errChan := make(chan error, 1) - - go func() { - tx, err := b.fetchFundingTx(chanID) - if err != nil { - errChan <- err - return - } - - txChan <- tx - }() - - select { - case tx := <-txChan: - return tx, nil - - case err := <-errChan: - return nil, err - - case <-b.quit: - return nil, ErrGraphBuilderShuttingDown - } -} - -// fetchFundingTx returns the funding transaction identified by the passed -// short channel ID. -// -// TODO(roasbeef): replace with call to GetBlockTransaction? (would allow to -// later use getblocktxn). -func (b *Builder) fetchFundingTx( - chanID *lnwire.ShortChannelID) (*wire.MsgTx, error) { - - // First fetch the block hash by the block number encoded, then use - // that hash to fetch the block itself. - blockNum := int64(chanID.BlockHeight) - blockHash, err := b.cfg.Chain.GetBlockHash(blockNum) - if err != nil { - return nil, err - } - fundingBlock, err := b.cfg.Chain.GetBlock(blockHash) - if err != nil { - return nil, err - } - - // As a sanity check, ensure that the advertised transaction index is - // within the bounds of the total number of transactions within a - // block. - numTxns := uint32(len(fundingBlock.Transactions)) - if chanID.TxIndex > numTxns-1 { - return nil, fmt.Errorf("tx_index=#%v "+ - "is out of range (max_index=%v), network_chan_id=%v", - chanID.TxIndex, numTxns-1, chanID) - } - - return fundingBlock.Transactions[chanID.TxIndex].Copy(), nil -} - // routingMsg couples a routing related routing topology update to the // error channel. type routingMsg struct { diff --git a/lnwallet/interface.go b/lnwallet/interface.go index d3b123509..3c59313f7 100644 --- a/lnwallet/interface.go +++ b/lnwallet/interface.go @@ -21,6 +21,7 @@ import ( "github.com/lightningnetwork/lnd/fn" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnwallet/chainfee" + "github.com/lightningnetwork/lnd/lnwire" ) const ( @@ -671,3 +672,68 @@ func SupportedWallets() []string { return supportedWallets } + +// FetchFundingTxWrapper is a wrapper around FetchFundingTx, except that it will +// exit when the supplied quit channel is closed. +func FetchFundingTxWrapper(chain BlockChainIO, chanID *lnwire.ShortChannelID, + quit chan struct{}) (*wire.MsgTx, error) { + + txChan := make(chan *wire.MsgTx, 1) + errChan := make(chan error, 1) + + go func() { + tx, err := FetchFundingTx(chain, chanID) + if err != nil { + errChan <- err + return + } + + txChan <- tx + }() + + select { + case tx := <-txChan: + return tx, nil + + case err := <-errChan: + return nil, err + + case <-quit: + return nil, fmt.Errorf("quit channel passed to " + + "lnwallet.FetchFundingTxWrapper has been closed") + } +} + +// FetchFundingTx uses the given BlockChainIO to fetch and return the funding +// transaction identified by the passed short channel ID. +// +// TODO(roasbeef): replace with call to GetBlockTransaction? (would allow to +// later use getblocktxn). +func FetchFundingTx(chain BlockChainIO, + chanID *lnwire.ShortChannelID) (*wire.MsgTx, error) { + + // First fetch the block hash by the block number encoded, then use + // that hash to fetch the block itself. + blockNum := int64(chanID.BlockHeight) + blockHash, err := chain.GetBlockHash(blockNum) + if err != nil { + return nil, err + } + + fundingBlock, err := chain.GetBlock(blockHash) + if err != nil { + return nil, err + } + + // As a sanity check, ensure that the advertised transaction index is + // within the bounds of the total number of transactions within a + // block. + numTxns := uint32(len(fundingBlock.Transactions)) + if chanID.TxIndex > numTxns-1 { + return nil, fmt.Errorf("tx_index=#%v "+ + "is out of range (max_index=%v), network_chan_id=%v", + chanID.TxIndex, numTxns-1, chanID) + } + + return fundingBlock.Transactions[chanID.TxIndex].Copy(), nil +}