@ -31,6 +31,7 @@ import (
"github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/internal/params"
lru "github.com/hashicorp/golang-lru"
lru "github.com/hashicorp/golang-lru"
"github.com/harmony-one/harmony/block"
consensus_engine "github.com/harmony-one/harmony/consensus/engine"
consensus_engine "github.com/harmony-one/harmony/consensus/engine"
"github.com/harmony-one/harmony/core/rawdb"
"github.com/harmony-one/harmony/core/rawdb"
"github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/core/types"
@ -52,7 +53,7 @@ type HeaderChain struct {
config * params . ChainConfig
config * params . ChainConfig
chainDb ethdb . Database
chainDb ethdb . Database
genesisHeader * types . Header
genesisHeader * block . Header
currentHeader atomic . Value // Current head of the header chain (may be above the block chain!)
currentHeader atomic . Value // Current head of the header chain (may be above the block chain!)
currentHeaderHash common . Hash // Hash of the current head of the header chain (prevent recomputing all the time)
currentHeaderHash common . Hash // Hash of the current head of the header chain (prevent recomputing all the time)
@ -132,7 +133,7 @@ func (hc *HeaderChain) GetBlockNumber(hash common.Hash) *uint64 {
// without the real blocks. Hence, writing headers directly should only be done
// without the real blocks. Hence, writing headers directly should only be done
// in two scenarios: pure-header mode of operation (light clients), or properly
// in two scenarios: pure-header mode of operation (light clients), or properly
// separated header/block phases (non-archive clients).
// separated header/block phases (non-archive clients).
func ( hc * HeaderChain ) WriteHeader ( header * types . Header ) ( status WriteStatus , err error ) {
func ( hc * HeaderChain ) WriteHeader ( header * block . Header ) ( status WriteStatus , err error ) {
// Cache some values to prevent constant recalculation
// Cache some values to prevent constant recalculation
var (
var (
hash = header . Hash ( )
hash = header . Hash ( )
@ -199,10 +200,10 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er
// processed and light chain events sent, while in a BlockChain this is not
// processed and light chain events sent, while in a BlockChain this is not
// necessary since chain events are sent after inserting blocks. Second, the
// necessary since chain events are sent after inserting blocks. Second, the
// header writes should be protected by the parent chain mutex individually.
// header writes should be protected by the parent chain mutex individually.
type WhCallback func ( * types . Header ) error
type WhCallback func ( * block . Header ) error
// ValidateHeaderChain validates header chain.
// ValidateHeaderChain validates header chain.
func ( hc * HeaderChain ) ValidateHeaderChain ( chain [ ] * types . Header , checkFreq int ) ( int , error ) {
func ( hc * HeaderChain ) ValidateHeaderChain ( chain [ ] * block . Header , checkFreq int ) ( int , error ) {
// Do a sanity check that the provided chain is actually ordered and linked
// Do a sanity check that the provided chain is actually ordered and linked
for i := 1 ; i < len ( chain ) ; i ++ {
for i := 1 ; i < len ( chain ) ; i ++ {
if chain [ i ] . Number . Uint64 ( ) != chain [ i - 1 ] . Number . Uint64 ( ) + 1 || chain [ i ] . ParentHash != chain [ i - 1 ] . Hash ( ) {
if chain [ i ] . Number . Uint64 ( ) != chain [ i - 1 ] . Number . Uint64 ( ) + 1 || chain [ i ] . ParentHash != chain [ i - 1 ] . Hash ( ) {
@ -259,7 +260,7 @@ func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, checkFreq int)
// should be done or not. The reason behind the optional check is because some
// should be done or not. The reason behind the optional check is because some
// of the header retrieval mechanisms already need to verfy nonces, as well as
// of the header retrieval mechanisms already need to verfy nonces, as well as
// because nonces can be verified sparsely, not needing to check each.
// because nonces can be verified sparsely, not needing to check each.
func ( hc * HeaderChain ) InsertHeaderChain ( chain [ ] * types . Header , writeHeader WhCallback , start time . Time ) ( int , error ) {
func ( hc * HeaderChain ) InsertHeaderChain ( chain [ ] * block . Header , writeHeader WhCallback , start time . Time ) ( int , error ) {
// Collect some import statistics to report on
// Collect some import statistics to report on
stats := struct { processed , ignored int } { }
stats := struct { processed , ignored int } { }
// All headers passed verification, import them into the database
// All headers passed verification, import them into the database
@ -395,10 +396,10 @@ func (hc *HeaderChain) WriteTd(hash common.Hash, number uint64, td *big.Int) err
// GetHeader retrieves a block header from the database by hash and number,
// GetHeader retrieves a block header from the database by hash and number,
// caching it if found.
// caching it if found.
func ( hc * HeaderChain ) GetHeader ( hash common . Hash , number uint64 ) * types . Header {
func ( hc * HeaderChain ) GetHeader ( hash common . Hash , number uint64 ) * block . Header {
// Short circuit if the header's already in the cache, retrieve otherwise
// Short circuit if the header's already in the cache, retrieve otherwise
if header , ok := hc . headerCache . Get ( hash ) ; ok {
if header , ok := hc . headerCache . Get ( hash ) ; ok {
return header . ( * types . Header )
return header . ( * block . Header )
}
}
header := rawdb . ReadHeader ( hc . chainDb , hash , number )
header := rawdb . ReadHeader ( hc . chainDb , hash , number )
if header == nil {
if header == nil {
@ -411,7 +412,7 @@ func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header
// GetHeaderByHash retrieves a block header from the database by hash, caching it if
// GetHeaderByHash retrieves a block header from the database by hash, caching it if
// found.
// found.
func ( hc * HeaderChain ) GetHeaderByHash ( hash common . Hash ) * types . Header {
func ( hc * HeaderChain ) GetHeaderByHash ( hash common . Hash ) * block . Header {
number := hc . GetBlockNumber ( hash )
number := hc . GetBlockNumber ( hash )
if number == nil {
if number == nil {
return nil
return nil
@ -429,7 +430,7 @@ func (hc *HeaderChain) HasHeader(hash common.Hash, number uint64) bool {
// GetHeaderByNumber retrieves a block header from the database by number,
// GetHeaderByNumber retrieves a block header from the database by number,
// caching it (associated with its hash) if found.
// caching it (associated with its hash) if found.
func ( hc * HeaderChain ) GetHeaderByNumber ( number uint64 ) * types . Header {
func ( hc * HeaderChain ) GetHeaderByNumber ( number uint64 ) * block . Header {
hash := rawdb . ReadCanonicalHash ( hc . chainDb , number )
hash := rawdb . ReadCanonicalHash ( hc . chainDb , number )
if hash == ( common . Hash { } ) {
if hash == ( common . Hash { } ) {
return nil
return nil
@ -439,12 +440,12 @@ func (hc *HeaderChain) GetHeaderByNumber(number uint64) *types.Header {
// CurrentHeader retrieves the current head header of the canonical chain. The
// CurrentHeader retrieves the current head header of the canonical chain. The
// header is retrieved from the HeaderChain's internal cache.
// header is retrieved from the HeaderChain's internal cache.
func ( hc * HeaderChain ) CurrentHeader ( ) * types . Header {
func ( hc * HeaderChain ) CurrentHeader ( ) * block . Header {
return hc . currentHeader . Load ( ) . ( * types . Header )
return hc . currentHeader . Load ( ) . ( * block . Header )
}
}
// SetCurrentHeader sets the current head header of the canonical chain.
// SetCurrentHeader sets the current head header of the canonical chain.
func ( hc * HeaderChain ) SetCurrentHeader ( head * types . Header ) {
func ( hc * HeaderChain ) SetCurrentHeader ( head * block . Header ) {
rawdb . WriteHeadHeaderHash ( hc . chainDb , head . Hash ( ) )
rawdb . WriteHeadHeaderHash ( hc . chainDb , head . Hash ( ) )
hc . currentHeader . Store ( head )
hc . currentHeader . Store ( head )
@ -495,7 +496,7 @@ func (hc *HeaderChain) SetHead(head uint64, delFn DeleteCallback) {
}
}
// SetGenesis sets a new genesis block header for the chain
// SetGenesis sets a new genesis block header for the chain
func ( hc * HeaderChain ) SetGenesis ( head * types . Header ) {
func ( hc * HeaderChain ) SetGenesis ( head * block . Header ) {
hc . genesisHeader = head
hc . genesisHeader = head
}
}