cmd, core, eth, les, node: chain freezer on top of db rework

This commit is contained in:
Péter Szilágyi
2019-03-08 15:56:20 +02:00
parent 0c5f8c078a
commit 006c21efc7
15 changed files with 755 additions and 35 deletions

View File

@ -30,8 +30,11 @@ import (
)
// ReadCanonicalHash retrieves the hash assigned to a canonical block number.
func ReadCanonicalHash(db ethdb.Reader, number uint64) common.Hash {
data, _ := db.Get(headerHashKey(number))
func ReadCanonicalHash(db ethdb.AncientReader, number uint64) common.Hash {
data, _ := db.Ancient("hashes", number)
if len(data) == 0 {
data, _ = db.Get(headerHashKey(number))
}
if len(data) == 0 {
return common.Hash{}
}
@ -52,6 +55,24 @@ func DeleteCanonicalHash(db ethdb.Writer, number uint64) {
}
}
// readAllHashes retrieves all the hashes assigned to blocks at a certain heights,
// both canonical and reorged forks included.
//
// This method is a helper for the chain reader. It should never be exposed to the
// outside world.
func readAllHashes(db ethdb.Iteratee, number uint64) []common.Hash {
prefix := headerKeyPrefix(number)
hashes := make([]common.Hash, 0, 1)
it := db.NewIteratorWithPrefix(prefix)
for it.Next() {
if key := it.Key(); len(key) == len(prefix)+32 {
hashes = append(hashes, common.BytesToHash(key[len(key)-32:]))
}
}
return hashes
}
// ReadHeaderNumber returns the header number assigned to a hash.
func ReadHeaderNumber(db ethdb.Reader, hash common.Hash) *uint64 {
data, _ := db.Get(headerNumberKey(hash))
@ -129,13 +150,19 @@ func WriteFastTrieProgress(db ethdb.Writer, count uint64) {
}
// ReadHeaderRLP retrieves a block header in its raw RLP database encoding.
func ReadHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
data, _ := db.Get(headerKey(number, hash))
func ReadHeaderRLP(db ethdb.AncientReader, hash common.Hash, number uint64) rlp.RawValue {
data, _ := db.Ancient("headers", number)
if len(data) == 0 {
data, _ = db.Get(headerKey(number, hash))
}
return data
}
// HasHeader verifies the existence of a block header corresponding to the hash.
func HasHeader(db ethdb.Reader, hash common.Hash, number uint64) bool {
func HasHeader(db ethdb.AncientReader, hash common.Hash, number uint64) bool {
if has, err := db.Ancient("hashes", number); err == nil && common.BytesToHash(has) == hash {
return true
}
if has, err := db.Has(headerKey(number, hash)); !has || err != nil {
return false
}
@ -143,7 +170,7 @@ func HasHeader(db ethdb.Reader, hash common.Hash, number uint64) bool {
}
// ReadHeader retrieves the block header corresponding to the hash.
func ReadHeader(db ethdb.Reader, hash common.Hash, number uint64) *types.Header {
func ReadHeader(db ethdb.AncientReader, hash common.Hash, number uint64) *types.Header {
data := ReadHeaderRLP(db, hash, number)
if len(data) == 0 {
return nil
@ -197,8 +224,11 @@ func deleteHeaderWithoutNumber(db ethdb.Writer, hash common.Hash, number uint64)
}
// ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding.
func ReadBodyRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
data, _ := db.Get(blockBodyKey(number, hash))
func ReadBodyRLP(db ethdb.AncientReader, hash common.Hash, number uint64) rlp.RawValue {
data, _ := db.Ancient("bodies", number)
if len(data) == 0 {
data, _ = db.Get(blockBodyKey(number, hash))
}
return data
}
@ -210,7 +240,10 @@ func WriteBodyRLP(db ethdb.Writer, hash common.Hash, number uint64, rlp rlp.RawV
}
// HasBody verifies the existence of a block body corresponding to the hash.
func HasBody(db ethdb.Reader, hash common.Hash, number uint64) bool {
func HasBody(db ethdb.AncientReader, hash common.Hash, number uint64) bool {
if has, err := db.Ancient("hashes", number); err == nil && common.BytesToHash(has) == hash {
return true
}
if has, err := db.Has(blockBodyKey(number, hash)); !has || err != nil {
return false
}
@ -218,7 +251,7 @@ func HasBody(db ethdb.Reader, hash common.Hash, number uint64) bool {
}
// ReadBody retrieves the block body corresponding to the hash.
func ReadBody(db ethdb.Reader, hash common.Hash, number uint64) *types.Body {
func ReadBody(db ethdb.AncientReader, hash common.Hash, number uint64) *types.Body {
data := ReadBodyRLP(db, hash, number)
if len(data) == 0 {
return nil
@ -248,13 +281,16 @@ func DeleteBody(db ethdb.Writer, hash common.Hash, number uint64) {
}
// ReadTdRLP retrieves a block's total difficulty corresponding to the hash in RLP encoding.
func ReadTdRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
data, _ := db.Get(headerTDKey(number, hash))
func ReadTdRLP(db ethdb.AncientReader, hash common.Hash, number uint64) rlp.RawValue {
data, _ := db.Ancient("diffs", number)
if len(data) == 0 {
data, _ = db.Get(headerTDKey(number, hash))
}
return data
}
// ReadTd retrieves a block's total difficulty corresponding to the hash.
func ReadTd(db ethdb.Reader, hash common.Hash, number uint64) *big.Int {
func ReadTd(db ethdb.AncientReader, hash common.Hash, number uint64) *big.Int {
data := ReadTdRLP(db, hash, number)
if len(data) == 0 {
return nil
@ -287,7 +323,10 @@ func DeleteTd(db ethdb.Writer, hash common.Hash, number uint64) {
// HasReceipts verifies the existence of all the transaction receipts belonging
// to a block.
func HasReceipts(db ethdb.Reader, hash common.Hash, number uint64) bool {
func HasReceipts(db ethdb.AncientReader, hash common.Hash, number uint64) bool {
if has, err := db.Ancient("hashes", number); err == nil && common.BytesToHash(has) == hash {
return true
}
if has, err := db.Has(blockReceiptsKey(number, hash)); !has || err != nil {
return false
}
@ -295,15 +334,18 @@ func HasReceipts(db ethdb.Reader, hash common.Hash, number uint64) bool {
}
// ReadReceiptsRLP retrieves all the transaction receipts belonging to a block in RLP encoding.
func ReadReceiptsRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
data, _ := db.Get(blockReceiptsKey(number, hash))
func ReadReceiptsRLP(db ethdb.AncientReader, hash common.Hash, number uint64) rlp.RawValue {
data, _ := db.Ancient("receipts", number)
if len(data) == 0 {
data, _ = db.Get(blockReceiptsKey(number, hash))
}
return data
}
// ReadRawReceipts retrieves all the transaction receipts belonging to a block.
// The receipt metadata fields are not guaranteed to be populated, so they
// should not be used. Use ReadReceipts instead if the metadata is needed.
func ReadRawReceipts(db ethdb.Reader, hash common.Hash, number uint64) types.Receipts {
func ReadRawReceipts(db ethdb.AncientReader, hash common.Hash, number uint64) types.Receipts {
// Retrieve the flattened receipt slice
data := ReadReceiptsRLP(db, hash, number)
if len(data) == 0 {
@ -329,7 +371,7 @@ func ReadRawReceipts(db ethdb.Reader, hash common.Hash, number uint64) types.Rec
// The current implementation populates these metadata fields by reading the receipts'
// corresponding block body, so if the block body is not found it will return nil even
// if the receipt itself is stored.
func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) types.Receipts {
func ReadReceipts(db ethdb.AncientReader, hash common.Hash, number uint64, config *params.ChainConfig) types.Receipts {
// We're deriving many fields from the block body, retrieve beside the receipt
receipts := ReadRawReceipts(db, hash, number)
if receipts == nil {
@ -377,7 +419,7 @@ func DeleteReceipts(db ethdb.Writer, hash common.Hash, number uint64) {
//
// Note, due to concurrent download of header and block body the header and thus
// canonical hash can be stored in the database but the body data not (yet).
func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block {
func ReadBlock(db ethdb.AncientReader, hash common.Hash, number uint64) *types.Block {
header := ReadHeader(db, hash, number)
if header == nil {
return nil
@ -413,7 +455,7 @@ func deleteBlockWithoutNumber(db ethdb.Writer, hash common.Hash, number uint64)
}
// FindCommonAncestor returns the last common ancestor of two block headers
func FindCommonAncestor(db ethdb.Reader, a, b *types.Header) *types.Header {
func FindCommonAncestor(db ethdb.AncientReader, a, b *types.Header) *types.Header {
for bn := b.Number.Uint64(); a.Number.Uint64() > bn; {
a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1)
if a == nil {