miner/stress/ethash¶
| Source (upstream pre-purge) | Current | |
|---|---|---|
| File | miner/stress/ethash/main.go |
main.go |
| Symbol | (entire file) |
(entire file) |
| Ref | dde2da0ef~1 |
etc/v1.17.3-full-node |
Standalone stress test: spins up 4 PoW nodes with ModeFake, interconnects them, starts mining, and bombards with transactions. Adapted from pre-purge3 with updated log API, TxPool.Add, legacypool.DefaultConfig, and minimal PoW genesis.
3-way merge — purge → getc ← upstream¶
pre-purgecore-geth≈ adapted (origin inferred by similarity)fork-only
// Copyright 2018 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
// This file contains a miner stress test based on the Ethash consensus engine.
package main
import (
"crypto/ecdsa"
"math/big"
"math/rand"
"os"
"os/signal"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/fdlimit"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/txpool/legacypool"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/eth/ethconfig"
"github.com/ethereum/go-ethereum/internal/version"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/miner"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/params"
)
func main() {
glogger := log.NewGlogHandler(log.NewTerminalHandler(os.Stderr, true))
glogger.Verbosity(log.LevelInfo)
log.SetDefault(log.NewLogger(glogger))
fdlimit.Raise(2048)
// Generate a batch of accounts to seal and fund with
faucets := make([]*ecdsa.PrivateKey, 128)
for i := 0; i < len(faucets); i++ {
faucets[i], _ = crypto.GenerateKey()
}
// Create an Ethash network
genesis := makeGenesis(faucets)
// Handle interrupts.
interruptCh := make(chan os.Signal, 5)
signal.Notify(interruptCh, os.Interrupt)
var (
stacks []*node.Node
nodes []*eth.Ethereum
enodes []*enode.Node
)
for i := 0; i < 4; i++ {
// Start the node and wait until it's up
stack, ethBackend, err := makeMiner(genesis)
if err != nil {
panic(err)
}
defer stack.Close()
for stack.Server().NodeInfo().Ports.Listener == 0 {
time.Sleep(250 * time.Millisecond)
}
// Connect the node to all the previous ones
for _, n := range enodes {
stack.Server().AddPeer(n)
}
// Start tracking the node and its enode
stacks = append(stacks, stack)
nodes = append(nodes, ethBackend)
enodes = append(enodes, stack.Server().Self())
}
// Iterate over all the nodes and start mining
time.Sleep(3 * time.Second)
for _, node := range nodes {
node.SetEtherbase(common.Address{1})
if err := node.StartMining(1); err != nil {
panic(err)
}
}
time.Sleep(3 * time.Second)
// Start injecting transactions from the faucets like crazy
nonces := make([]uint64, len(faucets))
for {
// Stop when interrupted.
select {
case <-interruptCh:
for _, node := range stacks {
node.Close()
}
return
default:
}
// Pick a random mining node
index := rand.Intn(len(faucets))
backend := nodes[index%len(nodes)]
// Create a self transaction and inject into the pool
tx, err := types.SignTx(types.NewTransaction(nonces[index], crypto.PubkeyToAddress(faucets[index].PublicKey), new(big.Int), 21000, big.NewInt(100000000000+rand.Int63n(65536)), nil), types.HomesteadSigner{}, faucets[index])
if err != nil {
panic(err)
}
if errs := backend.TxPool().Add([]*types.Transaction{tx}, true); errs[0] != nil {
panic(errs[0])
}
nonces[index]++
// Wait if we're too saturated
if pend, _ := backend.TxPool().Stats(); pend > 2048 {
time.Sleep(100 * time.Millisecond)
}
}
}
// makeGenesis creates a custom Ethash genesis block based on some pre-defined
// faucet accounts.
func makeGenesis(faucets []*ecdsa.PrivateKey) *core.Genesis {
genesis := &core.Genesis{
Config: ¶ms.ChainConfig{
ChainID: big.NewInt(18),
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
ByzantiumBlock: big.NewInt(0),
ConstantinopleBlock: big.NewInt(0),
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
Ethash: new(params.EthashConfig),
},
Difficulty: params.MinimumDifficulty,
GasLimit: 25000000,
Alloc: core.GenesisAlloc{},
}
for _, faucet := range faucets {
genesis.Alloc[crypto.PubkeyToAddress(faucet.PublicKey)] = core.GenesisAccount{
Balance: new(big.Int).Exp(big.NewInt(2), big.NewInt(128), nil),
}
}
return genesis
}
func makeMiner(genesis *core.Genesis) (*node.Node, *eth.Ethereum, error) {
// Define the basic configurations for the Ethereum node
datadir, _ := os.MkdirTemp("", "")
config := &node.Config{
Name: "geth",
Version: version.WithMeta,
DataDir: datadir,
P2P: p2p.Config{
ListenAddr: "0.0.0.0:0",
NoDiscovery: true,
MaxPeers: 25,
},
UseLightweightKDF: true,
}
// Create the node and configure a full Ethereum node on it
stack, err := node.New(config)
if err != nil {
return nil, nil, err
}
ethBackend, err := eth.New(stack, ðconfig.Config{
Genesis: genesis,
NetworkId: genesis.Config.ChainID.Uint64(),
SyncMode: ethconfig.FullSync,
DatabaseCache: 256,
DatabaseHandles: 256,
TxPool: legacypool.DefaultConfig,
GPO: ethconfig.Defaults.GPO,
Ethash: ethash.Config{
PowMode: ethash.ModeFake,
},
Miner: miner.Config{
Etherbase: common.Address{1},
GasCeil: genesis.GasLimit * 11 / 10,
GasPrice: big.NewInt(1),
Recommit: time.Second,
},
})
if err != nil {
return nil, nil, err
}
err = stack.Start()
return stack, ethBackend, err
}
core-geth validation — +35 -26
| | | |---|---| | File | [`main.go`](https://github.com/etclabscore/core-geth/blob/v1.12.20/miner/stress/ethash/main.go) | | Symbol | `` | | Ref | `v1.12.20` |--- a/core-geth/miner/stress/ethash/main.go
+++ b/etc/miner/stress/ethash/main.go
@@ -25,28 +25,28 @@
"os/signal"
"time"
- "golang.org/x/exp/slog"
-
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/fdlimit"
"github.com/ethereum/go-ethereum/consensus/ethash"
+ "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/txpool/legacypool"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/eth/downloader"
"github.com/ethereum/go-ethereum/eth/ethconfig"
+ "github.com/ethereum/go-ethereum/internal/version"
+ "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/miner"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/params/types/genesisT"
- "github.com/ethereum/go-ethereum/params/vars"
)
func main() {
- slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelInfo})))
+ glogger := log.NewGlogHandler(log.NewTerminalHandler(os.Stderr, true))
+ glogger.Verbosity(log.LevelInfo)
+ log.SetDefault(log.NewLogger(glogger))
fdlimit.Raise(2048)
// Generate a batch of accounts to seal and fund with
@@ -54,9 +54,6 @@
for i := 0; i < len(faucets); i++ {
faucets[i], _ = crypto.GenerateKey()
}
- // Pre-generate the ethash mining DAG so we don't race
- ethash.MakeDataset(1, ethash.CalcEpochLength(0, nil), ethconfig.Defaults.Ethash.DatasetDir)
-
// Create an Ethash network
genesis := makeGenesis(faucets)
@@ -93,6 +90,7 @@
// Iterate over all the nodes and start mining
time.Sleep(3 * time.Second)
for _, node := range nodes {
+ node.SetEtherbase(common.Address{1})
if err := node.StartMining(1); err != nil {
panic(err)
}
@@ -121,8 +119,8 @@
if err != nil {
panic(err)
}
- if err := backend.TxPool().Add([]*types.Transaction{tx}, true, false); err != nil {
- panic(err)
+ if errs := backend.TxPool().Add([]*types.Transaction{tx}, true); errs[0] != nil {
+ panic(errs[0])
}
nonces[index]++
@@ -135,30 +133,39 @@
// makeGenesis creates a custom Ethash genesis block based on some pre-defined
// faucet accounts.
-func makeGenesis(faucets []*ecdsa.PrivateKey) *genesisT.Genesis {
- genesis := params.DefaultGenesisBlock()
- genesis.Difficulty = vars.MinimumDifficulty
- genesis.GasLimit = 25000000
-
- genesis.SetChainID(big.NewInt(18))
- // genesis.Config.EIP150Hash = common.Hash{}
-
- genesis.Alloc = genesisT.GenesisAlloc{}
+func makeGenesis(faucets []*ecdsa.PrivateKey) *core.Genesis {
+ genesis := &core.Genesis{
+ Config: ¶ms.ChainConfig{
+ ChainID: big.NewInt(18),
+ HomesteadBlock: big.NewInt(0),
+ EIP150Block: big.NewInt(0),
+ EIP155Block: big.NewInt(0),
+ EIP158Block: big.NewInt(0),
+ ByzantiumBlock: big.NewInt(0),
+ ConstantinopleBlock: big.NewInt(0),
+ PetersburgBlock: big.NewInt(0),
+ IstanbulBlock: big.NewInt(0),
+ Ethash: new(params.EthashConfig),
+ },
+ Difficulty: params.MinimumDifficulty,
+ GasLimit: 25000000,
+ Alloc: core.GenesisAlloc{},
+ }
for _, faucet := range faucets {
- genesis.Alloc[crypto.PubkeyToAddress(faucet.PublicKey)] = genesisT.GenesisAccount{
+ genesis.Alloc[crypto.PubkeyToAddress(faucet.PublicKey)] = core.GenesisAccount{
Balance: new(big.Int).Exp(big.NewInt(2), big.NewInt(128), nil),
}
}
return genesis
}
-func makeMiner(genesis *genesisT.Genesis) (*node.Node, *eth.Ethereum, error) {
+func makeMiner(genesis *core.Genesis) (*node.Node, *eth.Ethereum, error) {
// Define the basic configurations for the Ethereum node
datadir, _ := os.MkdirTemp("", "")
config := &node.Config{
Name: "geth",
- Version: params.Version,
+ Version: version.WithMeta,
DataDir: datadir,
P2P: p2p.Config{
ListenAddr: "0.0.0.0:0",
@@ -174,13 +181,15 @@
}
ethBackend, err := eth.New(stack, ðconfig.Config{
Genesis: genesis,
- NetworkId: genesis.Config.GetChainID().Uint64(),
- SyncMode: downloader.FullSync,
+ NetworkId: genesis.Config.ChainID.Uint64(),
+ SyncMode: ethconfig.FullSync,
DatabaseCache: 256,
DatabaseHandles: 256,
TxPool: legacypool.DefaultConfig,
GPO: ethconfig.Defaults.GPO,
- Ethash: ethconfig.Defaults.Ethash,
+ Ethash: ethash.Config{
+ PowMode: ethash.ModeFake,
+ },
Miner: miner.Config{
Etherbase: common.Address{1},
GasCeil: genesis.GasLimit * 11 / 10,