1// Copyright 2018 The go-ethereum Authors
2// This file is part of the go-ethereum library.
3//
4// The go-ethereum library is free software: you can redistribute it and/or modify
5// it under the terms of the GNU Lesser General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// The go-ethereum library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU Lesser General Public License for more details.
13//
14// You should have received a copy of the GNU Lesser General Public License
15// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16
17package rawdb
18
19import (
20	"bytes"
21	"encoding/binary"
22	"errors"
23	"fmt"
24	"math/big"
25	"sort"
26
27	"github.com/ethereum/go-ethereum/common"
28	"github.com/ethereum/go-ethereum/core/types"
29	"github.com/ethereum/go-ethereum/crypto"
30	"github.com/ethereum/go-ethereum/ethdb"
31	"github.com/ethereum/go-ethereum/log"
32	"github.com/ethereum/go-ethereum/params"
33	"github.com/ethereum/go-ethereum/rlp"
34)
35
36// ReadCanonicalHash retrieves the hash assigned to a canonical block number.
37func ReadCanonicalHash(db ethdb.Reader, number uint64) common.Hash {
38	var data []byte
39	db.ReadAncients(func(reader ethdb.AncientReader) error {
40		data, _ = reader.Ancient(freezerHashTable, number)
41		if len(data) == 0 {
42			// Get it by hash from leveldb
43			data, _ = db.Get(headerHashKey(number))
44		}
45		return nil
46	})
47	return common.BytesToHash(data)
48}
49
50// WriteCanonicalHash stores the hash assigned to a canonical block number.
51func WriteCanonicalHash(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
52	if err := db.Put(headerHashKey(number), hash.Bytes()); err != nil {
53		log.Crit("Failed to store number to hash mapping", "err", err)
54	}
55}
56
57// DeleteCanonicalHash removes the number to hash canonical mapping.
58func DeleteCanonicalHash(db ethdb.KeyValueWriter, number uint64) {
59	if err := db.Delete(headerHashKey(number)); err != nil {
60		log.Crit("Failed to delete number to hash mapping", "err", err)
61	}
62}
63
64// ReadAllHashes retrieves all the hashes assigned to blocks at a certain heights,
65// both canonical and reorged forks included.
66func ReadAllHashes(db ethdb.Iteratee, number uint64) []common.Hash {
67	prefix := headerKeyPrefix(number)
68
69	hashes := make([]common.Hash, 0, 1)
70	it := db.NewIterator(prefix, nil)
71	defer it.Release()
72
73	for it.Next() {
74		if key := it.Key(); len(key) == len(prefix)+32 {
75			hashes = append(hashes, common.BytesToHash(key[len(key)-32:]))
76		}
77	}
78	return hashes
79}
80
81type NumberHash struct {
82	Number uint64
83	Hash   common.Hash
84}
85
86// ReadAllHashes retrieves all the hashes assigned to blocks at a certain heights,
87// both canonical and reorged forks included.
88// This method considers both limits to be _inclusive_.
89func ReadAllHashesInRange(db ethdb.Iteratee, first, last uint64) []*NumberHash {
90	var (
91		start     = encodeBlockNumber(first)
92		keyLength = len(headerPrefix) + 8 + 32
93		hashes    = make([]*NumberHash, 0, 1+last-first)
94		it        = db.NewIterator(headerPrefix, start)
95	)
96	defer it.Release()
97	for it.Next() {
98		key := it.Key()
99		if len(key) != keyLength {
100			continue
101		}
102		num := binary.BigEndian.Uint64(key[len(headerPrefix) : len(headerPrefix)+8])
103		if num > last {
104			break
105		}
106		hash := common.BytesToHash(key[len(key)-32:])
107		hashes = append(hashes, &NumberHash{num, hash})
108	}
109	return hashes
110}
111
112// ReadAllCanonicalHashes retrieves all canonical number and hash mappings at the
113// certain chain range. If the accumulated entries reaches the given threshold,
114// abort the iteration and return the semi-finish result.
115func ReadAllCanonicalHashes(db ethdb.Iteratee, from uint64, to uint64, limit int) ([]uint64, []common.Hash) {
116	// Short circuit if the limit is 0.
117	if limit == 0 {
118		return nil, nil
119	}
120	var (
121		numbers []uint64
122		hashes  []common.Hash
123	)
124	// Construct the key prefix of start point.
125	start, end := headerHashKey(from), headerHashKey(to)
126	it := db.NewIterator(nil, start)
127	defer it.Release()
128
129	for it.Next() {
130		if bytes.Compare(it.Key(), end) >= 0 {
131			break
132		}
133		if key := it.Key(); len(key) == len(headerPrefix)+8+1 && bytes.Equal(key[len(key)-1:], headerHashSuffix) {
134			numbers = append(numbers, binary.BigEndian.Uint64(key[len(headerPrefix):len(headerPrefix)+8]))
135			hashes = append(hashes, common.BytesToHash(it.Value()))
136			// If the accumulated entries reaches the limit threshold, return.
137			if len(numbers) >= limit {
138				break
139			}
140		}
141	}
142	return numbers, hashes
143}
144
145// ReadHeaderNumber returns the header number assigned to a hash.
146func ReadHeaderNumber(db ethdb.KeyValueReader, hash common.Hash) *uint64 {
147	data, _ := db.Get(headerNumberKey(hash))
148	if len(data) != 8 {
149		return nil
150	}
151	number := binary.BigEndian.Uint64(data)
152	return &number
153}
154
155// WriteHeaderNumber stores the hash->number mapping.
156func WriteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
157	key := headerNumberKey(hash)
158	enc := encodeBlockNumber(number)
159	if err := db.Put(key, enc); err != nil {
160		log.Crit("Failed to store hash to number mapping", "err", err)
161	}
162}
163
164// DeleteHeaderNumber removes hash->number mapping.
165func DeleteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash) {
166	if err := db.Delete(headerNumberKey(hash)); err != nil {
167		log.Crit("Failed to delete hash to number mapping", "err", err)
168	}
169}
170
171// ReadHeadHeaderHash retrieves the hash of the current canonical head header.
172func ReadHeadHeaderHash(db ethdb.KeyValueReader) common.Hash {
173	data, _ := db.Get(headHeaderKey)
174	if len(data) == 0 {
175		return common.Hash{}
176	}
177	return common.BytesToHash(data)
178}
179
180// WriteHeadHeaderHash stores the hash of the current canonical head header.
181func WriteHeadHeaderHash(db ethdb.KeyValueWriter, hash common.Hash) {
182	if err := db.Put(headHeaderKey, hash.Bytes()); err != nil {
183		log.Crit("Failed to store last header's hash", "err", err)
184	}
185}
186
187// ReadHeadBlockHash retrieves the hash of the current canonical head block.
188func ReadHeadBlockHash(db ethdb.KeyValueReader) common.Hash {
189	data, _ := db.Get(headBlockKey)
190	if len(data) == 0 {
191		return common.Hash{}
192	}
193	return common.BytesToHash(data)
194}
195
196// WriteHeadBlockHash stores the head block's hash.
197func WriteHeadBlockHash(db ethdb.KeyValueWriter, hash common.Hash) {
198	if err := db.Put(headBlockKey, hash.Bytes()); err != nil {
199		log.Crit("Failed to store last block's hash", "err", err)
200	}
201}
202
203// ReadHeadFastBlockHash retrieves the hash of the current fast-sync head block.
204func ReadHeadFastBlockHash(db ethdb.KeyValueReader) common.Hash {
205	data, _ := db.Get(headFastBlockKey)
206	if len(data) == 0 {
207		return common.Hash{}
208	}
209	return common.BytesToHash(data)
210}
211
212// WriteHeadFastBlockHash stores the hash of the current fast-sync head block.
213func WriteHeadFastBlockHash(db ethdb.KeyValueWriter, hash common.Hash) {
214	if err := db.Put(headFastBlockKey, hash.Bytes()); err != nil {
215		log.Crit("Failed to store last fast block's hash", "err", err)
216	}
217}
218
219// ReadLastPivotNumber retrieves the number of the last pivot block. If the node
220// full synced, the last pivot will always be nil.
221func ReadLastPivotNumber(db ethdb.KeyValueReader) *uint64 {
222	data, _ := db.Get(lastPivotKey)
223	if len(data) == 0 {
224		return nil
225	}
226	var pivot uint64
227	if err := rlp.DecodeBytes(data, &pivot); err != nil {
228		log.Error("Invalid pivot block number in database", "err", err)
229		return nil
230	}
231	return &pivot
232}
233
234// WriteLastPivotNumber stores the number of the last pivot block.
235func WriteLastPivotNumber(db ethdb.KeyValueWriter, pivot uint64) {
236	enc, err := rlp.EncodeToBytes(pivot)
237	if err != nil {
238		log.Crit("Failed to encode pivot block number", "err", err)
239	}
240	if err := db.Put(lastPivotKey, enc); err != nil {
241		log.Crit("Failed to store pivot block number", "err", err)
242	}
243}
244
245// ReadTxIndexTail retrieves the number of oldest indexed block
246// whose transaction indices has been indexed. If the corresponding entry
247// is non-existent in database it means the indexing has been finished.
248func ReadTxIndexTail(db ethdb.KeyValueReader) *uint64 {
249	data, _ := db.Get(txIndexTailKey)
250	if len(data) != 8 {
251		return nil
252	}
253	number := binary.BigEndian.Uint64(data)
254	return &number
255}
256
257// WriteTxIndexTail stores the number of oldest indexed block
258// into database.
259func WriteTxIndexTail(db ethdb.KeyValueWriter, number uint64) {
260	if err := db.Put(txIndexTailKey, encodeBlockNumber(number)); err != nil {
261		log.Crit("Failed to store the transaction index tail", "err", err)
262	}
263}
264
265// ReadFastTxLookupLimit retrieves the tx lookup limit used in fast sync.
266func ReadFastTxLookupLimit(db ethdb.KeyValueReader) *uint64 {
267	data, _ := db.Get(fastTxLookupLimitKey)
268	if len(data) != 8 {
269		return nil
270	}
271	number := binary.BigEndian.Uint64(data)
272	return &number
273}
274
275// WriteFastTxLookupLimit stores the txlookup limit used in fast sync into database.
276func WriteFastTxLookupLimit(db ethdb.KeyValueWriter, number uint64) {
277	if err := db.Put(fastTxLookupLimitKey, encodeBlockNumber(number)); err != nil {
278		log.Crit("Failed to store transaction lookup limit for fast sync", "err", err)
279	}
280}
281
282// ReadHeaderRange returns the rlp-encoded headers, starting at 'number', and going
283// backwards towards genesis. This method assumes that the caller already has
284// placed a cap on count, to prevent DoS issues.
285// Since this method operates in head-towards-genesis mode, it will return an empty
286// slice in case the head ('number') is missing. Hence, the caller must ensure that
287// the head ('number') argument is actually an existing header.
288//
289// N.B: Since the input is a number, as opposed to a hash, it's implicit that
290// this method only operates on canon headers.
291func ReadHeaderRange(db ethdb.Reader, number uint64, count uint64) []rlp.RawValue {
292	var rlpHeaders []rlp.RawValue
293	if count == 0 {
294		return rlpHeaders
295	}
296	i := number
297	if count-1 > number {
298		// It's ok to request block 0, 1 item
299		count = number + 1
300	}
301	limit, _ := db.Ancients()
302	// First read live blocks
303	if i >= limit {
304		// If we need to read live blocks, we need to figure out the hash first
305		hash := ReadCanonicalHash(db, number)
306		for ; i >= limit && count > 0; i-- {
307			if data, _ := db.Get(headerKey(i, hash)); len(data) > 0 {
308				rlpHeaders = append(rlpHeaders, data)
309				// Get the parent hash for next query
310				hash = types.HeaderParentHashFromRLP(data)
311			} else {
312				break // Maybe got moved to ancients
313			}
314			count--
315		}
316	}
317	if count == 0 {
318		return rlpHeaders
319	}
320	// read remaining from ancients
321	max := count * 700
322	data, err := db.AncientRange(freezerHeaderTable, i+1-count, count, max)
323	if err == nil && uint64(len(data)) == count {
324		// the data is on the order [h, h+1, .., n] -- reordering needed
325		for i := range data {
326			rlpHeaders = append(rlpHeaders, data[len(data)-1-i])
327		}
328	}
329	return rlpHeaders
330}
331
332// ReadHeaderRLP retrieves a block header in its raw RLP database encoding.
333func ReadHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
334	var data []byte
335	db.ReadAncients(func(reader ethdb.AncientReader) error {
336		// First try to look up the data in ancient database. Extra hash
337		// comparison is necessary since ancient database only maintains
338		// the canonical data.
339		data, _ = reader.Ancient(freezerHeaderTable, number)
340		if len(data) > 0 && crypto.Keccak256Hash(data) == hash {
341			return nil
342		}
343		// If not, try reading from leveldb
344		data, _ = db.Get(headerKey(number, hash))
345		return nil
346	})
347	return data
348}
349
350// HasHeader verifies the existence of a block header corresponding to the hash.
351func HasHeader(db ethdb.Reader, hash common.Hash, number uint64) bool {
352	if isCanon(db, number, hash) {
353		return true
354	}
355	if has, err := db.Has(headerKey(number, hash)); !has || err != nil {
356		return false
357	}
358	return true
359}
360
361// ReadHeader retrieves the block header corresponding to the hash.
362func ReadHeader(db ethdb.Reader, hash common.Hash, number uint64) *types.Header {
363	data := ReadHeaderRLP(db, hash, number)
364	if len(data) == 0 {
365		return nil
366	}
367	header := new(types.Header)
368	if err := rlp.Decode(bytes.NewReader(data), header); err != nil {
369		log.Error("Invalid block header RLP", "hash", hash, "err", err)
370		return nil
371	}
372	return header
373}
374
375// WriteHeader stores a block header into the database and also stores the hash-
376// to-number mapping.
377func WriteHeader(db ethdb.KeyValueWriter, header *types.Header) {
378	var (
379		hash   = header.Hash()
380		number = header.Number.Uint64()
381	)
382	// Write the hash -> number mapping
383	WriteHeaderNumber(db, hash, number)
384
385	// Write the encoded header
386	data, err := rlp.EncodeToBytes(header)
387	if err != nil {
388		log.Crit("Failed to RLP encode header", "err", err)
389	}
390	key := headerKey(number, hash)
391	if err := db.Put(key, data); err != nil {
392		log.Crit("Failed to store header", "err", err)
393	}
394}
395
396// DeleteHeader removes all block header data associated with a hash.
397func DeleteHeader(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
398	deleteHeaderWithoutNumber(db, hash, number)
399	if err := db.Delete(headerNumberKey(hash)); err != nil {
400		log.Crit("Failed to delete hash to number mapping", "err", err)
401	}
402}
403
404// deleteHeaderWithoutNumber removes only the block header but does not remove
405// the hash to number mapping.
406func deleteHeaderWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
407	if err := db.Delete(headerKey(number, hash)); err != nil {
408		log.Crit("Failed to delete header", "err", err)
409	}
410}
411
412// isCanon is an internal utility method, to check whether the given number/hash
413// is part of the ancient (canon) set.
414func isCanon(reader ethdb.AncientReader, number uint64, hash common.Hash) bool {
415	h, err := reader.Ancient(freezerHashTable, number)
416	if err != nil {
417		return false
418	}
419	return bytes.Equal(h, hash[:])
420}
421
422// ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding.
423func ReadBodyRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
424	// First try to look up the data in ancient database. Extra hash
425	// comparison is necessary since ancient database only maintains
426	// the canonical data.
427	var data []byte
428	db.ReadAncients(func(reader ethdb.AncientReader) error {
429		// Check if the data is in ancients
430		if isCanon(reader, number, hash) {
431			data, _ = reader.Ancient(freezerBodiesTable, number)
432			return nil
433		}
434		// If not, try reading from leveldb
435		data, _ = db.Get(blockBodyKey(number, hash))
436		return nil
437	})
438	return data
439}
440
441// ReadCanonicalBodyRLP retrieves the block body (transactions and uncles) for the canonical
442// block at number, in RLP encoding.
443func ReadCanonicalBodyRLP(db ethdb.Reader, number uint64) rlp.RawValue {
444	var data []byte
445	db.ReadAncients(func(reader ethdb.AncientReader) error {
446		data, _ = reader.Ancient(freezerBodiesTable, number)
447		if len(data) > 0 {
448			return nil
449		}
450		// Get it by hash from leveldb
451		data, _ = db.Get(blockBodyKey(number, ReadCanonicalHash(db, number)))
452		return nil
453	})
454	return data
455}
456
457// WriteBodyRLP stores an RLP encoded block body into the database.
458func WriteBodyRLP(db ethdb.KeyValueWriter, hash common.Hash, number uint64, rlp rlp.RawValue) {
459	if err := db.Put(blockBodyKey(number, hash), rlp); err != nil {
460		log.Crit("Failed to store block body", "err", err)
461	}
462}
463
464// HasBody verifies the existence of a block body corresponding to the hash.
465func HasBody(db ethdb.Reader, hash common.Hash, number uint64) bool {
466	if isCanon(db, number, hash) {
467		return true
468	}
469	if has, err := db.Has(blockBodyKey(number, hash)); !has || err != nil {
470		return false
471	}
472	return true
473}
474
475// ReadBody retrieves the block body corresponding to the hash.
476func ReadBody(db ethdb.Reader, hash common.Hash, number uint64) *types.Body {
477	data := ReadBodyRLP(db, hash, number)
478	if len(data) == 0 {
479		return nil
480	}
481	body := new(types.Body)
482	if err := rlp.Decode(bytes.NewReader(data), body); err != nil {
483		log.Error("Invalid block body RLP", "hash", hash, "err", err)
484		return nil
485	}
486	return body
487}
488
489// WriteBody stores a block body into the database.
490func WriteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64, body *types.Body) {
491	data, err := rlp.EncodeToBytes(body)
492	if err != nil {
493		log.Crit("Failed to RLP encode body", "err", err)
494	}
495	WriteBodyRLP(db, hash, number, data)
496}
497
498// DeleteBody removes all block body data associated with a hash.
499func DeleteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
500	if err := db.Delete(blockBodyKey(number, hash)); err != nil {
501		log.Crit("Failed to delete block body", "err", err)
502	}
503}
504
505// ReadTdRLP retrieves a block's total difficulty corresponding to the hash in RLP encoding.
506func ReadTdRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
507	var data []byte
508	db.ReadAncients(func(reader ethdb.AncientReader) error {
509		// Check if the data is in ancients
510		if isCanon(reader, number, hash) {
511			data, _ = reader.Ancient(freezerDifficultyTable, number)
512			return nil
513		}
514		// If not, try reading from leveldb
515		data, _ = db.Get(headerTDKey(number, hash))
516		return nil
517	})
518	return data
519}
520
521// ReadTd retrieves a block's total difficulty corresponding to the hash.
522func ReadTd(db ethdb.Reader, hash common.Hash, number uint64) *big.Int {
523	data := ReadTdRLP(db, hash, number)
524	if len(data) == 0 {
525		return nil
526	}
527	td := new(big.Int)
528	if err := rlp.Decode(bytes.NewReader(data), td); err != nil {
529		log.Error("Invalid block total difficulty RLP", "hash", hash, "err", err)
530		return nil
531	}
532	return td
533}
534
535// WriteTd stores the total difficulty of a block into the database.
536func WriteTd(db ethdb.KeyValueWriter, hash common.Hash, number uint64, td *big.Int) {
537	data, err := rlp.EncodeToBytes(td)
538	if err != nil {
539		log.Crit("Failed to RLP encode block total difficulty", "err", err)
540	}
541	if err := db.Put(headerTDKey(number, hash), data); err != nil {
542		log.Crit("Failed to store block total difficulty", "err", err)
543	}
544}
545
546// DeleteTd removes all block total difficulty data associated with a hash.
547func DeleteTd(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
548	if err := db.Delete(headerTDKey(number, hash)); err != nil {
549		log.Crit("Failed to delete block total difficulty", "err", err)
550	}
551}
552
553// HasReceipts verifies the existence of all the transaction receipts belonging
554// to a block.
555func HasReceipts(db ethdb.Reader, hash common.Hash, number uint64) bool {
556	if isCanon(db, number, hash) {
557		return true
558	}
559	if has, err := db.Has(blockReceiptsKey(number, hash)); !has || err != nil {
560		return false
561	}
562	return true
563}
564
565// ReadReceiptsRLP retrieves all the transaction receipts belonging to a block in RLP encoding.
566func ReadReceiptsRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
567	var data []byte
568	db.ReadAncients(func(reader ethdb.AncientReader) error {
569		// Check if the data is in ancients
570		if isCanon(reader, number, hash) {
571			data, _ = reader.Ancient(freezerReceiptTable, number)
572			return nil
573		}
574		// If not, try reading from leveldb
575		data, _ = db.Get(blockReceiptsKey(number, hash))
576		return nil
577	})
578	return data
579}
580
581// ReadRawReceipts retrieves all the transaction receipts belonging to a block.
582// The receipt metadata fields are not guaranteed to be populated, so they
583// should not be used. Use ReadReceipts instead if the metadata is needed.
584func ReadRawReceipts(db ethdb.Reader, hash common.Hash, number uint64) types.Receipts {
585	// Retrieve the flattened receipt slice
586	data := ReadReceiptsRLP(db, hash, number)
587	if len(data) == 0 {
588		return nil
589	}
590	// Convert the receipts from their storage form to their internal representation
591	storageReceipts := []*types.ReceiptForStorage{}
592	if err := rlp.DecodeBytes(data, &storageReceipts); err != nil {
593		log.Error("Invalid receipt array RLP", "hash", hash, "err", err)
594		return nil
595	}
596	receipts := make(types.Receipts, len(storageReceipts))
597	for i, storageReceipt := range storageReceipts {
598		receipts[i] = (*types.Receipt)(storageReceipt)
599	}
600	return receipts
601}
602
603// ReadReceipts retrieves all the transaction receipts belonging to a block, including
604// its correspoinding metadata fields. If it is unable to populate these metadata
605// fields then nil is returned.
606//
607// The current implementation populates these metadata fields by reading the receipts'
608// corresponding block body, so if the block body is not found it will return nil even
609// if the receipt itself is stored.
610func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) types.Receipts {
611	// We're deriving many fields from the block body, retrieve beside the receipt
612	receipts := ReadRawReceipts(db, hash, number)
613	if receipts == nil {
614		return nil
615	}
616	body := ReadBody(db, hash, number)
617	if body == nil {
618		log.Error("Missing body but have receipt", "hash", hash, "number", number)
619		return nil
620	}
621	if err := receipts.DeriveFields(config, hash, number, body.Transactions); err != nil {
622		log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err)
623		return nil
624	}
625	return receipts
626}
627
628// WriteReceipts stores all the transaction receipts belonging to a block.
629func WriteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64, receipts types.Receipts) {
630	// Convert the receipts into their storage form and serialize them
631	storageReceipts := make([]*types.ReceiptForStorage, len(receipts))
632	for i, receipt := range receipts {
633		storageReceipts[i] = (*types.ReceiptForStorage)(receipt)
634	}
635	bytes, err := rlp.EncodeToBytes(storageReceipts)
636	if err != nil {
637		log.Crit("Failed to encode block receipts", "err", err)
638	}
639	// Store the flattened receipt slice
640	if err := db.Put(blockReceiptsKey(number, hash), bytes); err != nil {
641		log.Crit("Failed to store block receipts", "err", err)
642	}
643}
644
645// DeleteReceipts removes all receipt data associated with a block hash.
646func DeleteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
647	if err := db.Delete(blockReceiptsKey(number, hash)); err != nil {
648		log.Crit("Failed to delete block receipts", "err", err)
649	}
650}
651
652// storedReceiptRLP is the storage encoding of a receipt.
653// Re-definition in core/types/receipt.go.
654type storedReceiptRLP struct {
655	PostStateOrStatus []byte
656	CumulativeGasUsed uint64
657	Logs              []*types.LogForStorage
658}
659
660// ReceiptLogs is a barebone version of ReceiptForStorage which only keeps
661// the list of logs. When decoding a stored receipt into this object we
662// avoid creating the bloom filter.
663type receiptLogs struct {
664	Logs []*types.Log
665}
666
667// DecodeRLP implements rlp.Decoder.
668func (r *receiptLogs) DecodeRLP(s *rlp.Stream) error {
669	var stored storedReceiptRLP
670	if err := s.Decode(&stored); err != nil {
671		return err
672	}
673	r.Logs = make([]*types.Log, len(stored.Logs))
674	for i, log := range stored.Logs {
675		r.Logs[i] = (*types.Log)(log)
676	}
677	return nil
678}
679
680// DeriveLogFields fills the logs in receiptLogs with information such as block number, txhash, etc.
681func deriveLogFields(receipts []*receiptLogs, hash common.Hash, number uint64, txs types.Transactions) error {
682	logIndex := uint(0)
683	if len(txs) != len(receipts) {
684		return errors.New("transaction and receipt count mismatch")
685	}
686	for i := 0; i < len(receipts); i++ {
687		txHash := txs[i].Hash()
688		// The derived log fields can simply be set from the block and transaction
689		for j := 0; j < len(receipts[i].Logs); j++ {
690			receipts[i].Logs[j].BlockNumber = number
691			receipts[i].Logs[j].BlockHash = hash
692			receipts[i].Logs[j].TxHash = txHash
693			receipts[i].Logs[j].TxIndex = uint(i)
694			receipts[i].Logs[j].Index = logIndex
695			logIndex++
696		}
697	}
698	return nil
699}
700
701// ReadLogs retrieves the logs for all transactions in a block. The log fields
702// are populated with metadata. In case the receipts or the block body
703// are not found, a nil is returned.
704func ReadLogs(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) [][]*types.Log {
705	// Retrieve the flattened receipt slice
706	data := ReadReceiptsRLP(db, hash, number)
707	if len(data) == 0 {
708		return nil
709	}
710	receipts := []*receiptLogs{}
711	if err := rlp.DecodeBytes(data, &receipts); err != nil {
712		// Receipts might be in the legacy format, try decoding that.
713		// TODO: to be removed after users migrated
714		if logs := readLegacyLogs(db, hash, number, config); logs != nil {
715			return logs
716		}
717		log.Error("Invalid receipt array RLP", "hash", hash, "err", err)
718		return nil
719	}
720
721	body := ReadBody(db, hash, number)
722	if body == nil {
723		log.Error("Missing body but have receipt", "hash", hash, "number", number)
724		return nil
725	}
726	if err := deriveLogFields(receipts, hash, number, body.Transactions); err != nil {
727		log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err)
728		return nil
729	}
730	logs := make([][]*types.Log, len(receipts))
731	for i, receipt := range receipts {
732		logs[i] = receipt.Logs
733	}
734	return logs
735}
736
737// readLegacyLogs is a temporary workaround for when trying to read logs
738// from a block which has its receipt stored in the legacy format. It'll
739// be removed after users have migrated their freezer databases.
740func readLegacyLogs(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) [][]*types.Log {
741	receipts := ReadReceipts(db, hash, number, config)
742	if receipts == nil {
743		return nil
744	}
745	logs := make([][]*types.Log, len(receipts))
746	for i, receipt := range receipts {
747		logs[i] = receipt.Logs
748	}
749	return logs
750}
751
752// ReadBlock retrieves an entire block corresponding to the hash, assembling it
753// back from the stored header and body. If either the header or body could not
754// be retrieved nil is returned.
755//
756// Note, due to concurrent download of header and block body the header and thus
757// canonical hash can be stored in the database but the body data not (yet).
758func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block {
759	header := ReadHeader(db, hash, number)
760	if header == nil {
761		return nil
762	}
763	body := ReadBody(db, hash, number)
764	if body == nil {
765		return nil
766	}
767	return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles)
768}
769
770// WriteBlock serializes a block into the database, header and body separately.
771func WriteBlock(db ethdb.KeyValueWriter, block *types.Block) {
772	WriteBody(db, block.Hash(), block.NumberU64(), block.Body())
773	WriteHeader(db, block.Header())
774}
775
776// WriteAncientBlock writes entire block data into ancient store and returns the total written size.
777func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts []types.Receipts, td *big.Int) (int64, error) {
778	var (
779		tdSum      = new(big.Int).Set(td)
780		stReceipts []*types.ReceiptForStorage
781	)
782	return db.ModifyAncients(func(op ethdb.AncientWriteOp) error {
783		for i, block := range blocks {
784			// Convert receipts to storage format and sum up total difficulty.
785			stReceipts = stReceipts[:0]
786			for _, receipt := range receipts[i] {
787				stReceipts = append(stReceipts, (*types.ReceiptForStorage)(receipt))
788			}
789			header := block.Header()
790			if i > 0 {
791				tdSum.Add(tdSum, header.Difficulty)
792			}
793			if err := writeAncientBlock(op, block, header, stReceipts, tdSum); err != nil {
794				return err
795			}
796		}
797		return nil
798	})
799}
800
801func writeAncientBlock(op ethdb.AncientWriteOp, block *types.Block, header *types.Header, receipts []*types.ReceiptForStorage, td *big.Int) error {
802	num := block.NumberU64()
803	if err := op.AppendRaw(freezerHashTable, num, block.Hash().Bytes()); err != nil {
804		return fmt.Errorf("can't add block %d hash: %v", num, err)
805	}
806	if err := op.Append(freezerHeaderTable, num, header); err != nil {
807		return fmt.Errorf("can't append block header %d: %v", num, err)
808	}
809	if err := op.Append(freezerBodiesTable, num, block.Body()); err != nil {
810		return fmt.Errorf("can't append block body %d: %v", num, err)
811	}
812	if err := op.Append(freezerReceiptTable, num, receipts); err != nil {
813		return fmt.Errorf("can't append block %d receipts: %v", num, err)
814	}
815	if err := op.Append(freezerDifficultyTable, num, td); err != nil {
816		return fmt.Errorf("can't append block %d total difficulty: %v", num, err)
817	}
818	return nil
819}
820
821// DeleteBlock removes all block data associated with a hash.
822func DeleteBlock(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
823	DeleteReceipts(db, hash, number)
824	DeleteHeader(db, hash, number)
825	DeleteBody(db, hash, number)
826	DeleteTd(db, hash, number)
827}
828
829// DeleteBlockWithoutNumber removes all block data associated with a hash, except
830// the hash to number mapping.
831func DeleteBlockWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
832	DeleteReceipts(db, hash, number)
833	deleteHeaderWithoutNumber(db, hash, number)
834	DeleteBody(db, hash, number)
835	DeleteTd(db, hash, number)
836}
837
838const badBlockToKeep = 10
839
840type badBlock struct {
841	Header *types.Header
842	Body   *types.Body
843}
844
845// badBlockList implements the sort interface to allow sorting a list of
846// bad blocks by their number in the reverse order.
847type badBlockList []*badBlock
848
849func (s badBlockList) Len() int { return len(s) }
850func (s badBlockList) Less(i, j int) bool {
851	return s[i].Header.Number.Uint64() < s[j].Header.Number.Uint64()
852}
853func (s badBlockList) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
854
855// ReadBadBlock retrieves the bad block with the corresponding block hash.
856func ReadBadBlock(db ethdb.Reader, hash common.Hash) *types.Block {
857	blob, err := db.Get(badBlockKey)
858	if err != nil {
859		return nil
860	}
861	var badBlocks badBlockList
862	if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
863		return nil
864	}
865	for _, bad := range badBlocks {
866		if bad.Header.Hash() == hash {
867			return types.NewBlockWithHeader(bad.Header).WithBody(bad.Body.Transactions, bad.Body.Uncles)
868		}
869	}
870	return nil
871}
872
873// ReadAllBadBlocks retrieves all the bad blocks in the database.
874// All returned blocks are sorted in reverse order by number.
875func ReadAllBadBlocks(db ethdb.Reader) []*types.Block {
876	blob, err := db.Get(badBlockKey)
877	if err != nil {
878		return nil
879	}
880	var badBlocks badBlockList
881	if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
882		return nil
883	}
884	var blocks []*types.Block
885	for _, bad := range badBlocks {
886		blocks = append(blocks, types.NewBlockWithHeader(bad.Header).WithBody(bad.Body.Transactions, bad.Body.Uncles))
887	}
888	return blocks
889}
890
891// WriteBadBlock serializes the bad block into the database. If the cumulated
892// bad blocks exceeds the limitation, the oldest will be dropped.
893func WriteBadBlock(db ethdb.KeyValueStore, block *types.Block) {
894	blob, err := db.Get(badBlockKey)
895	if err != nil {
896		log.Warn("Failed to load old bad blocks", "error", err)
897	}
898	var badBlocks badBlockList
899	if len(blob) > 0 {
900		if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
901			log.Crit("Failed to decode old bad blocks", "error", err)
902		}
903	}
904	for _, b := range badBlocks {
905		if b.Header.Number.Uint64() == block.NumberU64() && b.Header.Hash() == block.Hash() {
906			log.Info("Skip duplicated bad block", "number", block.NumberU64(), "hash", block.Hash())
907			return
908		}
909	}
910	badBlocks = append(badBlocks, &badBlock{
911		Header: block.Header(),
912		Body:   block.Body(),
913	})
914	sort.Sort(sort.Reverse(badBlocks))
915	if len(badBlocks) > badBlockToKeep {
916		badBlocks = badBlocks[:badBlockToKeep]
917	}
918	data, err := rlp.EncodeToBytes(badBlocks)
919	if err != nil {
920		log.Crit("Failed to encode bad blocks", "err", err)
921	}
922	if err := db.Put(badBlockKey, data); err != nil {
923		log.Crit("Failed to write bad blocks", "err", err)
924	}
925}
926
927// DeleteBadBlocks deletes all the bad blocks from the database
928func DeleteBadBlocks(db ethdb.KeyValueWriter) {
929	if err := db.Delete(badBlockKey); err != nil {
930		log.Crit("Failed to delete bad blocks", "err", err)
931	}
932}
933
934// FindCommonAncestor returns the last common ancestor of two block headers
935func FindCommonAncestor(db ethdb.Reader, a, b *types.Header) *types.Header {
936	for bn := b.Number.Uint64(); a.Number.Uint64() > bn; {
937		a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1)
938		if a == nil {
939			return nil
940		}
941	}
942	for an := a.Number.Uint64(); an < b.Number.Uint64(); {
943		b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1)
944		if b == nil {
945			return nil
946		}
947	}
948	for a.Hash() != b.Hash() {
949		a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1)
950		if a == nil {
951			return nil
952		}
953		b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1)
954		if b == nil {
955			return nil
956		}
957	}
958	return a
959}
960
961// ReadHeadHeader returns the current canonical head header.
962func ReadHeadHeader(db ethdb.Reader) *types.Header {
963	headHeaderHash := ReadHeadHeaderHash(db)
964	if headHeaderHash == (common.Hash{}) {
965		return nil
966	}
967	headHeaderNumber := ReadHeaderNumber(db, headHeaderHash)
968	if headHeaderNumber == nil {
969		return nil
970	}
971	return ReadHeader(db, headHeaderHash, *headHeaderNumber)
972}
973
974// ReadHeadBlock returns the current canonical head block.
975func ReadHeadBlock(db ethdb.Reader) *types.Block {
976	headBlockHash := ReadHeadBlockHash(db)
977	if headBlockHash == (common.Hash{}) {
978		return nil
979	}
980	headBlockNumber := ReadHeaderNumber(db, headBlockHash)
981	if headBlockNumber == nil {
982		return nil
983	}
984	return ReadBlock(db, headBlockHash, *headBlockNumber)
985}
986