node: refactor package node (#21105)

This PR significantly changes the APIs for instantiating Ethereum nodes in
a Go program. The new APIs are not backwards-compatible, but we feel that
this is made up for by the much simpler way of registering services on
node.Node. You can find more information and rationale in the design
document: https://gist.github.com/renaynay/5bec2de19fde66f4d04c535fd24f0775.

There is also a new feature in Node's Go API: it is now possible to
register arbitrary handlers on the user-facing HTTP server. In geth, this
facility is used to enable GraphQL.

There is a single minor change relevant for geth users in this PR: The
GraphQL API is no longer available separately from the JSON-RPC HTTP
server. If you want GraphQL, you need to enable it using the
./geth --http --graphql flag combination.

The --graphql.port and --graphql.addr flags are no longer available.
This commit is contained in:
rene
2020-08-03 19:40:46 +02:00
committed by GitHub
parent b2b14e6ce3
commit c0c01612e9
63 changed files with 2606 additions and 2887 deletions

View File

@ -61,30 +61,31 @@ func main() {
genesis := makeGenesis(faucets, sealers)
var (
nodes []*node.Node
nodes []*eth.Ethereum
enodes []*enode.Node
)
for _, sealer := range sealers {
// Start the node and wait until it's up
node, err := makeSealer(genesis)
stack, ethBackend, err := makeSealer(genesis)
if err != nil {
panic(err)
}
defer node.Close()
defer stack.Close()
for node.Server().NodeInfo().Ports.Listener == 0 {
for stack.Server().NodeInfo().Ports.Listener == 0 {
time.Sleep(250 * time.Millisecond)
}
// Connect the node to al the previous ones
// Connect the node to all the previous ones
for _, n := range enodes {
node.Server().AddPeer(n)
stack.Server().AddPeer(n)
}
// Start tracking the node and it's enode
nodes = append(nodes, node)
enodes = append(enodes, node.Server().Self())
// Start tracking the node and its enode
nodes = append(nodes, ethBackend)
enodes = append(enodes, stack.Server().Self())
// Inject the signer key and start sealing with it
store := node.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
store := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
signer, err := store.ImportECDSA(sealer, "")
if err != nil {
panic(err)
@ -93,15 +94,11 @@ func main() {
panic(err)
}
}
// Iterate over all the nodes and start signing with them
time.Sleep(3 * time.Second)
// Iterate over all the nodes and start signing on them
time.Sleep(3 * time.Second)
for _, node := range nodes {
var ethereum *eth.Ethereum
if err := node.Service(&ethereum); err != nil {
panic(err)
}
if err := ethereum.StartMining(1); err != nil {
if err := node.StartMining(1); err != nil {
panic(err)
}
}
@ -110,25 +107,22 @@ func main() {
// Start injecting transactions from the faucet like crazy
nonces := make([]uint64, len(faucets))
for {
// Pick a random signer node
index := rand.Intn(len(faucets))
backend := nodes[index%len(nodes)]
// Fetch the accessor for the relevant signer
var ethereum *eth.Ethereum
if err := nodes[index%len(nodes)].Service(&ethereum); err != nil {
panic(err)
}
// 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), nil), types.HomesteadSigner{}, faucets[index])
if err != nil {
panic(err)
}
if err := ethereum.TxPool().AddLocal(tx); err != nil {
if err := backend.TxPool().AddLocal(tx); err != nil {
panic(err)
}
nonces[index]++
// Wait if we're too saturated
if pend, _ := ethereum.TxPool().Stats(); pend > 2048 {
if pend, _ := backend.TxPool().Stats(); pend > 2048 {
time.Sleep(100 * time.Millisecond)
}
}
@ -171,7 +165,7 @@ func makeGenesis(faucets []*ecdsa.PrivateKey, sealers []*ecdsa.PrivateKey) *core
return genesis
}
func makeSealer(genesis *core.Genesis) (*node.Node, error) {
func makeSealer(genesis *core.Genesis) (*node.Node, *eth.Ethereum, error) {
// Define the basic configurations for the Ethereum node
datadir, _ := ioutil.TempDir("", "")
@ -189,27 +183,28 @@ func makeSealer(genesis *core.Genesis) (*node.Node, error) {
// Start the node and configure a full Ethereum node on it
stack, err := node.New(config)
if err != nil {
return nil, err
return nil, nil, err
}
if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
return eth.New(ctx, &eth.Config{
Genesis: genesis,
NetworkId: genesis.Config.ChainID.Uint64(),
SyncMode: downloader.FullSync,
DatabaseCache: 256,
DatabaseHandles: 256,
TxPool: core.DefaultTxPoolConfig,
GPO: eth.DefaultConfig.GPO,
Miner: miner.Config{
GasFloor: genesis.GasLimit * 9 / 10,
GasCeil: genesis.GasLimit * 11 / 10,
GasPrice: big.NewInt(1),
Recommit: time.Second,
},
})
}); err != nil {
return nil, err
// Create and register the backend
ethBackend, err := eth.New(stack, &eth.Config{
Genesis: genesis,
NetworkId: genesis.Config.ChainID.Uint64(),
SyncMode: downloader.FullSync,
DatabaseCache: 256,
DatabaseHandles: 256,
TxPool: core.DefaultTxPoolConfig,
GPO: eth.DefaultConfig.GPO,
Miner: miner.Config{
GasFloor: genesis.GasLimit * 9 / 10,
GasCeil: genesis.GasLimit * 11 / 10,
GasPrice: big.NewInt(1),
Recommit: time.Second,
},
})
if err != nil {
return nil, nil, err
}
// Start the node and return if successful
return stack, stack.Start()
err = stack.Start()
return stack, ethBackend, err
}