From ad69a7121b2b1d937c7287a67eaef910106244ce Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Mon, 28 May 2018 21:53:31 -0700 Subject: [PATCH] blockchain: update IndexManager interface to use spent txos In this commit, we update the IndexManager interface to use spent txos rather than the unspent output set for a particualr block. We do this in order to improve the performance of the current address index which requires reconstructing the utxo view from the PoV of that new block. In practice, this is very slow as we need to perform a series of random reads in order to reconstruct the utxo set. Instead, we can use the set of SpentTxOut's for that block as this already contains the previous output scripts which is what all of the current indexers really need. --- blockchain/chain.go | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/blockchain/chain.go b/blockchain/chain.go index c88bea6d..84996f31 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -640,7 +640,7 @@ func (b *BlockChain) connectBlock(node *blockNode, block *btcutil.Block, // optional indexes with the block being connected so they can // update themselves accordingly. if b.indexManager != nil { - err := b.indexManager.ConnectBlock(dbTx, block, view) + err := b.indexManager.ConnectBlock(dbTx, block, stxos) if err != nil { return err } @@ -741,8 +741,15 @@ func (b *BlockChain) disconnectBlock(node *blockNode, block *btcutil.Block, view return err } + // Before we delete the spend journal entry for this back, + // we'll fetch it as is so the indexers can utilize if needed. + stxos, err := dbFetchSpendJournalEntry(dbTx, block) + if err != nil { + return err + } + // Update the transaction spend journal by removing the record - // that contains all txos spent by the block . + // that contains all txos spent by the block. err = dbRemoveSpendJournalEntry(dbTx, block.Hash()) if err != nil { return err @@ -752,7 +759,7 @@ func (b *BlockChain) disconnectBlock(node *blockNode, block *btcutil.Block, view // optional indexes with the block being disconnected so they // can update themselves accordingly. if b.indexManager != nil { - err := b.indexManager.DisconnectBlock(dbTx, block, view) + err := b.indexManager.DisconnectBlock(dbTx, block, stxos) if err != nil { return err } @@ -1571,12 +1578,16 @@ type IndexManager interface { Init(*BlockChain, <-chan struct{}) error // ConnectBlock is invoked when a new block has been connected to the - // main chain. - ConnectBlock(database.Tx, *btcutil.Block, *UtxoViewpoint) error + // main chain. The set of output spent within a block is also passed in + // so indexers can access the previous output scripts input spent if + // required. + ConnectBlock(database.Tx, *btcutil.Block, []SpentTxOut) error // DisconnectBlock is invoked when a block has been disconnected from - // the main chain. - DisconnectBlock(database.Tx, *btcutil.Block, *UtxoViewpoint) error + // the main chain. The set of outputs scripts that were spent within + // this block is also returned so indexers can clean up the prior index + // state for this block. + DisconnectBlock(database.Tx, *btcutil.Block, []SpentTxOut) error } // Config is a descriptor which specifies the blockchain instance configuration.