2016-11-08 19:01:56 -06:00
// Copyright 2016 The go-ethereum Authors
2016-10-13 22:47:09 -05:00
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
2016-11-08 19:01:56 -06:00
2019-02-26 05:32:48 -06:00
// Package light implements on-demand retrieval capable state and chain objects
// for the Ethereum Light Client.
2016-10-13 22:47:09 -05:00
package light
import (
2017-03-22 12:20:33 -05:00
"context"
2018-02-05 10:40:32 -06:00
"errors"
2016-10-13 22:47:09 -05:00
"math/big"
"sync"
"sync/atomic"
2017-03-22 14:44:22 -05:00
"time"
2016-10-13 22:47:09 -05:00
"github.com/ethereum/go-ethereum/common"
2017-04-04 17:16:29 -05:00
"github.com/ethereum/go-ethereum/consensus"
2016-10-13 22:47:09 -05:00
"github.com/ethereum/go-ethereum/core"
2018-05-07 06:35:06 -05:00
"github.com/ethereum/go-ethereum/core/rawdb"
2018-02-05 10:40:32 -06:00
"github.com/ethereum/go-ethereum/core/state"
2016-10-13 22:47:09 -05:00
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
2017-02-22 06:10:07 -06:00
"github.com/ethereum/go-ethereum/log"
2016-10-20 06:36:29 -05:00
"github.com/ethereum/go-ethereum/params"
2016-10-13 22:47:09 -05:00
"github.com/ethereum/go-ethereum/rlp"
2019-01-24 06:40:37 -06:00
lru "github.com/hashicorp/golang-lru"
2016-10-13 22:47:09 -05:00
)
var (
bodyCacheLimit = 256
blockCacheLimit = 256
)
// LightChain represents a canonical chain that by default only handles block
// headers, downloading block bodies and receipts on demand through an ODR
// interface. It only does header validation during chain insertion.
type LightChain struct {
2017-08-18 05:58:36 -05:00
hc * core . HeaderChain
2018-08-28 02:08:16 -05:00
indexerConfig * IndexerConfig
2017-08-18 05:58:36 -05:00
chainDb ethdb . Database
2019-01-24 06:40:37 -06:00
engine consensus . Engine
2017-08-18 05:58:36 -05:00
odr OdrBackend
chainFeed event . Feed
chainSideFeed event . Feed
chainHeadFeed event . Feed
scope event . SubscriptionScope
genesisBlock * types . Block
all: core rework for the merge transition (#23761)
* all: work for eth1/2 transtition
* consensus/beacon, eth: change beacon difficulty to 0
* eth: updates
* all: add terminalBlockDifficulty config, fix rebasing issues
* eth: implemented merge interop spec
* internal/ethapi: update to v1.0.0.alpha.2
This commit updates the code to the new spec, moving payloadId into
it's own object. It also fixes an issue with finalizing an empty blockhash.
It also properly sets the basefee
* all: sync polishes, other fixes + refactors
* core, eth: correct semantics for LeavePoW, EnterPoS
* core: fixed rebasing artifacts
* core: light: performance improvements
* core: use keyed field (f)
* core: eth: fix compilation issues + tests
* eth/catalyst: dbetter error codes
* all: move Merger to consensus/, remove reliance on it in bc
* all: renamed EnterPoS and LeavePoW to ReachTDD and FinalizePoS
* core: make mergelogs a function
* core: use InsertChain instead of InsertBlock
* les: drop merger from lightchain object
* consensus: add merger
* core: recoverAncestors in catalyst mode
* core: fix nitpick
* all: removed merger from beacon, use TTD, nitpicks
* consensus: eth: add docstring, removed unnecessary code duplication
* consensus/beacon: better comment
* all: easy to fix nitpicks by karalabe
* consensus/beacon: verify known headers to be sure
* core: comments
* core: eth: don't drop peers who advertise blocks, nitpicks
* core: never add beacon blocks to the future queue
* core: fixed nitpicks
* consensus/beacon: simplify IsTTDReached check
* consensus/beacon: correct IsTTDReached check
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2021-11-26 05:23:02 -06:00
forker * core . ForkChoice
2016-10-13 22:47:09 -05:00
bodyCache * lru . Cache // Cache for the most recent block bodies
bodyRLPCache * lru . Cache // Cache for the most recent block bodies in RLP encoded format
blockCache * lru . Cache // Cache for the most recent entire blocks
2019-01-24 06:40:37 -06:00
chainmu sync . RWMutex // protects header inserts
2016-10-13 22:47:09 -05:00
quit chan struct { }
2019-01-24 06:40:37 -06:00
wg sync . WaitGroup
2019-01-24 05:18:26 -06:00
2019-01-24 06:40:37 -06:00
// Atomic boolean switches:
running int32 // whether LightChain is running or stopped
procInterrupt int32 // interrupts chain insert
disableCheckFreq int32 // disables header verification
2016-10-13 22:47:09 -05:00
}
// NewLightChain returns a fully initialised light chain using information
// available in the database. It initialises the default Ethereum header
// validator.
all: on-chain oracle checkpoint syncing (#19543)
* all: implement simple checkpoint syncing
cmd, les, node: remove callback mechanism
cmd, node: remove callback definition
les: simplify the registrar
les: expose checkpoint rpc services in the light client
les, light: don't store untrusted receipt
cmd, contracts, les: discard stale checkpoint
cmd, contracts/registrar: loose restriction of registeration
cmd, contracts: add replay-protection
all: off-chain multi-signature contract
params: deploy checkpoint contract for rinkeby
cmd/registrar: add raw signing mode for registrar
cmd/registrar, contracts/registrar, les: fixed messages
* cmd/registrar, contracts/registrar: fix lints
* accounts/abi/bind, les: address comments
* cmd, contracts, les, light, params: minor checkpoint sync cleanups
* cmd, eth, les, light: move checkpoint config to config file
* cmd, eth, les, params: address comments
* eth, les, params: address comments
* cmd: polish up the checkpoint admin CLI
* cmd, contracts, params: deploy new version contract
* cmd/checkpoint-admin: add another flag for clef mode signing
* cmd, contracts, les: rename and regen checkpoint oracle with abigen
2019-06-28 02:34:02 -05:00
func NewLightChain ( odr OdrBackend , config * params . ChainConfig , engine consensus . Engine , checkpoint * params . TrustedCheckpoint ) ( * LightChain , error ) {
2016-10-13 22:47:09 -05:00
bodyCache , _ := lru . New ( bodyCacheLimit )
bodyRLPCache , _ := lru . New ( bodyCacheLimit )
blockCache , _ := lru . New ( blockCacheLimit )
bc := & LightChain {
2018-08-28 02:08:16 -05:00
chainDb : odr . Database ( ) ,
indexerConfig : odr . IndexerConfig ( ) ,
odr : odr ,
quit : make ( chan struct { } ) ,
bodyCache : bodyCache ,
bodyRLPCache : bodyRLPCache ,
blockCache : blockCache ,
engine : engine ,
2016-10-13 22:47:09 -05:00
}
all: core rework for the merge transition (#23761)
* all: work for eth1/2 transtition
* consensus/beacon, eth: change beacon difficulty to 0
* eth: updates
* all: add terminalBlockDifficulty config, fix rebasing issues
* eth: implemented merge interop spec
* internal/ethapi: update to v1.0.0.alpha.2
This commit updates the code to the new spec, moving payloadId into
it's own object. It also fixes an issue with finalizing an empty blockhash.
It also properly sets the basefee
* all: sync polishes, other fixes + refactors
* core, eth: correct semantics for LeavePoW, EnterPoS
* core: fixed rebasing artifacts
* core: light: performance improvements
* core: use keyed field (f)
* core: eth: fix compilation issues + tests
* eth/catalyst: dbetter error codes
* all: move Merger to consensus/, remove reliance on it in bc
* all: renamed EnterPoS and LeavePoW to ReachTDD and FinalizePoS
* core: make mergelogs a function
* core: use InsertChain instead of InsertBlock
* les: drop merger from lightchain object
* consensus: add merger
* core: recoverAncestors in catalyst mode
* core: fix nitpick
* all: removed merger from beacon, use TTD, nitpicks
* consensus: eth: add docstring, removed unnecessary code duplication
* consensus/beacon: better comment
* all: easy to fix nitpicks by karalabe
* consensus/beacon: verify known headers to be sure
* core: comments
* core: eth: don't drop peers who advertise blocks, nitpicks
* core: never add beacon blocks to the future queue
* core: fixed nitpicks
* consensus/beacon: simplify IsTTDReached check
* consensus/beacon: correct IsTTDReached check
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2021-11-26 05:23:02 -06:00
bc . forker = core . NewForkChoice ( bc , nil )
2016-10-13 22:47:09 -05:00
var err error
2017-04-04 17:16:29 -05:00
bc . hc , err = core . NewHeaderChain ( odr . Database ( ) , config , bc . engine , bc . getProcInterrupt )
2016-10-13 22:47:09 -05:00
if err != nil {
return nil , err
}
bc . genesisBlock , _ = bc . GetBlockByNumber ( NoOdr , 0 )
if bc . genesisBlock == nil {
2017-03-02 07:03:33 -06:00
return nil , core . ErrNoGenesis
2016-10-13 22:47:09 -05:00
}
all: on-chain oracle checkpoint syncing (#19543)
* all: implement simple checkpoint syncing
cmd, les, node: remove callback mechanism
cmd, node: remove callback definition
les: simplify the registrar
les: expose checkpoint rpc services in the light client
les, light: don't store untrusted receipt
cmd, contracts, les: discard stale checkpoint
cmd, contracts/registrar: loose restriction of registeration
cmd, contracts: add replay-protection
all: off-chain multi-signature contract
params: deploy checkpoint contract for rinkeby
cmd/registrar: add raw signing mode for registrar
cmd/registrar, contracts/registrar, les: fixed messages
* cmd/registrar, contracts/registrar: fix lints
* accounts/abi/bind, les: address comments
* cmd, contracts, les, light, params: minor checkpoint sync cleanups
* cmd, eth, les, light: move checkpoint config to config file
* cmd, eth, les, params: address comments
* eth, les, params: address comments
* cmd: polish up the checkpoint admin CLI
* cmd, contracts, params: deploy new version contract
* cmd/checkpoint-admin: add another flag for clef mode signing
* cmd, contracts, les: rename and regen checkpoint oracle with abigen
2019-06-28 02:34:02 -05:00
if checkpoint != nil {
bc . AddTrustedCheckpoint ( checkpoint )
2017-09-11 16:36:16 -05:00
}
2016-10-13 22:47:09 -05:00
if err := bc . loadLastState ( ) ; err != nil {
return nil , err
}
// Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain
2017-01-06 08:52:03 -06:00
for hash := range core . BadHashes {
2016-10-13 22:47:09 -05:00
if header := bc . GetHeaderByHash ( hash ) ; header != nil {
2017-03-03 03:41:52 -06:00
log . Error ( "Found bad hash, rewinding chain" , "number" , header . Number , "hash" , header . ParentHash )
2016-10-13 22:47:09 -05:00
bc . SetHead ( header . Number . Uint64 ( ) - 1 )
2020-07-13 04:02:54 -05:00
log . Info ( "Chain rewind was successful, resuming normal operation" )
2016-10-13 22:47:09 -05:00
}
}
return bc , nil
}
all: on-chain oracle checkpoint syncing (#19543)
* all: implement simple checkpoint syncing
cmd, les, node: remove callback mechanism
cmd, node: remove callback definition
les: simplify the registrar
les: expose checkpoint rpc services in the light client
les, light: don't store untrusted receipt
cmd, contracts, les: discard stale checkpoint
cmd, contracts/registrar: loose restriction of registeration
cmd, contracts: add replay-protection
all: off-chain multi-signature contract
params: deploy checkpoint contract for rinkeby
cmd/registrar: add raw signing mode for registrar
cmd/registrar, contracts/registrar, les: fixed messages
* cmd/registrar, contracts/registrar: fix lints
* accounts/abi/bind, les: address comments
* cmd, contracts, les, light, params: minor checkpoint sync cleanups
* cmd, eth, les, light: move checkpoint config to config file
* cmd, eth, les, params: address comments
* eth, les, params: address comments
* cmd: polish up the checkpoint admin CLI
* cmd, contracts, params: deploy new version contract
* cmd/checkpoint-admin: add another flag for clef mode signing
* cmd, contracts, les: rename and regen checkpoint oracle with abigen
2019-06-28 02:34:02 -05:00
// AddTrustedCheckpoint adds a trusted checkpoint to the blockchain
func ( lc * LightChain ) AddTrustedCheckpoint ( cp * params . TrustedCheckpoint ) {
2019-02-07 04:53:45 -06:00
if lc . odr . ChtIndexer ( ) != nil {
StoreChtRoot ( lc . chainDb , cp . SectionIndex , cp . SectionHead , cp . CHTRoot )
lc . odr . ChtIndexer ( ) . AddCheckpoint ( cp . SectionIndex , cp . SectionHead )
2017-10-24 08:19:09 -05:00
}
2019-02-07 04:53:45 -06:00
if lc . odr . BloomTrieIndexer ( ) != nil {
StoreBloomTrieRoot ( lc . chainDb , cp . SectionIndex , cp . SectionHead , cp . BloomRoot )
lc . odr . BloomTrieIndexer ( ) . AddCheckpoint ( cp . SectionIndex , cp . SectionHead )
2017-10-24 08:19:09 -05:00
}
2019-02-07 04:53:45 -06:00
if lc . odr . BloomIndexer ( ) != nil {
lc . odr . BloomIndexer ( ) . AddCheckpoint ( cp . SectionIndex , cp . SectionHead )
2017-10-24 08:19:09 -05:00
}
all: on-chain oracle checkpoint syncing (#19543)
* all: implement simple checkpoint syncing
cmd, les, node: remove callback mechanism
cmd, node: remove callback definition
les: simplify the registrar
les: expose checkpoint rpc services in the light client
les, light: don't store untrusted receipt
cmd, contracts, les: discard stale checkpoint
cmd, contracts/registrar: loose restriction of registeration
cmd, contracts: add replay-protection
all: off-chain multi-signature contract
params: deploy checkpoint contract for rinkeby
cmd/registrar: add raw signing mode for registrar
cmd/registrar, contracts/registrar, les: fixed messages
* cmd/registrar, contracts/registrar: fix lints
* accounts/abi/bind, les: address comments
* cmd, contracts, les, light, params: minor checkpoint sync cleanups
* cmd, eth, les, light: move checkpoint config to config file
* cmd, eth, les, params: address comments
* eth, les, params: address comments
* cmd: polish up the checkpoint admin CLI
* cmd, contracts, params: deploy new version contract
* cmd/checkpoint-admin: add another flag for clef mode signing
* cmd, contracts, les: rename and regen checkpoint oracle with abigen
2019-06-28 02:34:02 -05:00
log . Info ( "Added trusted checkpoint" , "block" , ( cp . SectionIndex + 1 ) * lc . indexerConfig . ChtSize - 1 , "hash" , cp . SectionHead )
2017-10-24 08:19:09 -05:00
}
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) getProcInterrupt ( ) bool {
return atomic . LoadInt32 ( & lc . procInterrupt ) == 1
2016-10-13 22:47:09 -05:00
}
// Odr returns the ODR backend of the chain
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) Odr ( ) OdrBackend {
return lc . odr
2016-10-13 22:47:09 -05:00
}
2019-11-19 11:22:04 -06:00
// HeaderChain returns the underlying header chain.
func ( lc * LightChain ) HeaderChain ( ) * core . HeaderChain {
return lc . hc
}
2016-10-13 22:47:09 -05:00
// loadLastState loads the last known chain state from the database. This method
// assumes that the chain manager mutex is held.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) loadLastState ( ) error {
if head := rawdb . ReadHeadHeaderHash ( lc . chainDb ) ; head == ( common . Hash { } ) {
2016-10-13 22:47:09 -05:00
// Corrupt or empty database, init from scratch
2019-02-07 04:53:45 -06:00
lc . Reset ( )
2016-10-13 22:47:09 -05:00
} else {
2020-07-13 04:02:54 -05:00
header := lc . GetHeaderByHash ( head )
if header == nil {
// Corrupt or empty database, init from scratch
lc . Reset ( )
} else {
2019-02-07 04:53:45 -06:00
lc . hc . SetCurrentHeader ( header )
2016-10-13 22:47:09 -05:00
}
}
// Issue a status log and return
2019-02-07 04:53:45 -06:00
header := lc . hc . CurrentHeader ( )
headerTd := lc . GetTd ( header . Hash ( ) , header . Number . Uint64 ( ) )
2019-04-02 15:28:48 -05:00
log . Info ( "Loaded most recent local header" , "number" , header . Number , "hash" , header . Hash ( ) , "td" , headerTd , "age" , common . PrettyAge ( time . Unix ( int64 ( header . Time ) , 0 ) ) )
2016-10-13 22:47:09 -05:00
return nil
}
// SetHead rewinds the local chain to a new head. Everything above the new
// head will be deleted and the new one set.
all: integrate the freezer with fast sync
* all: freezer style syncing
core, eth, les, light: clean up freezer relative APIs
core, eth, les, trie, ethdb, light: clean a bit
core, eth, les, light: add unit tests
core, light: rewrite setHead function
core, eth: fix downloader unit tests
core: add receipt chain insertion test
core: use constant instead of hardcoding table name
core: fix rollback
core: fix setHead
core/rawdb: remove canonical block first and then iterate side chain
core/rawdb, ethdb: add hasAncient interface
eth/downloader: calculate ancient limit via cht first
core, eth, ethdb: lots of fixes
* eth/downloader: print ancient disable log only for fast sync
2019-04-25 09:59:48 -05:00
func ( lc * LightChain ) SetHead ( head uint64 ) error {
2019-02-07 04:53:45 -06:00
lc . chainmu . Lock ( )
defer lc . chainmu . Unlock ( )
2016-10-13 22:47:09 -05:00
all: integrate the freezer with fast sync
* all: freezer style syncing
core, eth, les, light: clean up freezer relative APIs
core, eth, les, trie, ethdb, light: clean a bit
core, eth, les, light: add unit tests
core, light: rewrite setHead function
core, eth: fix downloader unit tests
core: add receipt chain insertion test
core: use constant instead of hardcoding table name
core: fix rollback
core: fix setHead
core/rawdb: remove canonical block first and then iterate side chain
core/rawdb, ethdb: add hasAncient interface
eth/downloader: calculate ancient limit via cht first
core, eth, ethdb: lots of fixes
* eth/downloader: print ancient disable log only for fast sync
2019-04-25 09:59:48 -05:00
lc . hc . SetHead ( head , nil , nil )
return lc . loadLastState ( )
2016-10-13 22:47:09 -05:00
}
// GasLimit returns the gas limit of the current HEAD block.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) GasLimit ( ) uint64 {
return lc . hc . CurrentHeader ( ) . GasLimit
2016-10-13 22:47:09 -05:00
}
// Reset purges the entire blockchain, restoring it to its genesis state.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) Reset ( ) {
lc . ResetWithGenesisBlock ( lc . genesisBlock )
2016-10-13 22:47:09 -05:00
}
// ResetWithGenesisBlock purges the entire blockchain, restoring it to the
// specified genesis state.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) ResetWithGenesisBlock ( genesis * types . Block ) {
2016-10-13 22:47:09 -05:00
// Dump the entire block chain and purge the caches
2019-02-07 04:53:45 -06:00
lc . SetHead ( 0 )
2016-10-13 22:47:09 -05:00
2019-02-07 04:53:45 -06:00
lc . chainmu . Lock ( )
defer lc . chainmu . Unlock ( )
2016-10-13 22:47:09 -05:00
// Prepare the genesis block and reinitialise the chain
2020-01-17 04:49:32 -06:00
batch := lc . chainDb . NewBatch ( )
rawdb . WriteTd ( batch , genesis . Hash ( ) , genesis . NumberU64 ( ) , genesis . Difficulty ( ) )
rawdb . WriteBlock ( batch , genesis )
rawdb . WriteHeadHeaderHash ( batch , genesis . Hash ( ) )
if err := batch . Write ( ) ; err != nil {
log . Crit ( "Failed to reset genesis block" , "err" , err )
}
2019-02-07 04:53:45 -06:00
lc . genesisBlock = genesis
lc . hc . SetGenesis ( lc . genesisBlock . Header ( ) )
lc . hc . SetCurrentHeader ( lc . genesisBlock . Header ( ) )
2016-10-13 22:47:09 -05:00
}
// Accessors
2017-04-12 08:38:31 -05:00
// Engine retrieves the light chain's consensus engine.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) Engine ( ) consensus . Engine { return lc . engine }
2017-04-12 08:38:31 -05:00
2016-10-13 22:47:09 -05:00
// Genesis returns the genesis block
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) Genesis ( ) * types . Block {
return lc . genesisBlock
2016-10-13 22:47:09 -05:00
}
2019-03-18 06:19:40 -05:00
func ( lc * LightChain ) StateCache ( ) state . Database {
panic ( "not implemented" )
2018-02-05 10:40:32 -06:00
}
2016-10-13 22:47:09 -05:00
// GetBody retrieves a block body (transactions and uncles) from the database
// or ODR service by hash, caching it if found.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) GetBody ( ctx context . Context , hash common . Hash ) ( * types . Body , error ) {
2016-10-13 22:47:09 -05:00
// Short circuit if the body's already in the cache, retrieve otherwise
2019-02-07 04:53:45 -06:00
if cached , ok := lc . bodyCache . Get ( hash ) ; ok {
2016-10-13 22:47:09 -05:00
body := cached . ( * types . Body )
return body , nil
}
2019-02-07 04:53:45 -06:00
number := lc . hc . GetBlockNumber ( hash )
2018-05-07 06:35:06 -05:00
if number == nil {
return nil , errors . New ( "unknown block" )
}
2019-02-07 04:53:45 -06:00
body , err := GetBody ( ctx , lc . odr , hash , * number )
2016-10-13 22:47:09 -05:00
if err != nil {
return nil , err
}
// Cache the found body for next time and return
2019-02-07 04:53:45 -06:00
lc . bodyCache . Add ( hash , body )
2016-10-13 22:47:09 -05:00
return body , nil
}
// GetBodyRLP retrieves a block body in RLP encoding from the database or
// ODR service by hash, caching it if found.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) GetBodyRLP ( ctx context . Context , hash common . Hash ) ( rlp . RawValue , error ) {
2016-10-13 22:47:09 -05:00
// Short circuit if the body's already in the cache, retrieve otherwise
2019-02-07 04:53:45 -06:00
if cached , ok := lc . bodyRLPCache . Get ( hash ) ; ok {
2016-10-13 22:47:09 -05:00
return cached . ( rlp . RawValue ) , nil
}
2019-02-07 04:53:45 -06:00
number := lc . hc . GetBlockNumber ( hash )
2018-05-07 06:35:06 -05:00
if number == nil {
return nil , errors . New ( "unknown block" )
}
2019-02-07 04:53:45 -06:00
body , err := GetBodyRLP ( ctx , lc . odr , hash , * number )
2016-10-13 22:47:09 -05:00
if err != nil {
return nil , err
}
// Cache the found body for next time and return
2019-02-07 04:53:45 -06:00
lc . bodyRLPCache . Add ( hash , body )
2016-10-13 22:47:09 -05:00
return body , nil
}
// HasBlock checks if a block is fully present in the database or not, caching
// it if present.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) HasBlock ( hash common . Hash , number uint64 ) bool {
blk , _ := lc . GetBlock ( NoOdr , hash , number )
2016-10-13 22:47:09 -05:00
return blk != nil
}
// GetBlock retrieves a block from the database or ODR service by hash and number,
// caching it if found.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) GetBlock ( ctx context . Context , hash common . Hash , number uint64 ) ( * types . Block , error ) {
2016-10-13 22:47:09 -05:00
// Short circuit if the block's already in the cache, retrieve otherwise
2019-02-07 04:53:45 -06:00
if block , ok := lc . blockCache . Get ( hash ) ; ok {
2016-10-13 22:47:09 -05:00
return block . ( * types . Block ) , nil
}
2019-02-07 04:53:45 -06:00
block , err := GetBlock ( ctx , lc . odr , hash , number )
2016-10-13 22:47:09 -05:00
if err != nil {
return nil , err
}
// Cache the found block for next time and return
2019-02-07 04:53:45 -06:00
lc . blockCache . Add ( block . Hash ( ) , block )
2016-10-13 22:47:09 -05:00
return block , nil
}
// GetBlockByHash retrieves a block from the database or ODR service by hash,
// caching it if found.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) GetBlockByHash ( ctx context . Context , hash common . Hash ) ( * types . Block , error ) {
number := lc . hc . GetBlockNumber ( hash )
2018-05-07 06:35:06 -05:00
if number == nil {
return nil , errors . New ( "unknown block" )
}
2019-02-07 04:53:45 -06:00
return lc . GetBlock ( ctx , hash , * number )
2016-10-13 22:47:09 -05:00
}
// GetBlockByNumber retrieves a block from the database or ODR service by
// number, caching it (associated with its hash) if found.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) GetBlockByNumber ( ctx context . Context , number uint64 ) ( * types . Block , error ) {
hash , err := GetCanonicalHash ( ctx , lc . odr , number )
2016-10-13 22:47:09 -05:00
if hash == ( common . Hash { } ) || err != nil {
return nil , err
}
2019-02-07 04:53:45 -06:00
return lc . GetBlock ( ctx , hash , number )
2016-10-13 22:47:09 -05:00
}
// Stop stops the blockchain service. If any imports are currently in progress
// it will abort them using the procInterrupt.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) Stop ( ) {
if ! atomic . CompareAndSwapInt32 ( & lc . running , 0 , 1 ) {
2016-10-13 22:47:09 -05:00
return
}
2019-02-07 04:53:45 -06:00
close ( lc . quit )
2020-05-26 14:37:37 -05:00
lc . StopInsert ( )
2019-02-07 04:53:45 -06:00
lc . wg . Wait ( )
2020-05-26 14:37:37 -05:00
log . Info ( "Blockchain stopped" )
}
// StopInsert interrupts all insertion methods, causing them to return
// errInsertionInterrupted as soon as possible. Insertion is permanently disabled after
// calling this method.
func ( lc * LightChain ) StopInsert ( ) {
atomic . StoreInt32 ( & lc . procInterrupt , 1 )
2016-10-13 22:47:09 -05:00
}
// Rollback is designed to remove a chain of links from the database that aren't
// certain enough to be valid.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) Rollback ( chain [ ] common . Hash ) {
lc . chainmu . Lock ( )
defer lc . chainmu . Unlock ( )
2016-10-13 22:47:09 -05:00
2020-01-17 04:49:32 -06:00
batch := lc . chainDb . NewBatch ( )
2016-10-13 22:47:09 -05:00
for i := len ( chain ) - 1 ; i >= 0 ; i -- {
hash := chain [ i ]
2020-01-17 04:49:32 -06:00
// Degrade the chain markers if they are explicitly reverted.
// In theory we should update all in-memory markers in the
// last step, however the direction of rollback is from high
// to low, so it's safe the update in-memory markers directly.
2019-02-07 04:53:45 -06:00
if head := lc . hc . CurrentHeader ( ) ; head . Hash ( ) == hash {
2020-01-17 04:49:32 -06:00
rawdb . WriteHeadHeaderHash ( batch , head . ParentHash )
2019-02-07 04:53:45 -06:00
lc . hc . SetCurrentHeader ( lc . GetHeader ( head . ParentHash , head . Number . Uint64 ( ) - 1 ) )
2016-10-13 22:47:09 -05:00
}
}
2020-01-17 04:49:32 -06:00
if err := batch . Write ( ) ; err != nil {
log . Crit ( "Failed to rollback light chain" , "error" , err )
}
2016-10-13 22:47:09 -05:00
}
all: core rework for the merge transition (#23761)
* all: work for eth1/2 transtition
* consensus/beacon, eth: change beacon difficulty to 0
* eth: updates
* all: add terminalBlockDifficulty config, fix rebasing issues
* eth: implemented merge interop spec
* internal/ethapi: update to v1.0.0.alpha.2
This commit updates the code to the new spec, moving payloadId into
it's own object. It also fixes an issue with finalizing an empty blockhash.
It also properly sets the basefee
* all: sync polishes, other fixes + refactors
* core, eth: correct semantics for LeavePoW, EnterPoS
* core: fixed rebasing artifacts
* core: light: performance improvements
* core: use keyed field (f)
* core: eth: fix compilation issues + tests
* eth/catalyst: dbetter error codes
* all: move Merger to consensus/, remove reliance on it in bc
* all: renamed EnterPoS and LeavePoW to ReachTDD and FinalizePoS
* core: make mergelogs a function
* core: use InsertChain instead of InsertBlock
* les: drop merger from lightchain object
* consensus: add merger
* core: recoverAncestors in catalyst mode
* core: fix nitpick
* all: removed merger from beacon, use TTD, nitpicks
* consensus: eth: add docstring, removed unnecessary code duplication
* consensus/beacon: better comment
* all: easy to fix nitpicks by karalabe
* consensus/beacon: verify known headers to be sure
* core: comments
* core: eth: don't drop peers who advertise blocks, nitpicks
* core: never add beacon blocks to the future queue
* core: fixed nitpicks
* consensus/beacon: simplify IsTTDReached check
* consensus/beacon: correct IsTTDReached check
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2021-11-26 05:23:02 -06:00
func ( lc * LightChain ) InsertHeader ( header * types . Header ) error {
// Verify the header first before obtaining the lock
headers := [ ] * types . Header { header }
if _ , err := lc . hc . ValidateHeaderChain ( headers , 100 ) ; err != nil {
return err
}
// Make sure only one thread manipulates the chain at once
lc . chainmu . Lock ( )
defer lc . chainmu . Unlock ( )
lc . wg . Add ( 1 )
defer lc . wg . Done ( )
_ , err := lc . hc . WriteHeaders ( headers )
log . Info ( "Inserted header" , "number" , header . Number , "hash" , header . Hash ( ) )
return err
}
2022-05-05 02:36:26 -05:00
func ( lc * LightChain ) SetCanonical ( header * types . Header ) error {
all: core rework for the merge transition (#23761)
* all: work for eth1/2 transtition
* consensus/beacon, eth: change beacon difficulty to 0
* eth: updates
* all: add terminalBlockDifficulty config, fix rebasing issues
* eth: implemented merge interop spec
* internal/ethapi: update to v1.0.0.alpha.2
This commit updates the code to the new spec, moving payloadId into
it's own object. It also fixes an issue with finalizing an empty blockhash.
It also properly sets the basefee
* all: sync polishes, other fixes + refactors
* core, eth: correct semantics for LeavePoW, EnterPoS
* core: fixed rebasing artifacts
* core: light: performance improvements
* core: use keyed field (f)
* core: eth: fix compilation issues + tests
* eth/catalyst: dbetter error codes
* all: move Merger to consensus/, remove reliance on it in bc
* all: renamed EnterPoS and LeavePoW to ReachTDD and FinalizePoS
* core: make mergelogs a function
* core: use InsertChain instead of InsertBlock
* les: drop merger from lightchain object
* consensus: add merger
* core: recoverAncestors in catalyst mode
* core: fix nitpick
* all: removed merger from beacon, use TTD, nitpicks
* consensus: eth: add docstring, removed unnecessary code duplication
* consensus/beacon: better comment
* all: easy to fix nitpicks by karalabe
* consensus/beacon: verify known headers to be sure
* core: comments
* core: eth: don't drop peers who advertise blocks, nitpicks
* core: never add beacon blocks to the future queue
* core: fixed nitpicks
* consensus/beacon: simplify IsTTDReached check
* consensus/beacon: correct IsTTDReached check
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2021-11-26 05:23:02 -06:00
lc . chainmu . Lock ( )
defer lc . chainmu . Unlock ( )
lc . wg . Add ( 1 )
defer lc . wg . Done ( )
if err := lc . hc . Reorg ( [ ] * types . Header { header } ) ; err != nil {
return err
}
// Emit events
block := types . NewBlockWithHeader ( header )
lc . chainFeed . Send ( core . ChainEvent { Block : block , Hash : block . Hash ( ) } )
lc . chainHeadFeed . Send ( core . ChainHeadEvent { Block : block } )
log . Info ( "Set the chain head" , "number" , block . Number ( ) , "hash" , block . Hash ( ) )
return nil
}
2016-10-13 22:47:09 -05:00
// InsertHeaderChain attempts to insert the given header chain in to the local
// chain, possibly creating a reorg. If an error is returned, it will return the
// index number of the failing header as well an error describing what went wrong.
//
// The verify parameter can be used to fine tune whether nonce verification
// should be done or not. The reason behind the optional check is because some
2022-08-19 01:00:21 -05:00
// of the header retrieval mechanisms already need to verify nonces, as well as
2016-10-13 22:47:09 -05:00
// because nonces can be verified sparsely, not needing to check each.
//
// In the case of a light chain, InsertHeaderChain also creates and posts light
// chain events when necessary.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) InsertHeaderChain ( chain [ ] * types . Header , checkFreq int ) ( int , error ) {
2022-03-22 12:58:05 -05:00
if len ( chain ) == 0 {
return 0 , nil
}
2019-02-07 04:53:45 -06:00
if atomic . LoadInt32 ( & lc . disableCheckFreq ) == 1 {
2019-01-24 05:18:26 -06:00
checkFreq = 0
}
2017-03-22 14:44:22 -05:00
start := time . Now ( )
2019-02-07 04:53:45 -06:00
if i , err := lc . hc . ValidateHeaderChain ( chain , checkFreq ) ; err != nil {
2017-03-22 14:44:22 -05:00
return i , err
}
2016-10-13 22:47:09 -05:00
// Make sure only one thread manipulates the chain at once
2019-02-07 04:53:45 -06:00
lc . chainmu . Lock ( )
defer lc . chainmu . Unlock ( )
2016-10-13 22:47:09 -05:00
2019-02-07 04:53:45 -06:00
lc . wg . Add ( 1 )
defer lc . wg . Done ( )
2016-10-13 22:47:09 -05:00
all: core rework for the merge transition (#23761)
* all: work for eth1/2 transtition
* consensus/beacon, eth: change beacon difficulty to 0
* eth: updates
* all: add terminalBlockDifficulty config, fix rebasing issues
* eth: implemented merge interop spec
* internal/ethapi: update to v1.0.0.alpha.2
This commit updates the code to the new spec, moving payloadId into
it's own object. It also fixes an issue with finalizing an empty blockhash.
It also properly sets the basefee
* all: sync polishes, other fixes + refactors
* core, eth: correct semantics for LeavePoW, EnterPoS
* core: fixed rebasing artifacts
* core: light: performance improvements
* core: use keyed field (f)
* core: eth: fix compilation issues + tests
* eth/catalyst: dbetter error codes
* all: move Merger to consensus/, remove reliance on it in bc
* all: renamed EnterPoS and LeavePoW to ReachTDD and FinalizePoS
* core: make mergelogs a function
* core: use InsertChain instead of InsertBlock
* les: drop merger from lightchain object
* consensus: add merger
* core: recoverAncestors in catalyst mode
* core: fix nitpick
* all: removed merger from beacon, use TTD, nitpicks
* consensus: eth: add docstring, removed unnecessary code duplication
* consensus/beacon: better comment
* all: easy to fix nitpicks by karalabe
* consensus/beacon: verify known headers to be sure
* core: comments
* core: eth: don't drop peers who advertise blocks, nitpicks
* core: never add beacon blocks to the future queue
* core: fixed nitpicks
* consensus/beacon: simplify IsTTDReached check
* consensus/beacon: correct IsTTDReached check
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2021-11-26 05:23:02 -06:00
status , err := lc . hc . InsertHeaderChain ( chain , start , lc . forker )
2020-12-09 04:13:02 -06:00
if err != nil || len ( chain ) == 0 {
return 0 , err
}
// Create chain event for the new head block of this insertion.
var (
lastHeader = chain [ len ( chain ) - 1 ]
block = types . NewBlockWithHeader ( lastHeader )
)
switch status {
case core . CanonStatTy :
all: core rework for the merge transition (#23761)
* all: work for eth1/2 transtition
* consensus/beacon, eth: change beacon difficulty to 0
* eth: updates
* all: add terminalBlockDifficulty config, fix rebasing issues
* eth: implemented merge interop spec
* internal/ethapi: update to v1.0.0.alpha.2
This commit updates the code to the new spec, moving payloadId into
it's own object. It also fixes an issue with finalizing an empty blockhash.
It also properly sets the basefee
* all: sync polishes, other fixes + refactors
* core, eth: correct semantics for LeavePoW, EnterPoS
* core: fixed rebasing artifacts
* core: light: performance improvements
* core: use keyed field (f)
* core: eth: fix compilation issues + tests
* eth/catalyst: dbetter error codes
* all: move Merger to consensus/, remove reliance on it in bc
* all: renamed EnterPoS and LeavePoW to ReachTDD and FinalizePoS
* core: make mergelogs a function
* core: use InsertChain instead of InsertBlock
* les: drop merger from lightchain object
* consensus: add merger
* core: recoverAncestors in catalyst mode
* core: fix nitpick
* all: removed merger from beacon, use TTD, nitpicks
* consensus: eth: add docstring, removed unnecessary code duplication
* consensus/beacon: better comment
* all: easy to fix nitpicks by karalabe
* consensus/beacon: verify known headers to be sure
* core: comments
* core: eth: don't drop peers who advertise blocks, nitpicks
* core: never add beacon blocks to the future queue
* core: fixed nitpicks
* consensus/beacon: simplify IsTTDReached check
* consensus/beacon: correct IsTTDReached check
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2021-11-26 05:23:02 -06:00
lc . chainFeed . Send ( core . ChainEvent { Block : block , Hash : block . Hash ( ) } )
lc . chainHeadFeed . Send ( core . ChainHeadEvent { Block : block } )
2020-12-09 04:13:02 -06:00
case core . SideStatTy :
all: core rework for the merge transition (#23761)
* all: work for eth1/2 transtition
* consensus/beacon, eth: change beacon difficulty to 0
* eth: updates
* all: add terminalBlockDifficulty config, fix rebasing issues
* eth: implemented merge interop spec
* internal/ethapi: update to v1.0.0.alpha.2
This commit updates the code to the new spec, moving payloadId into
it's own object. It also fixes an issue with finalizing an empty blockhash.
It also properly sets the basefee
* all: sync polishes, other fixes + refactors
* core, eth: correct semantics for LeavePoW, EnterPoS
* core: fixed rebasing artifacts
* core: light: performance improvements
* core: use keyed field (f)
* core: eth: fix compilation issues + tests
* eth/catalyst: dbetter error codes
* all: move Merger to consensus/, remove reliance on it in bc
* all: renamed EnterPoS and LeavePoW to ReachTDD and FinalizePoS
* core: make mergelogs a function
* core: use InsertChain instead of InsertBlock
* les: drop merger from lightchain object
* consensus: add merger
* core: recoverAncestors in catalyst mode
* core: fix nitpick
* all: removed merger from beacon, use TTD, nitpicks
* consensus: eth: add docstring, removed unnecessary code duplication
* consensus/beacon: better comment
* all: easy to fix nitpicks by karalabe
* consensus/beacon: verify known headers to be sure
* core: comments
* core: eth: don't drop peers who advertise blocks, nitpicks
* core: never add beacon blocks to the future queue
* core: fixed nitpicks
* consensus/beacon: simplify IsTTDReached check
* consensus/beacon: correct IsTTDReached check
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2021-11-26 05:23:02 -06:00
lc . chainSideFeed . Send ( core . ChainSideEvent { Block : block } )
2016-10-13 22:47:09 -05:00
}
2020-12-09 04:13:02 -06:00
return 0 , err
2016-10-13 22:47:09 -05:00
}
// CurrentHeader retrieves the current head header of the canonical chain. The
// header is retrieved from the HeaderChain's internal cache.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) CurrentHeader ( ) * types . Header {
return lc . hc . CurrentHeader ( )
2016-10-13 22:47:09 -05:00
}
// GetTd retrieves a block's total difficulty in the canonical chain from the
// database by hash and number, caching it if found.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) GetTd ( hash common . Hash , number uint64 ) * big . Int {
return lc . hc . GetTd ( hash , number )
2016-10-13 22:47:09 -05:00
}
2022-10-04 01:44:05 -05:00
// GetTdOdr retrieves the total difficult from the database or
2020-07-13 04:02:54 -05:00
// network by hash and number, caching it (associated with its hash) if found.
func ( lc * LightChain ) GetTdOdr ( ctx context . Context , hash common . Hash , number uint64 ) * big . Int {
td := lc . GetTd ( hash , number )
if td != nil {
return td
}
td , _ = GetTd ( ctx , lc . odr , hash , number )
return td
}
2016-10-13 22:47:09 -05:00
// GetHeader retrieves a block header from the database by hash and number,
// caching it if found.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) GetHeader ( hash common . Hash , number uint64 ) * types . Header {
return lc . hc . GetHeader ( hash , number )
2016-10-13 22:47:09 -05:00
}
// GetHeaderByHash retrieves a block header from the database by hash, caching it if
// found.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) GetHeaderByHash ( hash common . Hash ) * types . Header {
return lc . hc . GetHeaderByHash ( hash )
2016-10-13 22:47:09 -05:00
}
// HasHeader checks if a block header is present in the database or not, caching
// it if present.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) HasHeader ( hash common . Hash , number uint64 ) bool {
return lc . hc . HasHeader ( hash , number )
2016-10-13 22:47:09 -05:00
}
2019-09-26 03:47:31 -05:00
// GetCanonicalHash returns the canonical hash for a given block number
func ( bc * LightChain ) GetCanonicalHash ( number uint64 ) common . Hash {
return bc . hc . GetCanonicalHash ( number )
}
2018-06-12 08:52:54 -05:00
// GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or
// a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the
// number of blocks to be individually checked before we reach the canonical chain.
//
// Note: ancestor == 0 returns the same block, 1 returns its parent and so on.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) GetAncestor ( hash common . Hash , number , ancestor uint64 , maxNonCanonical * uint64 ) ( common . Hash , uint64 ) {
return lc . hc . GetAncestor ( hash , number , ancestor , maxNonCanonical )
2018-06-12 08:52:54 -05:00
}
2016-10-13 22:47:09 -05:00
// GetHeaderByNumber retrieves a block header from the database by number,
// caching it (associated with its hash) if found.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) GetHeaderByNumber ( number uint64 ) * types . Header {
return lc . hc . GetHeaderByNumber ( number )
2016-10-13 22:47:09 -05:00
}
// GetHeaderByNumberOdr retrieves a block header from the database or network
// by number, caching it (associated with its hash) if found.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) GetHeaderByNumberOdr ( ctx context . Context , number uint64 ) ( * types . Header , error ) {
if header := lc . hc . GetHeaderByNumber ( number ) ; header != nil {
2016-10-13 22:47:09 -05:00
return header , nil
}
2019-02-07 04:53:45 -06:00
return GetHeaderByNumber ( ctx , lc . odr , number )
2016-10-13 22:47:09 -05:00
}
2017-12-28 07:18:34 -06:00
// Config retrieves the header chain's chain configuration.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) Config ( ) * params . ChainConfig { return lc . hc . Config ( ) }
2017-12-28 07:18:34 -06:00
all: on-chain oracle checkpoint syncing (#19543)
* all: implement simple checkpoint syncing
cmd, les, node: remove callback mechanism
cmd, node: remove callback definition
les: simplify the registrar
les: expose checkpoint rpc services in the light client
les, light: don't store untrusted receipt
cmd, contracts, les: discard stale checkpoint
cmd, contracts/registrar: loose restriction of registeration
cmd, contracts: add replay-protection
all: off-chain multi-signature contract
params: deploy checkpoint contract for rinkeby
cmd/registrar: add raw signing mode for registrar
cmd/registrar, contracts/registrar, les: fixed messages
* cmd/registrar, contracts/registrar: fix lints
* accounts/abi/bind, les: address comments
* cmd, contracts, les, light, params: minor checkpoint sync cleanups
* cmd, eth, les, light: move checkpoint config to config file
* cmd, eth, les, params: address comments
* eth, les, params: address comments
* cmd: polish up the checkpoint admin CLI
* cmd, contracts, params: deploy new version contract
* cmd/checkpoint-admin: add another flag for clef mode signing
* cmd, contracts, les: rename and regen checkpoint oracle with abigen
2019-06-28 02:34:02 -05:00
// SyncCheckpoint fetches the checkpoint point block header according to
// the checkpoint provided by the remote peer.
//
// Note if we are running the clique, fetches the last epoch snapshot header
// which covered by checkpoint.
func ( lc * LightChain ) SyncCheckpoint ( ctx context . Context , checkpoint * params . TrustedCheckpoint ) bool {
// Ensure the remote checkpoint head is ahead of us
2019-02-07 04:53:45 -06:00
head := lc . CurrentHeader ( ) . Number . Uint64 ( )
2018-08-21 06:39:28 -05:00
all: on-chain oracle checkpoint syncing (#19543)
* all: implement simple checkpoint syncing
cmd, les, node: remove callback mechanism
cmd, node: remove callback definition
les: simplify the registrar
les: expose checkpoint rpc services in the light client
les, light: don't store untrusted receipt
cmd, contracts, les: discard stale checkpoint
cmd, contracts/registrar: loose restriction of registeration
cmd, contracts: add replay-protection
all: off-chain multi-signature contract
params: deploy checkpoint contract for rinkeby
cmd/registrar: add raw signing mode for registrar
cmd/registrar, contracts/registrar, les: fixed messages
* cmd/registrar, contracts/registrar: fix lints
* accounts/abi/bind, les: address comments
* cmd, contracts, les, light, params: minor checkpoint sync cleanups
* cmd, eth, les, light: move checkpoint config to config file
* cmd, eth, les, params: address comments
* eth, les, params: address comments
* cmd: polish up the checkpoint admin CLI
* cmd, contracts, params: deploy new version contract
* cmd/checkpoint-admin: add another flag for clef mode signing
* cmd, contracts, les: rename and regen checkpoint oracle with abigen
2019-06-28 02:34:02 -05:00
latest := ( checkpoint . SectionIndex + 1 ) * lc . indexerConfig . ChtSize - 1
2019-02-07 04:53:45 -06:00
if clique := lc . hc . Config ( ) . Clique ; clique != nil {
2018-08-21 06:39:28 -05:00
latest -= latest % clique . Epoch // epoch snapshot for clique
}
if head >= latest {
all: on-chain oracle checkpoint syncing (#19543)
* all: implement simple checkpoint syncing
cmd, les, node: remove callback mechanism
cmd, node: remove callback definition
les: simplify the registrar
les: expose checkpoint rpc services in the light client
les, light: don't store untrusted receipt
cmd, contracts, les: discard stale checkpoint
cmd, contracts/registrar: loose restriction of registeration
cmd, contracts: add replay-protection
all: off-chain multi-signature contract
params: deploy checkpoint contract for rinkeby
cmd/registrar: add raw signing mode for registrar
cmd/registrar, contracts/registrar, les: fixed messages
* cmd/registrar, contracts/registrar: fix lints
* accounts/abi/bind, les: address comments
* cmd, contracts, les, light, params: minor checkpoint sync cleanups
* cmd, eth, les, light: move checkpoint config to config file
* cmd, eth, les, params: address comments
* eth, les, params: address comments
* cmd: polish up the checkpoint admin CLI
* cmd, contracts, params: deploy new version contract
* cmd/checkpoint-admin: add another flag for clef mode signing
* cmd, contracts, les: rename and regen checkpoint oracle with abigen
2019-06-28 02:34:02 -05:00
return true
2018-08-21 06:39:28 -05:00
}
// Retrieve the latest useful header and update to it
2019-02-07 04:53:45 -06:00
if header , err := GetHeaderByNumber ( ctx , lc . odr , latest ) ; header != nil && err == nil {
lc . chainmu . Lock ( )
defer lc . chainmu . Unlock ( )
2018-08-21 06:39:28 -05:00
// Ensure the chain didn't move past the latest block while retrieving it
2019-02-07 04:53:45 -06:00
if lc . hc . CurrentHeader ( ) . Number . Uint64 ( ) < header . Number . Uint64 ( ) {
2019-04-02 15:28:48 -05:00
log . Info ( "Updated latest header based on CHT" , "number" , header . Number , "hash" , header . Hash ( ) , "age" , common . PrettyAge ( time . Unix ( int64 ( header . Time ) , 0 ) ) )
2020-01-17 04:49:32 -06:00
rawdb . WriteHeadHeaderHash ( lc . chainDb , header . Hash ( ) )
2019-02-07 04:53:45 -06:00
lc . hc . SetCurrentHeader ( header )
2016-10-13 22:47:09 -05:00
}
2018-08-21 06:39:28 -05:00
return true
2016-10-13 22:47:09 -05:00
}
return false
}
2016-11-29 23:02:08 -06:00
// LockChain locks the chain mutex for reading so that multiple canonical hashes can be
// retrieved while it is guaranteed that they belong to the same version of the chain
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) LockChain ( ) {
lc . chainmu . RLock ( )
2016-11-29 23:02:08 -06:00
}
// UnlockChain unlocks the chain mutex
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) UnlockChain ( ) {
lc . chainmu . RUnlock ( )
2016-11-29 23:02:08 -06:00
}
2017-08-18 05:58:36 -05:00
// SubscribeChainEvent registers a subscription of ChainEvent.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) SubscribeChainEvent ( ch chan <- core . ChainEvent ) event . Subscription {
return lc . scope . Track ( lc . chainFeed . Subscribe ( ch ) )
2017-08-18 05:58:36 -05:00
}
// SubscribeChainHeadEvent registers a subscription of ChainHeadEvent.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) SubscribeChainHeadEvent ( ch chan <- core . ChainHeadEvent ) event . Subscription {
return lc . scope . Track ( lc . chainHeadFeed . Subscribe ( ch ) )
2017-08-18 05:58:36 -05:00
}
// SubscribeChainSideEvent registers a subscription of ChainSideEvent.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) SubscribeChainSideEvent ( ch chan <- core . ChainSideEvent ) event . Subscription {
return lc . scope . Track ( lc . chainSideFeed . Subscribe ( ch ) )
2017-08-18 05:58:36 -05:00
}
// SubscribeLogsEvent implements the interface of filters.Backend
// LightChain does not send logs events, so return an empty subscription.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) SubscribeLogsEvent ( ch chan <- [ ] * types . Log ) event . Subscription {
return lc . scope . Track ( new ( event . Feed ) . Subscribe ( ch ) )
2017-08-18 05:58:36 -05:00
}
// SubscribeRemovedLogsEvent implements the interface of filters.Backend
// LightChain does not send core.RemovedLogsEvent, so return an empty subscription.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) SubscribeRemovedLogsEvent ( ch chan <- core . RemovedLogsEvent ) event . Subscription {
return lc . scope . Track ( new ( event . Feed ) . Subscribe ( ch ) )
2017-08-18 05:58:36 -05:00
}
2019-01-24 05:18:26 -06:00
2019-01-24 06:40:37 -06:00
// DisableCheckFreq disables header validation. This is used for ultralight mode.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) DisableCheckFreq ( ) {
atomic . StoreInt32 ( & lc . disableCheckFreq , 1 )
2019-01-24 05:18:26 -06:00
}
2019-01-24 06:40:37 -06:00
// EnableCheckFreq enables header validation.
2019-02-07 04:53:45 -06:00
func ( lc * LightChain ) EnableCheckFreq ( ) {
atomic . StoreInt32 ( & lc . disableCheckFreq , 0 )
2019-01-24 05:18:26 -06:00
}