database: Stop writing block header data to LevelDB.
Now that all headers are stored in the in-memory index, the database bucket managed by blockchain, and in the flat files, it makes sense to drop the redundant data from the block index bucket in ffldb. To avoid modifying the database interface, this reimplements FetchBlockHeader(s) to use header data stored in flat files. This can be trivially implemented by delegating to FetchBlockRegion.
This commit is contained in:
parent
74fb6e56da
commit
ad00e7ff82
1 changed files with 11 additions and 69 deletions
|
@ -1255,27 +1255,11 @@ func (tx *transaction) fetchBlockRow(hash *chainhash.Hash) ([]byte, error) {
|
|||
//
|
||||
// This function is part of the database.Tx interface implementation.
|
||||
func (tx *transaction) FetchBlockHeader(hash *chainhash.Hash) ([]byte, error) {
|
||||
// Ensure transaction state is valid.
|
||||
if err := tx.checkClosed(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// When the block is pending to be written on commit return the bytes
|
||||
// from there.
|
||||
if idx, exists := tx.pendingBlocks[*hash]; exists {
|
||||
blockBytes := tx.pendingBlockData[idx].bytes
|
||||
return blockBytes[0:blockHdrSize:blockHdrSize], nil
|
||||
}
|
||||
|
||||
// Fetch the block index row and slice off the header. Notice the use
|
||||
// of the cap on the subslice to prevent the caller from accidentally
|
||||
// appending into the db data.
|
||||
blockRow, err := tx.fetchBlockRow(hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
endOffset := blockLocSize + blockHdrSize
|
||||
return blockRow[blockLocSize:endOffset:endOffset], nil
|
||||
return tx.FetchBlockRegion(&database.BlockRegion{
|
||||
Hash: hash,
|
||||
Offset: 0,
|
||||
Len: blockHdrSize,
|
||||
})
|
||||
}
|
||||
|
||||
// FetchBlockHeaders returns the raw serialized bytes for the block headers
|
||||
|
@ -1294,41 +1278,13 @@ func (tx *transaction) FetchBlockHeader(hash *chainhash.Hash) ([]byte, error) {
|
|||
//
|
||||
// This function is part of the database.Tx interface implementation.
|
||||
func (tx *transaction) FetchBlockHeaders(hashes []chainhash.Hash) ([][]byte, error) {
|
||||
// Ensure transaction state is valid.
|
||||
if err := tx.checkClosed(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// NOTE: This could check for the existence of all blocks before loading
|
||||
// any of the headers which would be faster in the failure case, however
|
||||
// callers will not typically be calling this function with invalid
|
||||
// values, so optimize for the common case.
|
||||
|
||||
// Load the headers.
|
||||
headers := make([][]byte, len(hashes))
|
||||
regions := make([]database.BlockRegion, len(hashes))
|
||||
for i := range hashes {
|
||||
hash := &hashes[i]
|
||||
|
||||
// When the block is pending to be written on commit return the
|
||||
// bytes from there.
|
||||
if idx, exists := tx.pendingBlocks[*hash]; exists {
|
||||
blkBytes := tx.pendingBlockData[idx].bytes
|
||||
headers[i] = blkBytes[0:blockHdrSize:blockHdrSize]
|
||||
continue
|
||||
}
|
||||
|
||||
// Fetch the block index row and slice off the header. Notice
|
||||
// the use of the cap on the subslice to prevent the caller
|
||||
// from accidentally appending into the db data.
|
||||
blockRow, err := tx.fetchBlockRow(hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
endOffset := blockLocSize + blockHdrSize
|
||||
headers[i] = blockRow[blockLocSize:endOffset:endOffset]
|
||||
regions[i].Hash = &hashes[i]
|
||||
regions[i].Offset = 0
|
||||
regions[i].Len = blockHdrSize
|
||||
}
|
||||
|
||||
return headers, nil
|
||||
return tx.FetchBlockRegions(regions)
|
||||
}
|
||||
|
||||
// FetchBlock returns the raw serialized bytes for the block identified by the
|
||||
|
@ -1656,19 +1612,6 @@ func (tx *transaction) close() {
|
|||
}
|
||||
}
|
||||
|
||||
// serializeBlockRow serializes a block row into a format suitable for storage
|
||||
// into the block index.
|
||||
func serializeBlockRow(blockLoc blockLocation, blockHdr []byte) []byte {
|
||||
// The serialized block index row format is:
|
||||
//
|
||||
// [0:blockLocSize] Block location
|
||||
// [blockLocSize:blockLocSize+blockHdrSize] Block header
|
||||
serializedRow := make([]byte, blockLocSize+blockHdrSize)
|
||||
copy(serializedRow, serializeBlockLoc(blockLoc))
|
||||
copy(serializedRow[blockHdrOffset:], blockHdr)
|
||||
return serializedRow
|
||||
}
|
||||
|
||||
// writePendingAndCommit writes pending block data to the flat block files,
|
||||
// updates the metadata with their locations as well as the new current write
|
||||
// location, and commits the metadata to the memory database cache. It also
|
||||
|
@ -1706,8 +1649,7 @@ func (tx *transaction) writePendingAndCommit() error {
|
|||
// includes the location information needed to locate the block
|
||||
// on the filesystem as well as the block header since they are
|
||||
// so commonly needed.
|
||||
blockHdr := blockData.bytes[0:blockHdrSize]
|
||||
blockRow := serializeBlockRow(location, blockHdr)
|
||||
blockRow := serializeBlockLoc(location)
|
||||
err = tx.blockIdxBucket.Put(blockData.hash[:], blockRow)
|
||||
if err != nil {
|
||||
rollback()
|
||||
|
|
Loading…
Add table
Reference in a new issue