This commit is contained in:
obscuren
2015-02-13 15:35:54 +01:00
52 changed files with 4872 additions and 1960 deletions

View File

@ -1,9 +1,9 @@
package eth
import (
"crypto/ecdsa"
"fmt"
"net"
"sync"
"strings"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto"
@ -12,27 +12,35 @@ import (
"github.com/ethereum/go-ethereum/event"
ethlogger "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/discover"
"github.com/ethereum/go-ethereum/p2p/nat"
"github.com/ethereum/go-ethereum/pow/ezp"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/whisper"
)
var logger = ethlogger.NewLogger("SERV")
type Config struct {
Name string
Version string
Identifier string
KeyStore string
DataDir string
LogFile string
LogLevel int
LogFormat string
KeyRing string
Name string
KeyStore string
DataDir string
LogFile string
LogLevel int
KeyRing string
MaxPeers int
Port string
NATType string
PMPGateway string
MaxPeers int
Port string
// This should be a space-separated list of
// discovery node URLs.
BootNodes string
// This key is used to identify the node on the network.
// If nil, an ephemeral key is used.
NodeKey *ecdsa.PrivateKey
NAT nat.Interface
Shh bool
Dial bool
@ -42,6 +50,22 @@ type Config struct {
var logger = ethlogger.NewLogger("SERV")
var jsonlogger = ethlogger.NewJsonLogger()
func (cfg *Config) parseBootNodes() []*discover.Node {
var ns []*discover.Node
for _, url := range strings.Split(cfg.BootNodes, " ") {
if url == "" {
continue
}
n, err := discover.ParseNode(url)
if err != nil {
logger.Errorf("Bootstrap URL %s: %v\n", url, err)
continue
}
ns = append(ns, n)
}
return ns
}
type Ethereum struct {
// Channel for shutting down the ethereum
shutdownChan chan bool
@ -68,11 +92,7 @@ type Ethereum struct {
WsServer rpc.RpcServer
keyManager *crypto.KeyManager
clientIdentity p2p.ClientIdentity
logger ethlogger.LogSystem
synclock sync.Mutex
syncGroup sync.WaitGroup
logger ethlogger.LogSystem
Mining bool
}
@ -105,21 +125,17 @@ func New(config *Config) (*Ethereum, error) {
// Initialise the keyring
keyManager.Init(config.KeyRing, 0, false)
// Create a new client id for this instance. This will help identifying the node on the network
clientId := p2p.NewSimpleClientIdentity(config.Name, config.Version, config.Identifier, keyManager.PublicKey())
saveProtocolVersion(db)
//ethutil.Config.Db = db
eth := &Ethereum{
shutdownChan: make(chan bool),
quit: make(chan bool),
db: db,
keyManager: keyManager,
clientIdentity: clientId,
blacklist: p2p.NewBlacklist(),
eventMux: &event.TypeMux{},
logger: logger,
shutdownChan: make(chan bool),
quit: make(chan bool),
db: db,
keyManager: keyManager,
blacklist: p2p.NewBlacklist(),
eventMux: &event.TypeMux{},
logger: logger,
}
eth.chainManager = core.NewChainManager(db, eth.EventMux())
@ -134,21 +150,22 @@ func New(config *Config) (*Ethereum, error) {
ethProto := EthProtocol(eth.txPool, eth.chainManager, eth.blockPool)
protocols := []p2p.Protocol{ethProto, eth.whisper.Protocol()}
nat, err := p2p.ParseNAT(config.NATType, config.PMPGateway)
if err != nil {
return nil, err
netprv := config.NodeKey
if netprv == nil {
if netprv, err = crypto.GenerateKey(); err != nil {
return nil, fmt.Errorf("could not generate server key: %v", err)
}
}
eth.net = &p2p.Server{
Identity: clientId,
MaxPeers: config.MaxPeers,
Protocols: protocols,
Blacklist: eth.blacklist,
NAT: nat,
NoDial: !config.Dial,
PrivateKey: netprv,
Name: config.Name,
MaxPeers: config.MaxPeers,
Protocols: protocols,
Blacklist: eth.blacklist,
NAT: config.NAT,
NoDial: !config.Dial,
BootstrapNodes: config.parseBootNodes(),
}
if len(config.Port) > 0 {
eth.net.ListenAddr = ":" + config.Port
}
@ -164,8 +181,8 @@ func (s *Ethereum) Logger() ethlogger.LogSystem {
return s.logger
}
func (s *Ethereum) ClientIdentity() p2p.ClientIdentity {
return s.clientIdentity
func (s *Ethereum) Name() string {
return s.net.Name
}
func (s *Ethereum) ChainManager() *core.ChainManager {
@ -221,7 +238,7 @@ func (s *Ethereum) Coinbase() []byte {
}
// Start the ethereum
func (s *Ethereum) Start(seedNode string) error {
func (s *Ethereum) Start() error {
jsonlogger.LogJson(&ethlogger.LogStarting{
ClientString: s.ClientIdentity().String(),
Coinbase: ethutil.Bytes2Hex(s.KeyManager().Address()),
@ -250,26 +267,16 @@ func (s *Ethereum) Start(seedNode string) error {
s.blockSub = s.eventMux.Subscribe(core.NewMinedBlockEvent{})
go s.blockBroadcastLoop()
// TODO: read peers here
if len(seedNode) > 0 {
logger.Infof("Connect to seed node %v", seedNode)
if err := s.SuggestPeer(seedNode); err != nil {
logger.Infoln(err)
}
}
logger.Infoln("Server started")
return nil
}
func (self *Ethereum) SuggestPeer(addr string) error {
netaddr, err := net.ResolveTCPAddr("tcp", addr)
func (self *Ethereum) SuggestPeer(nodeURL string) error {
n, err := discover.ParseNode(nodeURL)
if err != nil {
logger.Errorf("couldn't resolve %s:", addr, err)
return err
return fmt.Errorf("invalid node URL: %v", err)
}
self.net.SuggestPeer(netaddr.IP, netaddr.Port, nil)
self.net.SuggestPeer(n)
return nil
}