diff options
author | Paweł Bylica <pawel.bylica@imapp.pl> | 2015-02-24 01:39:05 +0800 |
---|---|---|
committer | Paweł Bylica <pawel.bylica@imapp.pl> | 2015-02-24 01:39:05 +0800 |
commit | 114c3b4efe7f30ab7be0bec013210e7b4c3d08d7 (patch) | |
tree | 5230f6fee87dcbac36e1d71d6ab731b55eab8268 /eth | |
parent | b9894c1d0979b9f3e8428b1dc230f1ece106f676 (diff) | |
parent | dd086791acf477da7641c168f82de70ed0b2dca6 (diff) | |
download | go-tangerine-114c3b4efe7f30ab7be0bec013210e7b4c3d08d7.tar go-tangerine-114c3b4efe7f30ab7be0bec013210e7b4c3d08d7.tar.gz go-tangerine-114c3b4efe7f30ab7be0bec013210e7b4c3d08d7.tar.bz2 go-tangerine-114c3b4efe7f30ab7be0bec013210e7b4c3d08d7.tar.lz go-tangerine-114c3b4efe7f30ab7be0bec013210e7b4c3d08d7.tar.xz go-tangerine-114c3b4efe7f30ab7be0bec013210e7b4c3d08d7.tar.zst go-tangerine-114c3b4efe7f30ab7be0bec013210e7b4c3d08d7.zip |
Merge remote-tracking branch 'upstream/develop' into evmjit
Diffstat (limited to 'eth')
-rw-r--r-- | eth/backend.go | 254 | ||||
-rw-r--r-- | eth/block_pool_test.go | 1 | ||||
-rw-r--r-- | eth/protocol.go | 5 | ||||
-rw-r--r-- | eth/protocol_test.go | 24 |
4 files changed, 140 insertions, 144 deletions
diff --git a/eth/backend.go b/eth/backend.go index 43e757435..0e5d24429 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -1,9 +1,11 @@ package eth import ( + "crypto/ecdsa" "fmt" - "net" - "sync" + "io/ioutil" + "path" + "strings" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/crypto" @@ -11,34 +13,95 @@ import ( "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/event" ethlogger "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/miner" "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" ) -type Config struct { - Name string - Version string - Identifier string - KeyStore string - DataDir string - LogFile string - LogLevel int - KeyRing string - - MaxPeers int - Port string - NATType string - PMPGateway string +var ( + logger = ethlogger.NewLogger("SERV") + jsonlogger = ethlogger.NewJsonLogger() + + defaultBootNodes = []*discover.Node{ + // ETH/DEV cmd/bootnode + discover.MustParseNode("enode://6cdd090303f394a1cac34ecc9f7cda18127eafa2a3a06de39f6d920b0e583e062a7362097c7c65ee490a758b442acd5c80c6fce4b148c6a391e946b45131365b@54.169.166.226:30303"), + // ETH/DEV cpp-ethereum (poc-8.ethdev.com) + discover.MustParseNode("enode://4a44599974518ea5b0f14c31c4463692ac0329cb84851f3435e6d1b18ee4eae4aa495f846a0fa1219bd58035671881d44423876e57db2abd57254d0197da0ebe@5.1.83.226:30303"), + } +) +type Config struct { + Name string + KeyStore string + DataDir string + LogFile string + LogLevel int + KeyRing string + LogFormat 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 + MinerThreads int + KeyManager *crypto.KeyManager } -var logger = ethlogger.NewLogger("SERV") +func (cfg *Config) parseBootNodes() []*discover.Node { + if cfg.BootNodes == "" { + return defaultBootNodes + } + 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 +} + +func (cfg *Config) nodeKey() (*ecdsa.PrivateKey, error) { + // use explicit key from command line args if set + if cfg.NodeKey != nil { + return cfg.NodeKey, nil + } + // use persistent key if present + keyfile := path.Join(cfg.DataDir, "nodekey") + key, err := crypto.LoadECDSA(keyfile) + if err == nil { + return key, nil + } + // no persistent key, generate and store a new one + if key, err = crypto.GenerateKey(); err != nil { + return nil, fmt.Errorf("could not generate server key: %v", err) + } + if err := ioutil.WriteFile(keyfile, crypto.FromECDSA(key), 0600); err != nil { + logger.Errorln("could not persist nodekey: ", err) + } + return key, nil +} type Ethereum struct { // Channel for shutting down the ethereum @@ -61,23 +124,20 @@ type Ethereum struct { eventMux *event.TypeMux txSub event.Subscription blockSub event.Subscription + miner *miner.Miner RpcServer rpc.RpcServer WsServer rpc.RpcServer keyManager *crypto.KeyManager - clientIdentity p2p.ClientIdentity - logger ethlogger.LogSystem - - synclock sync.Mutex - syncGroup sync.WaitGroup + logger ethlogger.LogSystem Mining bool } func New(config *Config) (*Ethereum, error) { // Boostrap database - logger := ethlogger.New(config.DataDir, config.LogFile, config.LogLevel) + logger := ethlogger.New(config.DataDir, config.LogFile, config.LogLevel, config.LogFormat) db, err := ethdb.NewLDBDatabase("blockchain") if err != nil { return nil, err @@ -103,21 +163,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()) @@ -125,28 +181,32 @@ func New(config *Config) (*Ethereum, error) { eth.blockProcessor = core.NewBlockProcessor(db, eth.txPool, eth.chainManager, eth.EventMux()) eth.chainManager.SetProcessor(eth.blockProcessor) eth.whisper = whisper.New() + eth.miner = miner.New(keyManager.Address(), eth, config.MinerThreads) hasBlock := eth.chainManager.HasBlock insertChain := eth.chainManager.InsertChain eth.blockPool = NewBlockPool(hasBlock, insertChain, ezp.Verify) - ethProto := EthProtocol(eth.txPool, eth.chainManager, eth.blockPool) - protocols := []p2p.Protocol{ethProto, eth.whisper.Protocol()} - - nat, err := p2p.ParseNAT(config.NATType, config.PMPGateway) + netprv, err := config.nodeKey() if err != nil { return nil, err } + ethProto := EthProtocol(eth.txPool, eth.chainManager, eth.blockPool) + protocols := []p2p.Protocol{ethProto} + if config.Shh { + protocols = append(protocols, eth.whisper.Protocol()) + } 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 } @@ -154,72 +214,30 @@ func New(config *Config) (*Ethereum, error) { return eth, nil } -func (s *Ethereum) KeyManager() *crypto.KeyManager { - return s.keyManager -} - -func (s *Ethereum) Logger() ethlogger.LogSystem { - return s.logger -} - -func (s *Ethereum) ClientIdentity() p2p.ClientIdentity { - return s.clientIdentity -} - -func (s *Ethereum) ChainManager() *core.ChainManager { - return s.chainManager -} - -func (s *Ethereum) BlockProcessor() *core.BlockProcessor { - return s.blockProcessor -} - -func (s *Ethereum) TxPool() *core.TxPool { - return s.txPool -} - -func (s *Ethereum) BlockPool() *BlockPool { - return s.blockPool -} - -func (s *Ethereum) Whisper() *whisper.Whisper { - return s.whisper -} - -func (s *Ethereum) EventMux() *event.TypeMux { - return s.eventMux -} -func (self *Ethereum) Db() ethutil.Database { - return self.db -} - -func (s *Ethereum) IsMining() bool { - return s.Mining -} - -func (s *Ethereum) IsListening() bool { - // XXX TODO - return false -} - -func (s *Ethereum) PeerCount() int { - return s.net.PeerCount() -} - -func (s *Ethereum) Peers() []*p2p.Peer { - return s.net.Peers() -} - -func (s *Ethereum) MaxPeers() int { - return s.net.MaxPeers -} - -func (s *Ethereum) Coinbase() []byte { - return nil // TODO -} +func (s *Ethereum) KeyManager() *crypto.KeyManager { return s.keyManager } +func (s *Ethereum) Logger() ethlogger.LogSystem { return s.logger } +func (s *Ethereum) Name() string { return s.net.Name } +func (s *Ethereum) ChainManager() *core.ChainManager { return s.chainManager } +func (s *Ethereum) BlockProcessor() *core.BlockProcessor { return s.blockProcessor } +func (s *Ethereum) TxPool() *core.TxPool { return s.txPool } +func (s *Ethereum) BlockPool() *BlockPool { return s.blockPool } +func (s *Ethereum) Whisper() *whisper.Whisper { return s.whisper } +func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux } +func (s *Ethereum) Db() ethutil.Database { return s.db } +func (s *Ethereum) Miner() *miner.Miner { return s.miner } +func (s *Ethereum) IsListening() bool { return true } // Always listening +func (s *Ethereum) PeerCount() int { return s.net.PeerCount() } +func (s *Ethereum) Peers() []*p2p.Peer { return s.net.Peers() } +func (s *Ethereum) MaxPeers() int { return s.net.MaxPeers } +func (s *Ethereum) Coinbase() []byte { return nil } // TODO // Start the ethereum -func (s *Ethereum) Start(seedNode string) error { +func (s *Ethereum) Start() error { + jsonlogger.LogJson(ðlogger.LogStarting{ + ClientString: s.net.Name, + ProtocolVersion: ProtocolVersion, + }) + err := s.net.Start() if err != nil { return err @@ -241,26 +259,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/block_pool_test.go b/eth/block_pool_test.go index 94c3b43d2..331dbe504 100644 --- a/eth/block_pool_test.go +++ b/eth/block_pool_test.go @@ -613,6 +613,7 @@ func TestInvalidBlock(t *testing.T) { } func TestVerifyPoW(t *testing.T) { + t.Skip("***FIX*** This test is broken") logInit() _, blockPool, blockPoolTester := newTestBlockPool(t) blockPoolTester.blockChain[0] = nil diff --git a/eth/protocol.go b/eth/protocol.go index d7a7fa910..8221c1b29 100644 --- a/eth/protocol.go +++ b/eth/protocol.go @@ -13,7 +13,7 @@ import ( ) const ( - ProtocolVersion = 52 + ProtocolVersion = 54 NetworkId = 0 ProtocolLength = uint64(8) ProtocolMaxMsgSize = 10 * 1024 * 1024 @@ -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 { |