mirror of
https://github.com/luxfi/evm.git
synced 2026-09-24 00:27:44 +00:00
first commit
This commit is contained in:
+66
@@ -0,0 +1,66 @@
|
||||
// (c) 2019-2020, Ava Labs, Inc.
|
||||
//
|
||||
// This file is a derived work, based on the go-ethereum library whose original
|
||||
// notices appear below.
|
||||
//
|
||||
// It is distributed under a license compatible with the licensing terms of the
|
||||
// original code from which it is derived.
|
||||
//
|
||||
// Much love to the original authors for their work.
|
||||
// **********
|
||||
// Copyright 2015 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/>.
|
||||
|
||||
package node
|
||||
|
||||
import (
|
||||
"github.com/ava-labs/subnet-evm/internal/debug"
|
||||
"github.com/ava-labs/subnet-evm/rpc"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
)
|
||||
|
||||
// apis returns the collection of built-in RPC APIs.
|
||||
func (n *Node) apis() []rpc.API {
|
||||
return []rpc.API{
|
||||
{
|
||||
Namespace: "debug",
|
||||
Version: "1.0",
|
||||
Service: debug.Handler,
|
||||
}, {
|
||||
Namespace: "web3",
|
||||
Version: "1.0",
|
||||
Service: &publicWeb3API{n},
|
||||
Public: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// publicWeb3API offers helper utils
|
||||
type publicWeb3API struct {
|
||||
stack *Node
|
||||
}
|
||||
|
||||
// ClientVersion returns the node name
|
||||
func (s *publicWeb3API) ClientVersion() string {
|
||||
return s.stack.config.SubnetEVMVersion
|
||||
}
|
||||
|
||||
// Sha3 applies the ethereum sha3 implementation on the input.
|
||||
// It assumes the input is hex encoded.
|
||||
func (s *publicWeb3API) Sha3(input hexutil.Bytes) hexutil.Bytes {
|
||||
return crypto.Keccak256(input)
|
||||
}
|
||||
+246
@@ -0,0 +1,246 @@
|
||||
// (c) 2019-2020, Ava Labs, Inc.
|
||||
//
|
||||
// This file is a derived work, based on the go-ethereum library whose original
|
||||
// notices appear below.
|
||||
//
|
||||
// It is distributed under a license compatible with the licensing terms of the
|
||||
// original code from which it is derived.
|
||||
//
|
||||
// Much love to the original authors for their work.
|
||||
// **********
|
||||
// Copyright 2014 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/>.
|
||||
|
||||
package node
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/ava-labs/subnet-evm/accounts"
|
||||
"github.com/ava-labs/subnet-evm/accounts/external"
|
||||
"github.com/ava-labs/subnet-evm/accounts/keystore"
|
||||
"github.com/ava-labs/subnet-evm/rpc"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
)
|
||||
|
||||
// Config represents a small collection of configuration values to fine tune the
|
||||
// P2P network layer of a protocol stack. These values can be further extended by
|
||||
// all registered services.
|
||||
type Config struct {
|
||||
// KeyStoreDir is the file system folder that contains private keys. The directory can
|
||||
// be specified as a relative path, in which case it is resolved relative to the
|
||||
// current directory.
|
||||
//
|
||||
// If KeyStoreDir is empty, the default location is the "keystore" subdirectory of
|
||||
// DataDir. If DataDir is unspecified and KeyStoreDir is empty, an ephemeral directory
|
||||
// is created by New and destroyed when the node is stopped.
|
||||
KeyStoreDir string `toml:",omitempty"`
|
||||
|
||||
// ExternalSigner specifies an external URI for a clef-type signer
|
||||
ExternalSigner string `toml:",omitempty"`
|
||||
|
||||
// UseLightweightKDF lowers the memory and CPU requirements of the key store
|
||||
// scrypt KDF at the expense of security.
|
||||
UseLightweightKDF bool `toml:",omitempty"`
|
||||
|
||||
// InsecureUnlockAllowed allows user to unlock accounts in unsafe http environment.
|
||||
InsecureUnlockAllowed bool `toml:",omitempty"`
|
||||
|
||||
// HTTPHost is the host interface on which to start the HTTP RPC server. If this
|
||||
// field is empty, no HTTP API endpoint will be started.
|
||||
HTTPHost string
|
||||
|
||||
// HTTPPort is the TCP port number on which to start the HTTP RPC server. The
|
||||
// default zero value is/ valid and will pick a port number randomly (useful
|
||||
// for ephemeral nodes).
|
||||
HTTPPort int `toml:",omitempty"`
|
||||
|
||||
// HTTPCors is the Cross-Origin Resource Sharing header to send to requesting
|
||||
// clients. Please be aware that CORS is a browser enforced security, it's fully
|
||||
// useless for custom HTTP clients.
|
||||
HTTPCors []string `toml:",omitempty"`
|
||||
|
||||
// HTTPVirtualHosts is the list of virtual hostnames which are allowed on incoming requests.
|
||||
// This is by default {'localhost'}. Using this prevents attacks like
|
||||
// DNS rebinding, which bypasses SOP by simply masquerading as being within the same
|
||||
// origin. These attacks do not utilize CORS, since they are not cross-domain.
|
||||
// By explicitly checking the Host-header, the server will not allow requests
|
||||
// made against the server with a malicious host domain.
|
||||
// Requests using ip address directly are not affected
|
||||
HTTPVirtualHosts []string `toml:",omitempty"`
|
||||
|
||||
// HTTPModules is a list of API modules to expose via the HTTP RPC interface.
|
||||
// If the module list is empty, all RPC API endpoints designated public will be
|
||||
// exposed.
|
||||
HTTPModules []string
|
||||
|
||||
// HTTPTimeouts allows for customization of the timeout values used by the HTTP RPC
|
||||
// interface.
|
||||
HTTPTimeouts rpc.HTTPTimeouts
|
||||
|
||||
// WSHost is the host interface on which to start the websocket RPC server. If
|
||||
// this field is empty, no websocket API endpoint will be started.
|
||||
WSHost string
|
||||
|
||||
// WSPort is the TCP port number on which to start the websocket RPC server. The
|
||||
// default zero value is/ valid and will pick a port number randomly (useful for
|
||||
// ephemeral nodes).
|
||||
WSPort int `toml:",omitempty"`
|
||||
|
||||
// WSOrigins is the list of domain to accept websocket requests from. Please be
|
||||
// aware that the server can only act upon the HTTP request the client sends and
|
||||
// cannot verify the validity of the request header.
|
||||
WSOrigins []string `toml:",omitempty"`
|
||||
|
||||
// WSModules is a list of API modules to expose via the websocket RPC interface.
|
||||
// If the module list is empty, all RPC API endpoints designated public will be
|
||||
// exposed.
|
||||
WSModules []string
|
||||
|
||||
// WSExposeAll exposes all API modules via the WebSocket RPC interface rather
|
||||
// than just the public ones.
|
||||
//
|
||||
// *WARNING* Only set this if the node is running in a trusted network, exposing
|
||||
// private APIs to untrusted users is a major security risk.
|
||||
WSExposeAll bool `toml:",omitempty"`
|
||||
|
||||
// GraphQLCors is the Cross-Origin Resource Sharing header to send to requesting
|
||||
// clients. Please be aware that CORS is a browser enforced security, it's fully
|
||||
// useless for custom HTTP clients.
|
||||
GraphQLCors []string `toml:",omitempty"`
|
||||
|
||||
// GraphQLVirtualHosts is the list of virtual hostnames which are allowed on incoming requests.
|
||||
// This is by default {'localhost'}. Using this prevents attacks like
|
||||
// DNS rebinding, which bypasses SOP by simply masquerading as being within the same
|
||||
// origin. These attacks do not utilize CORS, since they are not cross-domain.
|
||||
// By explicitly checking the Host-header, the server will not allow requests
|
||||
// made against the server with a malicious host domain.
|
||||
// Requests using ip address directly are not affected
|
||||
GraphQLVirtualHosts []string `toml:",omitempty"`
|
||||
|
||||
SubnetEVMVersion string
|
||||
}
|
||||
|
||||
// HTTPEndpoint resolves an HTTP endpoint based on the configured host interface
|
||||
// and port parameters.
|
||||
func (c *Config) HTTPEndpoint() string {
|
||||
if c.HTTPHost == "" {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%s:%d", c.HTTPHost, c.HTTPPort)
|
||||
}
|
||||
|
||||
// DefaultHTTPEndpoint returns the HTTP endpoint used by default.
|
||||
func DefaultHTTPEndpoint() string {
|
||||
config := &Config{HTTPHost: DefaultHTTPHost, HTTPPort: DefaultHTTPPort}
|
||||
return config.HTTPEndpoint()
|
||||
}
|
||||
|
||||
// WSEndpoint resolves a websocket endpoint based on the configured host interface
|
||||
// and port parameters.
|
||||
func (c *Config) WSEndpoint() string {
|
||||
if c.WSHost == "" {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%s:%d", c.WSHost, c.WSPort)
|
||||
}
|
||||
|
||||
// DefaultWSEndpoint returns the websocket endpoint used by default.
|
||||
func DefaultWSEndpoint() string {
|
||||
config := &Config{WSHost: DefaultWSHost, WSPort: DefaultWSPort}
|
||||
return config.WSEndpoint()
|
||||
}
|
||||
|
||||
// ExtRPCEnabled returns the indicator whether node enables the external
|
||||
// RPC(http, ws or graphql).
|
||||
func (c *Config) ExtRPCEnabled() bool {
|
||||
return c.HTTPHost != "" || c.WSHost != ""
|
||||
}
|
||||
|
||||
// KeyDirConfig determines the settings for keydirectory
|
||||
func (c *Config) KeyDirConfig() (string, error) {
|
||||
var (
|
||||
keydir string
|
||||
err error
|
||||
)
|
||||
switch {
|
||||
case filepath.IsAbs(c.KeyStoreDir):
|
||||
keydir = c.KeyStoreDir
|
||||
case c.KeyStoreDir != "":
|
||||
keydir, err = filepath.Abs(c.KeyStoreDir)
|
||||
}
|
||||
return keydir, err
|
||||
}
|
||||
|
||||
// getKeyStoreDir retrieves the key directory and will create
|
||||
// and ephemeral one if necessary.
|
||||
func getKeyStoreDir(conf *Config) (string, bool, error) {
|
||||
keydir, err := conf.KeyDirConfig()
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
isEphemeral := false
|
||||
if keydir == "" {
|
||||
// There is no datadir.
|
||||
keydir, err = ioutil.TempDir("", "subnet-evm-keystore")
|
||||
isEphemeral = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
if err := os.MkdirAll(keydir, 0700); err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
|
||||
return keydir, isEphemeral, nil
|
||||
}
|
||||
|
||||
func makeAccountManager(conf *Config) (*accounts.Manager, error) {
|
||||
scryptN := keystore.StandardScryptN
|
||||
scryptP := keystore.StandardScryptP
|
||||
if conf.UseLightweightKDF {
|
||||
scryptN = keystore.LightScryptN
|
||||
scryptP = keystore.LightScryptP
|
||||
}
|
||||
|
||||
keydir, _, err := getKeyStoreDir(conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Assemble the account manager and supported backends
|
||||
var backends []accounts.Backend
|
||||
if len(conf.ExternalSigner) > 0 {
|
||||
log.Info("Using external signer", "url", conf.ExternalSigner)
|
||||
if extapi, err := external.NewExternalBackend(conf.ExternalSigner); err == nil {
|
||||
backends = append(backends, extapi)
|
||||
} else {
|
||||
return nil, fmt.Errorf("error connecting to external signer: %v", err)
|
||||
}
|
||||
}
|
||||
if len(backends) == 0 {
|
||||
// For now, we're using EITHER external signer OR local signers.
|
||||
// If/when we implement some form of lockfile for USB and keystore wallets,
|
||||
// we can have both, but it's very confusing for the user to see the same
|
||||
// accounts in both externally and locally, plus very racey.
|
||||
backends = append(backends, keystore.NewKeyStore(keydir, scryptN, scryptP))
|
||||
}
|
||||
|
||||
return accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: conf.InsecureUnlockAllowed}, backends...), nil
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// (c) 2019-2020, Ava Labs, Inc.
|
||||
//
|
||||
// This file is a derived work, based on the go-ethereum library whose original
|
||||
// notices appear below.
|
||||
//
|
||||
// It is distributed under a license compatible with the licensing terms of the
|
||||
// original code from which it is derived.
|
||||
//
|
||||
// Much love to the original authors for their work.
|
||||
// **********
|
||||
// Copyright 2016 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/>.
|
||||
|
||||
package node
|
||||
|
||||
import (
|
||||
"github.com/ava-labs/subnet-evm/rpc"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultHTTPHost = "localhost" // Default host interface for the HTTP RPC server
|
||||
DefaultHTTPPort = 8545 // Default TCP port for the HTTP RPC server
|
||||
DefaultWSHost = "localhost" // Default host interface for the websocket RPC server
|
||||
DefaultWSPort = 8546 // Default TCP port for the websocket RPC server
|
||||
DefaultGraphQLHost = "localhost" // Default host interface for the GraphQL server
|
||||
DefaultGraphQLPort = 8547 // Default TCP port for the GraphQL server
|
||||
)
|
||||
|
||||
// DefaultConfig contains reasonable default settings.
|
||||
var DefaultConfig = Config{
|
||||
HTTPPort: DefaultHTTPPort,
|
||||
HTTPModules: []string{"net", "web3"},
|
||||
HTTPVirtualHosts: []string{"localhost"},
|
||||
HTTPTimeouts: rpc.DefaultHTTPTimeouts,
|
||||
WSPort: DefaultWSPort,
|
||||
WSModules: []string{"net", "web3"},
|
||||
GraphQLVirtualHosts: []string{"localhost"},
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// (c) 2019-2020, Ava Labs, Inc.
|
||||
//
|
||||
// This file is a derived work, based on the go-ethereum library whose original
|
||||
// notices appear below.
|
||||
//
|
||||
// It is distributed under a license compatible with the licensing terms of the
|
||||
// original code from which it is derived.
|
||||
//
|
||||
// Much love to the original authors for their work.
|
||||
// **********
|
||||
// Copyright 2015 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/>.
|
||||
|
||||
package node
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNodeStopped = errors.New("node not started")
|
||||
)
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
// (c) 2019-2020, Ava Labs, Inc.
|
||||
//
|
||||
// This file is a derived work, based on the go-ethereum library whose original
|
||||
// notices appear below.
|
||||
//
|
||||
// It is distributed under a license compatible with the licensing terms of the
|
||||
// original code from which it is derived.
|
||||
//
|
||||
// Much love to the original authors for their work.
|
||||
// **********
|
||||
// Copyright 2015 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/>.
|
||||
|
||||
package node
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/ava-labs/subnet-evm/accounts"
|
||||
"github.com/ava-labs/subnet-evm/rpc"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
)
|
||||
|
||||
// Node is a container on which services can be registered.
|
||||
type Node struct {
|
||||
eventmux *event.TypeMux
|
||||
config *Config
|
||||
accman *accounts.Manager
|
||||
// log log.Logger
|
||||
// ephemKeystore string // if non-empty, the key directory that will be removed by Stop
|
||||
// dirLock fileutil.Releaser // prevents concurrent use of instance directory
|
||||
// stop chan struct{} // Channel to wait for termination notifications
|
||||
// server *p2p.Server // Currently running P2P networking layer
|
||||
// startStopLock sync.Mutex // Start/Stop are protected by an additional lock
|
||||
// state int // Tracks state of node lifecycle
|
||||
|
||||
lock sync.Mutex
|
||||
rpcAPIs []rpc.API // List of APIs currently provided by the node
|
||||
// inprocHandler *rpc.Server // In-process RPC request handler to process the API requests
|
||||
|
||||
// databases map[*closeTrackingDB]struct{} // All open databases
|
||||
|
||||
subnetEVMVersion string
|
||||
}
|
||||
|
||||
// const (
|
||||
// initializingState = iota
|
||||
// closedState
|
||||
// )
|
||||
|
||||
// func (n *Node) openDataDir() error {
|
||||
// if n.config.DataDir == "" {
|
||||
// return nil // ephemeral
|
||||
// }
|
||||
//
|
||||
// instdir := filepath.Join(n.config.DataDir, n.config.name())
|
||||
// if err := os.MkdirAll(instdir, 0700); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// // Lock the instance directory to prevent concurrent use by another instance as well as
|
||||
// // accidental use of the instance directory as a database.
|
||||
// release, _, err := fileutil.Flock(filepath.Join(instdir, "LOCK"))
|
||||
// if err != nil {
|
||||
// return convertFileLockError(err)
|
||||
// }
|
||||
// n.dirLock = release
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// New creates a new P2P node, ready for protocol registration.
|
||||
func New(conf *Config) (*Node, error) {
|
||||
// Copy config and resolve the datadir so future changes to the current
|
||||
// working directory don't affect the node.
|
||||
confCopy := *conf
|
||||
conf = &confCopy
|
||||
|
||||
node := &Node{
|
||||
config: conf,
|
||||
eventmux: new(event.TypeMux),
|
||||
}
|
||||
|
||||
// Register built-in APIs.
|
||||
node.rpcAPIs = append(node.rpcAPIs, node.apis()...)
|
||||
|
||||
// Ensure that the AccountManager method works before the node has started. We rely on
|
||||
// this in cmd/geth.
|
||||
am, err := makeAccountManager(conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node.accman = am
|
||||
|
||||
// Configure RPC servers.
|
||||
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// Config returns the configuration of node.
|
||||
func (n *Node) Config() *Config {
|
||||
return n.config
|
||||
}
|
||||
|
||||
// AccountManager retrieves the account manager used by the protocol stack.
|
||||
func (n *Node) AccountManager() *accounts.Manager {
|
||||
return n.accman
|
||||
}
|
||||
|
||||
// EventMux retrieves the event multiplexer used by all the network services in
|
||||
// the current protocol stack.
|
||||
func (n *Node) EventMux() *event.TypeMux {
|
||||
return n.eventmux
|
||||
}
|
||||
|
||||
// RegisterAPIs registers the APIs a service provides on the node.
|
||||
func (n *Node) RegisterAPIs(apis []rpc.API) {
|
||||
n.lock.Lock()
|
||||
defer n.lock.Unlock()
|
||||
|
||||
n.rpcAPIs = append(n.rpcAPIs, apis...)
|
||||
}
|
||||
Reference in New Issue
Block a user