diff options
Diffstat (limited to 'eth')
-rw-r--r-- | eth/backend.go | 129 | ||||
-rw-r--r-- | eth/protocol.go | 3 | ||||
-rw-r--r-- | eth/protocol_test.go | 24 |
3 files changed, 75 insertions, 81 deletions
diff --git a/eth/backend.go b/eth/backend.go index ab348afe5..684f15136 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -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 - - MaxPeers int - Port string - NATType string - PMPGateway string + Name string + KeyStore string + DataDir string + LogFile string + LogLevel int + KeyRing 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(ðlogger.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 } diff --git a/eth/protocol.go b/eth/protocol.go index d7a7fa910..fb694c877 100644 --- a/eth/protocol.go +++ b/eth/protocol.go @@ -92,13 +92,14 @@ func EthProtocol(txPool txPool, chainManager chainManager, blockPool blockPool) // the main loop that handles incoming messages // note RemovePeer in the post-disconnect hook func runEthProtocol(txPool txPool, chainManager chainManager, blockPool blockPool, peer *p2p.Peer, rw p2p.MsgReadWriter) (err error) { + id := peer.ID() self := ðProtocol{ txPool: txPool, chainManager: chainManager, blockPool: blockPool, rw: rw, peer: peer, - id: fmt.Sprintf("%x", peer.Identity().Pubkey()[:8]), + id: fmt.Sprintf("%x", id[:8]), } err = self.handleStatus() if err == nil { diff --git a/eth/protocol_test.go b/eth/protocol_test.go index 1fe6d8f6b..a91806a1c 100644 --- a/eth/protocol_test.go +++ b/eth/protocol_test.go @@ -14,6 +14,7 @@ import ( "github.com/ethereum/go-ethereum/ethutil" ethlogger "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discover" ) var sys = ethlogger.NewStdLogSystem(os.Stdout, log.LstdFlags, ethlogger.LogLevel(ethlogger.DebugDetailLevel)) @@ -128,26 +129,11 @@ func (self *testBlockPool) RemovePeer(peerId string) { } } -// TODO: refactor this into p2p/client_identity -type peerId struct { - pubkey []byte -} - -func (self *peerId) String() string { - return "test peer" -} - -func (self *peerId) Pubkey() (pubkey []byte) { - pubkey = self.pubkey - if len(pubkey) == 0 { - pubkey = crypto.GenerateNewKeyPair().PublicKey - self.pubkey = pubkey - } - return -} - func testPeer() *p2p.Peer { - return p2p.NewPeer(&peerId{}, []p2p.Cap{}) + var id discover.NodeID + pk := crypto.GenerateNewKeyPair().PublicKey + copy(id[:], pk) + return p2p.NewPeer(id, "test peer", []p2p.Cap{}) } type ethProtocolTester struct { |