all: core rework for the merge transition (#23761)
* all: work for eth1/2 transtition
* consensus/beacon, eth: change beacon difficulty to 0
* eth: updates
* all: add terminalBlockDifficulty config, fix rebasing issues
* eth: implemented merge interop spec
* internal/ethapi: update to v1.0.0.alpha.2
This commit updates the code to the new spec, moving payloadId into
it's own object. It also fixes an issue with finalizing an empty blockhash.
It also properly sets the basefee
* all: sync polishes, other fixes + refactors
* core, eth: correct semantics for LeavePoW, EnterPoS
* core: fixed rebasing artifacts
* core: light: performance improvements
* core: use keyed field (f)
* core: eth: fix compilation issues + tests
* eth/catalyst: dbetter error codes
* all: move Merger to consensus/, remove reliance on it in bc
* all: renamed EnterPoS and LeavePoW to ReachTDD and FinalizePoS
* core: make mergelogs a function
* core: use InsertChain instead of InsertBlock
* les: drop merger from lightchain object
* consensus: add merger
* core: recoverAncestors in catalyst mode
* core: fix nitpick
* all: removed merger from beacon, use TTD, nitpicks
* consensus: eth: add docstring, removed unnecessary code duplication
* consensus/beacon: better comment
* all: easy to fix nitpicks by karalabe
* consensus/beacon: verify known headers to be sure
* core: comments
* core: eth: don't drop peers who advertise blocks, nitpicks
* core: never add beacon blocks to the future queue
* core: fixed nitpicks
* consensus/beacon: simplify IsTTDReached check
* consensus/beacon: correct IsTTDReached check
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2021-11-26 05:23:02 -06:00
|
|
|
// Copyright 2021 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 for the eth1/2 transition
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/ecdsa"
|
|
|
|
"errors"
|
|
|
|
"io/ioutil"
|
|
|
|
"math/big"
|
|
|
|
"math/rand"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/accounts/keystore"
|
|
|
|
"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/types"
|
|
|
|
"github.com/ethereum/go-ethereum/crypto"
|
|
|
|
"github.com/ethereum/go-ethereum/eth"
|
|
|
|
"github.com/ethereum/go-ethereum/eth/catalyst"
|
|
|
|
"github.com/ethereum/go-ethereum/eth/downloader"
|
|
|
|
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
|
|
|
"github.com/ethereum/go-ethereum/les"
|
|
|
|
"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"
|
|
|
|
)
|
|
|
|
|
|
|
|
type nodetype int
|
|
|
|
|
|
|
|
const (
|
|
|
|
legacyMiningNode nodetype = iota
|
|
|
|
legacyNormalNode
|
|
|
|
eth2MiningNode
|
|
|
|
eth2NormalNode
|
|
|
|
eth2LightClient
|
|
|
|
)
|
|
|
|
|
|
|
|
func (typ nodetype) String() string {
|
|
|
|
switch typ {
|
|
|
|
case legacyMiningNode:
|
|
|
|
return "legacyMiningNode"
|
|
|
|
case legacyNormalNode:
|
|
|
|
return "legacyNormalNode"
|
|
|
|
case eth2MiningNode:
|
|
|
|
return "eth2MiningNode"
|
|
|
|
case eth2NormalNode:
|
|
|
|
return "eth2NormalNode"
|
|
|
|
case eth2LightClient:
|
|
|
|
return "eth2LightClient"
|
|
|
|
default:
|
|
|
|
return "undefined"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
// transitionDifficulty is the target total difficulty for transition
|
|
|
|
transitionDifficulty = new(big.Int).Mul(big.NewInt(20), params.MinimumDifficulty)
|
|
|
|
|
|
|
|
// blockInterval is the time interval for creating a new eth2 block
|
|
|
|
blockInterval = time.Second * 3
|
|
|
|
blockIntervalInt = 3
|
|
|
|
|
|
|
|
// finalizationDist is the block distance for finalizing block
|
|
|
|
finalizationDist = 10
|
|
|
|
)
|
|
|
|
|
|
|
|
type ethNode struct {
|
|
|
|
typ nodetype
|
|
|
|
api *catalyst.ConsensusAPI
|
|
|
|
ethBackend *eth.Ethereum
|
|
|
|
lesBackend *les.LightEthereum
|
|
|
|
stack *node.Node
|
|
|
|
enode *enode.Node
|
|
|
|
}
|
|
|
|
|
|
|
|
func newNode(typ nodetype, genesis *core.Genesis, enodes []*enode.Node) *ethNode {
|
|
|
|
var (
|
|
|
|
err error
|
|
|
|
api *catalyst.ConsensusAPI
|
|
|
|
stack *node.Node
|
|
|
|
ethBackend *eth.Ethereum
|
|
|
|
lesBackend *les.LightEthereum
|
|
|
|
)
|
|
|
|
// Start the node and wait until it's up
|
|
|
|
if typ == eth2LightClient {
|
|
|
|
stack, lesBackend, api, err = makeLightNode(genesis)
|
|
|
|
} else {
|
|
|
|
stack, ethBackend, api, err = makeFullNode(genesis)
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
enode := stack.Server().Self()
|
|
|
|
|
|
|
|
// Inject the signer key and start sealing with it
|
|
|
|
stack.AccountManager().AddBackend(keystore.NewPlaintextKeyStore("beacon-stress"))
|
|
|
|
store := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
|
|
|
|
if _, err := store.NewAccount(""); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return ðNode{
|
|
|
|
typ: typ,
|
|
|
|
api: api,
|
|
|
|
ethBackend: ethBackend,
|
|
|
|
lesBackend: lesBackend,
|
|
|
|
stack: stack,
|
|
|
|
enode: enode,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-03 09:26:28 -06:00
|
|
|
func (n *ethNode) assembleBlock(parentHash common.Hash, parentTimestamp uint64) (*catalyst.ExecutableDataV1, error) {
|
all: core rework for the merge transition (#23761)
* all: work for eth1/2 transtition
* consensus/beacon, eth: change beacon difficulty to 0
* eth: updates
* all: add terminalBlockDifficulty config, fix rebasing issues
* eth: implemented merge interop spec
* internal/ethapi: update to v1.0.0.alpha.2
This commit updates the code to the new spec, moving payloadId into
it's own object. It also fixes an issue with finalizing an empty blockhash.
It also properly sets the basefee
* all: sync polishes, other fixes + refactors
* core, eth: correct semantics for LeavePoW, EnterPoS
* core: fixed rebasing artifacts
* core: light: performance improvements
* core: use keyed field (f)
* core: eth: fix compilation issues + tests
* eth/catalyst: dbetter error codes
* all: move Merger to consensus/, remove reliance on it in bc
* all: renamed EnterPoS and LeavePoW to ReachTDD and FinalizePoS
* core: make mergelogs a function
* core: use InsertChain instead of InsertBlock
* les: drop merger from lightchain object
* consensus: add merger
* core: recoverAncestors in catalyst mode
* core: fix nitpick
* all: removed merger from beacon, use TTD, nitpicks
* consensus: eth: add docstring, removed unnecessary code duplication
* consensus/beacon: better comment
* all: easy to fix nitpicks by karalabe
* consensus/beacon: verify known headers to be sure
* core: comments
* core: eth: don't drop peers who advertise blocks, nitpicks
* core: never add beacon blocks to the future queue
* core: fixed nitpicks
* consensus/beacon: simplify IsTTDReached check
* consensus/beacon: correct IsTTDReached check
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2021-11-26 05:23:02 -06:00
|
|
|
if n.typ != eth2MiningNode {
|
|
|
|
return nil, errors.New("invalid node type")
|
|
|
|
}
|
2021-12-03 09:26:28 -06:00
|
|
|
payloadAttribute := catalyst.PayloadAttributesV1{
|
|
|
|
Timestamp: uint64(time.Now().Unix()),
|
|
|
|
}
|
|
|
|
fcState := catalyst.ForkchoiceStateV1{
|
|
|
|
HeadBlockHash: parentHash,
|
|
|
|
SafeBlockHash: common.Hash{},
|
|
|
|
FinalizedBlockHash: common.Hash{},
|
|
|
|
}
|
|
|
|
payload, err := n.api.ForkchoiceUpdatedV1(fcState, &payloadAttribute)
|
all: core rework for the merge transition (#23761)
* all: work for eth1/2 transtition
* consensus/beacon, eth: change beacon difficulty to 0
* eth: updates
* all: add terminalBlockDifficulty config, fix rebasing issues
* eth: implemented merge interop spec
* internal/ethapi: update to v1.0.0.alpha.2
This commit updates the code to the new spec, moving payloadId into
it's own object. It also fixes an issue with finalizing an empty blockhash.
It also properly sets the basefee
* all: sync polishes, other fixes + refactors
* core, eth: correct semantics for LeavePoW, EnterPoS
* core: fixed rebasing artifacts
* core: light: performance improvements
* core: use keyed field (f)
* core: eth: fix compilation issues + tests
* eth/catalyst: dbetter error codes
* all: move Merger to consensus/, remove reliance on it in bc
* all: renamed EnterPoS and LeavePoW to ReachTDD and FinalizePoS
* core: make mergelogs a function
* core: use InsertChain instead of InsertBlock
* les: drop merger from lightchain object
* consensus: add merger
* core: recoverAncestors in catalyst mode
* core: fix nitpick
* all: removed merger from beacon, use TTD, nitpicks
* consensus: eth: add docstring, removed unnecessary code duplication
* consensus/beacon: better comment
* all: easy to fix nitpicks by karalabe
* consensus/beacon: verify known headers to be sure
* core: comments
* core: eth: don't drop peers who advertise blocks, nitpicks
* core: never add beacon blocks to the future queue
* core: fixed nitpicks
* consensus/beacon: simplify IsTTDReached check
* consensus/beacon: correct IsTTDReached check
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2021-11-26 05:23:02 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-12-03 09:26:28 -06:00
|
|
|
return n.api.GetPayloadV1(*payload.PayloadID)
|
all: core rework for the merge transition (#23761)
* all: work for eth1/2 transtition
* consensus/beacon, eth: change beacon difficulty to 0
* eth: updates
* all: add terminalBlockDifficulty config, fix rebasing issues
* eth: implemented merge interop spec
* internal/ethapi: update to v1.0.0.alpha.2
This commit updates the code to the new spec, moving payloadId into
it's own object. It also fixes an issue with finalizing an empty blockhash.
It also properly sets the basefee
* all: sync polishes, other fixes + refactors
* core, eth: correct semantics for LeavePoW, EnterPoS
* core: fixed rebasing artifacts
* core: light: performance improvements
* core: use keyed field (f)
* core: eth: fix compilation issues + tests
* eth/catalyst: dbetter error codes
* all: move Merger to consensus/, remove reliance on it in bc
* all: renamed EnterPoS and LeavePoW to ReachTDD and FinalizePoS
* core: make mergelogs a function
* core: use InsertChain instead of InsertBlock
* les: drop merger from lightchain object
* consensus: add merger
* core: recoverAncestors in catalyst mode
* core: fix nitpick
* all: removed merger from beacon, use TTD, nitpicks
* consensus: eth: add docstring, removed unnecessary code duplication
* consensus/beacon: better comment
* all: easy to fix nitpicks by karalabe
* consensus/beacon: verify known headers to be sure
* core: comments
* core: eth: don't drop peers who advertise blocks, nitpicks
* core: never add beacon blocks to the future queue
* core: fixed nitpicks
* consensus/beacon: simplify IsTTDReached check
* consensus/beacon: correct IsTTDReached check
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2021-11-26 05:23:02 -06:00
|
|
|
}
|
|
|
|
|
2021-12-03 09:26:28 -06:00
|
|
|
func (n *ethNode) insertBlock(eb catalyst.ExecutableDataV1) error {
|
all: core rework for the merge transition (#23761)
* all: work for eth1/2 transtition
* consensus/beacon, eth: change beacon difficulty to 0
* eth: updates
* all: add terminalBlockDifficulty config, fix rebasing issues
* eth: implemented merge interop spec
* internal/ethapi: update to v1.0.0.alpha.2
This commit updates the code to the new spec, moving payloadId into
it's own object. It also fixes an issue with finalizing an empty blockhash.
It also properly sets the basefee
* all: sync polishes, other fixes + refactors
* core, eth: correct semantics for LeavePoW, EnterPoS
* core: fixed rebasing artifacts
* core: light: performance improvements
* core: use keyed field (f)
* core: eth: fix compilation issues + tests
* eth/catalyst: dbetter error codes
* all: move Merger to consensus/, remove reliance on it in bc
* all: renamed EnterPoS and LeavePoW to ReachTDD and FinalizePoS
* core: make mergelogs a function
* core: use InsertChain instead of InsertBlock
* les: drop merger from lightchain object
* consensus: add merger
* core: recoverAncestors in catalyst mode
* core: fix nitpick
* all: removed merger from beacon, use TTD, nitpicks
* consensus: eth: add docstring, removed unnecessary code duplication
* consensus/beacon: better comment
* all: easy to fix nitpicks by karalabe
* consensus/beacon: verify known headers to be sure
* core: comments
* core: eth: don't drop peers who advertise blocks, nitpicks
* core: never add beacon blocks to the future queue
* core: fixed nitpicks
* consensus/beacon: simplify IsTTDReached check
* consensus/beacon: correct IsTTDReached check
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2021-11-26 05:23:02 -06:00
|
|
|
if !eth2types(n.typ) {
|
|
|
|
return errors.New("invalid node type")
|
|
|
|
}
|
2021-12-03 09:26:28 -06:00
|
|
|
newResp, err := n.api.ExecutePayloadV1(eb)
|
all: core rework for the merge transition (#23761)
* all: work for eth1/2 transtition
* consensus/beacon, eth: change beacon difficulty to 0
* eth: updates
* all: add terminalBlockDifficulty config, fix rebasing issues
* eth: implemented merge interop spec
* internal/ethapi: update to v1.0.0.alpha.2
This commit updates the code to the new spec, moving payloadId into
it's own object. It also fixes an issue with finalizing an empty blockhash.
It also properly sets the basefee
* all: sync polishes, other fixes + refactors
* core, eth: correct semantics for LeavePoW, EnterPoS
* core: fixed rebasing artifacts
* core: light: performance improvements
* core: use keyed field (f)
* core: eth: fix compilation issues + tests
* eth/catalyst: dbetter error codes
* all: move Merger to consensus/, remove reliance on it in bc
* all: renamed EnterPoS and LeavePoW to ReachTDD and FinalizePoS
* core: make mergelogs a function
* core: use InsertChain instead of InsertBlock
* les: drop merger from lightchain object
* consensus: add merger
* core: recoverAncestors in catalyst mode
* core: fix nitpick
* all: removed merger from beacon, use TTD, nitpicks
* consensus: eth: add docstring, removed unnecessary code duplication
* consensus/beacon: better comment
* all: easy to fix nitpicks by karalabe
* consensus/beacon: verify known headers to be sure
* core: comments
* core: eth: don't drop peers who advertise blocks, nitpicks
* core: never add beacon blocks to the future queue
* core: fixed nitpicks
* consensus/beacon: simplify IsTTDReached check
* consensus/beacon: correct IsTTDReached check
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2021-11-26 05:23:02 -06:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
} else if newResp.Status != "VALID" {
|
|
|
|
return errors.New("failed to insert block")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-12-03 09:26:28 -06:00
|
|
|
func (n *ethNode) insertBlockAndSetHead(parent *types.Header, ed catalyst.ExecutableDataV1) error {
|
all: core rework for the merge transition (#23761)
* all: work for eth1/2 transtition
* consensus/beacon, eth: change beacon difficulty to 0
* eth: updates
* all: add terminalBlockDifficulty config, fix rebasing issues
* eth: implemented merge interop spec
* internal/ethapi: update to v1.0.0.alpha.2
This commit updates the code to the new spec, moving payloadId into
it's own object. It also fixes an issue with finalizing an empty blockhash.
It also properly sets the basefee
* all: sync polishes, other fixes + refactors
* core, eth: correct semantics for LeavePoW, EnterPoS
* core: fixed rebasing artifacts
* core: light: performance improvements
* core: use keyed field (f)
* core: eth: fix compilation issues + tests
* eth/catalyst: dbetter error codes
* all: move Merger to consensus/, remove reliance on it in bc
* all: renamed EnterPoS and LeavePoW to ReachTDD and FinalizePoS
* core: make mergelogs a function
* core: use InsertChain instead of InsertBlock
* les: drop merger from lightchain object
* consensus: add merger
* core: recoverAncestors in catalyst mode
* core: fix nitpick
* all: removed merger from beacon, use TTD, nitpicks
* consensus: eth: add docstring, removed unnecessary code duplication
* consensus/beacon: better comment
* all: easy to fix nitpicks by karalabe
* consensus/beacon: verify known headers to be sure
* core: comments
* core: eth: don't drop peers who advertise blocks, nitpicks
* core: never add beacon blocks to the future queue
* core: fixed nitpicks
* consensus/beacon: simplify IsTTDReached check
* consensus/beacon: correct IsTTDReached check
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2021-11-26 05:23:02 -06:00
|
|
|
if !eth2types(n.typ) {
|
|
|
|
return errors.New("invalid node type")
|
|
|
|
}
|
|
|
|
if err := n.insertBlock(ed); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
block, err := catalyst.ExecutableDataToBlock(ed)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-12-03 09:26:28 -06:00
|
|
|
fcState := catalyst.ForkchoiceStateV1{
|
|
|
|
HeadBlockHash: block.ParentHash(),
|
|
|
|
SafeBlockHash: common.Hash{},
|
|
|
|
FinalizedBlockHash: common.Hash{},
|
|
|
|
}
|
|
|
|
if _, err := n.api.ForkchoiceUpdatedV1(fcState, nil); err != nil {
|
all: core rework for the merge transition (#23761)
* all: work for eth1/2 transtition
* consensus/beacon, eth: change beacon difficulty to 0
* eth: updates
* all: add terminalBlockDifficulty config, fix rebasing issues
* eth: implemented merge interop spec
* internal/ethapi: update to v1.0.0.alpha.2
This commit updates the code to the new spec, moving payloadId into
it's own object. It also fixes an issue with finalizing an empty blockhash.
It also properly sets the basefee
* all: sync polishes, other fixes + refactors
* core, eth: correct semantics for LeavePoW, EnterPoS
* core: fixed rebasing artifacts
* core: light: performance improvements
* core: use keyed field (f)
* core: eth: fix compilation issues + tests
* eth/catalyst: dbetter error codes
* all: move Merger to consensus/, remove reliance on it in bc
* all: renamed EnterPoS and LeavePoW to ReachTDD and FinalizePoS
* core: make mergelogs a function
* core: use InsertChain instead of InsertBlock
* les: drop merger from lightchain object
* consensus: add merger
* core: recoverAncestors in catalyst mode
* core: fix nitpick
* all: removed merger from beacon, use TTD, nitpicks
* consensus: eth: add docstring, removed unnecessary code duplication
* consensus/beacon: better comment
* all: easy to fix nitpicks by karalabe
* consensus/beacon: verify known headers to be sure
* core: comments
* core: eth: don't drop peers who advertise blocks, nitpicks
* core: never add beacon blocks to the future queue
* core: fixed nitpicks
* consensus/beacon: simplify IsTTDReached check
* consensus/beacon: correct IsTTDReached check
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2021-11-26 05:23:02 -06:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type nodeManager struct {
|
|
|
|
genesis *core.Genesis
|
|
|
|
genesisBlock *types.Block
|
|
|
|
nodes []*ethNode
|
|
|
|
enodes []*enode.Node
|
|
|
|
close chan struct{}
|
|
|
|
}
|
|
|
|
|
|
|
|
func newNodeManager(genesis *core.Genesis) *nodeManager {
|
|
|
|
return &nodeManager{
|
|
|
|
close: make(chan struct{}),
|
|
|
|
genesis: genesis,
|
|
|
|
genesisBlock: genesis.ToBlock(nil),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mgr *nodeManager) createNode(typ nodetype) {
|
|
|
|
node := newNode(typ, mgr.genesis, mgr.enodes)
|
|
|
|
mgr.nodes = append(mgr.nodes, node)
|
|
|
|
mgr.enodes = append(mgr.enodes, node.enode)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mgr *nodeManager) getNodes(typ nodetype) []*ethNode {
|
|
|
|
var ret []*ethNode
|
|
|
|
for _, node := range mgr.nodes {
|
|
|
|
if node.typ == typ {
|
|
|
|
ret = append(ret, node)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mgr *nodeManager) startMining() {
|
|
|
|
for _, node := range append(mgr.getNodes(eth2MiningNode), mgr.getNodes(legacyMiningNode)...) {
|
|
|
|
if err := node.ethBackend.StartMining(1); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mgr *nodeManager) shutdown() {
|
|
|
|
close(mgr.close)
|
|
|
|
for _, node := range mgr.nodes {
|
|
|
|
node.stack.Close()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mgr *nodeManager) run() {
|
|
|
|
if len(mgr.nodes) == 0 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
chain := mgr.nodes[0].ethBackend.BlockChain()
|
|
|
|
sink := make(chan core.ChainHeadEvent, 1024)
|
|
|
|
sub := chain.SubscribeChainHeadEvent(sink)
|
|
|
|
defer sub.Unsubscribe()
|
|
|
|
|
|
|
|
var (
|
|
|
|
transitioned bool
|
|
|
|
parentBlock *types.Block
|
|
|
|
waitFinalise []*types.Block
|
|
|
|
)
|
|
|
|
timer := time.NewTimer(0)
|
|
|
|
defer timer.Stop()
|
|
|
|
<-timer.C // discard the initial tick
|
|
|
|
|
|
|
|
// Handle the by default transition.
|
|
|
|
if transitionDifficulty.Sign() == 0 {
|
|
|
|
transitioned = true
|
|
|
|
parentBlock = mgr.genesisBlock
|
|
|
|
timer.Reset(blockInterval)
|
|
|
|
log.Info("Enable the transition by default")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle the block finalization.
|
|
|
|
checkFinalise := func() {
|
|
|
|
if parentBlock == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if len(waitFinalise) == 0 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
oldest := waitFinalise[0]
|
|
|
|
if oldest.NumberU64() > parentBlock.NumberU64() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
distance := parentBlock.NumberU64() - oldest.NumberU64()
|
|
|
|
if int(distance) < finalizationDist {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
nodes := mgr.getNodes(eth2MiningNode)
|
|
|
|
nodes = append(nodes, mgr.getNodes(eth2NormalNode)...)
|
|
|
|
nodes = append(nodes, mgr.getNodes(eth2LightClient)...)
|
|
|
|
for _, node := range append(nodes) {
|
2021-12-03 09:26:28 -06:00
|
|
|
fcState := catalyst.ForkchoiceStateV1{
|
|
|
|
HeadBlockHash: oldest.Hash(),
|
|
|
|
SafeBlockHash: common.Hash{},
|
|
|
|
FinalizedBlockHash: common.Hash{},
|
|
|
|
}
|
|
|
|
node.api.ForkchoiceUpdatedV1(fcState, nil)
|
all: core rework for the merge transition (#23761)
* all: work for eth1/2 transtition
* consensus/beacon, eth: change beacon difficulty to 0
* eth: updates
* all: add terminalBlockDifficulty config, fix rebasing issues
* eth: implemented merge interop spec
* internal/ethapi: update to v1.0.0.alpha.2
This commit updates the code to the new spec, moving payloadId into
it's own object. It also fixes an issue with finalizing an empty blockhash.
It also properly sets the basefee
* all: sync polishes, other fixes + refactors
* core, eth: correct semantics for LeavePoW, EnterPoS
* core: fixed rebasing artifacts
* core: light: performance improvements
* core: use keyed field (f)
* core: eth: fix compilation issues + tests
* eth/catalyst: dbetter error codes
* all: move Merger to consensus/, remove reliance on it in bc
* all: renamed EnterPoS and LeavePoW to ReachTDD and FinalizePoS
* core: make mergelogs a function
* core: use InsertChain instead of InsertBlock
* les: drop merger from lightchain object
* consensus: add merger
* core: recoverAncestors in catalyst mode
* core: fix nitpick
* all: removed merger from beacon, use TTD, nitpicks
* consensus: eth: add docstring, removed unnecessary code duplication
* consensus/beacon: better comment
* all: easy to fix nitpicks by karalabe
* consensus/beacon: verify known headers to be sure
* core: comments
* core: eth: don't drop peers who advertise blocks, nitpicks
* core: never add beacon blocks to the future queue
* core: fixed nitpicks
* consensus/beacon: simplify IsTTDReached check
* consensus/beacon: correct IsTTDReached check
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2021-11-26 05:23:02 -06:00
|
|
|
}
|
|
|
|
log.Info("Finalised eth2 block", "number", oldest.NumberU64(), "hash", oldest.Hash())
|
|
|
|
waitFinalise = waitFinalise[1:]
|
|
|
|
}
|
|
|
|
|
|
|
|
for {
|
|
|
|
checkFinalise()
|
|
|
|
select {
|
|
|
|
case <-mgr.close:
|
|
|
|
return
|
|
|
|
|
|
|
|
case ev := <-sink:
|
|
|
|
if transitioned {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
td := chain.GetTd(ev.Block.Hash(), ev.Block.NumberU64())
|
|
|
|
if td.Cmp(transitionDifficulty) < 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
transitioned, parentBlock = true, ev.Block
|
|
|
|
timer.Reset(blockInterval)
|
|
|
|
log.Info("Transition difficulty reached", "td", td, "target", transitionDifficulty, "number", ev.Block.NumberU64(), "hash", ev.Block.Hash())
|
|
|
|
|
|
|
|
case <-timer.C:
|
|
|
|
producers := mgr.getNodes(eth2MiningNode)
|
|
|
|
if len(producers) == 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
hash, timestamp := parentBlock.Hash(), parentBlock.Time()
|
|
|
|
if parentBlock.NumberU64() == 0 {
|
|
|
|
timestamp = uint64(time.Now().Unix()) - uint64(blockIntervalInt)
|
|
|
|
}
|
|
|
|
ed, err := producers[0].assembleBlock(hash, timestamp)
|
|
|
|
if err != nil {
|
|
|
|
log.Error("Failed to assemble the block", "err", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
block, _ := catalyst.ExecutableDataToBlock(*ed)
|
|
|
|
|
|
|
|
nodes := mgr.getNodes(eth2MiningNode)
|
|
|
|
nodes = append(nodes, mgr.getNodes(eth2NormalNode)...)
|
|
|
|
nodes = append(nodes, mgr.getNodes(eth2LightClient)...)
|
|
|
|
|
|
|
|
for _, node := range nodes {
|
|
|
|
if err := node.insertBlockAndSetHead(parentBlock.Header(), *ed); err != nil {
|
|
|
|
log.Error("Failed to insert block", "type", node.typ, "err", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.Info("Create and insert eth2 block", "number", ed.Number)
|
|
|
|
parentBlock = block
|
|
|
|
waitFinalise = append(waitFinalise, block)
|
|
|
|
timer.Reset(blockInterval)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
log.Root().SetHandler(log.LvlFilterHandler(log.LvlInfo, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
|
|
|
|
fdlimit.Raise(2048)
|
|
|
|
|
|
|
|
// Generate a batch of accounts to seal and fund with
|
|
|
|
faucets := make([]*ecdsa.PrivateKey, 16)
|
|
|
|
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, filepath.Join(os.Getenv("HOME"), ".ethash"))
|
|
|
|
|
|
|
|
// Create an Ethash network based off of the Ropsten config
|
|
|
|
genesis := makeGenesis(faucets)
|
|
|
|
manager := newNodeManager(genesis)
|
|
|
|
defer manager.shutdown()
|
|
|
|
|
|
|
|
manager.createNode(eth2NormalNode)
|
|
|
|
manager.createNode(eth2MiningNode)
|
|
|
|
manager.createNode(legacyMiningNode)
|
|
|
|
manager.createNode(legacyNormalNode)
|
|
|
|
manager.createNode(eth2LightClient)
|
|
|
|
|
|
|
|
// Iterate over all the nodes and start mining
|
|
|
|
time.Sleep(3 * time.Second)
|
|
|
|
if transitionDifficulty.Sign() != 0 {
|
|
|
|
manager.startMining()
|
|
|
|
}
|
|
|
|
go manager.run()
|
|
|
|
|
|
|
|
// Start injecting transactions from the faucets like crazy
|
|
|
|
time.Sleep(3 * time.Second)
|
|
|
|
nonces := make([]uint64, len(faucets))
|
|
|
|
for {
|
|
|
|
// Pick a random mining node
|
|
|
|
nodes := manager.getNodes(eth2MiningNode)
|
|
|
|
|
|
|
|
index := rand.Intn(len(faucets))
|
|
|
|
node := 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 err := node.ethBackend.TxPool().AddLocal(tx); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
nonces[index]++
|
|
|
|
|
|
|
|
// Wait if we're too saturated
|
|
|
|
if pend, _ := node.ethBackend.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.DefaultRopstenGenesisBlock()
|
|
|
|
genesis.Difficulty = params.MinimumDifficulty
|
|
|
|
genesis.GasLimit = 25000000
|
|
|
|
|
|
|
|
genesis.Config.ChainID = big.NewInt(18)
|
|
|
|
genesis.Config.EIP150Hash = common.Hash{}
|
|
|
|
genesis.BaseFee = big.NewInt(params.InitialBaseFee)
|
|
|
|
genesis.Config.TerminalTotalDifficulty = transitionDifficulty
|
|
|
|
|
|
|
|
genesis.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 makeFullNode(genesis *core.Genesis) (*node.Node, *eth.Ethereum, *catalyst.ConsensusAPI, error) {
|
|
|
|
// Define the basic configurations for the Ethereum node
|
|
|
|
datadir, _ := ioutil.TempDir("", "")
|
|
|
|
|
|
|
|
config := &node.Config{
|
|
|
|
Name: "geth",
|
|
|
|
Version: params.Version,
|
|
|
|
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, nil, err
|
|
|
|
}
|
|
|
|
econfig := ðconfig.Config{
|
|
|
|
Genesis: genesis,
|
|
|
|
NetworkId: genesis.Config.ChainID.Uint64(),
|
|
|
|
SyncMode: downloader.FullSync,
|
|
|
|
DatabaseCache: 256,
|
|
|
|
DatabaseHandles: 256,
|
|
|
|
TxPool: core.DefaultTxPoolConfig,
|
|
|
|
GPO: ethconfig.Defaults.GPO,
|
|
|
|
Ethash: ethconfig.Defaults.Ethash,
|
|
|
|
Miner: miner.Config{
|
|
|
|
GasFloor: genesis.GasLimit * 9 / 10,
|
|
|
|
GasCeil: genesis.GasLimit * 11 / 10,
|
|
|
|
GasPrice: big.NewInt(1),
|
|
|
|
Recommit: 10 * time.Second, // Disable the recommit
|
|
|
|
},
|
|
|
|
LightServ: 100,
|
|
|
|
LightPeers: 10,
|
|
|
|
LightNoSyncServe: true,
|
|
|
|
}
|
|
|
|
ethBackend, err := eth.New(stack, econfig)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, nil, err
|
|
|
|
}
|
|
|
|
_, err = les.NewLesServer(stack, ethBackend, econfig)
|
|
|
|
if err != nil {
|
|
|
|
log.Crit("Failed to create the LES server", "err", err)
|
|
|
|
}
|
|
|
|
err = stack.Start()
|
|
|
|
return stack, ethBackend, catalyst.NewConsensusAPI(ethBackend, nil), err
|
|
|
|
}
|
|
|
|
|
|
|
|
func makeLightNode(genesis *core.Genesis) (*node.Node, *les.LightEthereum, *catalyst.ConsensusAPI, error) {
|
|
|
|
// Define the basic configurations for the Ethereum node
|
|
|
|
datadir, _ := ioutil.TempDir("", "")
|
|
|
|
|
|
|
|
config := &node.Config{
|
|
|
|
Name: "geth",
|
|
|
|
Version: params.Version,
|
|
|
|
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, nil, err
|
|
|
|
}
|
|
|
|
lesBackend, err := les.New(stack, ðconfig.Config{
|
|
|
|
Genesis: genesis,
|
|
|
|
NetworkId: genesis.Config.ChainID.Uint64(),
|
|
|
|
SyncMode: downloader.LightSync,
|
|
|
|
DatabaseCache: 256,
|
|
|
|
DatabaseHandles: 256,
|
|
|
|
TxPool: core.DefaultTxPoolConfig,
|
|
|
|
GPO: ethconfig.Defaults.GPO,
|
|
|
|
Ethash: ethconfig.Defaults.Ethash,
|
|
|
|
LightPeers: 10,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, nil, err
|
|
|
|
}
|
|
|
|
err = stack.Start()
|
|
|
|
return stack, lesBackend, catalyst.NewConsensusAPI(nil, lesBackend), err
|
|
|
|
}
|
|
|
|
|
|
|
|
func eth2types(typ nodetype) bool {
|
|
|
|
if typ == eth2LightClient || typ == eth2NormalNode || typ == eth2MiningNode {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|