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 return body
} }
number := bc.hc.GetBlockNumber(hash) number := bc.hc.GetBlockNumber(hash)
if number == nil { if number == rawdb.UnknownNumber {
return nil return nil
} }
body := rawdb.ReadBody(bc.db, hash, *number) body := rawdb.ReadBody(bc.db, hash, number)
if body == nil { if body == nil {
return nil return nil
} }
@ -551,10 +551,10 @@ func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue {
return cached.(rlp.RawValue) return cached.(rlp.RawValue)
} }
number := bc.hc.GetBlockNumber(hash) number := bc.hc.GetBlockNumber(hash)
if number == nil { if number == rawdb.UnknownNumber {
return nil return nil
} }
body := rawdb.ReadBodyRLP(bc.db, hash, *number) body := rawdb.ReadBodyRLP(bc.db, hash, number)
if len(body) == 0 { if len(body) == 0 {
return nil 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. // GetBlockByHash retrieves a block from the database by hash, caching it if found.
func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block { func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block {
number := bc.hc.GetBlockNumber(hash) number := bc.hc.GetBlockNumber(hash)
if number == nil { if number == rawdb.UnknownNumber {
return nil return nil
} }
return bc.GetBlock(hash, *number) return bc.GetBlock(hash, number)
} }
// GetBlockByNumber retrieves a block from the database by number, caching it // 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) return receipts.(types.Receipts)
} }
number := rawdb.ReadHeaderNumber(bc.db, hash) number := rawdb.ReadHeaderNumber(bc.db, hash)
if number == nil { if number == rawdb.UnknownNumber {
return nil return nil
} }
receipts := rawdb.ReadReceipts(bc.db, hash, *number) receipts := rawdb.ReadReceipts(bc.db, hash, number)
if receipts == nil { if receipts == nil {
return nil return nil
} }
@ -655,17 +655,17 @@ func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
// [deprecated by eth/62] // [deprecated by eth/62]
func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) { func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
number := bc.hc.GetBlockNumber(hash) number := bc.hc.GetBlockNumber(hash)
if number == nil { if number == rawdb.UnknownNumber {
return nil return nil
} }
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
block := bc.GetBlock(hash, *number) block := bc.GetBlock(hash, number)
if block == nil { if block == nil {
break break
} }
blocks = append(blocks, block) blocks = append(blocks, block)
hash = block.ParentHash() hash = block.ParentHash()
*number-- number--
} }
return return
} }
@ -1408,10 +1408,10 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
collectLogs = func(hash common.Hash) { collectLogs = func(hash common.Hash) {
// Coalesce logs and set 'Removed'. // Coalesce logs and set 'Removed'.
number := bc.hc.GetBlockNumber(hash) number := bc.hc.GetBlockNumber(hash)
if number == nil { if number == rawdb.UnknownNumber {
return return
} }
receipts := rawdb.ReadReceipts(bc.db, hash, *number) receipts := rawdb.ReadReceipts(bc.db, hash, number)
for _, receipt := range receipts { for _, receipt := range receipts {
for _, log := range receipt.Logs { for _, log := range receipt.Logs {
del := *log 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 // Check config compatibility and write the config. Compatibility errors
// are returned to the caller unless we're already at block zero. // are returned to the caller unless we're already at block zero.
height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db)) 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") return newcfg, stored, fmt.Errorf("missing block number for head header hash")
} }
compatErr := storedcfg.CheckCompatible(newcfg, *height) compatErr := storedcfg.CheckCompatible(newcfg, height)
if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 { if compatErr != nil && height != 0 && compatErr.RewindTo != 0 {
return newcfg, stored, compatErr return newcfg, stored, compatErr
} }
rawdb.WriteChainConfig(db, stored, newcfg) 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 // GetBlockNumber retrieves the block number belonging to the given hash
// from the cache or database // 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 { if cached, ok := hc.numberCache.Get(hash); ok {
number := cached.(uint64) number := cached.(uint64)
return &number return number
} }
number := rawdb.ReadHeaderNumber(hc.chainDb, hash) number := rawdb.ReadHeaderNumber(hc.chainDb, hash)
if number != nil { if number != rawdb.UnknownNumber {
hc.numberCache.Add(hash, *number) hc.numberCache.Add(hash, number)
} }
return 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. // database by hash, caching it if found.
func (hc *HeaderChain) GetTdByHash(hash common.Hash) *big.Int { func (hc *HeaderChain) GetTdByHash(hash common.Hash) *big.Int {
number := hc.GetBlockNumber(hash) number := hc.GetBlockNumber(hash)
if number == nil { if number == rawdb.UnknownNumber {
return nil 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 // 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. // found.
func (hc *HeaderChain) GetHeaderByHash(hash common.Hash) *types.Header { func (hc *HeaderChain) GetHeaderByHash(hash common.Hash) *types.Header {
number := hc.GetBlockNumber(hash) number := hc.GetBlockNumber(hash)
if number == nil { if number == rawdb.UnknownNumber {
return nil 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. // 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" "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. // ReadCanonicalHash retrieves the hash assigned to a canonical block number.
func ReadCanonicalHash(db DatabaseReader, number uint64) common.Hash { func ReadCanonicalHash(db DatabaseReader, number uint64) common.Hash {
data, _ := db.Get(headerHashKey(number)) data, _ := db.Get(headerHashKey(number))
@ -51,13 +54,13 @@ func DeleteCanonicalHash(db DatabaseDeleter, number uint64) {
} }
// ReadHeaderNumber returns the header number assigned to a hash. // 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)) data, _ := db.Get(headerNumberKey(hash))
if len(data) != 8 { if len(data) != 8 {
return nil return UnknownNumber
} }
number := binary.BigEndian.Uint64(data) number := binary.BigEndian.Uint64(data)
return &number return number
} }
// ReadHeadHeaderHash retrieves the hash of the current canonical head header. // 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 uncles [][]*types.Header
) )
for _, hash := range hashes { 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()) txs = append(txs, block.Transactions())
uncles = append(uncles, block.Uncles()) 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 { func (p *FakePeer) RequestReceipts(hashes []common.Hash) error {
var receipts [][]*types.Receipt var receipts [][]*types.Receipt
for _, hash := range hashes { 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) p.dl.DeliverReceipts(p.id, receipts)
return nil 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) { func (b *LesApiBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != nil { if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != rawdb.UnknownNumber {
return light.GetBlockReceipts(ctx, b.eth.odr, hash, *number) return light.GetBlockReceipts(ctx, b.eth.odr, hash, number)
} }
return nil, nil return nil, nil
} }
func (b *LesApiBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) { func (b *LesApiBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != nil { if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != rawdb.UnknownNumber {
return light.GetBlockLogs(ctx, b.eth.odr, hash, *number) return light.GetBlockLogs(ctx, b.eth.odr, hash, number)
} }
return nil, nil return nil, nil
} }

View file

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

View file

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