Skip to content

Commit d21a396

Browse files
committed
reduce allocations
1 parent 8b8c926 commit d21a396

11 files changed

Lines changed: 114 additions & 237 deletions

core/blockchain_reader.go

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@ func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
8686
return bc.hc.GetHeaderByNumber(number)
8787
}
8888

89+
// GetBlockNumber retrieves the block number associated with a block hash.
90+
func (bc *BlockChain) GetBlockNumber(hash common.Hash) *uint64 {
91+
if num, ok := bc.hc.GetBlockNumber(hash); ok {
92+
return &num
93+
}
94+
return nil
95+
}
96+
8997
// GetHeadersFrom returns a contiguous segment of headers, in rlp-form, going
9098
// backwards from the given number.
9199
func (bc *BlockChain) GetHeadersFrom(number, count uint64) []rlp.RawValue {
@@ -99,11 +107,11 @@ func (bc *BlockChain) GetBody(hash common.Hash) *types.Body {
99107
if cached, ok := bc.bodyCache.Get(hash); ok {
100108
return cached
101109
}
102-
number := bc.hc.GetBlockNumber(hash)
103-
if number == nil {
110+
number, ok := bc.hc.GetBlockNumber(hash)
111+
if !ok {
104112
return nil
105113
}
106-
body := rawdb.ReadBody(bc.db, hash, *number)
114+
body := rawdb.ReadBody(bc.db, hash, number)
107115
if body == nil {
108116
return nil
109117
}
@@ -119,11 +127,11 @@ func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue {
119127
if cached, ok := bc.bodyRLPCache.Get(hash); ok {
120128
return cached
121129
}
122-
number := bc.hc.GetBlockNumber(hash)
123-
if number == nil {
130+
number, ok := bc.hc.GetBlockNumber(hash)
131+
if !ok {
124132
return nil
125133
}
126-
body := rawdb.ReadBodyRLP(bc.db, hash, *number)
134+
body := rawdb.ReadBodyRLP(bc.db, hash, number)
127135
if len(body) == 0 {
128136
return nil
129137
}
@@ -172,11 +180,11 @@ func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
172180

173181
// GetBlockByHash retrieves a block from the database by hash, caching it if found.
174182
func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block {
175-
number := bc.hc.GetBlockNumber(hash)
176-
if number == nil {
183+
number, ok := bc.hc.GetBlockNumber(hash)
184+
if !ok {
177185
return nil
178186
}
179-
return bc.GetBlock(hash, *number)
187+
return bc.GetBlock(hash, number)
180188
}
181189

182190
// GetBlockByNumber retrieves a block from the database by number, caching it
@@ -192,18 +200,18 @@ func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block {
192200
// GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors.
193201
// [deprecated by eth/62]
194202
func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
195-
number := bc.hc.GetBlockNumber(hash)
196-
if number == nil {
203+
number, ok := bc.hc.GetBlockNumber(hash)
204+
if !ok {
197205
return nil
198206
}
199207
for i := 0; i < n; i++ {
200-
block := bc.GetBlock(hash, *number)
208+
block := bc.GetBlock(hash, number)
201209
if block == nil {
202210
break
203211
}
204212
blocks = append(blocks, block)
205213
hash = block.ParentHash()
206-
*number--
214+
number--
207215
}
208216
return
209217
}
@@ -213,15 +221,15 @@ func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
213221
if receipts, ok := bc.receiptsCache.Get(hash); ok {
214222
return receipts
215223
}
216-
number := rawdb.ReadHeaderNumber(bc.db, hash)
217-
if number == nil {
224+
number, ok := rawdb.ReadHeaderNumber(bc.db, hash)
225+
if !ok {
218226
return nil
219227
}
220-
header := bc.GetHeader(hash, *number)
228+
header := bc.GetHeader(hash, number)
221229
if header == nil {
222230
return nil
223231
}
224-
receipts := rawdb.ReadReceipts(bc.db, hash, *number, header.Time, bc.chainConfig)
232+
receipts := rawdb.ReadReceipts(bc.db, hash, number, header.Time, bc.chainConfig)
225233
if receipts == nil {
226234
return nil
227235
}
@@ -230,11 +238,29 @@ func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
230238
}
231239

232240
func (bc *BlockChain) GetRawReceiptsByHash(hash common.Hash) types.Receipts {
233-
number := rawdb.ReadHeaderNumber(bc.db, hash)
234-
if number == nil {
241+
number, ok := rawdb.ReadHeaderNumber(bc.db, hash)
242+
if !ok {
243+
return nil
244+
}
245+
return rawdb.ReadRawReceipts(bc.db, hash, number)
246+
}
247+
248+
// GetRawReceipts retrieves the receipts for all transactions in a given block
249+
// without deriving the internal fields and the Bloom.
250+
func (bc *BlockChain) GetRawReceipts(hash common.Hash, number uint64) types.Receipts {
251+
if receipts, ok := bc.receiptsCache.Get(hash); ok {
252+
return receipts
253+
}
254+
return rawdb.ReadRawReceipts(bc.db, hash, number)
255+
}
256+
257+
// GetReceiptsRLP retrieves the receipts of a block.
258+
func (bc *BlockChain) GetReceiptsRLP(hash common.Hash) rlp.RawValue {
259+
number, ok := rawdb.ReadHeaderNumber(bc.db, hash)
260+
if !ok {
235261
return nil
236262
}
237-
return rawdb.ReadRawReceipts(bc.db, hash, *number)
263+
return rawdb.ReadReceiptsRLP(bc.db, hash, number)
238264
}
239265

240266
// GetUnclesInChain retrieves all the uncles from a given block backwards until

core/genesis.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,12 +223,12 @@ func SetupGenesisBlock(db ctxcdb.Database, genesis *Genesis) (*params.ChainConfi
223223

224224
// Check config compatibility and write the config. Compatibility errors
225225
// are returned to the caller unless we're already at block zero.
226-
height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db))
227-
if height == nil {
226+
height, ok := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db))
227+
if !ok {
228228
return newcfg, stored, fmt.Errorf("missing block number for head header hash")
229229
}
230-
compatErr := storedcfg.CheckCompatible(newcfg, *height)
231-
if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 {
230+
compatErr := storedcfg.CheckCompatible(newcfg, height)
231+
if compatErr != nil && height != 0 && compatErr.RewindTo != 0 {
232232
return newcfg, stored, compatErr
233233
}
234234
rawdb.WriteChainConfig(db, stored, newcfg)

core/headerchain.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,15 @@ func NewHeaderChain(chainDb ctxcdb.Database, config *params.ChainConfig, engine
109109

110110
// GetBlockNumber retrieves the block number belonging to the given hash
111111
// from the cache or database
112-
func (hc *HeaderChain) GetBlockNumber(hash common.Hash) *uint64 {
112+
func (hc *HeaderChain) GetBlockNumber(hash common.Hash) (uint64, bool) {
113113
if cached, ok := hc.numberCache.Get(hash); ok {
114-
return &cached
114+
return cached, true
115115
}
116-
number := rawdb.ReadHeaderNumber(hc.chainDb, hash)
117-
if number != nil {
118-
hc.numberCache.Add(hash, *number)
116+
number, ok := rawdb.ReadHeaderNumber(hc.chainDb, hash)
117+
if ok {
118+
hc.numberCache.Add(hash, number)
119119
}
120-
return number
120+
return number, ok
121121
}
122122

123123
type headerWriteResult struct {
@@ -463,11 +463,11 @@ func (hc *HeaderChain) GetTd(hash common.Hash, number uint64) *big.Int {
463463
// GetTdByHash retrieves a block's total difficulty in the canonical chain from the
464464
// database by hash, caching it if found.
465465
func (hc *HeaderChain) GetTdByHash(hash common.Hash) *big.Int {
466-
number := hc.GetBlockNumber(hash)
467-
if number == nil {
466+
number, ok := hc.GetBlockNumber(hash)
467+
if !ok {
468468
return nil
469469
}
470-
return hc.GetTd(hash, *number)
470+
return hc.GetTd(hash, number)
471471
}
472472

473473
// GetHeader retrieves a block header from the database by hash and number,
@@ -489,11 +489,11 @@ func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header
489489
// GetHeaderByHash retrieves a block header from the database by hash, caching it if
490490
// found.
491491
func (hc *HeaderChain) GetHeaderByHash(hash common.Hash) *types.Header {
492-
number := hc.GetBlockNumber(hash)
493-
if number == nil {
492+
number, ok := hc.GetBlockNumber(hash)
493+
if !ok {
494494
return nil
495495
}
496-
return hc.GetHeader(hash, *number)
496+
return hc.GetHeader(hash, number)
497497
}
498498

499499
// HasHeader checks if a block header is present in the database or not.

core/rawdb/accessors_chain.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,13 @@ func ReadAllCanonicalHashes(db ctxcdb.Iteratee, from uint64, to uint64, limit in
143143
}
144144

145145
// ReadHeaderNumber returns the header number assigned to a hash.
146-
func ReadHeaderNumber(db ctxcdb.KeyValueReader, hash common.Hash) *uint64 {
146+
func ReadHeaderNumber(db ctxcdb.KeyValueReader, hash common.Hash) (uint64, bool) {
147147
data, _ := db.Get(headerNumberKey(hash))
148148
if len(data) != 8 {
149-
return nil
149+
return 0, false
150150
}
151151
number := binary.BigEndian.Uint64(data)
152-
return &number
152+
return number, true
153153
}
154154

155155
// WriteHeaderNumber stores the hash->number mapping.
@@ -986,11 +986,11 @@ func ReadHeadHeader(db ctxcdb.Reader) *types.Header {
986986
if headHeaderHash == (common.Hash{}) {
987987
return nil
988988
}
989-
headHeaderNumber := ReadHeaderNumber(db, headHeaderHash)
990-
if headHeaderNumber == nil {
989+
headHeaderNumber, ok := ReadHeaderNumber(db, headHeaderHash)
990+
if !ok {
991991
return nil
992992
}
993-
return ReadHeader(db, headHeaderHash, *headHeaderNumber)
993+
return ReadHeader(db, headHeaderHash, headHeaderNumber)
994994
}
995995

996996
// ReadHeadBlock returns the current canonical head block.
@@ -999,9 +999,9 @@ func ReadHeadBlock(db ctxcdb.Reader) *types.Block {
999999
if headBlockHash == (common.Hash{}) {
10001000
return nil
10011001
}
1002-
headBlockNumber := ReadHeaderNumber(db, headBlockHash)
1003-
if headBlockNumber == nil {
1002+
headBlockNumber, ok := ReadHeaderNumber(db, headBlockHash)
1003+
if !ok {
10041004
return nil
10051005
}
1006-
return ReadBlock(db, headBlockHash, *headBlockNumber)
1006+
return ReadBlock(db, headBlockHash, headBlockNumber)
10071007
}

core/rawdb/accessors_indexes.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,11 @@ func DecodeTxLookupEntry(data []byte, db ctxcdb.Reader) *uint64 {
4040
}
4141
// Database v4-v5 tx lookup format just stores the hash
4242
if len(data) == common.HashLength {
43-
return ReadHeaderNumber(db, common.BytesToHash(data))
43+
number, ok := ReadHeaderNumber(db, common.BytesToHash(data))
44+
if !ok {
45+
return nil
46+
}
47+
return &number
4448
}
4549
// Finally try database v3 tx lookup format
4650
var entry LegacyTxLookupEntry

core/rawdb/chain_freezer.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,12 @@ func (f *chainFreezer) readHeadNumber(db ctxcdb.KeyValueReader) uint64 {
107107
log.Error("Head block is not reachable")
108108
return 0
109109
}
110-
number := ReadHeaderNumber(db, hash)
111-
if number == nil {
110+
number, ok := ReadHeaderNumber(db, hash)
111+
if !ok {
112112
log.Error("Number of head block is missing")
113113
return 0
114114
}
115-
return *number
115+
return number
116116
}
117117

118118
// readFinalizedNumber returns the number of finalized block. 0 is returned
@@ -122,12 +122,12 @@ func (f *chainFreezer) readFinalizedNumber(db ctxcdb.KeyValueReader) uint64 {
122122
if hash == (common.Hash{}) {
123123
return 0
124124
}
125-
number := ReadHeaderNumber(db, hash)
126-
if number == nil {
125+
number, ok := ReadHeaderNumber(db, hash)
126+
if !ok {
127127
log.Error("Number of finalized block is missing")
128128
return 0
129129
}
130-
return *number
130+
return number
131131
}
132132

133133
// freezeThreshold returns the threshold for chain freezing. It's determined

core/rawdb/database.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,12 @@ func Open(db ctxcdb.KeyValueStore, opts OpenOptions) (ctxcdb.Database, error) {
268268
if kvhash, _ := db.Get(headerHashKey(frozen)); len(kvhash) == 0 {
269269
// Subsequent header after the freezer limit is missing from the database.
270270
// Reject startup if the database has a more recent head.
271-
if head := *ReadHeaderNumber(db, ReadHeadHeaderHash(db)); head > frozen-1 {
271+
head, ok := ReadHeaderNumber(db, ReadHeadHeaderHash(db))
272+
if !ok {
273+
printChainMetadata(db)
274+
return nil, fmt.Errorf("could not read header number, hash %v", ReadHeadHeaderHash(db))
275+
}
276+
if head > frozen-1 {
272277
// Find the smallest block stored in the key-value store
273278
// in range of [frozen, head]
274279
var number uint64

core/txindexer.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,11 +216,11 @@ func (indexer *txIndexer) resolveHead() uint64 {
216216
if headBlockHash == (common.Hash{}) {
217217
return 0
218218
}
219-
headBlockNumber := rawdb.ReadHeaderNumber(indexer.db, headBlockHash)
220-
if headBlockNumber == nil {
219+
headBlockNumber, ok := rawdb.ReadHeaderNumber(indexer.db, headBlockHash)
220+
if !ok {
221221
return 0
222222
}
223-
return *headBlockNumber
223+
return headBlockNumber
224224
}
225225

226226
// loop is the scheduler of the indexer, assigning indexing/unindexing tasks depending

0 commit comments

Comments
 (0)