mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
cmd, eth, les, light: move checkpoint config to config file
This commit is contained in:
parent
2f66fee3b7
commit
1e51c9a14f
19 changed files with 123 additions and 228 deletions
|
|
@ -27,17 +27,10 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/math"
|
|
||||||
"github.com/ethereum/go-ethereum/contracts/registrar/contract"
|
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
|
||||||
"github.com/ethereum/go-ethereum/core/vm/runtime"
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
@ -140,65 +133,6 @@ func (w *wizard) makeGenesis() {
|
||||||
fmt.Println("Specify your chain/network ID if you want an explicit one (default = random)")
|
fmt.Println("Specify your chain/network ID if you want an explicit one (default = random)")
|
||||||
genesis.Config.ChainID = new(big.Int).SetUint64(uint64(w.readDefaultInt(rand.Intn(65536))))
|
genesis.Config.ChainID = new(big.Int).SetUint64(uint64(w.readDefaultInt(rand.Intn(65536))))
|
||||||
|
|
||||||
// Query the user for checkpoint contract config
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println("Should a checkpoint contract be deployed (y/n)? (default = no)")
|
|
||||||
if w.readDefaultYesNo(false) {
|
|
||||||
// Read the addresses of the trusted signers
|
|
||||||
fmt.Println("Which accounts should be trusted signers? (mandatory at least one)")
|
|
||||||
var (
|
|
||||||
signers []common.Address
|
|
||||||
threshold uint64
|
|
||||||
)
|
|
||||||
// Get trusted signer addresses
|
|
||||||
for {
|
|
||||||
if address := w.readAddress(); address != nil {
|
|
||||||
signers = append(signers, *address)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if len(signers) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
// Read the checkpoint signature threshold
|
|
||||||
for {
|
|
||||||
fmt.Printf("What is the minimal approval threshold (maximum %d)?\n", len(signers))
|
|
||||||
threshold = uint64(w.readInt())
|
|
||||||
if threshold <= 0 || threshold > uint64(len(signers)) {
|
|
||||||
log.Error(fmt.Sprintf("Invalid approval threshold, please enter in range [1, %d]\n", len(signers)))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
parsed, err := abi.JSON(strings.NewReader(contract.ContractABI))
|
|
||||||
if err != nil {
|
|
||||||
log.Crit("Parse contract ABI failed", "err", err)
|
|
||||||
}
|
|
||||||
input, err := parsed.Pack("", signers, big.NewInt(params.CheckpointFrequency), big.NewInt(params.CheckpointProcessConfirmations), new(big.Int).SetUint64(threshold))
|
|
||||||
if err != nil {
|
|
||||||
log.Crit("Pack contract constructor arguments failed", "err", err)
|
|
||||||
}
|
|
||||||
config := &runtime.Config{GasLimit: math.MaxInt64}
|
|
||||||
config.State, _ = state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()))
|
|
||||||
code, address, _, err := runtime.Create(append(common.FromHex(contract.ContractBin), input...), config)
|
|
||||||
if err != nil {
|
|
||||||
log.Crit("Execute contract constructor failed", "err", err)
|
|
||||||
}
|
|
||||||
config.State.Commit(true)
|
|
||||||
genesis.Alloc[address] = core.GenesisAccount{Code: code, Storage: make(map[common.Hash]common.Hash), Balance: big.NewInt(1)}
|
|
||||||
if err = config.State.ForEachStorage(address, func(key, value common.Hash) bool {
|
|
||||||
genesis.Alloc[address].Storage[key] = value
|
|
||||||
return true
|
|
||||||
}); err != nil {
|
|
||||||
log.Crit("Failed to iterate contract storage", "err", err)
|
|
||||||
}
|
|
||||||
genesis.Config.CheckpointConfig = ¶ms.CheckpointContractConfig{
|
|
||||||
Address: address,
|
|
||||||
Signers: signers,
|
|
||||||
Threshold: threshold,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// All done, store the genesis and flush to disk
|
// All done, store the genesis and flush to disk
|
||||||
log.Info("Configured new genesis block")
|
log.Info("Configured new genesis block")
|
||||||
|
|
||||||
|
|
@ -296,77 +230,6 @@ func (w *wizard) manageGenesis() {
|
||||||
fmt.Printf("Which block should Petersburg come into effect? (default = %v)\n", w.conf.Genesis.Config.PetersburgBlock)
|
fmt.Printf("Which block should Petersburg come into effect? (default = %v)\n", w.conf.Genesis.Config.PetersburgBlock)
|
||||||
w.conf.Genesis.Config.PetersburgBlock = w.readDefaultBigInt(w.conf.Genesis.Config.PetersburgBlock)
|
w.conf.Genesis.Config.PetersburgBlock = w.readDefaultBigInt(w.conf.Genesis.Config.PetersburgBlock)
|
||||||
|
|
||||||
// The registrar contract might have been deployed
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Printf("Should a checkpoint contract be active (y/n)? (default = %v)\n", w.conf.Genesis.Config.CheckpointConfig != nil)
|
|
||||||
if !w.readDefaultYesNo(w.conf.Genesis.Config.CheckpointConfig != nil) {
|
|
||||||
w.conf.Genesis.Config.CheckpointConfig = nil
|
|
||||||
} else {
|
|
||||||
// Make sure we have a checkpoint config to fill out
|
|
||||||
checkpoint := w.conf.Genesis.Config.CheckpointConfig
|
|
||||||
if checkpoint == nil {
|
|
||||||
checkpoint = new(params.CheckpointContractConfig)
|
|
||||||
}
|
|
||||||
// Read the Ethereum address of the deployed contract
|
|
||||||
fmt.Println()
|
|
||||||
if checkpoint.Address == (common.Address{}) {
|
|
||||||
fmt.Printf("Which address does the checkpoint contract reside at?\n")
|
|
||||||
for checkpoint.Address == (common.Address{}) {
|
|
||||||
if address := w.readAddress(); address != nil {
|
|
||||||
checkpoint.Address = *address
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Printf("Which address does the checkpoint contract reside at? (default = %s)\n", checkpoint.Address.Hex())
|
|
||||||
checkpoint.Address = w.readDefaultAddress(checkpoint.Address)
|
|
||||||
}
|
|
||||||
// Read the addresses of the trusted signers
|
|
||||||
if len(checkpoint.Signers) > 0 {
|
|
||||||
signers := make([]string, len(checkpoint.Signers))
|
|
||||||
for i, signer := range checkpoint.Signers {
|
|
||||||
signers[i] = signer.Hex()
|
|
||||||
}
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Printf("Keep existing list of authorized signers %s? (default = yes)\n", strings.Join(signers, ","))
|
|
||||||
if !w.readDefaultYesNo(true) {
|
|
||||||
checkpoint.Signers = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(checkpoint.Signers) == 0 {
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println("Which accounts should be trusted signers? (mandatory at least one)")
|
|
||||||
for {
|
|
||||||
if address := w.readAddress(); address != nil {
|
|
||||||
checkpoint.Signers = append(checkpoint.Signers, *address)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if len(checkpoint.Signers) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Read the checkpoint signature threshold
|
|
||||||
fmt.Println()
|
|
||||||
if checkpoint.Threshold == 0 {
|
|
||||||
fmt.Printf("What is the minimal approval threshold (maximum %d)?\n", len(checkpoint.Signers))
|
|
||||||
} else {
|
|
||||||
fmt.Printf("What is the minimal approval threshold (maximum %d)? (default = %d)\n", len(checkpoint.Signers), checkpoint.Threshold)
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
if checkpoint.Threshold == 0 {
|
|
||||||
checkpoint.Threshold = uint64(w.readInt())
|
|
||||||
} else {
|
|
||||||
checkpoint.Threshold = uint64(w.readDefaultInt(int(checkpoint.Threshold)))
|
|
||||||
}
|
|
||||||
if checkpoint.Threshold <= 0 || checkpoint.Threshold > uint64(len(checkpoint.Signers)) {
|
|
||||||
log.Error(fmt.Sprintf("Invalid approval threshold, please enter in range [1, %d]\n", len(checkpoint.Signers)))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
w.conf.Genesis.Config.CheckpointConfig = checkpoint
|
|
||||||
}
|
|
||||||
out, _ := json.MarshalIndent(w.conf.Genesis.Config, "", " ")
|
out, _ := json.MarshalIndent(w.conf.Genesis.Config, "", " ")
|
||||||
fmt.Printf("Chain configuration updated:\n\n%s\n", out)
|
fmt.Printf("Chain configuration updated:\n\n%s\n", out)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1468,16 +1468,34 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
|
||||||
cfg.NetworkId = 3
|
cfg.NetworkId = 3
|
||||||
}
|
}
|
||||||
cfg.Genesis = core.DefaultTestnetGenesisBlock()
|
cfg.Genesis = core.DefaultTestnetGenesisBlock()
|
||||||
|
// Only override default checkpoint so that user can customize checkpoint
|
||||||
|
// by themselves.
|
||||||
|
if cfg.Checkpoint == eth.DefaultConfig.Checkpoint {
|
||||||
|
cfg.Checkpoint = params.TestnetTrustedCheckpoint
|
||||||
|
}
|
||||||
case ctx.GlobalBool(RinkebyFlag.Name):
|
case ctx.GlobalBool(RinkebyFlag.Name):
|
||||||
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
|
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
|
||||||
cfg.NetworkId = 4
|
cfg.NetworkId = 4
|
||||||
}
|
}
|
||||||
cfg.Genesis = core.DefaultRinkebyGenesisBlock()
|
cfg.Genesis = core.DefaultRinkebyGenesisBlock()
|
||||||
|
// Only override default checkpoint so that user can customize checkpoint
|
||||||
|
// by themselves.
|
||||||
|
if cfg.Checkpoint == eth.DefaultConfig.Checkpoint {
|
||||||
|
cfg.Checkpoint = params.RinkebyTrustedCheckpoint
|
||||||
|
}
|
||||||
|
if cfg.CheckpointConfig == nil {
|
||||||
|
cfg.CheckpointConfig = params.RinkebyCheckpointConfig // Enable checkpoint contract for rinkeby testnet.
|
||||||
|
}
|
||||||
case ctx.GlobalBool(GoerliFlag.Name):
|
case ctx.GlobalBool(GoerliFlag.Name):
|
||||||
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
|
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
|
||||||
cfg.NetworkId = 5
|
cfg.NetworkId = 5
|
||||||
}
|
}
|
||||||
cfg.Genesis = core.DefaultGoerliGenesisBlock()
|
cfg.Genesis = core.DefaultGoerliGenesisBlock()
|
||||||
|
// Only override default checkpoint so that user can customize checkpoint
|
||||||
|
// by themselves.
|
||||||
|
if cfg.Checkpoint == eth.DefaultConfig.Checkpoint {
|
||||||
|
cfg.Checkpoint = params.GoerliTrustedCheckpoint
|
||||||
|
}
|
||||||
case ctx.GlobalBool(DeveloperFlag.Name):
|
case ctx.GlobalBool(DeveloperFlag.Name):
|
||||||
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
|
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
|
||||||
cfg.NetworkId = 1337
|
cfg.NetworkId = 1337
|
||||||
|
|
|
||||||
|
|
@ -202,7 +202,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
|
|
||||||
// Permit the downloader to use the trie cache allowance during fast sync
|
// Permit the downloader to use the trie cache allowance during fast sync
|
||||||
cacheLimit := cacheConfig.TrieCleanLimit + cacheConfig.TrieDirtyLimit
|
cacheLimit := cacheConfig.TrieCleanLimit + cacheConfig.TrieDirtyLimit
|
||||||
if eth.protocolManager, err = NewProtocolManager(chainConfig, config.SyncMode, config.NetworkId, eth.eventMux, eth.txPool, eth.engine, eth.blockchain, chainDb, cacheLimit, config.Whitelist); err != nil {
|
if eth.protocolManager, err = NewProtocolManager(chainConfig, config.Checkpoint, config.SyncMode, config.NetworkId, eth.eventMux, eth.txPool, eth.engine, eth.blockchain, chainDb, cacheLimit, config.Whitelist); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
eth.miner = miner.New(eth, &config.Miner, chainConfig, eth.EventMux(), eth.engine, eth.isLocalBlock)
|
eth.miner = miner.New(eth, &config.Miner, chainConfig, eth.EventMux(), eth.engine, eth.isLocalBlock)
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ var DefaultConfig = Config{
|
||||||
Blocks: 20,
|
Blocks: 20,
|
||||||
Percentile: 60,
|
Percentile: 60,
|
||||||
},
|
},
|
||||||
|
Checkpoint: params.MainnetTrustedCheckpoint,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
@ -149,4 +150,10 @@ type Config struct {
|
||||||
|
|
||||||
// RPCGasCap is the global gas cap for eth-call variants.
|
// RPCGasCap is the global gas cap for eth-call variants.
|
||||||
RPCGasCap *big.Int `toml:",omitempty"`
|
RPCGasCap *big.Int `toml:",omitempty"`
|
||||||
|
|
||||||
|
// Checkpoint is a hardcoded checkpoint which can be nil.
|
||||||
|
Checkpoint *params.TrustedCheckpoint
|
||||||
|
|
||||||
|
// CheckpointConfig is a set of checkpoint contract configs.
|
||||||
|
CheckpointConfig *params.CheckpointContractConfig
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||||
"github.com/ethereum/go-ethereum/eth/gasprice"
|
"github.com/ethereum/go-ethereum/eth/gasprice"
|
||||||
"github.com/ethereum/go-ethereum/miner"
|
"github.com/ethereum/go-ethereum/miner"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MarshalTOML marshals as TOML.
|
// MarshalTOML marshals as TOML.
|
||||||
|
|
@ -32,6 +33,7 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
||||||
SkipBcVersionCheck bool `toml:"-"`
|
SkipBcVersionCheck bool `toml:"-"`
|
||||||
DatabaseHandles int `toml:"-"`
|
DatabaseHandles int `toml:"-"`
|
||||||
DatabaseCache int
|
DatabaseCache int
|
||||||
|
DatabaseFreezer string
|
||||||
TrieCleanCache int
|
TrieCleanCache int
|
||||||
TrieDirtyCache int
|
TrieDirtyCache int
|
||||||
TrieTimeout time.Duration
|
TrieTimeout time.Duration
|
||||||
|
|
@ -45,6 +47,8 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
||||||
EVMInterpreter string
|
EVMInterpreter string
|
||||||
ConstantinopleOverride *big.Int
|
ConstantinopleOverride *big.Int
|
||||||
RPCGasCap *big.Int `toml:",omitempty"`
|
RPCGasCap *big.Int `toml:",omitempty"`
|
||||||
|
Checkpoint *params.TrustedCheckpoint
|
||||||
|
CheckpointConfig *params.CheckpointContractConfig
|
||||||
}
|
}
|
||||||
var enc Config
|
var enc Config
|
||||||
enc.Genesis = c.Genesis
|
enc.Genesis = c.Genesis
|
||||||
|
|
@ -62,6 +66,7 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
||||||
enc.SkipBcVersionCheck = c.SkipBcVersionCheck
|
enc.SkipBcVersionCheck = c.SkipBcVersionCheck
|
||||||
enc.DatabaseHandles = c.DatabaseHandles
|
enc.DatabaseHandles = c.DatabaseHandles
|
||||||
enc.DatabaseCache = c.DatabaseCache
|
enc.DatabaseCache = c.DatabaseCache
|
||||||
|
enc.DatabaseFreezer = c.DatabaseFreezer
|
||||||
enc.TrieCleanCache = c.TrieCleanCache
|
enc.TrieCleanCache = c.TrieCleanCache
|
||||||
enc.TrieDirtyCache = c.TrieDirtyCache
|
enc.TrieDirtyCache = c.TrieDirtyCache
|
||||||
enc.TrieTimeout = c.TrieTimeout
|
enc.TrieTimeout = c.TrieTimeout
|
||||||
|
|
@ -75,6 +80,8 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
||||||
enc.EVMInterpreter = c.EVMInterpreter
|
enc.EVMInterpreter = c.EVMInterpreter
|
||||||
enc.ConstantinopleOverride = c.ConstantinopleOverride
|
enc.ConstantinopleOverride = c.ConstantinopleOverride
|
||||||
enc.RPCGasCap = c.RPCGasCap
|
enc.RPCGasCap = c.RPCGasCap
|
||||||
|
enc.Checkpoint = c.Checkpoint
|
||||||
|
enc.CheckpointConfig = c.CheckpointConfig
|
||||||
return &enc, nil
|
return &enc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,6 +103,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
||||||
SkipBcVersionCheck *bool `toml:"-"`
|
SkipBcVersionCheck *bool `toml:"-"`
|
||||||
DatabaseHandles *int `toml:"-"`
|
DatabaseHandles *int `toml:"-"`
|
||||||
DatabaseCache *int
|
DatabaseCache *int
|
||||||
|
DatabaseFreezer *string
|
||||||
TrieCleanCache *int
|
TrieCleanCache *int
|
||||||
TrieDirtyCache *int
|
TrieDirtyCache *int
|
||||||
TrieTimeout *time.Duration
|
TrieTimeout *time.Duration
|
||||||
|
|
@ -109,6 +117,8 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
||||||
EVMInterpreter *string
|
EVMInterpreter *string
|
||||||
ConstantinopleOverride *big.Int
|
ConstantinopleOverride *big.Int
|
||||||
RPCGasCap *big.Int `toml:",omitempty"`
|
RPCGasCap *big.Int `toml:",omitempty"`
|
||||||
|
Checkpoint *params.TrustedCheckpoint
|
||||||
|
CheckpointConfig *params.CheckpointContractConfig
|
||||||
}
|
}
|
||||||
var dec Config
|
var dec Config
|
||||||
if err := unmarshal(&dec); err != nil {
|
if err := unmarshal(&dec); err != nil {
|
||||||
|
|
@ -159,6 +169,9 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
||||||
if dec.DatabaseCache != nil {
|
if dec.DatabaseCache != nil {
|
||||||
c.DatabaseCache = *dec.DatabaseCache
|
c.DatabaseCache = *dec.DatabaseCache
|
||||||
}
|
}
|
||||||
|
if dec.DatabaseFreezer != nil {
|
||||||
|
c.DatabaseFreezer = *dec.DatabaseFreezer
|
||||||
|
}
|
||||||
if dec.TrieCleanCache != nil {
|
if dec.TrieCleanCache != nil {
|
||||||
c.TrieCleanCache = *dec.TrieCleanCache
|
c.TrieCleanCache = *dec.TrieCleanCache
|
||||||
}
|
}
|
||||||
|
|
@ -198,5 +211,11 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
||||||
if dec.RPCGasCap != nil {
|
if dec.RPCGasCap != nil {
|
||||||
c.RPCGasCap = dec.RPCGasCap
|
c.RPCGasCap = dec.RPCGasCap
|
||||||
}
|
}
|
||||||
|
if dec.Checkpoint != nil {
|
||||||
|
c.Checkpoint = dec.Checkpoint
|
||||||
|
}
|
||||||
|
if dec.CheckpointConfig != nil {
|
||||||
|
c.CheckpointConfig = dec.CheckpointConfig
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ type ProtocolManager struct {
|
||||||
|
|
||||||
// NewProtocolManager returns a new Ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
|
// NewProtocolManager returns a new Ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
|
||||||
// with the Ethereum network.
|
// with the Ethereum network.
|
||||||
func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, networkID uint64, mux *event.TypeMux, txpool txPool, engine consensus.Engine, blockchain *core.BlockChain, chaindb ethdb.Database, cacheLimit int, whitelist map[uint64]common.Hash) (*ProtocolManager, error) {
|
func NewProtocolManager(config *params.ChainConfig, checkpoint *params.TrustedCheckpoint, mode downloader.SyncMode, networkID uint64, mux *event.TypeMux, txpool txPool, engine consensus.Engine, blockchain *core.BlockChain, chaindb ethdb.Database, cacheLimit int, whitelist map[uint64]common.Hash) (*ProtocolManager, error) {
|
||||||
// Create the protocol manager with the base fields
|
// Create the protocol manager with the base fields
|
||||||
manager := &ProtocolManager{
|
manager := &ProtocolManager{
|
||||||
networkID: networkID,
|
networkID: networkID,
|
||||||
|
|
@ -145,7 +145,7 @@ func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, ne
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If we have trusted checkpoints, enforce them on the chain
|
// If we have trusted checkpoints, enforce them on the chain
|
||||||
if checkpoint, ok := params.TrustedCheckpoints[blockchain.Genesis().Hash()]; ok {
|
if checkpoint != nil {
|
||||||
manager.checkpointNumber = (checkpoint.SectionIndex+1)*params.CHTFrequency - 1
|
manager.checkpointNumber = (checkpoint.SectionIndex+1)*params.CHTFrequency - 1
|
||||||
manager.checkpointHash = checkpoint.SectionHead
|
manager.checkpointHash = checkpoint.SectionHead
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -499,31 +499,30 @@ func testCheckpointChallenge(t *testing.T, syncmode downloader.SyncMode, checkpo
|
||||||
|
|
||||||
// Initialize a chain and generate a fake CHT if checkpointing is enabled
|
// Initialize a chain and generate a fake CHT if checkpointing is enabled
|
||||||
var (
|
var (
|
||||||
db = rawdb.NewMemoryDatabase()
|
db = rawdb.NewMemoryDatabase()
|
||||||
config = new(params.ChainConfig)
|
config = new(params.ChainConfig)
|
||||||
genesis = (&core.Genesis{Config: config}).MustCommit(db)
|
|
||||||
)
|
)
|
||||||
|
(&core.Genesis{Config: config}).MustCommit(db) // Commit genesis block
|
||||||
// If checkpointing is enabled, create and inject a fake CHT and the corresponding
|
// If checkpointing is enabled, create and inject a fake CHT and the corresponding
|
||||||
// chllenge response.
|
// chllenge response.
|
||||||
var response *types.Header
|
var response *types.Header
|
||||||
|
var cht *params.TrustedCheckpoint
|
||||||
if checkpoint {
|
if checkpoint {
|
||||||
index := uint64(rand.Intn(500))
|
index := uint64(rand.Intn(500))
|
||||||
number := (index+1)*params.CHTFrequency - 1
|
number := (index+1)*params.CHTFrequency - 1
|
||||||
response = &types.Header{Number: big.NewInt(int64(number)), Extra: []byte("valid")}
|
response = &types.Header{Number: big.NewInt(int64(number)), Extra: []byte("valid")}
|
||||||
|
|
||||||
cht := ¶ms.TrustedCheckpoint{
|
cht = ¶ms.TrustedCheckpoint{
|
||||||
SectionIndex: index,
|
SectionIndex: index,
|
||||||
SectionHead: response.Hash(),
|
SectionHead: response.Hash(),
|
||||||
}
|
}
|
||||||
params.TrustedCheckpoints[genesis.Hash()] = cht
|
|
||||||
defer delete(params.TrustedCheckpoints, genesis.Hash())
|
|
||||||
}
|
}
|
||||||
// Create a checkpoint aware protocol manager
|
// Create a checkpoint aware protocol manager
|
||||||
blockchain, err := core.NewBlockChain(db, nil, config, ethash.NewFaker(), vm.Config{}, nil)
|
blockchain, err := core.NewBlockChain(db, nil, config, ethash.NewFaker(), vm.Config{}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create new blockchain: %v", err)
|
t.Fatalf("failed to create new blockchain: %v", err)
|
||||||
}
|
}
|
||||||
pm, err := NewProtocolManager(config, syncmode, DefaultConfig.NetworkId, new(event.TypeMux), new(testTxPool), ethash.NewFaker(), blockchain, db, 1, nil)
|
pm, err := NewProtocolManager(config, cht, syncmode, DefaultConfig.NetworkId, new(event.TypeMux), new(testTxPool), ethash.NewFaker(), blockchain, db, 1, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to start test protocol manager: %v", err)
|
t.Fatalf("failed to start test protocol manager: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -610,7 +609,7 @@ func testBroadcastBlock(t *testing.T, totalPeers, broadcastExpected int) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create new blockchain: %v", err)
|
t.Fatalf("failed to create new blockchain: %v", err)
|
||||||
}
|
}
|
||||||
pm, err := NewProtocolManager(config, downloader.FullSync, DefaultConfig.NetworkId, evmux, new(testTxPool), pow, blockchain, db, 1, nil)
|
pm, err := NewProtocolManager(config, nil, downloader.FullSync, DefaultConfig.NetworkId, evmux, new(testTxPool), pow, blockchain, db, 1, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to start test protocol manager: %v", err)
|
t.Fatalf("failed to start test protocol manager: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ func newTestProtocolManager(mode downloader.SyncMode, blocks int, generator func
|
||||||
if _, err := blockchain.InsertChain(chain); err != nil {
|
if _, err := blockchain.InsertChain(chain); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
pm, err := NewProtocolManager(gspec.Config, mode, DefaultConfig.NetworkId, evmux, &testTxPool{added: newtx}, engine, blockchain, db, 1, nil)
|
pm, err := NewProtocolManager(gspec.Config, nil, mode, DefaultConfig.NetworkId, evmux, &testTxPool{added: newtx}, engine, blockchain, db, 1, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) {
|
||||||
|
|
||||||
// Note: NewLightChain adds the trusted checkpoint so it needs an ODR with
|
// Note: NewLightChain adds the trusted checkpoint so it needs an ODR with
|
||||||
// indexers already set but not started yet
|
// indexers already set but not started yet
|
||||||
if leth.blockchain, err = light.NewLightChain(leth.odr, leth.chainConfig, leth.engine); err != nil {
|
if leth.blockchain, err = light.NewLightChain(leth.odr, leth.chainConfig, leth.engine, config.Checkpoint); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Note: AddChildIndexer starts the update process for the child
|
// Note: AddChildIndexer starts the update process for the child
|
||||||
|
|
@ -150,8 +150,8 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) {
|
||||||
}
|
}
|
||||||
leth.ApiBackend.gpo = gasprice.NewOracle(leth.ApiBackend, gpoParams)
|
leth.ApiBackend.gpo = gasprice.NewOracle(leth.ApiBackend, gpoParams)
|
||||||
|
|
||||||
registrar := newCheckpointRegistrar(chainConfig.CheckpointConfig, leth.getLocalCheckpoint)
|
registrar := newCheckpointRegistrar(config.CheckpointConfig, leth.getLocalCheckpoint)
|
||||||
if leth.protocolManager, err = NewProtocolManager(leth.chainConfig, light.DefaultClientIndexerConfig, config.ULC, true, config.NetworkId, leth.eventMux, leth.peers, leth.blockchain, nil, chainDb, leth.odr, leth.serverPool, registrar, quitSync, &leth.wg, nil); err != nil {
|
if leth.protocolManager, err = NewProtocolManager(leth.chainConfig, config.Checkpoint, light.DefaultClientIndexerConfig, config.ULC, true, config.NetworkId, leth.eventMux, leth.peers, leth.blockchain, nil, chainDb, leth.odr, leth.serverPool, registrar, quitSync, &leth.wg, nil); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if leth.protocolManager.isULCEnabled() {
|
if leth.protocolManager.isULCEnabled() {
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,7 @@ type ProtocolManager struct {
|
||||||
fetcher *lightFetcher
|
fetcher *lightFetcher
|
||||||
ulc *ulc
|
ulc *ulc
|
||||||
peers *peerSet
|
peers *peerSet
|
||||||
|
checkpoint *params.TrustedCheckpoint
|
||||||
reg *checkpointRegistrar // If reg == nil, it means the checkpoint registrar is not activated
|
reg *checkpointRegistrar // If reg == nil, it means the checkpoint registrar is not activated
|
||||||
|
|
||||||
// channels for fetcher, syncer, txsyncLoop
|
// channels for fetcher, syncer, txsyncLoop
|
||||||
|
|
@ -131,7 +132,7 @@ type ProtocolManager struct {
|
||||||
|
|
||||||
// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
|
// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
|
||||||
// with the ethereum network.
|
// with the ethereum network.
|
||||||
func NewProtocolManager(chainConfig *params.ChainConfig, indexerConfig *light.IndexerConfig, ulcConfig *eth.ULCConfig, client bool, networkId uint64, mux *event.TypeMux, peers *peerSet, blockchain BlockChain, txpool txPool, chainDb ethdb.Database, odr *LesOdr, serverPool *serverPool, registrar *checkpointRegistrar, quitSync chan struct{}, wg *sync.WaitGroup, synced func() bool) (*ProtocolManager, error) {
|
func NewProtocolManager(chainConfig *params.ChainConfig, checkpoint *params.TrustedCheckpoint, indexerConfig *light.IndexerConfig, ulcConfig *eth.ULCConfig, client bool, networkId uint64, mux *event.TypeMux, peers *peerSet, blockchain BlockChain, txpool txPool, chainDb ethdb.Database, odr *LesOdr, serverPool *serverPool, registrar *checkpointRegistrar, quitSync chan struct{}, wg *sync.WaitGroup, synced func() bool) (*ProtocolManager, error) {
|
||||||
// Create the protocol manager with the base fields
|
// Create the protocol manager with the base fields
|
||||||
manager := &ProtocolManager{
|
manager := &ProtocolManager{
|
||||||
client: client,
|
client: client,
|
||||||
|
|
@ -150,6 +151,7 @@ func NewProtocolManager(chainConfig *params.ChainConfig, indexerConfig *light.In
|
||||||
quitSync: quitSync,
|
quitSync: quitSync,
|
||||||
wg: wg,
|
wg: wg,
|
||||||
noMorePeers: make(chan struct{}),
|
noMorePeers: make(chan struct{}),
|
||||||
|
checkpoint: checkpoint,
|
||||||
synced: synced,
|
synced: synced,
|
||||||
}
|
}
|
||||||
if odr != nil {
|
if odr != nil {
|
||||||
|
|
@ -166,11 +168,11 @@ func NewProtocolManager(chainConfig *params.ChainConfig, indexerConfig *light.In
|
||||||
removePeer = func(id string) {}
|
removePeer = func(id string) {}
|
||||||
}
|
}
|
||||||
if client {
|
if client {
|
||||||
var checkpoint uint64
|
var checkpointNumber uint64
|
||||||
if cht, ok := params.TrustedCheckpoints[blockchain.Genesis().Hash()]; ok {
|
if checkpoint != nil {
|
||||||
checkpoint = (cht.SectionIndex+1)*params.CHTFrequency - 1
|
checkpointNumber = (checkpoint.SectionIndex+1)*params.CHTFrequency - 1
|
||||||
}
|
}
|
||||||
manager.downloader = downloader.New(checkpoint, chainDb, nil, manager.eventMux, nil, blockchain, removePeer)
|
manager.downloader = downloader.New(checkpointNumber, chainDb, nil, manager.eventMux, nil, blockchain, removePeer)
|
||||||
manager.peers.notify((*downloaderPeerNotify)(manager))
|
manager.peers.notify((*downloaderPeerNotify)(manager))
|
||||||
manager.fetcher = newLightFetcher(manager)
|
manager.fetcher = newLightFetcher(manager)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@ func newTestProtocolManager(lightSync bool, blocks int, odr *LesOdr, indexers []
|
||||||
|
|
||||||
// initialize empty chain for light client or pre-committed chain for server.
|
// initialize empty chain for light client or pre-committed chain for server.
|
||||||
if lightSync {
|
if lightSync {
|
||||||
chain, _ = light.NewLightChain(odr, gspec.Config, engine)
|
chain, _ = light.NewLightChain(odr, gspec.Config, engine, nil)
|
||||||
} else {
|
} else {
|
||||||
chain = simulation.Blockchain()
|
chain = simulation.Blockchain()
|
||||||
pool = core.NewTxPool(core.DefaultTxPoolConfig, gspec.Config, simulation.Blockchain())
|
pool = core.NewTxPool(core.DefaultTxPoolConfig, gspec.Config, simulation.Blockchain())
|
||||||
|
|
@ -201,7 +201,6 @@ func newTestProtocolManager(lightSync bool, blocks int, odr *LesOdr, indexers []
|
||||||
indexConfig = light.TestClientIndexerConfig
|
indexConfig = light.TestClientIndexerConfig
|
||||||
}
|
}
|
||||||
config := ¶ms.CheckpointContractConfig{
|
config := ¶ms.CheckpointContractConfig{
|
||||||
Name: "test",
|
|
||||||
Address: crypto.CreateAddress(bankAddr, 0),
|
Address: crypto.CreateAddress(bankAddr, 0),
|
||||||
Signers: []common.Address{signerAddr},
|
Signers: []common.Address{signerAddr},
|
||||||
Threshold: 1,
|
Threshold: 1,
|
||||||
|
|
@ -220,7 +219,7 @@ func newTestProtocolManager(lightSync bool, blocks int, odr *LesOdr, indexers []
|
||||||
}
|
}
|
||||||
reg = newCheckpointRegistrar(config, getLocal)
|
reg = newCheckpointRegistrar(config, getLocal)
|
||||||
}
|
}
|
||||||
pm, err := NewProtocolManager(gspec.Config, indexConfig, ulcConfig, lightSync, NetworkId, evmux, peers, chain, pool, db, odr, nil, reg, exitCh, new(sync.WaitGroup), func() bool { return true })
|
pm, err := NewProtocolManager(gspec.Config, nil, indexConfig, ulcConfig, lightSync, NetworkId, evmux, peers, chain, pool, db, odr, nil, reg, exitCh, new(sync.WaitGroup), func() bool { return true })
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
25
les/peer.go
25
les/peer.go
|
|
@ -81,9 +81,8 @@ type peer struct {
|
||||||
announceType uint64
|
announceType uint64
|
||||||
|
|
||||||
// Checkpoint relative fields
|
// Checkpoint relative fields
|
||||||
advertisedCheckpoint params.TrustedCheckpoint
|
checkpoint params.TrustedCheckpoint
|
||||||
registeredHeight uint64
|
checkpointNumber uint64
|
||||||
hardcodedCheckpoint bool // Indicator whether the checkpoint is hardcoded
|
|
||||||
|
|
||||||
id string
|
id string
|
||||||
|
|
||||||
|
|
@ -687,24 +686,8 @@ func (p *peer) Handshake(td *big.Int, head common.Hash, headNum uint64, genesis
|
||||||
p.fcServer = flowcontrol.NewServerNode(sParams, &mclock.System{})
|
p.fcServer = flowcontrol.NewServerNode(sParams, &mclock.System{})
|
||||||
p.fcCosts = MRC.decode(ProtocolLengths[uint(p.version)])
|
p.fcCosts = MRC.decode(ProtocolLengths[uint(p.version)])
|
||||||
|
|
||||||
// Recap the checkpoint.
|
recv.get("checkpoint/value", &p.checkpoint)
|
||||||
//
|
recv.get("checkpoint/registerHeight", &p.checkpointNumber)
|
||||||
// The light client may be connected to several different versions of the server.
|
|
||||||
// (1) Old version server which can not provide stable checkpoint in the handshake packet.
|
|
||||||
// => Use hardcoded checkpoint or empty checkpoint
|
|
||||||
// (2) New version server but simple checkpoint syncing is not enabled(e.g. mainnet, new testnet or private network)
|
|
||||||
// => Use hardcoded checkpoint or empty checkpoint
|
|
||||||
// (3) New version server but the provided stable checkpoint is even lower than the hardcoded one.
|
|
||||||
// => Use hardcoded checkpoint
|
|
||||||
// (4) New version server with valid and higher stable checkpoint
|
|
||||||
// => Use provided checkpoint
|
|
||||||
hardcoded := params.TrustedCheckpoints[genesis]
|
|
||||||
if err := recv.get("checkpoint/value", &p.advertisedCheckpoint); hardcoded != nil &&
|
|
||||||
(err != nil || p.advertisedCheckpoint.SectionIndex < hardcoded.SectionIndex) {
|
|
||||||
p.advertisedCheckpoint = *hardcoded
|
|
||||||
p.hardcodedCheckpoint = true
|
|
||||||
}
|
|
||||||
recv.get("checkpoint/registerHeight", &p.registeredHeight)
|
|
||||||
|
|
||||||
if !p.isOnlyAnnounce {
|
if !p.isOnlyAnnounce {
|
||||||
for msgCode := range reqAvgTimeCost {
|
for msgCode := range reqAvgTimeCost {
|
||||||
|
|
|
||||||
|
|
@ -120,8 +120,8 @@ func NewLesServer(e *eth.Ethereum, config *eth.Config) (*LesServer, error) {
|
||||||
|
|
||||||
srv.chtIndexer.Start(e.BlockChain())
|
srv.chtIndexer.Start(e.BlockChain())
|
||||||
|
|
||||||
registrar := newCheckpointRegistrar(e.BlockChain().Config().CheckpointConfig, srv.getLocalCheckpoint)
|
registrar := newCheckpointRegistrar(config.CheckpointConfig, srv.getLocalCheckpoint)
|
||||||
pm, err := NewProtocolManager(e.BlockChain().Config(), light.DefaultServerIndexerConfig, config.ULC, false, config.NetworkId, e.EventMux(), newPeerSet(), e.BlockChain(), e.TxPool(), e.ChainDb(), nil, nil, registrar, quitSync, new(sync.WaitGroup), e.Synced)
|
pm, err := NewProtocolManager(e.BlockChain().Config(), config.Checkpoint, light.DefaultServerIndexerConfig, config.ULC, false, config.NetworkId, e.EventMux(), newPeerSet(), e.BlockChain(), e.TxPool(), e.ChainDb(), nil, nil, registrar, quitSync, new(sync.WaitGroup), e.Synced)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
39
les/sync.go
39
les/sync.go
|
|
@ -26,7 +26,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||||
"github.com/ethereum/go-ethereum/light"
|
"github.com/ethereum/go-ethereum/light"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var errInvalidCheckpoint = errors.New("invalid advertised checkpoint")
|
var errInvalidCheckpoint = errors.New("invalid advertised checkpoint")
|
||||||
|
|
@ -86,8 +85,8 @@ func (pm *ProtocolManager) validateCheckpoint(peer *peer) error {
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// Fetch the block header corresponding to the checkpoint registration.
|
// Fetch the block header corresponding to the checkpoint registration.
|
||||||
cp := peer.advertisedCheckpoint
|
cp := peer.checkpoint
|
||||||
header, err := light.GetUntrustedHeaderByNumber(ctx, pm.odr, peer.registeredHeight, peer.id)
|
header, err := light.GetUntrustedHeaderByNumber(ctx, pm.odr, peer.checkpointNumber, peer.id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -128,6 +127,23 @@ func (pm *ProtocolManager) synchronise(peer *peer) {
|
||||||
if currentTd != nil && peer.headBlockInfo().Td.Cmp(currentTd) < 0 {
|
if currentTd != nil && peer.headBlockInfo().Td.Cmp(currentTd) < 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// Recap the checkpoint.
|
||||||
|
//
|
||||||
|
// The light client may be connected to several different versions of the server.
|
||||||
|
// (1) Old version server which can not provide stable checkpoint in the handshake packet.
|
||||||
|
// => Use hardcoded checkpoint or empty checkpoint
|
||||||
|
// (2) New version server but simple checkpoint syncing is not enabled(e.g. mainnet, new testnet or private network)
|
||||||
|
// => Use hardcoded checkpoint or empty checkpoint
|
||||||
|
// (3) New version server but the provided stable checkpoint is even lower than the hardcoded one.
|
||||||
|
// => Use hardcoded checkpoint
|
||||||
|
// (4) New version server with valid and higher stable checkpoint
|
||||||
|
// => Use provided checkpoint
|
||||||
|
var checkpoint = &peer.checkpoint
|
||||||
|
var hardcoded bool
|
||||||
|
if pm.checkpoint != nil && pm.checkpoint.SectionIndex > peer.checkpoint.SectionIndex {
|
||||||
|
checkpoint = pm.checkpoint // Use the hardcoded one.
|
||||||
|
hardcoded = true
|
||||||
|
}
|
||||||
// Determine whether we should run checkpoint syncing or normal light syncing.
|
// Determine whether we should run checkpoint syncing or normal light syncing.
|
||||||
//
|
//
|
||||||
// Here has four situations that we will disable the checkpoint syncing:
|
// Here has four situations that we will disable the checkpoint syncing:
|
||||||
|
|
@ -136,16 +152,15 @@ func (pm *ProtocolManager) synchronise(peer *peer) {
|
||||||
// 2. The latest head block of the local chain is above the checkpoint.
|
// 2. The latest head block of the local chain is above the checkpoint.
|
||||||
// 3. The checkpoint is hardcoded(recap with local hardcoded checkpoint)
|
// 3. The checkpoint is hardcoded(recap with local hardcoded checkpoint)
|
||||||
// 4. For some networks the checkpoint syncing is not activated.
|
// 4. For some networks the checkpoint syncing is not activated.
|
||||||
cp := &peer.advertisedCheckpoint
|
|
||||||
mode := checkpointSync
|
mode := checkpointSync
|
||||||
switch {
|
switch {
|
||||||
case cp.Empty():
|
case checkpoint.Empty():
|
||||||
mode = lightSync
|
mode = lightSync
|
||||||
log.Debug("Disable checkpoint syncing", "reason", "empty checkpoint")
|
log.Debug("Disable checkpoint syncing", "reason", "empty checkpoint")
|
||||||
case latest.Number.Uint64() >= (cp.SectionIndex+1)*pm.iConfig.ChtSize-1:
|
case latest.Number.Uint64() >= (checkpoint.SectionIndex+1)*pm.iConfig.ChtSize-1:
|
||||||
mode = lightSync
|
mode = lightSync
|
||||||
log.Debug("Disable checkpoint syncing", "reason", "local chain beyond the checkpoint")
|
log.Debug("Disable checkpoint syncing", "reason", "local chain beyonds the checkpoint")
|
||||||
case peer.hardcodedCheckpoint:
|
case hardcoded:
|
||||||
mode = legacyCheckpointSync
|
mode = legacyCheckpointSync
|
||||||
log.Debug("Disable checkpoint syncing", "reason", "checkpoint is hardcoded")
|
log.Debug("Disable checkpoint syncing", "reason", "checkpoint is hardcoded")
|
||||||
case pm.reg == nil || !pm.reg.isRunning():
|
case pm.reg == nil || !pm.reg.isRunning():
|
||||||
|
|
@ -162,16 +177,16 @@ func (pm *ProtocolManager) synchronise(peer *peer) {
|
||||||
if mode == checkpointSync || mode == legacyCheckpointSync {
|
if mode == checkpointSync || mode == legacyCheckpointSync {
|
||||||
// Validate the advertised checkpoint
|
// Validate the advertised checkpoint
|
||||||
if mode == legacyCheckpointSync {
|
if mode == legacyCheckpointSync {
|
||||||
cp = params.TrustedCheckpoints[pm.blockchain.Genesis().Hash()]
|
checkpoint = pm.checkpoint
|
||||||
} else if mode == checkpointSync {
|
} else if mode == checkpointSync {
|
||||||
if err := pm.validateCheckpoint(peer); err != nil {
|
if err := pm.validateCheckpoint(peer); err != nil {
|
||||||
log.Debug("Failed to validate checkpoint", "reason", err)
|
log.Debug("Failed to validate checkpoint", "reason", err)
|
||||||
pm.removePeer(peer.id)
|
pm.removePeer(peer.id)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
pm.blockchain.(*light.LightChain).AddTrustedCheckpoint(cp)
|
pm.blockchain.(*light.LightChain).AddTrustedCheckpoint(checkpoint)
|
||||||
}
|
}
|
||||||
log.Debug("Checkpoint syncing start", "peer", peer.id, "checkpoint", cp.SectionIndex)
|
log.Debug("Checkpoint syncing start", "peer", peer.id, "checkpoint", checkpoint.SectionIndex)
|
||||||
|
|
||||||
// Fetch the start point block header.
|
// Fetch the start point block header.
|
||||||
//
|
//
|
||||||
|
|
@ -182,7 +197,7 @@ func (pm *ProtocolManager) synchronise(peer *peer) {
|
||||||
// of the latest epoch covered by checkpoint.
|
// of the latest epoch covered by checkpoint.
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
if !cp.Empty() && !pm.blockchain.(*light.LightChain).SyncCheckpoint(ctx, cp) {
|
if !checkpoint.Empty() && !pm.blockchain.(*light.LightChain).SyncCheckpoint(ctx, checkpoint) {
|
||||||
log.Debug("Sync checkpoint failed")
|
log.Debug("Sync checkpoint failed")
|
||||||
pm.removePeer(peer.id)
|
pm.removePeer(peer.id)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ type LightChain struct {
|
||||||
// NewLightChain returns a fully initialised light chain using information
|
// NewLightChain returns a fully initialised light chain using information
|
||||||
// available in the database. It initialises the default Ethereum header
|
// available in the database. It initialises the default Ethereum header
|
||||||
// validator.
|
// validator.
|
||||||
func NewLightChain(odr OdrBackend, config *params.ChainConfig, engine consensus.Engine) (*LightChain, error) {
|
func NewLightChain(odr OdrBackend, config *params.ChainConfig, engine consensus.Engine, checkpoint *params.TrustedCheckpoint) (*LightChain, error) {
|
||||||
bodyCache, _ := lru.New(bodyCacheLimit)
|
bodyCache, _ := lru.New(bodyCacheLimit)
|
||||||
bodyRLPCache, _ := lru.New(bodyCacheLimit)
|
bodyRLPCache, _ := lru.New(bodyCacheLimit)
|
||||||
blockCache, _ := lru.New(blockCacheLimit)
|
blockCache, _ := lru.New(blockCacheLimit)
|
||||||
|
|
@ -101,8 +101,8 @@ func NewLightChain(odr OdrBackend, config *params.ChainConfig, engine consensus.
|
||||||
if bc.genesisBlock == nil {
|
if bc.genesisBlock == nil {
|
||||||
return nil, core.ErrNoGenesis
|
return nil, core.ErrNoGenesis
|
||||||
}
|
}
|
||||||
if cp, ok := params.TrustedCheckpoints[bc.genesisBlock.Hash()]; ok {
|
if checkpoint != nil {
|
||||||
bc.AddTrustedCheckpoint(cp)
|
bc.AddTrustedCheckpoint(checkpoint)
|
||||||
}
|
}
|
||||||
if err := bc.loadLastState(); err != nil {
|
if err := bc.loadLastState(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ func newCanonical(n int) (ethdb.Database, *LightChain, error) {
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
gspec := core.Genesis{Config: params.TestChainConfig}
|
gspec := core.Genesis{Config: params.TestChainConfig}
|
||||||
genesis := gspec.MustCommit(db)
|
genesis := gspec.MustCommit(db)
|
||||||
blockchain, _ := NewLightChain(&dummyOdr{db: db, indexerConfig: TestClientIndexerConfig}, gspec.Config, ethash.NewFaker())
|
blockchain, _ := NewLightChain(&dummyOdr{db: db, indexerConfig: TestClientIndexerConfig}, gspec.Config, ethash.NewFaker(), nil)
|
||||||
|
|
||||||
// Create and inject the requested chain
|
// Create and inject the requested chain
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
|
|
@ -75,7 +75,7 @@ func newTestLightChain() *LightChain {
|
||||||
Config: params.TestChainConfig,
|
Config: params.TestChainConfig,
|
||||||
}
|
}
|
||||||
gspec.MustCommit(db)
|
gspec.MustCommit(db)
|
||||||
lc, err := NewLightChain(&dummyOdr{db: db}, gspec.Config, ethash.NewFullFaker())
|
lc, err := NewLightChain(&dummyOdr{db: db}, gspec.Config, ethash.NewFullFaker(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
@ -344,7 +344,7 @@ func TestReorgBadHeaderHashes(t *testing.T) {
|
||||||
defer func() { delete(core.BadHashes, headers[3].Hash()) }()
|
defer func() { delete(core.BadHashes, headers[3].Hash()) }()
|
||||||
|
|
||||||
// Create a new LightChain and check that it rolled back the state.
|
// Create a new LightChain and check that it rolled back the state.
|
||||||
ncm, err := NewLightChain(&dummyOdr{db: bc.chainDb}, params.TestChainConfig, ethash.NewFaker())
|
ncm, err := NewLightChain(&dummyOdr{db: bc.chainDb}, params.TestChainConfig, ethash.NewFaker(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create new chain manager: %v", err)
|
t.Fatalf("failed to create new chain manager: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -264,7 +264,7 @@ func testChainOdr(t *testing.T, protocol int, fn odrTestFn) {
|
||||||
}
|
}
|
||||||
|
|
||||||
odr := &testOdr{sdb: sdb, ldb: ldb, indexerConfig: TestClientIndexerConfig}
|
odr := &testOdr{sdb: sdb, ldb: ldb, indexerConfig: TestClientIndexerConfig}
|
||||||
lightchain, err := NewLightChain(odr, params.TestChainConfig, ethash.NewFullFaker())
|
lightchain, err := NewLightChain(odr, params.TestChainConfig, ethash.NewFullFaker(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ func TestTxPool(t *testing.T) {
|
||||||
discard: make(chan int, 1),
|
discard: make(chan int, 1),
|
||||||
mined: make(chan int, 1),
|
mined: make(chan int, 1),
|
||||||
}
|
}
|
||||||
lightchain, _ := NewLightChain(odr, params.TestChainConfig, ethash.NewFullFaker())
|
lightchain, _ := NewLightChain(odr, params.TestChainConfig, ethash.NewFullFaker(), nil)
|
||||||
txPermanent = 50
|
txPermanent = 50
|
||||||
pool := NewTxPool(params.TestChainConfig, lightchain, relay)
|
pool := NewTxPool(params.TestChainConfig, lightchain, relay)
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
||||||
|
|
|
||||||
|
|
@ -33,15 +33,6 @@ var (
|
||||||
GoerliGenesisHash = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a")
|
GoerliGenesisHash = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a")
|
||||||
)
|
)
|
||||||
|
|
||||||
// TrustedCheckpoints associates each known checkpoint with the genesis hash of
|
|
||||||
// the chain it belongs to.
|
|
||||||
var TrustedCheckpoints = map[common.Hash]*TrustedCheckpoint{
|
|
||||||
MainnetGenesisHash: MainnetTrustedCheckpoint,
|
|
||||||
TestnetGenesisHash: TestnetTrustedCheckpoint,
|
|
||||||
RinkebyGenesisHash: RinkebyTrustedCheckpoint,
|
|
||||||
GoerliGenesisHash: GoerliTrustedCheckpoint,
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// MainnetChainConfig is the chain parameters to run a node on the main network.
|
// MainnetChainConfig is the chain parameters to run a node on the main network.
|
||||||
MainnetChainConfig = &ChainConfig{
|
MainnetChainConfig = &ChainConfig{
|
||||||
|
|
@ -108,16 +99,6 @@ var (
|
||||||
Period: 15,
|
Period: 15,
|
||||||
Epoch: 30000,
|
Epoch: 30000,
|
||||||
},
|
},
|
||||||
CheckpointConfig: &CheckpointContractConfig{
|
|
||||||
Address: common.HexToAddress("0x62652ed8e969ce7bd5e3dd13590efa1e569215f1"),
|
|
||||||
Signers: []common.Address{
|
|
||||||
common.HexToAddress("0xd9c9cd5f6779558b6e0ed4e6acf6b1947e7fa1f3"), // Peter
|
|
||||||
common.HexToAddress("0x78d1ad571a1a09d60d9bbf25894b44e4c8859595"), // Martin
|
|
||||||
common.HexToAddress("0x286834935f4A8Cfb4FF4C77D5770C2775aE2b0E7"), // Zsolt
|
|
||||||
common.HexToAddress("0xb86e2B0Ab5A4B1373e40c51A7C712c70Ba2f9f8E"), // Gary
|
|
||||||
},
|
|
||||||
Threshold: 2,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RinkebyTrustedCheckpoint contains the light client trusted checkpoint for the Rinkeby test network.
|
// RinkebyTrustedCheckpoint contains the light client trusted checkpoint for the Rinkeby test network.
|
||||||
|
|
@ -128,6 +109,18 @@ var (
|
||||||
BloomRoot: common.HexToHash("0xa3048fe8b7e30f77f11bc755a88478363d7d3e71c2bdfe4e8ab9e269cd804ba2"),
|
BloomRoot: common.HexToHash("0xa3048fe8b7e30f77f11bc755a88478363d7d3e71c2bdfe4e8ab9e269cd804ba2"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RinkebyCheckpointConfig contains a set of checkpoint contract configs for the Rinkeby test network.
|
||||||
|
RinkebyCheckpointConfig = &CheckpointContractConfig{
|
||||||
|
Address: common.HexToAddress("0x62652ed8e969ce7bd5e3dd13590efa1e569215f1"),
|
||||||
|
Signers: []common.Address{
|
||||||
|
common.HexToAddress("0xd9c9cd5f6779558b6e0ed4e6acf6b1947e7fa1f3"), // Peter
|
||||||
|
common.HexToAddress("0x78d1ad571a1a09d60d9bbf25894b44e4c8859595"), // Martin
|
||||||
|
common.HexToAddress("0x286834935f4A8Cfb4FF4C77D5770C2775aE2b0E7"), // Zsolt
|
||||||
|
common.HexToAddress("0xb86e2B0Ab5A4B1373e40c51A7C712c70Ba2f9f8E"), // Gary
|
||||||
|
},
|
||||||
|
Threshold: 2,
|
||||||
|
}
|
||||||
|
|
||||||
// GoerliChainConfig contains the chain parameters to run a node on the Görli test network.
|
// GoerliChainConfig contains the chain parameters to run a node on the Görli test network.
|
||||||
GoerliChainConfig = &ChainConfig{
|
GoerliChainConfig = &ChainConfig{
|
||||||
ChainID: big.NewInt(5),
|
ChainID: big.NewInt(5),
|
||||||
|
|
@ -159,16 +152,16 @@ var (
|
||||||
//
|
//
|
||||||
// This configuration is intentionally not using keyed fields to force anyone
|
// This configuration is intentionally not using keyed fields to force anyone
|
||||||
// adding flags to the config to also have to set these fields.
|
// adding flags to the config to also have to set these fields.
|
||||||
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil}
|
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil}
|
||||||
|
|
||||||
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
|
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
|
||||||
// and accepted by the Ethereum core developers into the Clique consensus.
|
// and accepted by the Ethereum core developers into the Clique consensus.
|
||||||
//
|
//
|
||||||
// This configuration is intentionally not using keyed fields to force anyone
|
// This configuration is intentionally not using keyed fields to force anyone
|
||||||
// adding flags to the config to also have to set these fields.
|
// adding flags to the config to also have to set these fields.
|
||||||
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil}
|
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}}
|
||||||
|
|
||||||
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil}
|
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil}
|
||||||
TestRules = TestChainConfig.Rules(new(big.Int))
|
TestRules = TestChainConfig.Rules(new(big.Int))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -242,9 +235,6 @@ type ChainConfig struct {
|
||||||
// Various consensus engines
|
// Various consensus engines
|
||||||
Ethash *EthashConfig `json:"ethash,omitempty"`
|
Ethash *EthashConfig `json:"ethash,omitempty"`
|
||||||
Clique *CliqueConfig `json:"clique,omitempty"`
|
Clique *CliqueConfig `json:"clique,omitempty"`
|
||||||
|
|
||||||
// Checkpoint contract configs
|
|
||||||
CheckpointConfig *CheckpointContractConfig `json:"checkpointContract,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EthashConfig is the consensus engine configs for proof-of-work based sealing.
|
// EthashConfig is the consensus engine configs for proof-of-work based sealing.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue