@ -35,20 +35,15 @@ import (
// ReadCanonicalHash retrieves the hash assigned to a canonical block number.
// ReadCanonicalHash retrieves the hash assigned to a canonical block number.
func ReadCanonicalHash ( db ethdb . Reader , number uint64 ) common . Hash {
func ReadCanonicalHash ( db ethdb . Reader , number uint64 ) common . Hash {
data , _ := db . Ancient ( freezerHashTable , number )
var data [ ] byte
if len ( data ) == 0 {
db . ReadAncients ( func ( reader ethdb . AncientReader ) error {
data , _ = db . Get ( headerHashKey ( number ) )
data , _ = reader . Ancient ( freezerHashTable , number )
// In the background freezer is moving data from leveldb to flatten files.
// So during the first check for ancient db, the data is not yet in there,
// but when we reach into leveldb, the data was already moved. That would
// result in a not found error.
if len ( data ) == 0 {
if len ( data ) == 0 {
data , _ = db . Ancient ( freezerHashTable , number )
// Get it by hash from leveldb
data , _ = db . Get ( headerHashKey ( number ) )
}
}
}
return nil
if len ( data ) == 0 {
} )
return common . Hash { }
}
return common . BytesToHash ( data )
return common . BytesToHash ( data )
}
}
@ -304,32 +299,25 @@ func WriteFastTxLookupLimit(db ethdb.KeyValueWriter, number uint64) {
// ReadHeaderRLP retrieves a block header in its raw RLP database encoding.
// ReadHeaderRLP retrieves a block header in its raw RLP database encoding.
func ReadHeaderRLP ( db ethdb . Reader , hash common . Hash , number uint64 ) rlp . RawValue {
func ReadHeaderRLP ( db ethdb . Reader , hash common . Hash , number uint64 ) rlp . RawValue {
// First try to look up the data in ancient database. Extra hash
var data [ ] byte
// comparison is necessary since ancient database only maintains
db . ReadAncients ( func ( reader ethdb . AncientReader ) error {
// the canonical data.
// First try to look up the data in ancient database. Extra hash
data , _ := db . Ancient ( freezerHeaderTable , number )
// comparison is necessary since ancient database only maintains
if len ( data ) > 0 && crypto . Keccak256Hash ( data ) == hash {
// the canonical data.
return data
data , _ = reader . Ancient ( freezerHeaderTable , number )
}
if len ( data ) > 0 && crypto . Keccak256Hash ( data ) == hash {
// Then try to look up the data in leveldb.
return nil
data , _ = db . Get ( headerKey ( number , hash ) )
}
if len ( data ) > 0 {
// If not, try reading from leveldb
return data
data , _ = db . Get ( headerKey ( number , hash ) )
}
return nil
// In the background freezer is moving data from leveldb to flatten files.
} )
// So during the first check for ancient db, the data is not yet in there,
return data
// but when we reach into leveldb, the data was already moved. That would
// result in a not found error.
data , _ = db . Ancient ( freezerHeaderTable , number )
if len ( data ) > 0 && crypto . Keccak256Hash ( data ) == hash {
return data
}
return nil // Can't find the data anywhere.
}
}
// HasHeader verifies the existence of a block header corresponding to the hash.
// 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 . Reader , hash common . Hash , number uint64 ) bool {
if has , err := db . Ancient ( freezerHashTable , number ) ; err == nil && common . BytesToHash ( has ) == hash {
if isCanon ( db , number , hash ) {
return true
return true
}
}
if has , err := db . Has ( headerKey ( number , hash ) ) ; ! has || err != nil {
if has , err := db . Has ( headerKey ( number , hash ) ) ; ! has || err != nil {
@ -389,53 +377,48 @@ func deleteHeaderWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number
}
}
}
}
// isCanon is an internal utility method, to check whether the given number/hash
// is part of the ancient (canon) set.
func isCanon ( reader ethdb . AncientReader , number uint64 , hash common . Hash ) bool {
h , err := reader . Ancient ( freezerHashTable , number )
if err != nil {
return false
}
return bytes . Equal ( h , hash [ : ] )
}
// ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding.
// ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding.
func ReadBodyRLP ( db ethdb . Reader , hash common . Hash , number uint64 ) rlp . RawValue {
func ReadBodyRLP ( db ethdb . Reader , hash common . Hash , number uint64 ) rlp . RawValue {
// First try to look up the data in ancient database. Extra hash
// First try to look up the data in ancient database. Extra hash
// comparison is necessary since ancient database only maintains
// comparison is necessary since ancient database only maintains
// the canonical data.
// the canonical data.
data , _ := db . Ancient ( freezerBodiesTable , number )
var data [ ] byte
if len ( data ) > 0 {
db . ReadAncients ( func ( reader ethdb . AncientReader ) error {
h , _ := db . Ancient ( freezerHashTable , number )
// Check if the data is in ancients
if common . BytesToHash ( h ) == hash {
if isCanon ( reader , number , hash ) {
return data
data , _ = reader . Ancient ( freezerBodiesTable , number )
}
return nil
}
// Then try to look up the data in leveldb.
data , _ = db . Get ( blockBodyKey ( number , hash ) )
if len ( data ) > 0 {
return data
}
// In the background freezer is moving data from leveldb to flatten files.
// So during the first check for ancient db, the data is not yet in there,
// but when we reach into leveldb, the data was already moved. That would
// result in a not found error.
data , _ = db . Ancient ( freezerBodiesTable , number )
if len ( data ) > 0 {
h , _ := db . Ancient ( freezerHashTable , number )
if common . BytesToHash ( h ) == hash {
return data
}
}
}
// If not, try reading from leveldb
return nil // Can't find the data anywhere.
data , _ = db . Get ( blockBodyKey ( number , hash ) )
return nil
} )
return data
}
}
// ReadCanonicalBodyRLP retrieves the block body (transactions and uncles) for the canonical
// ReadCanonicalBodyRLP retrieves the block body (transactions and uncles) for the canonical
// block at number, in RLP encoding.
// block at number, in RLP encoding.
func ReadCanonicalBodyRLP ( db ethdb . Reader , number uint64 ) rlp . RawValue {
func ReadCanonicalBodyRLP ( db ethdb . Reader , number uint64 ) rlp . RawValue {
// If it's an ancient one, we don't need the canonical hash
var data [ ] byte
data , _ := db . Ancient ( freezerBodiesTable , number )
db . ReadAncients ( func ( reader ethdb . AncientReader ) error {
if len ( data ) == 0 {
data , _ = reader . Ancient ( freezerBodiesTable , number )
// Need to get the hash
if len ( data ) > 0 {
data , _ = db . Get ( blockBodyKey ( number , ReadCanonicalHash ( db , number ) ) )
return nil
// In the background freezer is moving data from leveldb to flatten files.
// So during the first check for ancient db, the data is not yet in there,
// but when we reach into leveldb, the data was already moved. That would
// result in a not found error.
if len ( data ) == 0 {
data , _ = db . Ancient ( freezerBodiesTable , number )
}
}
}
// Get it by hash from leveldb
data , _ = db . Get ( blockBodyKey ( number , ReadCanonicalHash ( db , number ) ) )
return nil
} )
return data
return data
}
}
@ -448,7 +431,7 @@ func WriteBodyRLP(db ethdb.KeyValueWriter, hash common.Hash, number uint64, rlp
// HasBody verifies the existence of a block body corresponding to the hash.
// 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 . Reader , hash common . Hash , number uint64 ) bool {
if has , err := db . Ancient ( freezerHashTable , number ) ; err == nil && common . BytesToHash ( has ) == hash {
if isCanon ( db , number , hash ) {
return true
return true
}
}
if has , err := db . Has ( blockBodyKey ( number , hash ) ) ; ! has || err != nil {
if has , err := db . Has ( blockBodyKey ( number , hash ) ) ; ! has || err != nil {
@ -489,33 +472,18 @@ func DeleteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
// ReadTdRLP retrieves a block's total difficulty corresponding to the hash in RLP encoding.
// 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 {
func ReadTdRLP ( db ethdb . Reader , hash common . Hash , number uint64 ) rlp . RawValue {
// First try to look up the data in ancient database. Extra hash
var data [ ] byte
// comparison is necessary since ancient database only maintains
db . ReadAncients ( func ( reader ethdb . AncientReader ) error {
// the canonical data.
// Check if the data is in ancients
data , _ := db . Ancient ( freezerDifficultyTable , number )
if isCanon ( reader , number , hash ) {
if len ( data ) > 0 {
data , _ = reader . Ancient ( freezerDifficultyTable , number )
h , _ := db . Ancient ( freezerHashTable , number )
return nil
if common . BytesToHash ( h ) == hash {
return data
}
}
// Then try to look up the data in leveldb.
data , _ = db . Get ( headerTDKey ( number , hash ) )
if len ( data ) > 0 {
return data
}
// In the background freezer is moving data from leveldb to flatten files.
// So during the first check for ancient db, the data is not yet in there,
// but when we reach into leveldb, the data was already moved. That would
// result in a not found error.
data , _ = db . Ancient ( freezerDifficultyTable , number )
if len ( data ) > 0 {
h , _ := db . Ancient ( freezerHashTable , number )
if common . BytesToHash ( h ) == hash {
return data
}
}
}
// If not, try reading from leveldb
return nil // Can't find the data anywhere.
data , _ = db . Get ( headerTDKey ( number , hash ) )
return nil
} )
return data
}
}
// ReadTd retrieves a block's total difficulty corresponding to the hash.
// ReadTd retrieves a block's total difficulty corresponding to the hash.
@ -553,7 +521,7 @@ func DeleteTd(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
// HasReceipts verifies the existence of all the transaction receipts belonging
// HasReceipts verifies the existence of all the transaction receipts belonging
// to a block.
// to a block.
func HasReceipts ( db ethdb . Reader , hash common . Hash , number uint64 ) bool {
func HasReceipts ( db ethdb . Reader , hash common . Hash , number uint64 ) bool {
if has , err := db . Ancient ( freezerHashTable , number ) ; err == nil && common . BytesToHash ( has ) == hash {
if isCanon ( db , number , hash ) {
return true
return true
}
}
if has , err := db . Has ( blockReceiptsKey ( number , hash ) ) ; ! has || err != nil {
if has , err := db . Has ( blockReceiptsKey ( number , hash ) ) ; ! has || err != nil {
@ -564,33 +532,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.
// 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 {
func ReadReceiptsRLP ( db ethdb . Reader , hash common . Hash , number uint64 ) rlp . RawValue {
// First try to look up the data in ancient database. Extra hash
var data [ ] byte
// comparison is necessary since ancient database only maintains
db . ReadAncients ( func ( reader ethdb . AncientReader ) error {
// the canonical data.
// Check if the data is in ancients
data , _ := db . Ancient ( freezerReceiptTable , number )
if isCanon ( reader , number , hash ) {
if len ( data ) > 0 {
data , _ = reader . Ancient ( freezerReceiptTable , number )
h , _ := db . Ancient ( freezerHashTable , number )
return nil
if common . BytesToHash ( h ) == hash {
return data
}
}
// Then try to look up the data in leveldb.
data , _ = db . Get ( blockReceiptsKey ( number , hash ) )
if len ( data ) > 0 {
return data
}
// In the background freezer is moving data from leveldb to flatten files.
// So during the first check for ancient db, the data is not yet in there,
// but when we reach into leveldb, the data was already moved. That would
// result in a not found error.
data , _ = db . Ancient ( freezerReceiptTable , number )
if len ( data ) > 0 {
h , _ := db . Ancient ( freezerHashTable , number )
if common . BytesToHash ( h ) == hash {
return data
}
}
}
// If not, try reading from leveldb
return nil // Can't find the data anywhere.
data , _ = db . Get ( blockReceiptsKey ( number , hash ) )
return nil
} )
return data
}
}
// ReadRawReceipts retrieves all the transaction receipts belonging to a block.
// ReadRawReceipts retrieves all the transaction receipts belonging to a block.