From 04a2df48d6547e9d8c8eeedc4f85cfc8505c5565 Mon Sep 17 00:00:00 2001 From: Jonathan Downing Date: Wed, 4 Dec 2024 17:18:48 -0600 Subject: [PATCH] Refactor chain indexer to use an address-utxo map per block --- core/chain_indexer.go | 59 ++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/core/chain_indexer.go b/core/chain_indexer.go index 154f99494..b5a4ca101 100644 --- a/core/chain_indexer.go +++ b/core/chain_indexer.go @@ -368,14 +368,6 @@ func (c *ChainIndexer) indexerLoop(currentHeader *types.WorkObject, qiIndexerCh continue } time1 := time.Since(start) - var validUtxoIndex bool - var addressOutpoints map[[20]byte][]*types.OutpointAndDenomination - var addressLockups map[[20]byte][]*types.Lockup - if c.indexAddressUtxos { - validUtxoIndex = true - addressOutpoints = make(map[[20]byte][]*types.OutpointAndDenomination) - addressLockups = make(map[[20]byte][]*types.Lockup) - } time2 := time.Since(start) var time3, time4, time5 time.Duration @@ -432,10 +424,9 @@ func (c *ChainIndexer) indexerLoop(currentHeader *types.WorkObject, qiIndexerCh time3 = time.Since(start) // Remove all outpoints of the reorg headers (old chain) - err := c.reorgUtxoIndexer(prevHashStack, addressOutpoints, addressLockups, nodeCtx) + err := c.reorgUtxoIndexer(prevHashStack, nodeCtx) if err != nil { c.logger.Error("ChainIndexer: Failed to reorg utxo indexer", "err", err) - validUtxoIndex = false } time4 = time.Since(start) @@ -447,7 +438,7 @@ func (c *ChainIndexer) indexerLoop(currentHeader *types.WorkObject, qiIndexerCh c.logger.Error("ChainIndexer: Failed to read block during reorg") continue } - c.addOutpointsToIndexer(addressOutpoints, addressLockups, nodeCtx, config, block) + c.addOutpointsToIndexer(nodeCtx, config, block) } } @@ -457,31 +448,15 @@ func (c *ChainIndexer) indexerLoop(currentHeader *types.WorkObject, qiIndexerCh } else { time3 = time.Since(start) if c.indexAddressUtxos { - c.addOutpointsToIndexer(addressOutpoints, addressLockups, nodeCtx, config, block) + c.addOutpointsToIndexer(nodeCtx, config, block) } time4 = time.Since(start) c.newHead(block.NumberU64(nodeCtx), false) time5 = time.Since(start) } - if c.indexAddressUtxos && validUtxoIndex { - err := rawdb.WriteAddressOutpoints(c.chainDb, addressOutpoints) - if err != nil { - panic(err) - } - err = rawdb.WriteAddressLockups(c.chainDb, addressLockups) - if err != nil { - panic(err) - } - } - time9 := time.Since(start) - for key, _ := range addressOutpoints { - delete(addressOutpoints, key) - } - addressOutpoints = nil - time10 := time.Since(start) prevHeader, prevHash = block, block.Hash() @@ -821,10 +796,11 @@ func (c *ChainIndexer) removeSectionHead(section uint64) { } // addOutpointsToIndexer removes the spent outpoints and adds new utxos to the indexer. -func (c *ChainIndexer) addOutpointsToIndexer(addressOutpointsWithBlockHeight map[[20]byte][]*types.OutpointAndDenomination, addressLockups map[[20]byte][]*types.Lockup, nodeCtx int, config params.ChainConfig, block *types.WorkObject) { +func (c *ChainIndexer) addOutpointsToIndexer(nodeCtx int, config params.ChainConfig, block *types.WorkObject) { utxos := block.QiTransactions() - + addressOutpointsWithBlockHeight := make(map[[20]byte][]*types.OutpointAndDenomination) + addressLockups := make(map[[20]byte][]*types.Lockup) for _, tx := range utxos { for _, in := range tx.TxIn() { @@ -1044,13 +1020,24 @@ func (c *ChainIndexer) addOutpointsToIndexer(addressOutpointsWithBlockHeight map } } } + + err := rawdb.WriteAddressOutpoints(c.chainDb, addressOutpointsWithBlockHeight) + if err != nil { + panic(err) + } + err = rawdb.WriteAddressLockups(c.chainDb, addressLockups) + if err != nil { + panic(err) + } } // reorgUtxoIndexer adds back previously removed outpoints and removes newly added outpoints. // This is done in reverse order from the old header to the common ancestor. -func (c *ChainIndexer) reorgUtxoIndexer(headers []*types.WorkObject, addressOutpoints map[[20]byte][]*types.OutpointAndDenomination, addressLockups map[[20]byte][]*types.Lockup, nodeCtx int) error { - for _, header := range headers { +func (c *ChainIndexer) reorgUtxoIndexer(headers []*types.WorkObject, nodeCtx int) error { + for _, header := range headers { + addressOutpoints := make(map[[20]byte][]*types.OutpointAndDenomination) + addressLockups := make(map[[20]byte][]*types.Lockup) block := rawdb.ReadWorkObject(c.chainDb, header.NumberU64(nodeCtx), header.Hash(), types.BlockObject) if block == nil { c.logger.Errorf("ChainIndexer: Error reading block during reorg hash: %s", block.Hash().String()) @@ -1180,6 +1167,14 @@ func (c *ChainIndexer) reorgUtxoIndexer(headers []*types.WorkObject, addressOutp } } } + err = rawdb.WriteAddressOutpoints(c.chainDb, addressOutpoints) + if err != nil { + panic(err) + } + err = rawdb.WriteAddressLockups(c.chainDb, addressLockups) + if err != nil { + panic(err) + } } return nil }