core, eth, les, light: return block number as uint64 instead of pointer

Returning a pointer to a primitive type for retrieval is not a common
convention. However, a pointer makes it clear whether or not the block
number exists as it can be `nil`. Instead a new UnknownNumber constant
has been added and substituted for the `nil` check.
This commit is contained in:
Matthew Halpern 2019-02-05 10:09:59 -08:00
parent 520024dfd6
commit 88535c7bf8
8 changed files with 52 additions and 49 deletions

View file

@ -531,10 +531,10 @@ func (bc *BlockChain) GetBody(hash common.Hash) *types.Body {
return body
}
number := bc.hc.GetBlockNumber(hash)
if number == nil {
if number == rawdb.UnknownNumber {
return nil
}
body := rawdb.ReadBody(bc.db, hash, *number)
body := rawdb.ReadBody(bc.db, hash, number)
if body == nil {
return nil
}
@ -551,10 +551,10 @@ func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue {
return cached.(rlp.RawValue)
}
number := bc.hc.GetBlockNumber(hash)
if number == nil {
if number == rawdb.UnknownNumber {
return nil
}
body := rawdb.ReadBodyRLP(bc.db, hash, *number)
body := rawdb.ReadBodyRLP(bc.db, hash, number)
if len(body) == 0 {
return nil
}
@ -618,10 +618,10 @@ func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
// GetBlockByHash retrieves a block from the database by hash, caching it if found.
func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block {
number := bc.hc.GetBlockNumber(hash)
if number == nil {
if number == rawdb.UnknownNumber {
return nil
}
return bc.GetBlock(hash, *number)
return bc.GetBlock(hash, number)
}
// GetBlockByNumber retrieves a block from the database by number, caching it
@ -640,10 +640,10 @@ func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
return receipts.(types.Receipts)
}
number := rawdb.ReadHeaderNumber(bc.db, hash)
if number == nil {
if number == rawdb.UnknownNumber {
return nil
}
receipts := rawdb.ReadReceipts(bc.db, hash, *number)
receipts := rawdb.ReadReceipts(bc.db, hash, number)
if receipts == nil {
return nil
}
@ -655,17 +655,17 @@ func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
// [deprecated by eth/62]
func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
number := bc.hc.GetBlockNumber(hash)
if number == nil {
if number == rawdb.UnknownNumber {
return nil
}
for i := 0; i < n; i++ {
block := bc.GetBlock(hash, *number)
block := bc.GetBlock(hash, number)
if block == nil {
break
}
blocks = append(blocks, block)
hash = block.ParentHash()
*number--
number--
}
return
}
@ -1408,10 +1408,10 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
collectLogs = func(hash common.Hash) {
// Coalesce logs and set 'Removed'.
number := bc.hc.GetBlockNumber(hash)
if number == nil {
if number == rawdb.UnknownNumber {
return
}
receipts := rawdb.ReadReceipts(bc.db, hash, *number)
receipts := rawdb.ReadReceipts(bc.db, hash, number)
for _, receipt := range receipts {
for _, log := range receipt.Logs {
del := *log

View file

@ -200,11 +200,11 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, constant
// Check config compatibility and write the config. Compatibility errors
// are returned to the caller unless we're already at block zero.
height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db))
if height == nil {
if height == rawdb.UnknownNumber {
return newcfg, stored, fmt.Errorf("missing block number for head header hash")
}
compatErr := storedcfg.CheckCompatible(newcfg, *height)
if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 {
compatErr := storedcfg.CheckCompatible(newcfg, height)
if compatErr != nil && height != 0 && compatErr.RewindTo != 0 {
return newcfg, stored, compatErr
}
rawdb.WriteChainConfig(db, stored, newcfg)

View file

@ -110,14 +110,14 @@ func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine c
// GetBlockNumber retrieves the block number belonging to the given hash
// from the cache or database
func (hc *HeaderChain) GetBlockNumber(hash common.Hash) *uint64 {
func (hc *HeaderChain) GetBlockNumber(hash common.Hash) uint64 {
if cached, ok := hc.numberCache.Get(hash); ok {
number := cached.(uint64)
return &number
return number
}
number := rawdb.ReadHeaderNumber(hc.chainDb, hash)
if number != nil {
hc.numberCache.Add(hash, *number)
if number != rawdb.UnknownNumber {
hc.numberCache.Add(hash, number)
}
return number
}
@ -381,10 +381,10 @@ func (hc *HeaderChain) GetTd(hash common.Hash, number uint64) *big.Int {
// database by hash, caching it if found.
func (hc *HeaderChain) GetTdByHash(hash common.Hash) *big.Int {
number := hc.GetBlockNumber(hash)
if number == nil {
if number == rawdb.UnknownNumber {
return nil
}
return hc.GetTd(hash, *number)
return hc.GetTd(hash, number)
}
// WriteTd stores a block's total difficulty into the database, also caching it
@ -415,10 +415,10 @@ func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header
// found.
func (hc *HeaderChain) GetHeaderByHash(hash common.Hash) *types.Header {
number := hc.GetBlockNumber(hash)
if number == nil {
if number == rawdb.UnknownNumber {
return nil
}
return hc.GetHeader(hash, *number)
return hc.GetHeader(hash, number)
}
// HasHeader checks if a block header is present in the database or not.

View file

@ -27,6 +27,9 @@ import (
"github.com/ethereum/go-ethereum/rlp"
)
// The block number is unknown.
const UnknownNumber = ^uint64(0)
// ReadCanonicalHash retrieves the hash assigned to a canonical block number.
func ReadCanonicalHash(db DatabaseReader, number uint64) common.Hash {
data, _ := db.Get(headerHashKey(number))
@ -51,13 +54,13 @@ func DeleteCanonicalHash(db DatabaseDeleter, number uint64) {
}
// ReadHeaderNumber returns the header number assigned to a hash.
func ReadHeaderNumber(db DatabaseReader, hash common.Hash) *uint64 {
func ReadHeaderNumber(db DatabaseReader, hash common.Hash) uint64 {
data, _ := db.Get(headerNumberKey(hash))
if len(data) != 8 {
return nil
return UnknownNumber
}
number := binary.BigEndian.Uint64(data)
return &number
return number
}
// ReadHeadHeaderHash retrieves the hash of the current canonical head header.

View file

@ -127,7 +127,7 @@ func (p *FakePeer) RequestBodies(hashes []common.Hash) error {
uncles [][]*types.Header
)
for _, hash := range hashes {
block := rawdb.ReadBlock(p.db, hash, *p.hc.GetBlockNumber(hash))
block := rawdb.ReadBlock(p.db, hash, p.hc.GetBlockNumber(hash))
txs = append(txs, block.Transactions())
uncles = append(uncles, block.Uncles())
@ -141,7 +141,7 @@ func (p *FakePeer) RequestBodies(hashes []common.Hash) error {
func (p *FakePeer) RequestReceipts(hashes []common.Hash) error {
var receipts [][]*types.Receipt
for _, hash := range hashes {
receipts = append(receipts, rawdb.ReadReceipts(p.db, hash, *p.hc.GetBlockNumber(hash)))
receipts = append(receipts, rawdb.ReadReceipts(p.db, hash, p.hc.GetBlockNumber(hash)))
}
p.dl.DeliverReceipts(p.id, receipts)
return nil

View file

@ -88,15 +88,15 @@ func (b *LesApiBackend) GetBlock(ctx context.Context, blockHash common.Hash) (*t
}
func (b *LesApiBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != nil {
return light.GetBlockReceipts(ctx, b.eth.odr, hash, *number)
if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != rawdb.UnknownNumber {
return light.GetBlockReceipts(ctx, b.eth.odr, hash, number)
}
return nil, nil
}
func (b *LesApiBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != nil {
return light.GetBlockLogs(ctx, b.eth.odr, hash, *number)
if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != rawdb.UnknownNumber {
return light.GetBlockLogs(ctx, b.eth.odr, hash, number)
}
return nil, nil
}

View file

@ -568,8 +568,8 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
break
}
// Retrieve the requested block body, stopping if enough was found
if number := rawdb.ReadHeaderNumber(pm.chainDb, hash); number != nil {
if data := rawdb.ReadBodyRLP(pm.chainDb, hash, *number); len(data) != 0 {
if number := rawdb.ReadHeaderNumber(pm.chainDb, hash); number != rawdb.UnknownNumber {
if data := rawdb.ReadBodyRLP(pm.chainDb, hash, number); len(data) != 0 {
bodies = append(bodies, data)
bytes += len(data)
}
@ -621,8 +621,8 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
}
for _, req := range req.Reqs {
// Retrieve the requested state entry, stopping if enough was found
if number := rawdb.ReadHeaderNumber(pm.chainDb, req.BHash); number != nil {
if header := rawdb.ReadHeader(pm.chainDb, req.BHash, *number); header != nil {
if number := rawdb.ReadHeaderNumber(pm.chainDb, req.BHash); number != rawdb.UnknownNumber {
if header := rawdb.ReadHeader(pm.chainDb, req.BHash, number); header != nil {
statedb, err := pm.blockchain.State()
if err != nil {
continue
@ -690,8 +690,8 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
}
// Retrieve the requested block's receipts, skipping if unknown to us
var results types.Receipts
if number := rawdb.ReadHeaderNumber(pm.chainDb, hash); number != nil {
results = rawdb.ReadReceipts(pm.chainDb, hash, *number)
if number := rawdb.ReadHeaderNumber(pm.chainDb, hash); number != rawdb.UnknownNumber {
results = rawdb.ReadReceipts(pm.chainDb, hash, number)
}
if results == nil {
if header := pm.blockchain.GetHeaderByHash(hash); header == nil || header.ReceiptHash != types.EmptyRootHash {
@ -752,8 +752,8 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
}
for _, req := range req.Reqs {
// Retrieve the requested state entry, stopping if enough was found
if number := rawdb.ReadHeaderNumber(pm.chainDb, req.BHash); number != nil {
if header := rawdb.ReadHeader(pm.chainDb, req.BHash, *number); header != nil {
if number := rawdb.ReadHeaderNumber(pm.chainDb, req.BHash); number != rawdb.UnknownNumber {
if header := rawdb.ReadHeader(pm.chainDb, req.BHash, number); header != nil {
statedb, err := pm.blockchain.State()
if err != nil {
continue
@ -812,8 +812,8 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
if statedb == nil || req.BHash != lastBHash {
statedb, root, lastBHash = nil, common.Hash{}, req.BHash
if number := rawdb.ReadHeaderNumber(pm.chainDb, req.BHash); number != nil {
if header := rawdb.ReadHeader(pm.chainDb, req.BHash, *number); header != nil {
if number := rawdb.ReadHeaderNumber(pm.chainDb, req.BHash); number != rawdb.UnknownNumber {
if header := rawdb.ReadHeader(pm.chainDb, req.BHash, number); header != nil {
statedb, _ = pm.blockchain.State()
root = header.Root
}

View file

@ -223,10 +223,10 @@ func (self *LightChain) GetBody(ctx context.Context, hash common.Hash) (*types.B
return body, nil
}
number := self.hc.GetBlockNumber(hash)
if number == nil {
if number == rawdb.UnknownNumber {
return nil, errors.New("unknown block")
}
body, err := GetBody(ctx, self.odr, hash, *number)
body, err := GetBody(ctx, self.odr, hash, number)
if err != nil {
return nil, err
}
@ -243,10 +243,10 @@ func (self *LightChain) GetBodyRLP(ctx context.Context, hash common.Hash) (rlp.R
return cached.(rlp.RawValue), nil
}
number := self.hc.GetBlockNumber(hash)
if number == nil {
if number == rawdb.UnknownNumber {
return nil, errors.New("unknown block")
}
body, err := GetBodyRLP(ctx, self.odr, hash, *number)
body, err := GetBodyRLP(ctx, self.odr, hash, number)
if err != nil {
return nil, err
}
@ -282,10 +282,10 @@ func (self *LightChain) GetBlock(ctx context.Context, hash common.Hash, number u
// caching it if found.
func (self *LightChain) GetBlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
number := self.hc.GetBlockNumber(hash)
if number == nil {
if number == rawdb.UnknownNumber {
return nil, errors.New("unknown block")
}
return self.GetBlock(ctx, hash, *number)
return self.GetBlock(ctx, hash, number)
}
// GetBlockByNumber retrieves a block from the database or ODR service by