Skip to content

Commit

Permalink
fix: doing the right hash compare when reading blocks from the ancien…
Browse files Browse the repository at this point in the history
…t db (#1182)
  • Loading branch information
ricardolyn committed Apr 28, 2021
1 parent f2edcc3 commit a44b482
Showing 1 changed file with 42 additions and 15 deletions.
57 changes: 42 additions & 15 deletions core/rawdb/accessors_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
Expand Down Expand Up @@ -268,29 +267,61 @@ func WriteFastTxLookupLimit(db ethdb.KeyValueWriter, number uint64) {
}
}

// Quorum
// 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, *types.Header) {
// First try to look up the data in ancient database. Extra hash
// comparison is necessary since ancient database only maintains
// the canonical data.
data, _ := db.Ancient(freezerHeaderTable, number)
if len(data) > 0 && crypto.Keccak256Hash(data) == hash {
return data

// Quorum: parse header to make sure we compare using the right hash (IBFT hash is based on a filtered header)
if len(data) > 0 {
header := decodeHeaderRLP(data)
if header.Hash() == hash {
return data, header
}
}
// End Quorum

// Then try to look up the data in leveldb.
data, _ = db.Get(headerKey(number, hash))
if len(data) > 0 {
return data
return data, decodeHeaderRLP(data) // Quorum: return decodeHeaderRLP(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(freezerHeaderTable, number)
if len(data) > 0 && crypto.Keccak256Hash(data) == hash {
return data

// Quorum: parse header to make sure we compare using the right hash (IBFT hash is based on a filtered header)
if len(data) > 0 {
header := decodeHeaderRLP(data)
if header.Hash() == hash {
return data, header
}
}
return nil // Can't find the data anywhere.
// End Quorum

return nil, nil // Can't find the data anywhere.
}

// Quorum
func decodeHeaderRLP(data rlp.RawValue) *types.Header {
header := new(types.Header)
if err := rlp.Decode(bytes.NewReader(data), header); err != nil {
log.Error("Invalid block header RLP", "err", err)
return nil
}
return header
}

// ReadHeaderRLP retrieves a block header in its raw RLP database encoding.
func ReadHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
// Quorum: original code implemented inside `readHeaderRLP(...)` with some modifications from Quorum
data, _ := readHeaderRLP(db, hash, number)
return data
}

// HasHeader verifies the existence of a block header corresponding to the hash.
Expand All @@ -306,13 +337,9 @@ 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 {
data := ReadHeaderRLP(db, hash, number)
if len(data) == 0 {
return nil
}
header := new(types.Header)
if err := rlp.Decode(bytes.NewReader(data), header); err != nil {
log.Error("Invalid block header RLP", "hash", hash, "err", err)
_, header := readHeaderRLP(db, hash, number)
if header == nil {
log.Error("Invalid block header RLP", "hash", hash)
return nil
}
return header
Expand Down

0 comments on commit a44b482

Please sign in to comment.