Skip to content

[WIP] cmd/puppeth: generate Istanbul genesis.json #138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 20 commits into
base: istanbul/develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
c5e38d5
cmd, consensus, eth, ethstats: add protocol interface into consensus …
markya0616 Aug 7, 2017
3c3d649
params: add Istanbul consensus engine config to ChainConfig
markya0616 Apr 13, 2017
8ab94e9
cmd/*: add Istanbul command line flags
bailantaotao Jun 22, 2017
edf2f7b
consensus/istanbul, eth: add Istanbul configuration
bailantaotao Jun 22, 2017
b695dee
node: add an interface to retrieve node key from config
Jun 19, 2017
bcd1819
consensus: add Istanbul consensus engine interface
markya0616 Aug 7, 2017
354d9da
consensus/istanbul: common Istanbul interfaces and types
markya0616 Aug 7, 2017
2701b0d
consensus/istanbul: Istanbul validator set implementation
tailingchen Jun 22, 2017
691efcb
consensus/istanbul: Istanbul core implementation
markya0616 Aug 7, 2017
806d923
consensus/istanbul: add tests for Istanbul core
markya0616 Aug 7, 2017
4884b2c
core/types: add Istanbul specific block hash calculation
bailantaotao Jun 22, 2017
25adb7a
consensus/istanbul: Istanbul consensus backend implementation
markya0616 Aug 7, 2017
5fbeae8
internal/web3ext: add Istanbul JS RPC API
bailantaotao Jun 22, 2017
54e5030
eth, miner: Istanbul consensus integration
markya0616 Aug 7, 2017
98a18ad
cmd/*, core, params: add ottoman testnet
markya0616 Jul 17, 2017
38f82a8
consensus/istanbul: add block lock
markya0616 Aug 7, 2017
0f066fb
consensus/istanbul: implement gossip network
markya0616 Aug 7, 2017
35d36a2
travis: update travis notification url
yutelin Apr 11, 2017
762b82e
cmd/puppeth: generate Istanbul genesis.json
markya0616 Aug 4, 2017
7647535
cmd/puppeth: add istanbul puppeth node info script
markya0616 Aug 4, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,6 @@ script:
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/e09ccdce1048c5e03445
- https://webhooks.gitter.im/e/a513fc5759b168761b82
on_success: change
on_failure: always
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Official golang implementation of the Ethereum protocol.
[![API Reference](
https://camo.githubusercontent.com/915b7be44ada53c290eb157634330494ebe3e30a/68747470733a2f2f676f646f632e6f72672f6769746875622e636f6d2f676f6c616e672f6764646f3f7374617475732e737667
)](https://godoc.org/github.com/ethereum/go-ethereum)
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ethereum/go-ethereum?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/amisbft/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)

Automated builds are available for stable releases and the unstable master branch.
Binary archives are published at https://geth.ethereum.org/downloads/.
Expand Down
4 changes: 4 additions & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ var (
utils.DevModeFlag,
utils.TestnetFlag,
utils.RinkebyFlag,
utils.OttomanFlag,
utils.VMEnableDebugFlag,
utils.NetworkIdFlag,
utils.RPCCORSDomainFlag,
Expand All @@ -112,6 +113,9 @@ var (
utils.GpoPercentileFlag,
utils.ExtraDataFlag,
configFileFlag,
utils.IstanbulRequestTimeoutFlag,
utils.IstanbulBlockPeriodFlag,
utils.IstanbulBlockPauseTimeFlag,
}

rpcFlags = []cli.Flag{
Expand Down
1 change: 0 additions & 1 deletion cmd/geth/misccmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ func version(ctx *cli.Context) error {
fmt.Println("Git Commit:", gitCommit)
}
fmt.Println("Architecture:", runtime.GOARCH)
fmt.Println("Protocol Versions:", eth.ProtocolVersions)
fmt.Println("Network Id:", eth.DefaultConfig.NetworkId)
fmt.Println("Go Version:", runtime.Version())
fmt.Println("Operating System:", runtime.GOOS)
Expand Down
9 changes: 9 additions & 0 deletions cmd/geth/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ var AppHelpFlagGroups = []flagGroup{
utils.NetworkIdFlag,
utils.TestnetFlag,
utils.RinkebyFlag,
utils.OttomanFlag,
utils.DevModeFlag,
utils.SyncModeFlag,
utils.EthStatsURLFlag,
Expand Down Expand Up @@ -204,6 +205,14 @@ var AppHelpFlagGroups = []flagGroup{
{
Name: "MISC",
},
{
Name: "ISTANBUL",
Flags: []cli.Flag{
utils.IstanbulRequestTimeoutFlag,
utils.IstanbulBlockPeriodFlag,
utils.IstanbulBlockPauseTimeFlag,
},
},
}

// byCategory sorts an array of flagGroup by Name in the order
Expand Down
10 changes: 8 additions & 2 deletions cmd/puppeth/module_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ ADD genesis.json /genesis.json
RUN \
echo '/geth init /genesis.json' > geth.sh && \{{if .Unlock}}
echo 'mkdir -p /root/.ethereum/keystore/ && cp /signer.json /root/.ethereum/keystore/' >> geth.sh && \{{end}}
echo $'/geth --networkid {{.NetworkID}} --cache 512 --port {{.Port}} --maxpeers {{.Peers}} {{.LightFlag}} --ethstats \'{{.Ethstats}}\' {{if .BootV4}}--bootnodesv4 {{.BootV4}}{{end}} {{if .BootV5}}--bootnodesv5 {{.BootV5}}{{end}} {{if .Etherbase}}--etherbase {{.Etherbase}} --mine{{end}}{{if .Unlock}}--unlock 0 --password /signer.pass --mine{{end}} --targetgaslimit {{.GasTarget}} --gasprice {{.GasPrice}}' >> geth.sh
echo $'/geth --networkid {{.NetworkID}} --cache 512 --port {{.Port}} --maxpeers {{.Peers}} {{.LightFlag}} --ethstats \'{{.Ethstats}}\' {{if .BootV4}}--bootnodesv4 {{.BootV4}}{{end}} {{if .BootV5}}--bootnodesv5 {{.BootV5}}{{end}} {{if .Etherbase}}--etherbase {{.Etherbase}} --mine{{end}}{{if .Unlock}}--unlock 0 --password /signer.pass --mine{{end}} --targetgaslimit {{.GasTarget}} --gasprice {{.GasPrice}} {{if .NodeKey}}--nodekeyhex {{.NodeKey}} {{.NodeKey}}{{end}}' >> geth.sh

ENTRYPOINT ["/bin/sh", "geth.sh"]
`
Expand All @@ -67,7 +67,8 @@ services:
- STATS_NAME={{.Ethstats}}
- MINER_NAME={{.Etherbase}}
- GAS_TARGET={{.GasTarget}}
- GAS_PRICE={{.GasPrice}}
- GAS_PRICE={{.GasPrice}}{{if .NodeKey}}
- NODE_KEY={{.NodeKey}}{{end}}
logging:
driver: "json-file"
options:
Expand Down Expand Up @@ -107,6 +108,7 @@ func deployNode(client *sshClient, network string, bootv4, bootv5 []string, conf
"GasTarget": uint64(1000000 * config.gasTarget),
"GasPrice": uint64(1000000000 * config.gasPrice),
"Unlock": config.keyJSON != "",
"NodeKey": config.nodeKey,
})
files[filepath.Join(workdir, "Dockerfile")] = dockerfile.Bytes()

Expand All @@ -124,6 +126,7 @@ func deployNode(client *sshClient, network string, bootv4, bootv5 []string, conf
"Etherbase": config.etherbase,
"GasTarget": config.gasTarget,
"GasPrice": config.gasPrice,
"NodeKey": config.nodeKey,
})
files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes()

Expand Down Expand Up @@ -162,6 +165,7 @@ type nodeInfos struct {
keyPass string
gasTarget float64
gasPrice float64
nodeKey string
}

// String implements the stringer interface.
Expand Down Expand Up @@ -194,6 +198,7 @@ func checkNode(client *sshClient, network string, boot bool) (*nodeInfos, error)
lightPeers, _ := strconv.Atoi(infos.envvars["LIGHT_PEERS"])
gasTarget, _ := strconv.ParseFloat(infos.envvars["GAS_TARGET"], 64)
gasPrice, _ := strconv.ParseFloat(infos.envvars["GAS_PRICE"], 64)
nodeKey := infos.envvars["NODE_KEY"]

// Container available, retrieve its node ID and its genesis json
var out []byte
Expand Down Expand Up @@ -233,6 +238,7 @@ func checkNode(client *sshClient, network string, boot bool) (*nodeInfos, error)
keyPass: keyPass,
gasTarget: gasTarget,
gasPrice: gasPrice,
nodeKey: nodeKey,
}
stats.enodeFull = fmt.Sprintf("enode://%s@%s:%d", id, client.address, stats.portFull)
if stats.portLight != 0 {
Expand Down
46 changes: 46 additions & 0 deletions cmd/puppeth/wizard_genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@ import (
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/istanbul"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
)

// makeGenesis creates a new genesis struct based on some user input.
Expand All @@ -49,6 +52,7 @@ func (w *wizard) makeGenesis() {
fmt.Println("Which consensus engine to use? (default = clique)")
fmt.Println(" 1. Ethash - proof-of-work")
fmt.Println(" 2. Clique - proof-of-authority")
fmt.Println(" 3. Istanbul - IBFT")

choice := w.read()
switch {
Expand Down Expand Up @@ -95,6 +99,48 @@ func (w *wizard) makeGenesis() {
copy(genesis.ExtraData[32+i*common.AddressLength:], signer[:])
}

case choice == "3":
// In the case of istanbul, configure the consensus parameters
genesis.Difficulty = big.NewInt(1)
genesis.Mixhash = types.IstanbulDigest
genesis.Config.Istanbul = &params.IstanbulConfig{
ProposerPolicy: uint64(istanbul.DefaultConfig.ProposerPolicy),
Epoch: istanbul.DefaultConfig.Epoch,
}
fmt.Println()
fmt.Println("Select one proposer policy: Round Robin = 0, Sticky = 1 (default = 0)")
genesis.Config.Istanbul.ProposerPolicy = uint64(w.readDefaultInt(0))

// We also need the initial list of signers
fmt.Println()
fmt.Println("Which accounts are allowed to seal? (mandatory at least one)")

var signers []common.Address
for {
if address := w.readAddress(); address != nil {
signers = append(signers, *address)
continue
}
if len(signers) > 0 {
break
}
}
// Sort the signers and embed into the extra-data section
for i := 0; i < len(signers); i++ {
for j := i + 1; j < len(signers); j++ {
if bytes.Compare(signers[i][:], signers[j][:]) > 0 {
signers[i], signers[j] = signers[j], signers[i]
}
}
}

ist := &types.IstanbulExtra{
Validators: signers,
Seal: []byte{},
CommittedSeal: [][]byte{},
}
payload, _ := rlp.EncodeToBytes(&ist)
genesis.ExtraData = append(bytes.Repeat([]byte{0x00}, 32), payload...)
default:
log.Crit("Invalid consensus engine choice", "choice", choice)
}
Expand Down
4 changes: 4 additions & 0 deletions cmd/puppeth/wizard_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ func (w *wizard) deployNode(boot bool) {
return
}
}
} else if w.conf.genesis.Config.Istanbul != nil {
fmt.Println()
fmt.Println("Please paste the node key:")
infos.nodeKey = w.readString()
}
// Establish the gas dynamics to be enforced by the signer
fmt.Println()
Expand Down
52 changes: 50 additions & 2 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ var (
}
NetworkIdFlag = cli.Uint64Flag{
Name: "networkid",
Usage: "Network identifier (integer, 1=Frontier, 2=Morden (disused), 3=Ropsten, 4=Rinkeby)",
Usage: "Network identifier (integer, 1=Frontier, 2=Morden (disused), 3=Ropsten, 4=Rinkeby, 5=Ottoman)",
Value: eth.DefaultConfig.NetworkId,
}
TestnetFlag = cli.BoolFlag{
Expand All @@ -136,6 +136,10 @@ var (
Name: "rinkeby",
Usage: "Rinkeby network: pre-configured proof-of-authority test network",
}
OttomanFlag = cli.BoolFlag{
Name: "ottoman",
Usage: "Ottoman network: pre-configured istanbul bft test network",
}
DevModeFlag = cli.BoolFlag{
Name: "dev",
Usage: "Developer mode: pre-configured private network with several debugging flags",
Expand Down Expand Up @@ -486,6 +490,23 @@ var (
Usage: "Minimum POW accepted",
Value: whisper.DefaultMinimumPoW,
}

// Istanbul settings
IstanbulRequestTimeoutFlag = cli.Uint64Flag{
Name: "istanbul.requesttimeout",
Usage: "Timeout for each Istanbul round in milliseconds",
Value: eth.DefaultConfig.Istanbul.RequestTimeout,
}
IstanbulBlockPeriodFlag = cli.Uint64Flag{
Name: "istanbul.blockperiod",
Usage: "Default minimum difference between two consecutive block's timestamps in seconds",
Value: eth.DefaultConfig.Istanbul.BlockPeriod,
}
IstanbulBlockPauseTimeFlag = cli.Uint64Flag{
Name: "istanbul.blockpausetime",
Usage: "Pause time when zero tx in previous block, values should be larger than istanbul.blockperiod",
Value: eth.DefaultConfig.Istanbul.BlockPauseTime,
}
)

// MakeDataDir retrieves the currently requested data directory, terminating
Expand All @@ -499,6 +520,9 @@ func MakeDataDir(ctx *cli.Context) string {
if ctx.GlobalBool(RinkebyFlag.Name) {
return filepath.Join(path, "rinkeby")
}
if ctx.GlobalBool(OttomanFlag.Name) {
return filepath.Join(path, "ottoman")
}
return path
}
Fatalf("Cannot determine default data directory, please set manually (--datadir)")
Expand Down Expand Up @@ -553,6 +577,8 @@ func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) {
urls = params.TestnetBootnodes
case ctx.GlobalBool(RinkebyFlag.Name):
urls = params.RinkebyBootnodes
case ctx.GlobalBool(OttomanFlag.Name):
urls = params.OttomanBootnodes
}

cfg.BootstrapNodes = make([]*discover.Node, 0, len(urls))
Expand Down Expand Up @@ -822,6 +848,8 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "testnet")
case ctx.GlobalBool(RinkebyFlag.Name):
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "rinkeby")
case ctx.GlobalBool(OttomanFlag.Name):
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "ottoman")
}

if ctx.GlobalIsSet(KeyStoreDirFlag.Name) {
Expand Down Expand Up @@ -898,6 +926,18 @@ func setEthash(ctx *cli.Context, cfg *eth.Config) {
}
}

func setIstanbul(ctx *cli.Context, cfg *eth.Config) {
if ctx.GlobalIsSet(IstanbulRequestTimeoutFlag.Name) {
cfg.Istanbul.RequestTimeout = ctx.GlobalUint64(IstanbulRequestTimeoutFlag.Name)
}
if ctx.GlobalIsSet(IstanbulBlockPeriodFlag.Name) {
cfg.Istanbul.BlockPeriod = ctx.GlobalUint64(IstanbulBlockPeriodFlag.Name)
}
if ctx.GlobalIsSet(IstanbulBlockPauseTimeFlag.Name) {
cfg.Istanbul.BlockPauseTime = ctx.GlobalUint64(IstanbulBlockPauseTimeFlag.Name)
}
}

func checkExclusive(ctx *cli.Context, flags ...cli.Flag) {
set := make([]string, 0, 1)
for _, flag := range flags {
Expand All @@ -923,14 +963,15 @@ func SetShhConfig(ctx *cli.Context, stack *node.Node, cfg *whisper.Config) {
// SetEthConfig applies eth-related command line flags to the config.
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
// Avoid conflicting network flags
checkExclusive(ctx, DevModeFlag, TestnetFlag, RinkebyFlag)
checkExclusive(ctx, DevModeFlag, TestnetFlag, RinkebyFlag, OttomanFlag)
checkExclusive(ctx, FastSyncFlag, LightModeFlag, SyncModeFlag)

ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
setEtherbase(ctx, ks, cfg)
setGPO(ctx, &cfg.GPO)
setTxPool(ctx, &cfg.TxPool)
setEthash(ctx, cfg)
setIstanbul(ctx, cfg)

switch {
case ctx.GlobalIsSet(SyncModeFlag.Name):
Expand Down Expand Up @@ -988,6 +1029,11 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
cfg.NetworkId = 4
}
cfg.Genesis = core.DefaultRinkebyGenesisBlock()
case ctx.GlobalBool(OttomanFlag.Name):
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 5
}
cfg.Genesis = core.DefaultOttomanGenesisBlock()
case ctx.GlobalBool(DevModeFlag.Name):
cfg.Genesis = core.DevGenesisBlock()
if !ctx.GlobalIsSet(GasPriceFlag.Name) {
Expand Down Expand Up @@ -1080,6 +1126,8 @@ func MakeGenesis(ctx *cli.Context) *core.Genesis {
genesis = core.DefaultTestnetGenesisBlock()
case ctx.GlobalBool(RinkebyFlag.Name):
genesis = core.DefaultRinkebyGenesisBlock()
case ctx.GlobalBool(OttomanFlag.Name):
genesis = core.DefaultOttomanGenesisBlock()
case ctx.GlobalBool(DevModeFlag.Name):
genesis = core.DevGenesisBlock()
}
Expand Down
5 changes: 5 additions & 0 deletions consensus/clique/clique.go
Original file line number Diff line number Diff line change
Expand Up @@ -654,3 +654,8 @@ func (c *Clique) APIs(chain consensus.ChainReader) []rpc.API {
Public: false,
}}
}

// Protocol implements consensus.Engine.Protocol
func (c *Clique) Protocol() consensus.Protocol {
return consensus.EthProtocol
}
24 changes: 24 additions & 0 deletions consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
)
Expand Down Expand Up @@ -90,6 +91,18 @@ type Engine interface {

// APIs returns the RPC APIs this consensus engine provides.
APIs(chain ChainReader) []rpc.API

// Protocol returns the protocol for this consensus
Protocol() Protocol
}

// Handler should be implemented is the consensus needs to handle and send peer's message
type Handler interface {
// HandleMsg handles a message from peer
HandleMsg(address common.Address, data p2p.Msg) (bool, error)

// SetBroadcaster sets the broadcaster to send message to peers
SetBroadcaster(Broadcaster)
}

// PoW is a consensus engine based on proof-of-work.
Expand All @@ -99,3 +112,14 @@ type PoW interface {
// Hashrate returns the current mining hashrate of a PoW consensus engine.
Hashrate() float64
}

// Istanbul is a consensus engine to avoid byzantine failure
type Istanbul interface {
Engine

// Start starts the engine
Start(chain ChainReader, inserter func(types.Blocks) (int, error)) error

// Stop stops the engine
Stop() error
}
5 changes: 5 additions & 0 deletions consensus/ethash/ethash.go
Original file line number Diff line number Diff line change
Expand Up @@ -597,3 +597,8 @@ func (ethash *Ethash) APIs(chain consensus.ChainReader) []rpc.API {
func SeedHash(block uint64) []byte {
return seedHash(block)
}

// Protocol implements consensus.Engine.Protocol
func (ethash *Ethash) Protocol() consensus.Protocol {
return consensus.EthProtocol
}
Loading