diff --git a/db.go b/db.go index a1144ec0..68853f68 100644 --- a/db.go +++ b/db.go @@ -59,6 +59,13 @@ type Db interface { // cache the underlying data if desired. FetchBlockBySha(sha *btcwire.ShaHash) (blk *btcutil.Block, err error) + // FetchBlockHeightBySha returns the block height for the given hash. + FetchBlockHeightBySha(sha *btcwire.ShaHash) (height int64, err error) + + // FetchBlockHeaderBySha returns a btcwire.BlockHeader for the given + // sha. The implementation may cache the underlying data if desired. + FetchBlockHeaderBySha(sha *btcwire.ShaHash) (bh *btcwire.BlockHeader, err error) + // FetchBlockShaByHeight returns a block hash based on its height in the // block chain. FetchBlockShaByHeight(height int64) (sha *btcwire.ShaHash, err error) diff --git a/ldb/block.go b/ldb/block.go index bcfa0696..64f2053c 100644 --- a/ldb/block.go +++ b/ldb/block.go @@ -38,6 +38,38 @@ func (db *LevelDb) fetchBlockBySha(sha *btcwire.ShaHash) (blk *btcutil.Block, er return } +// FetchBlockHeightBySha returns the block height for the given hash. This is +// part of the btcdb.Db interface implementation. +func (db *LevelDb) FetchBlockHeightBySha(sha *btcwire.ShaHash) (int64, error) { + db.dbLock.Lock() + defer db.dbLock.Unlock() + + return db.getBlkLoc(sha) +} + +// FetchBlockHeaderBySha - return a btcwire ShaHash +func (db *LevelDb) FetchBlockHeaderBySha(sha *btcwire.ShaHash) (bh *btcwire.BlockHeader, err error) { + db.dbLock.Lock() + defer db.dbLock.Unlock() + + // Read the raw block from the database. + buf, _, err := db.fetchSha(sha) + if err != nil { + return nil, err + } + + // Only deserialize the header portion and ensure the transaction count + // is zero since this is a standalone header. + var blockHeader btcwire.BlockHeader + err = blockHeader.Deserialize(bytes.NewBuffer(buf)) + if err != nil { + return nil, err + } + bh = &blockHeader + + return bh, err +} + func (db *LevelDb) getBlkLoc(sha *btcwire.ShaHash) (int64, error) { var blkHeight int64 diff --git a/memdb/memdb.go b/memdb/memdb.go index 4b805627..e9bd795a 100644 --- a/memdb/memdb.go +++ b/memdb/memdb.go @@ -230,6 +230,44 @@ func (db *MemDb) FetchBlockBySha(sha *btcwire.ShaHash) (*btcutil.Block, error) { return nil, fmt.Errorf("block %v is not in database", sha) } +// FetchBlockHeightBySha returns the block height for the given hash. This is +// part of the btcdb.Db interface implementation. +func (db *MemDb) FetchBlockHeightBySha(sha *btcwire.ShaHash) (int64, error) { + db.Lock() + defer db.Unlock() + + if db.closed { + return 0, ErrDbClosed + } + + if blockHeight, exists := db.blocksBySha[*sha]; exists { + return blockHeight, nil + } + + return 0, fmt.Errorf("block %v is not in database", sha) +} + +// FetchBlockHeaderBySha returns a btcwire.BlockHeader for the given sha. The +// implementation may cache the underlying data if desired. This is part of the +// btcdb.Db interface implementation. +// +// This implementation does not use any additional cache since the entire +// database is already in memory. +func (db *MemDb) FetchBlockHeaderBySha(sha *btcwire.ShaHash) (*btcwire.BlockHeader, error) { + db.Lock() + defer db.Unlock() + + if db.closed { + return nil, ErrDbClosed + } + + if blockHeight, exists := db.blocksBySha[*sha]; exists { + return &db.blocks[int(blockHeight)].Header, nil + } + + return nil, fmt.Errorf("block header %v is not in database", sha) +} + // FetchBlockShaByHeight returns a block hash based on its height in the block // chain. This is part of the btcdb.Db interface implementation. func (db *MemDb) FetchBlockShaByHeight(height int64) (*btcwire.ShaHash, error) {