-
Notifications
You must be signed in to change notification settings - Fork 296
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
blockchain: Refactor db main chain idx to blk idx. #1332
blockchain: Refactor db main chain idx to blk idx. #1332
Conversation
blockchain/chain.go
Outdated
return err | ||
}) | ||
return block, err | ||
} | ||
|
||
// fetchBlockByHash returns the block with the given hash from all known sources | ||
// fetchBlockByNode returns the block with the given hash from all known sources |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No longer takes a hash. Comment needs update.
blockchain/chain.go
Outdated
// such as the internal caches and the database. This function returns blocks | ||
// regardless or whether or not they are part of the main chain. | ||
// | ||
// This function is safe for concurrent access. | ||
func (b *BlockChain) fetchBlockByHash(hash *chainhash.Hash) (*dcrutil.Block, error) { | ||
func (b *BlockChain) fetchBlockByNode(node *blockNode) (*dcrutil.Block, error) { | ||
// Check orphan cache. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The order of the main and orphan cache checks here should probably be reversed because the chances the block is in the main chain cache is much higher than being an orphan.
blockchain/chain.go
Outdated
} | ||
|
||
// Return the block from either cache or the database. Note that this is | ||
// note using fetchMainChainBlockByNode since the main chain check has |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/note/not/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tOK testnet2 miner
Running smooth on testnet and did a successful idb on mainnet |
So far, so good on testnet.
|
Running mainnet and testnet instances for the last 4 days with no issues found. |
blockchain/chain.go
Outdated
} | ||
|
||
// There is nothing to do when the start and end heights are the same, | ||
// so return now to avoid the chain lock and a database transaction. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment needs to be updated since a database transaction is no longer needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
blockchain/chain.go
Outdated
// fetchBlockByHash returns the block with the given hash from all known sources | ||
// such as the internal caches and the database. This function returns blocks | ||
// regardless or whether or not they are part of the main chain. | ||
// fetchBlockByNode returns the block assocaited with the given node all known |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
associated is misspelled
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
blockchain/chain.go
Outdated
// height. The end height will be limited to the current main chain height. | ||
// | ||
// This function is safe for concurrent access. | ||
func (b *BlockChain) HeightRange(startHeight, endHeight int64) ([]chainhash.Hash, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps document that this is the half open range [startHeight, endHeight)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It says It is inclusive of the start height and exclusive of the end height
already. I figured that would make it clear. I'll go ahead and expand on it a bit to include the blurb you suggest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
b.heightLock.RLock() | ||
iterNode := b.mainNodesByHeight[endHeight-1] | ||
b.heightLock.RUnlock() | ||
for i := startHeight; i < endHeight; i++ { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this would read better to me if it iterated backwards until reaching the start height
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather not change this since it has already been well tested manually and reversing it could easily introduce an off by one. Since the blocklocator bits no longer use this function, the only remaining caller is from RPC handlers for which there are, unfortunately, no automated tests.
// Generate the results sorted by descending height. | ||
sort.Sort(sort.Reverse(nodeHeightSorter(chainTips))) | ||
results := make([]dcrjson.GetChainTipsResult, len(chainTips)) | ||
b.chainLock.RLock() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is being protected by this mutex (why is being held longer here now?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The inMainChain
flag on the node is protected by the chain lock.
9814565
to
1788cc3
Compare
Rebased to latest master and squashed all review commits. |
This refactors the code that relies on the database main chain index to use the in-memory block index now that the full index is in memory. This is a major optimization for several functions because they no longer have to first consult the database (which is incredibly slow in many cases due to the way leveldb splits all of the information across files) to perform lookups and determine if blocks are in the main chain. It should also be noted that even though the main chain index is no longer used as of this commit, the code which writes the main chain index entries to the database in connectBlock, disconnectBlock, and createChainState have not been removed because, once that is done, it will no longer be possible to downgrade and thus those changes must be performed along with a database migration and associated version bump. An overview of the changes are as follows: - Update all code which previously used the db to use the main chain by height map instead - Update several internal functions which previously accepted the hash to instead accept the block node as the parameter - Rename fetchMainChainBlockByHash to fetchMainChainBlockByNode - Rename fetchBlockByHash to fetchBlockByNode - Rename dbFetchBlockByHash to dbFetchBlockByNode - Update all callers to use the new names and semantics - Optimize HeaderByHeight to use block index/height map instead of db - Move to chain.go since it no longer involves database I/O - Optimize BlockByHash to use block index instead of db - Move to chain.go since it no longer involves database I/O - Optimize BlockByHeight to use block index/height map instead of db - Move to chain.go since it no longer involves database I/O - Optimize MainChainHasBlock to use block index instead of db - Move to chain.go since it no longer involves database I/O - Removed error return since it can no longer fail - Optimize BlockHeightByHash to use block index instead of db - Move to chain.go since it no longer involves database I/O - Optimize BlockHashByHeight to use block index instead of db - Move to chain.go since it no longer involves database I/O - Optimize HeightRange to use block index instead of db - Move to chain.go since it no longer involves database I/O - Remove several unused functions related to the main chain index - dbFetchHeaderByHash - DBFetchHeaderByHeight - dbFetchBlockByHeight - DBFetchBlockByHeight - dbMainChainHasBlock - DBMainChainHasBlock - Rework IsCheckpointCandidate to use block index - Modify the upgrade code to expose the old dbFetchBlockByHeight function only in the local scope since upgrades require the ability to read the old format - Update indexers to fetch the blocks themselves while only querying chain for chain-related details
1788cc3
to
c6b5f6d
Compare
This refactors the code that relies on the database main chain index to use the in-memory block index now that the full index is in memory.
This is a major optimization for several functions because they no longer have to first consult the database (which is incredibly slow in many cases due to the way
leveldb
splits all of the information across files) to perform lookups and determine if blocks are in the main chain.It should also be noted that even though the main chain index is no longer used as of this commit, the code which writes the main chain index entries to the database in
connectBlock
,disconnectBlock
, andcreateChainState
have not been removed because, once that is done, it will no longer be possible to downgrade and thus those changes must be performed along with a database migration and associated version bump.An overview of the changes are as follows:
fetchMainChainBlockByHash
tofetchMainChainBlockByNode
fetchBlockByHash
tofetchBlockByNode
dbFetchBlockByHash
todbFetchBlockByNode
HeaderByHeight
to use block index/height map instead of dbchain.go
since it no longer involves database I/OBlockByHash
to use block index instead of dbchain.go
since it no longer involves database I/OBlockByHeight
to use block index/height map instead of dbchain.go
since it no longer involves database I/OMainChainHasBlock
to use block index instead of dbchain.go
since it no longer involves database I/OBlockHeightByHash
to use block index instead of dbchain.go
since it no longer involves database I/OBlockHashByHeight
to use block index instead of dbchain.go
since it no longer involves database I/OHeightRange
to use block index instead of dbchain.go
since it no longer involves database I/OdbFetchHeaderByHash
DBFetchHeaderByHeight
dbFetchBlockByHeight
DBFetchBlockByHeight
dbMainChainHasBlock
DBMainChainHasBlock
IsCheckpointCandidate
to use block indexdbFetchBlockByHeight
function only in the local scope since upgrades require the ability to read the old formatThis is work towards #1145.