Skip to content

Commit

Permalink
cmd, eth, les, light: move checkpoint config to config file
Browse files Browse the repository at this point in the history
  • Loading branch information
rjl493456442 committed Jun 25, 2019
1 parent 40e7199 commit 15d322f
Show file tree
Hide file tree
Showing 19 changed files with 117 additions and 228 deletions.
137 changes: 0 additions & 137 deletions cmd/puppeth/wizard_genesis.go
Expand Up @@ -27,17 +27,10 @@ import (
"net/http"
"os"
"path/filepath"
"strings"
"time"

"github.com/ethereum/go-ethereum/accounts/abi"
"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/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/params"
)
Expand Down Expand Up @@ -140,65 +133,6 @@ func (w *wizard) makeGenesis() {
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))))

// 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 = &params.CheckpointContractConfig{
Address: address,
Signers: signers,
Threshold: threshold,
}
}
// All done, store the genesis and flush to disk
log.Info("Configured new genesis block")

Expand Down Expand Up @@ -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)
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, "", " ")
fmt.Printf("Chain configuration updated:\n\n%s\n", out)

Expand Down
12 changes: 12 additions & 0 deletions cmd/utils/flags.go
Expand Up @@ -1451,16 +1451,28 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
cfg.NetworkId = 3
}
cfg.Genesis = core.DefaultTestnetGenesisBlock()
if cfg.Checkpoint == nil {
cfg.Checkpoint = params.TestnetTrustedCheckpoint
}
case ctx.GlobalBool(RinkebyFlag.Name):
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 4
}
cfg.Genesis = core.DefaultRinkebyGenesisBlock()
if cfg.Checkpoint == nil {
cfg.Checkpoint = params.RinkebyTrustedCheckpoint
}
if cfg.CheckpointConfig == nil {
cfg.CheckpointConfig = params.RinkebyCheckpointConfig // Enable checkpoint contract for rinkeby testnet.
}
case ctx.GlobalBool(GoerliFlag.Name):
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 5
}
cfg.Genesis = core.DefaultGoerliGenesisBlock()
if cfg.Checkpoint == nil {
cfg.Checkpoint = params.GoerliTrustedCheckpoint
}
case ctx.GlobalBool(DeveloperFlag.Name):
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 1337
Expand Down
2 changes: 1 addition & 1 deletion eth/backend.go
Expand Up @@ -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
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
}
eth.miner = miner.New(eth, &config.Miner, chainConfig, eth.EventMux(), eth.engine, eth.isLocalBlock)
Expand Down
7 changes: 7 additions & 0 deletions eth/config.go
Expand Up @@ -60,6 +60,7 @@ var DefaultConfig = Config{
Blocks: 20,
Percentile: 60,
},
Checkpoint: params.MainnetTrustedCheckpoint,
}

func init() {
Expand Down Expand Up @@ -149,4 +150,10 @@ type Config struct {

// RPCGasCap is the global gas cap for eth-call variants.
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
}
19 changes: 19 additions & 0 deletions eth/gen_config.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions eth/handler.go
Expand Up @@ -106,7 +106,7 @@ type ProtocolManager struct {

// NewProtocolManager returns a new Ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
// 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
manager := &ProtocolManager{
networkID: networkID,
Expand All @@ -126,7 +126,7 @@ func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, ne
manager.fastSync = uint32(1)
}
// 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.checkpointHash = checkpoint.SectionHead
}
Expand Down
15 changes: 7 additions & 8 deletions eth/handler_test.go
Expand Up @@ -504,31 +504,30 @@ func testCheckpointChallenge(t *testing.T, syncmode downloader.SyncMode, checkpo

// Initialize a chain and generate a fake CHT if checkpointing is enabled
var (
db = rawdb.NewMemoryDatabase()
config = new(params.ChainConfig)
genesis = (&core.Genesis{Config: config}).MustCommit(db)
db = rawdb.NewMemoryDatabase()
config = new(params.ChainConfig)
)
(&core.Genesis{Config: config}).MustCommit(db) // Commit genesis block
// If checkpointing is enabled, create and inject a fake CHT and the corresponding
// chllenge response.
var response *types.Header
var cht *params.TrustedCheckpoint
if checkpoint {
index := uint64(rand.Intn(500))
number := (index+1)*params.CHTFrequency - 1
response = &types.Header{Number: big.NewInt(int64(number)), Extra: []byte("valid")}

cht := &params.TrustedCheckpoint{
cht = &params.TrustedCheckpoint{
SectionIndex: index,
SectionHead: response.Hash(),
}
params.TrustedCheckpoints[genesis.Hash()] = cht
defer delete(params.TrustedCheckpoints, genesis.Hash())
}
// Create a checkpoint aware protocol manager
blockchain, err := core.NewBlockChain(db, nil, config, ethash.NewFaker(), vm.Config{}, nil)
if err != nil {
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 {
t.Fatalf("failed to start test protocol manager: %v", err)
}
Expand Down Expand Up @@ -615,7 +614,7 @@ func testBroadcastBlock(t *testing.T, totalPeers, broadcastExpected int) {
if err != nil {
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 {
t.Fatalf("failed to start test protocol manager: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion eth/helper_test.go
Expand Up @@ -66,7 +66,7 @@ func newTestProtocolManager(mode downloader.SyncMode, blocks int, generator func
if _, err := blockchain.InsertChain(chain); err != nil {
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 {
return nil, nil, err
}
Expand Down
6 changes: 3 additions & 3 deletions les/backend.go
Expand Up @@ -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
// 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
}
// Note: AddChildIndexer starts the update process for the child
Expand All @@ -150,8 +150,8 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) {
}
leth.ApiBackend.gpo = gasprice.NewOracle(leth.ApiBackend, gpoParams)

registrar := newCheckpointRegistrar(chainConfig.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 {
registrar := newCheckpointRegistrar(config.CheckpointConfig, leth.getLocalCheckpoint)
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
}
if leth.protocolManager.isULCEnabled() {
Expand Down

0 comments on commit 15d322f

Please sign in to comment.