diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index db226c73d823..ac594ef4f920 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -2146,7 +2146,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh if err != nil { Fatalf("%v", err) } - engine, err := ethconfig.CreateConsensusEngine(config, chainDb) + engine, err := ethconfig.CreateDefaultConsensusEngine(config, chainDb) if err != nil { Fatalf("%v", err) } diff --git a/core/txpool/legacypool/legacypool_qng.go b/core/txpool/legacypool/legacypool_qng.go new file mode 100644 index 000000000000..041c4036d899 --- /dev/null +++ b/core/txpool/legacypool/legacypool_qng.go @@ -0,0 +1,20 @@ +package legacypool + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +func (pool *LegacyPool) RemoveTx(hash common.Hash, outofbound bool) { + pool.mu.Lock() + defer pool.mu.Unlock() + pool.removeTx(hash, outofbound, true) +} + +func (pool *LegacyPool) All() *lookup { + return pool.all +} + +func (pool *LegacyPool) AddRemotesSync(txs []*types.Transaction) []error { + return pool.addRemotesSync(txs) +} diff --git a/core/txpool/txpool_qng.go b/core/txpool/txpool_qng.go new file mode 100644 index 000000000000..afc2aafebba4 --- /dev/null +++ b/core/txpool/txpool_qng.go @@ -0,0 +1,5 @@ +package txpool + +func (p *TxPool) Subpools() []SubPool { + return p.subpools +} diff --git a/eth/api_backend.go b/eth/api_backend.go index 601e55515857..c63095d16801 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -400,7 +400,7 @@ func (b *EthAPIBackend) CurrentHeader() *types.Header { return b.eth.blockchain.CurrentHeader() } -func (b *EthAPIBackend) Miner() *miner.Miner { +func (b *EthAPIBackend) Miner() miner.IMiner { return b.eth.Miner() } diff --git a/eth/backend.go b/eth/backend.go index c6787870ca02..11cd3be1f2a6 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -89,7 +89,7 @@ type Ethereum struct { APIBackend *EthAPIBackend - miner *miner.Miner + miner miner.IMiner gasPrice *big.Int etherbase common.Address @@ -148,10 +148,11 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if err != nil { return nil, err } - engine, err := ethconfig.CreateConsensusEngine(chainConfig, chainDb) + engine, err := config.ConsensusEngine(chainConfig, chainDb) if err != nil { return nil, err } + eth := &Ethereum{ config: config, merger: consensus.NewMerger(chainDb), @@ -245,7 +246,12 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { return nil, err } - eth.miner = miner.New(eth, &config.Miner, eth.blockchain.Config(), eth.EventMux(), eth.engine, eth.isLocalBlock) + if config.Miner.External == nil { + eth.miner = miner.New(eth, &config.Miner, eth.blockchain.Config(), eth.EventMux(), eth.engine, eth.isLocalBlock) + } else { + eth.miner = config.Miner.External + } + eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData)) eth.APIBackend = &EthAPIBackend{stack.Config().ExtRPCEnabled(), stack.Config().AllowUnprotectedTxs, eth, nil} @@ -468,7 +474,7 @@ func (s *Ethereum) StopMining() { } func (s *Ethereum) IsMining() bool { return s.miner.Mining() } -func (s *Ethereum) Miner() *miner.Miner { return s.miner } +func (s *Ethereum) Miner() miner.IMiner { return s.miner } func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager } func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain } diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index bfb1df3fb15e..6b69ac2a0fd1 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -77,8 +77,11 @@ var Defaults = Config{ RPCEVMTimeout: 5 * time.Second, GPO: FullNodeGPO, RPCTxFeeCap: 1, // 1 ether + ConsensusEngine: CreateDefaultConsensusEngine, } +type CreateConsensusEngine func(*params.ChainConfig, ethdb.Database) (consensus.Engine, error) + //go:generate go run github.com/fjl/gencodec -type Config -formats toml -out gen_config.go // Config contains configuration options for ETH and LES protocols. @@ -168,12 +171,14 @@ type Config struct { // OverrideVerkle (TODO: remove after the fork) OverrideVerkle *uint64 `toml:",omitempty"` + + ConsensusEngine CreateConsensusEngine } // CreateConsensusEngine creates a consensus engine for the given chain config. // Clique is allowed for now to live standalone, but ethash is forbidden and can // only exist on already merged networks. -func CreateConsensusEngine(config *params.ChainConfig, db ethdb.Database) (consensus.Engine, error) { +func CreateDefaultConsensusEngine(config *params.ChainConfig, db ethdb.Database) (consensus.Engine, error) { // If proof-of-authority is requested, set it up if config.Clique != nil { return beacon.New(clique.New(config.Clique, db)), nil diff --git a/expose.go b/expose.go new file mode 100644 index 000000000000..d86ef4d4c87b --- /dev/null +++ b/expose.go @@ -0,0 +1,16 @@ +// Copyright (c) 2017-2022 The qitmeer developers + +package ethereum + +import ( + "github.com/ethereum/go-ethereum/internal/flags" + "github.com/ethereum/go-ethereum/internal/web3ext" + "github.com/urfave/cli/v2" + "math/big" +) + +var Modules = web3ext.Modules + +func GlobalBig(ctx *cli.Context, name string) *big.Int { + return flags.GlobalBig(ctx, name) +} diff --git a/les/client.go b/les/client.go index be5e9fd5641d..a5aff7376ff6 100644 --- a/les/client.go +++ b/les/client.go @@ -103,7 +103,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*LightEthereum, error) { if _, isCompat := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !isCompat { return nil, genesisErr } - engine, err := ethconfig.CreateConsensusEngine(chainConfig, chainDb) + engine, err := ethconfig.CreateDefaultConsensusEngine(chainConfig, chainDb) if err != nil { return nil, err } diff --git a/miner/miner.go b/miner/miner.go index b7273948f5e7..d947098bbeef 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -51,6 +51,7 @@ type Config struct { GasCeil uint64 // Target gas ceiling for mined blocks. GasPrice *big.Int // Minimum gas price for mining a transaction Recommit time.Duration // The time interval for miner to re-create mining work. + External IMiner // External miner NewPayloadTimeout time.Duration // The maximum time allowance for creating a new payload } diff --git a/miner/miner_qng.go b/miner/miner_qng.go new file mode 100644 index 000000000000..dc5cf4ed3482 --- /dev/null +++ b/miner/miner_qng.go @@ -0,0 +1,38 @@ +package miner + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/txpool" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "math/big" + "time" +) + +type IMiner interface { + Start() + Stop() + Close() + Mining() bool + Hashrate() uint64 + SetExtra(extra []byte) error + SetRecommitInterval(interval time.Duration) + Pending() (*types.Block, *state.StateDB) + PendingBlock() *types.Block + PendingBlockAndReceipts() (*types.Block, types.Receipts) + SetEtherbase(addr common.Address) + SetGasCeil(ceil uint64) + SubscribePendingLogs(ch chan<- []*types.Log) event.Subscription + BuildPayload(args *BuildPayloadArgs) (*Payload, error) +} + +type TransactionsByPriceAndNonce interface { + Peek() *txpool.LazyTransaction + Shift() + Pop() +} + +func NewTransactionsByPriceAndNonce(signer types.Signer, txs map[common.Address][]*txpool.LazyTransaction, baseFee *big.Int) TransactionsByPriceAndNonce { + return newTransactionsByPriceAndNonce(signer, txs, baseFee) +} diff --git a/params/config.go b/params/config.go index 88ff772a1d5c..3b39041722fb 100644 --- a/params/config.go +++ b/params/config.go @@ -364,6 +364,18 @@ func (c *ChainConfig) Description() string { } banner += fmt.Sprintf("Chain ID: %v (%s)\n", c.ChainID, network) switch { + case IsQngNetwork(c.ChainID): + banner += "Consensus: MeerDAG (proof-of-work)\n" + return QngEIPsBanner(banner, c) + case IsAmanaNetwork(c.ChainID): + banner += "Consensus: Amana (proof-of-authority)\n" + return QngEIPsBanner(banner, c) + case IsFlanaNetwork(c.ChainID): + banner += "Consensus: Flana (rollup)\n" + return QngEIPsBanner(banner, c) + case IsMizanaNetwork(c.ChainID): + banner += "Consensus: Mizana (ZK rollup)\n" + return QngEIPsBanner(banner, c) case c.Ethash != nil: if c.TerminalTotalDifficulty == nil { banner += "Consensus: Ethash (proof-of-work)\n" diff --git a/params/config_qng.go b/params/config_qng.go new file mode 100644 index 000000000000..99ded40db7eb --- /dev/null +++ b/params/config_qng.go @@ -0,0 +1,187 @@ +package params + +import ( + "fmt" + "math/big" +) + +type MeerChainConfig struct { + ChainID *big.Int // chainId identifies the current chain and is used for replay protection +} + +var ( + QngMainnetChainConfig = &MeerChainConfig{ + ChainID: big.NewInt(813), + } + QngTestnetChainConfig = &MeerChainConfig{ + ChainID: big.NewInt(8131), + } + QngMixnetChainConfig = &MeerChainConfig{ + ChainID: big.NewInt(8132), + } + QngPrivnetChainConfig = &MeerChainConfig{ + ChainID: big.NewInt(8133), + } + + AmanaChainConfig = &MeerChainConfig{ + ChainID: big.NewInt(8134), + } + AmanaTestnetChainConfig = &MeerChainConfig{ + ChainID: big.NewInt(81341), + } + AmanaMixnetChainConfig = &MeerChainConfig{ + ChainID: big.NewInt(81342), + } + AmanaPrivnetChainConfig = &MeerChainConfig{ + ChainID: big.NewInt(81343), + } + + FlanaChainConfig = &MeerChainConfig{ + ChainID: big.NewInt(8135), + } + FlanaTestnetChainConfig = &MeerChainConfig{ + ChainID: big.NewInt(81351), + } + FlanaMixnetChainConfig = &MeerChainConfig{ + ChainID: big.NewInt(81352), + } + FlanaPrivnetChainConfig = &MeerChainConfig{ + ChainID: big.NewInt(81353), + } + + MizanaChainConfig = &MeerChainConfig{ + ChainID: big.NewInt(8136), + } + MizanaTestnetChainConfig = &MeerChainConfig{ + ChainID: big.NewInt(81361), + } + MizanaMixnetChainConfig = &MeerChainConfig{ + ChainID: big.NewInt(81362), + } + MizanaPrivnetChainConfig = &MeerChainConfig{ + ChainID: big.NewInt(81363), + } +) + +func init() { + NetworkNames[QngMainnetChainConfig.ChainID.String()] = "qng" + NetworkNames[QngTestnetChainConfig.ChainID.String()] = "qng-test" + NetworkNames[QngMixnetChainConfig.ChainID.String()] = "qng-mix" + NetworkNames[QngPrivnetChainConfig.ChainID.String()] = "qng-priv" + + NetworkNames[AmanaChainConfig.ChainID.String()] = "amana" + NetworkNames[AmanaTestnetChainConfig.ChainID.String()] = "amana-test" + NetworkNames[AmanaMixnetChainConfig.ChainID.String()] = "amana-mix" + NetworkNames[AmanaPrivnetChainConfig.ChainID.String()] = "amana-priv" + + NetworkNames[FlanaChainConfig.ChainID.String()] = "flana" + NetworkNames[FlanaTestnetChainConfig.ChainID.String()] = "flana-test" + NetworkNames[FlanaMixnetChainConfig.ChainID.String()] = "flana-mix" + NetworkNames[FlanaPrivnetChainConfig.ChainID.String()] = "flana-priv" + + NetworkNames[MizanaChainConfig.ChainID.String()] = "mizana" + NetworkNames[MizanaTestnetChainConfig.ChainID.String()] = "mizana-test" + NetworkNames[MizanaMixnetChainConfig.ChainID.String()] = "mizana-mix" + NetworkNames[MizanaPrivnetChainConfig.ChainID.String()] = "mizana-priv" +} + +func IsQngNetwork(chainID *big.Int) bool { + if chainID.Cmp(QngMainnetChainConfig.ChainID) == 0 || + chainID.Cmp(QngTestnetChainConfig.ChainID) == 0 || + chainID.Cmp(QngMixnetChainConfig.ChainID) == 0 || + chainID.Cmp(QngPrivnetChainConfig.ChainID) == 0 { + return true + } + return false +} + +func IsAmanaNetwork(chainID *big.Int) bool { + if chainID.Cmp(AmanaChainConfig.ChainID) == 0 || + chainID.Cmp(AmanaTestnetChainConfig.ChainID) == 0 || + chainID.Cmp(AmanaMixnetChainConfig.ChainID) == 0 || + chainID.Cmp(AmanaPrivnetChainConfig.ChainID) == 0 { + return true + } + return false +} + +func IsFlanaNetwork(chainID *big.Int) bool { + if chainID.Cmp(FlanaChainConfig.ChainID) == 0 || + chainID.Cmp(FlanaTestnetChainConfig.ChainID) == 0 || + chainID.Cmp(FlanaMixnetChainConfig.ChainID) == 0 || + chainID.Cmp(FlanaPrivnetChainConfig.ChainID) == 0 { + return true + } + return false +} + +func IsMizanaNetwork(chainID *big.Int) bool { + if chainID.Cmp(MizanaChainConfig.ChainID) == 0 || + chainID.Cmp(MizanaTestnetChainConfig.ChainID) == 0 || + chainID.Cmp(MizanaMixnetChainConfig.ChainID) == 0 || + chainID.Cmp(MizanaPrivnetChainConfig.ChainID) == 0 { + return true + } + return false +} + +func QngEIPsBanner(banner string, c *ChainConfig) string { + banner += "\n" + + // Create a list of forks with a short description of them. Forks that only + // makes sense for mainnet should be optional at printing to avoid bloating + // the output for testnets and private networks. + banner += "Pre-Merge hard forks (block based):\n" + banner += fmt.Sprintf(" - Homestead: #%-8v (EIP-606 Requires:EIP-2, EIP-7, EIP-8)\n", c.HomesteadBlock) + if c.DAOForkBlock != nil { + banner += fmt.Sprintf(" - DAO Fork: #%-8v (EIP-779 Requires:EIP-606)\n", c.DAOForkBlock) + } + banner += fmt.Sprintf(" - Tangerine Whistle (EIP 150): #%-8v (EIP-608 Requires:EIP-150, EIP-779)\n", c.EIP150Block) + banner += fmt.Sprintf(" - Spurious Dragon/1 (EIP 155): #%-8v (EIP-607 Requires:EIP-155, EIP-160, EIP-161, EIP-170, EIP-608)\n", c.EIP155Block) + banner += fmt.Sprintf(" - Spurious Dragon/2 (EIP 158): #%-8v (EIP-607 Requires:EIP-155, EIP-160, EIP-161, EIP-170, EIP-608)\n", c.EIP155Block) + banner += fmt.Sprintf(" - Byzantium: #%-8v (EIP-609 Requires:EIP-100, EIP-140, EIP-196, EIP-197, EIP-198, EIP-211, EIP-214, EIP-607, EIP-649, EIP-658)\n", c.ByzantiumBlock) + banner += fmt.Sprintf(" - Constantinople: #%-8v (EIP-1013 Requires:EIP-145, EIP-609, EIP-1014, EIP-1052, EIP-1234, EIP-1283)\n", c.ConstantinopleBlock) + banner += fmt.Sprintf(" - Petersburg: #%-8v (EIP-1716 Requires:EIP-1013, EIP-1283)\n", c.PetersburgBlock) + banner += fmt.Sprintf(" - Istanbul: #%-8v (EIP-1679 Requires:EIP-152, EIP-1108, EIP-1344, EIP-1716, EIP-1884, EIP-2028, EIP-2200)\n", c.IstanbulBlock) + if c.MuirGlacierBlock != nil { + banner += fmt.Sprintf(" - Muir Glacier: #%-8v (EIP-2387 Requires:EIP-1679, EIP-2384)\n", c.MuirGlacierBlock) + } + banner += fmt.Sprintf(" - Berlin: #%-8v (EIP-2565 EIP-2929 EIP-2718 EIP-2930 Requires:EIP-198)\n", c.BerlinBlock) + banner += fmt.Sprintf(" - London: #%-8v (EIP-1559 EIP-3198 EIP-3529 EIP-3541 EIP-3554 Requires:EIP-2718, EIP-2930, EIP-2200, EIP-2929, EIP-2930)\n", c.LondonBlock) + if c.ArrowGlacierBlock != nil { + banner += fmt.Sprintf(" - Arrow Glacier: #%-8v (EIP-4345)\n", c.ArrowGlacierBlock) + } + if c.GrayGlacierBlock != nil { + banner += fmt.Sprintf(" - Gray Glacier: #%-8v (EIP-5133)\n", c.GrayGlacierBlock) + } + banner += "\n" + + // Add a special section for the merge as it's non-obvious + if c.TerminalTotalDifficulty == nil { + banner += "The Merge is not yet available for this network!\n" + banner += " - Hard-fork specification: EIP-3675 EIP-4399 Requires:EIP-2124\n" + } else { + banner += "Merge configured:\n" + banner += " - Hard-fork specification: EIP-3675 EIP-4399 Requires:EIP-2124\n" + banner += fmt.Sprintf(" - Network known to be merged: %v\n", c.TerminalTotalDifficultyPassed) + banner += fmt.Sprintf(" - Total terminal difficulty: %v\n", c.TerminalTotalDifficulty) + if c.MergeNetsplitBlock != nil { + banner += fmt.Sprintf(" - Merge netsplit block: #%-8v\n", c.MergeNetsplitBlock) + } + } + banner += "\n" + + // Create a list of forks post-merge + banner += "Post-Merge hard forks (timestamp based):\n" + if c.ShanghaiTime != nil { + banner += fmt.Sprintf(" - Shanghai: @%-10v (EIP-3651 EIP-3855 EIP-3860 EIP-4895 EIP-6049 Requires:EIP-2929, EIP-170)\n", *c.ShanghaiTime) + } + if c.CancunTime != nil { + banner += fmt.Sprintf(" - Cancun: @%-10v\n", *c.CancunTime) + } + if c.PragueTime != nil { + banner += fmt.Sprintf(" - Prague: @%-10v\n", *c.PragueTime) + } + + return banner +}