From 432b1f05881e3433c47dd63e69b3b88a0e72bc88 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Tue, 6 Apr 2021 10:42:09 +0200 Subject: [PATCH] btcwallet: lock blockcache for Neutrino GetBlock This commit ensures that for the neutrino implementation of lnwallet.BlockChainIO, the neutrino GetBlock method is called directly (since it already uses the blockcache). It also ensures that the block cache mutex for the given hash is locked before the call to GetBlock. --- lnwallet/btcwallet/blockchain.go | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/lnwallet/btcwallet/blockchain.go b/lnwallet/btcwallet/blockchain.go index 1b114748..1373c060 100644 --- a/lnwallet/btcwallet/blockchain.go +++ b/lnwallet/btcwallet/blockchain.go @@ -8,10 +8,10 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" - "github.com/btcsuite/btcwallet/chain" "github.com/lightninglabs/neutrino" "github.com/lightninglabs/neutrino/headerfs" + "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnwallet" ) @@ -127,11 +127,26 @@ func (b *BtcWallet) GetUtxo(op *wire.OutPoint, pkScript []byte, } } -// GetBlock returns a raw block from the server given its hash. +// GetBlock returns a raw block from the server given its hash. For the Neutrino +// implementation of the lnwallet.BlockChainIO interface, the Neutrino GetBlock +// method is called directly. For other implementations, the block cache is used +// to wrap the call to GetBlock. // // This method is a part of the lnwallet.BlockChainIO interface. func (b *BtcWallet) GetBlock(blockHash *chainhash.Hash) (*wire.MsgBlock, error) { - return b.blockCache.GetBlock(blockHash, b.chain.GetBlock) + _, ok := b.chain.(*chain.NeutrinoClient) + if !ok { + return b.blockCache.GetBlock(blockHash, b.chain.GetBlock) + } + + // For the neutrino implementation of lnwallet.BlockChainIO the neutrino + // GetBlock function can be called directly since it uses the same block + // cache. However, it does not lock the block cache mutex for the given + // block hash and so that is done here. + b.blockCache.HashMutex.Lock(lntypes.Hash(*blockHash)) + defer b.blockCache.HashMutex.Unlock(lntypes.Hash(*blockHash)) + + return b.chain.GetBlock(blockHash) } // GetBlockHash returns the hash of the block in the best blockchain at the