diff --git a/cmd/geth/main.go b/cmd/geth/main.go index f55adb144..a726451d4 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -273,6 +273,9 @@ func main() { func prepare(ctx *cli.Context) { // If we're running a known preset, log it for convenience. switch { + case ctx.IsSet(utils.PulseChainFlag.Name): + log.Info("Starting Geth on PulseChain mainnet...") + case ctx.IsSet(utils.RinkebyFlag.Name): log.Info("Starting Geth on Rinkeby testnet...") @@ -282,6 +285,9 @@ func prepare(ctx *cli.Context) { case ctx.IsSet(utils.SepoliaFlag.Name): log.Info("Starting Geth on Sepolia testnet...") + case ctx.IsSet(utils.PulseChainTestnetFlag.Name): + log.Info("Starting Geth on PulseChain testnet...") + case ctx.IsSet(utils.DeveloperFlag.Name): log.Info("Starting Geth in ephemeral dev mode...") log.Warn(`You are running Geth in --dev mode. Please note the following: @@ -310,7 +316,7 @@ func prepare(ctx *cli.Context) { !ctx.IsSet(utils.RinkebyFlag.Name) && !ctx.IsSet(utils.GoerliFlag.Name) && !ctx.IsSet(utils.DeveloperFlag.Name) { - // Nope, we're really on mainnet. Bump that cache up! + // Nope, we're really on mainnet or PulseChain. Bump that cache up! log.Info("Bumping default cache on mainnet", "provided", ctx.Int(utils.CacheFlag.Name), "updated", 4096) ctx.Set(utils.CacheFlag.Name, strconv.Itoa(4096)) } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 08de71ee8..e436d556d 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -142,6 +142,10 @@ var ( Usage: "Ethereum mainnet", Category: flags.EthCategory, } + PulseChainFlag = &cli.BoolFlag{ + Name: "pulsechain", + Usage: "PulseChain mainnet", + } RinkebyFlag = &cli.BoolFlag{ Name: "rinkeby", Usage: "Rinkeby network: pre-configured proof-of-authority test network", @@ -157,6 +161,10 @@ var ( Usage: "Sepolia network: pre-configured proof-of-work test network", Category: flags.EthCategory, } + PulseChainTestnetFlag = &cli.BoolFlag{ + Name: "pulsechain-testnet", + Usage: "PulseChain testnet", + } // Dev mode DeveloperFlag = &cli.BoolFlag{ @@ -1002,9 +1010,13 @@ var ( RinkebyFlag, GoerliFlag, SepoliaFlag, + PulseChainTestnetFlag, } // NetworkFlags is the flag group of all built-in supported networks. - NetworkFlags = append([]cli.Flag{MainnetFlag}, TestnetFlags...) + NetworkFlags = append([]cli.Flag{ + MainnetFlag, + PulseChainFlag, + }, TestnetFlags...) // DatabasePathFlags is the flag group of all database path flags. DatabasePathFlags = []cli.Flag{ @@ -1026,6 +1038,9 @@ func init() { // then a subdirectory of the specified datadir will be used. func MakeDataDir(ctx *cli.Context) string { if path := ctx.String(DataDirFlag.Name); path != "" { + if ctx.Bool(PulseChainFlag.Name) { + return filepath.Join(path, "pulsechain") + } if ctx.Bool(RinkebyFlag.Name) { return filepath.Join(path, "rinkeby") } @@ -1035,6 +1050,9 @@ func MakeDataDir(ctx *cli.Context) string { if ctx.Bool(SepoliaFlag.Name) { return filepath.Join(path, "sepolia") } + if ctx.Bool(PulseChainTestnetFlag.Name) { + return filepath.Join(path, "pulsechain-testnet") + } return path } Fatalf("Cannot determine default data directory, please set manually (--datadir)") @@ -1081,12 +1099,16 @@ func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) { switch { case ctx.IsSet(BootnodesFlag.Name): urls = SplitAndTrim(ctx.String(BootnodesFlag.Name)) + case ctx.Bool(PulseChainFlag.Name): + urls = params.PulseChainBootnodes case ctx.Bool(SepoliaFlag.Name): urls = params.SepoliaBootnodes case ctx.Bool(RinkebyFlag.Name): urls = params.RinkebyBootnodes case ctx.Bool(GoerliFlag.Name): urls = params.GoerliBootnodes + case ctx.Bool(PulseChainTestnetFlag.Name): + urls = params.PulseChainTestnetBootnodes } // don't apply defaults if BootstrapNodes is already set @@ -1532,12 +1554,16 @@ func SetDataDir(ctx *cli.Context, cfg *node.Config) { cfg.DataDir = ctx.String(DataDirFlag.Name) case ctx.Bool(DeveloperFlag.Name): cfg.DataDir = "" // unless explicitly requested, use memory databases + case ctx.Bool(PulseChainFlag.Name) && cfg.DataDir == node.DefaultDataDir(): + cfg.DataDir = filepath.Join(node.DefaultDataDir(), "pulsechain") case ctx.Bool(RinkebyFlag.Name) && cfg.DataDir == node.DefaultDataDir(): cfg.DataDir = filepath.Join(node.DefaultDataDir(), "rinkeby") case ctx.Bool(GoerliFlag.Name) && cfg.DataDir == node.DefaultDataDir(): cfg.DataDir = filepath.Join(node.DefaultDataDir(), "goerli") case ctx.Bool(SepoliaFlag.Name) && cfg.DataDir == node.DefaultDataDir(): cfg.DataDir = filepath.Join(node.DefaultDataDir(), "sepolia") + case ctx.Bool(PulseChainTestnetFlag.Name) && cfg.DataDir == node.DefaultDataDir(): + cfg.DataDir = filepath.Join(node.DefaultDataDir(), "pulsechain-testnet") } } @@ -1728,7 +1754,7 @@ func CheckExclusive(ctx *cli.Context, args ...interface{}) { // SetEthConfig applies eth-related command line flags to the config. func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { // Avoid conflicting network flags - CheckExclusive(ctx, MainnetFlag, DeveloperFlag, RinkebyFlag, GoerliFlag, SepoliaFlag) + CheckExclusive(ctx, MainnetFlag, PulseChainFlag, DeveloperFlag, RinkebyFlag, GoerliFlag, SepoliaFlag, PulseChainTestnetFlag) CheckExclusive(ctx, LightServeFlag, SyncModeFlag, "light") CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer if ctx.String(GCModeFlag.Name) == "archive" && ctx.Uint64(TxLookupLimitFlag.Name) != 0 { @@ -1866,6 +1892,12 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { } cfg.Genesis = core.DefaultGenesisBlock() SetDNSDiscoveryDefaults(cfg, params.MainnetGenesisHash) + case ctx.Bool(PulseChainFlag.Name): + if !ctx.IsSet(NetworkIdFlag.Name) { + cfg.NetworkId = 369 + } + cfg.Genesis = core.DefaultPulseChainGenesisBlock() + SetDNSDiscoveryDefaults(cfg, params.MainnetGenesisHash) case ctx.Bool(SepoliaFlag.Name): if !ctx.IsSet(NetworkIdFlag.Name) { cfg.NetworkId = 11155111 @@ -1894,6 +1926,12 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { } cfg.Genesis = core.DefaultGoerliGenesisBlock() SetDNSDiscoveryDefaults(cfg, params.GoerliGenesisHash) + case ctx.Bool(PulseChainTestnetFlag.Name): + if !ctx.IsSet(NetworkIdFlag.Name) { + cfg.NetworkId = 942 + } + cfg.Genesis = core.DefaultPulseChainTestnetGenesisBlock() + SetDNSDiscoveryDefaults(cfg, params.MainnetGenesisHash) case ctx.Bool(DeveloperFlag.Name): if !ctx.IsSet(NetworkIdFlag.Name) { cfg.NetworkId = 1337 @@ -2208,12 +2246,16 @@ func MakeGenesis(ctx *cli.Context) *core.Genesis { switch { case ctx.Bool(MainnetFlag.Name): genesis = core.DefaultGenesisBlock() + case ctx.Bool(PulseChainFlag.Name): + genesis = core.DefaultPulseChainGenesisBlock() case ctx.Bool(SepoliaFlag.Name): genesis = core.DefaultSepoliaGenesisBlock() case ctx.Bool(RinkebyFlag.Name): genesis = core.DefaultRinkebyGenesisBlock() case ctx.Bool(GoerliFlag.Name): genesis = core.DefaultGoerliGenesisBlock() + case ctx.Bool(PulseChainTestnetFlag.Name): + genesis = core.DefaultPulseChainTestnetGenesisBlock() case ctx.Bool(DeveloperFlag.Name): Fatalf("Developer chains are ephemeral") } diff --git a/core/genesis.go b/core/genesis.go index 269c1486d..f99b7eeb6 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -531,6 +531,18 @@ func DefaultGenesisBlock() *Genesis { } } +// DefaultPulseChainGenesisBlock returns the PulseChain mainnet genesis block. +func DefaultPulseChainGenesisBlock() *Genesis { + return &Genesis{ + Config: params.PulseChainConfig, + Nonce: 66, + ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"), + GasLimit: 5000, + Difficulty: big.NewInt(17179869184), + Alloc: decodePrealloc(mainnetAllocData), + } +} + // DefaultRinkebyGenesisBlock returns the Rinkeby network genesis block. func DefaultRinkebyGenesisBlock() *Genesis { return &Genesis{ @@ -568,6 +580,18 @@ func DefaultSepoliaGenesisBlock() *Genesis { } } +// DefaultPulseChainTestnetGenesisBlock returns the PulseChain testnet genesis block. +func DefaultPulseChainTestnetGenesisBlock() *Genesis { + return &Genesis{ + Config: params.PulseChainTestnetConfig, + Nonce: 66, + ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"), + GasLimit: 5000, + Difficulty: big.NewInt(17179869184), + Alloc: decodePrealloc(mainnetAllocData), + } +} + // DeveloperGenesisBlock returns the 'geth --dev' genesis block. func DeveloperGenesisBlock(period uint64, gasLimit uint64, faucet common.Address) *Genesis { // Override the default period to the user requested one diff --git a/params/bootnodes.go b/params/bootnodes.go index 4ae94cfbd..4ac9baee7 100644 --- a/params/bootnodes.go +++ b/params/bootnodes.go @@ -28,6 +28,14 @@ var MainnetBootnodes = []string{ "enode://4aeb4ab6c14b23e2c4cfdce879c04b0748a20d8e9b59e25ded2a08143e265c6c25936e74cbc8e641e3312ca288673d91f2f93f8e277de3cfa444ecdaaf982052@157.90.35.166:30303", // bootnode-hetzner-fsn } +// PulseChainBootnodes are the enode URLs of the P2P bootstrap nodes running on +// the main PulseChain network. +var PulseChainBootnodes []string // TODO + +// PulseChainTestnetBootnodes are the enode URLs of the P2P bootstrap nodes running on +// the main PulseChain network. +var PulseChainTestnetBootnodes []string // TODO + // SepoliaBootnodes are the enode URLs of the P2P bootstrap nodes running on the // Sepolia test network. var SepoliaBootnodes = []string{