| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | package eth | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 	"net" | 
					
						
							|  |  |  | 	"sync" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/core" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/crypto" | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/ethdb" | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 	"github.com/ethereum/go-ethereum/ethutil" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/event" | 
					
						
							|  |  |  | 	ethlogger "github.com/ethereum/go-ethereum/logger" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/p2p" | 
					
						
							| 
									
										
										
										
											2014-12-14 20:08:24 +00:00
										 |  |  | 	"github.com/ethereum/go-ethereum/pow/ezp" | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 	"github.com/ethereum/go-ethereum/rpc" | 
					
						
							| 
									
										
										
										
											2014-12-15 12:01:55 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/whisper" | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const ( | 
					
						
							| 
									
										
										
										
											2015-01-06 13:31:52 +01:00
										 |  |  | 	seedNodeAddress = "poc-8.ethdev.com:30303" | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-05 17:10:42 +01:00
										 |  |  | 	Shh  bool | 
					
						
							|  |  |  | 	Dial bool | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 	KeyManager *crypto.KeyManager | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | var logger = ethlogger.NewLogger("SERV") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type Ethereum struct { | 
					
						
							|  |  |  | 	// Channel for shutting down the ethereum | 
					
						
							|  |  |  | 	shutdownChan chan bool | 
					
						
							|  |  |  | 	quit         chan bool | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// DB interface | 
					
						
							| 
									
										
										
										
											2014-12-15 12:01:55 +01:00
										 |  |  | 	db        ethutil.Database | 
					
						
							|  |  |  | 	blacklist p2p.Blacklist | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//*** SERVICES *** | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 	// State manager for processing new blocks and managing the over all states | 
					
						
							| 
									
										
										
										
											2015-01-05 00:18:44 +01:00
										 |  |  | 	blockProcessor *core.BlockProcessor | 
					
						
							|  |  |  | 	txPool         *core.TxPool | 
					
						
							|  |  |  | 	chainManager   *core.ChainManager | 
					
						
							|  |  |  | 	blockPool      *BlockPool | 
					
						
							|  |  |  | 	whisper        *whisper.Whisper | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 	net      *p2p.Server | 
					
						
							| 
									
										
										
										
											2014-12-15 12:01:55 +01:00
										 |  |  | 	eventMux *event.TypeMux | 
					
						
							|  |  |  | 	txSub    event.Subscription | 
					
						
							|  |  |  | 	blockSub event.Subscription | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-15 12:01:55 +01:00
										 |  |  | 	RpcServer  *rpc.JsonRpcServer | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 	keyManager *crypto.KeyManager | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	clientIdentity p2p.ClientIdentity | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 	logger         ethlogger.LogSystem | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	synclock  sync.Mutex | 
					
						
							|  |  |  | 	syncGroup sync.WaitGroup | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-15 11:37:23 +01:00
										 |  |  | 	Mining bool | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | func New(config *Config) (*Ethereum, error) { | 
					
						
							|  |  |  | 	// Boostrap database | 
					
						
							|  |  |  | 	logger := ethlogger.New(config.DataDir, config.LogFile, config.LogLevel) | 
					
						
							| 
									
										
										
										
											2015-01-07 13:17:48 +01:00
										 |  |  | 	db, err := ethdb.NewLDBDatabase("blockchain") | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Perform database sanity checks | 
					
						
							|  |  |  | 	d, _ := db.Get([]byte("ProtocolVersion")) | 
					
						
							|  |  |  | 	protov := ethutil.NewValue(d).Uint() | 
					
						
							|  |  |  | 	if protov != ProtocolVersion && protov != 0 { | 
					
						
							|  |  |  | 		return nil, fmt.Errorf("Database version mismatch. Protocol(%d / %d). `rm -rf %s`", protov, ProtocolVersion, ethutil.Config.ExecPath+"/database") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Create new keymanager | 
					
						
							|  |  |  | 	var keyManager *crypto.KeyManager | 
					
						
							|  |  |  | 	switch config.KeyStore { | 
					
						
							|  |  |  | 	case "db": | 
					
						
							|  |  |  | 		keyManager = crypto.NewDBKeyManager(db) | 
					
						
							|  |  |  | 	case "file": | 
					
						
							|  |  |  | 		keyManager = crypto.NewFileKeyManager(config.DataDir) | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return nil, fmt.Errorf("unknown keystore type: %s", config.KeyStore) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// 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()) | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	saveProtocolVersion(db) | 
					
						
							| 
									
										
										
										
											2015-01-07 13:17:48 +01:00
										 |  |  | 	//ethutil.Config.Db = db | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	eth := &Ethereum{ | 
					
						
							| 
									
										
										
										
											2014-12-15 11:37:23 +01:00
										 |  |  | 		shutdownChan:   make(chan bool), | 
					
						
							|  |  |  | 		quit:           make(chan bool), | 
					
						
							|  |  |  | 		db:             db, | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 		keyManager:     keyManager, | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 		clientIdentity: clientId, | 
					
						
							| 
									
										
										
										
											2014-12-15 12:01:55 +01:00
										 |  |  | 		blacklist:      p2p.NewBlacklist(), | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 		eventMux:       &event.TypeMux{}, | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 		logger:         logger, | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-07 13:17:48 +01:00
										 |  |  | 	eth.chainManager = core.NewChainManager(db, eth.EventMux()) | 
					
						
							| 
									
										
										
										
											2015-01-02 12:26:55 +01:00
										 |  |  | 	eth.txPool = core.NewTxPool(eth.EventMux()) | 
					
						
							| 
									
										
										
										
											2015-01-07 13:17:48 +01:00
										 |  |  | 	eth.blockProcessor = core.NewBlockProcessor(db, eth.txPool, eth.chainManager, eth.EventMux()) | 
					
						
							| 
									
										
										
										
											2015-01-05 00:18:44 +01:00
										 |  |  | 	eth.chainManager.SetProcessor(eth.blockProcessor) | 
					
						
							| 
									
										
										
										
											2014-12-15 12:01:55 +01:00
										 |  |  | 	eth.whisper = whisper.New() | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	hasBlock := eth.chainManager.HasBlock | 
					
						
							|  |  |  | 	insertChain := eth.chainManager.InsertChain | 
					
						
							| 
									
										
										
										
											2014-12-15 11:37:23 +01:00
										 |  |  | 	eth.blockPool = NewBlockPool(hasBlock, insertChain, ezp.Verify) | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ethProto := EthProtocol(eth.txPool, eth.chainManager, eth.blockPool) | 
					
						
							| 
									
										
										
										
											2015-01-08 22:18:23 +01:00
										 |  |  | 	protocols := []p2p.Protocol{ethProto, eth.whisper.Protocol()} | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 	nat, err := p2p.ParseNAT(config.NATType, config.PMPGateway) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-08 22:18:23 +01:00
										 |  |  | 	fmt.Println(nat) | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	eth.net = &p2p.Server{ | 
					
						
							| 
									
										
										
										
											2015-01-05 17:10:42 +01:00
										 |  |  | 		Identity:  clientId, | 
					
						
							|  |  |  | 		MaxPeers:  config.MaxPeers, | 
					
						
							|  |  |  | 		Protocols: protocols, | 
					
						
							|  |  |  | 		Blacklist: eth.blacklist, | 
					
						
							| 
									
										
										
										
											2015-01-08 22:18:23 +01:00
										 |  |  | 		NAT:       p2p.UPNP(), | 
					
						
							| 
									
										
										
										
											2015-01-05 17:10:42 +01:00
										 |  |  | 		NoDial:    !config.Dial, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if len(config.Port) > 0 { | 
					
						
							|  |  |  | 		eth.net.ListenAddr = ":" + config.Port | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return eth, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (s *Ethereum) KeyManager() *crypto.KeyManager { | 
					
						
							|  |  |  | 	return s.keyManager | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | func (s *Ethereum) Logger() ethlogger.LogSystem { | 
					
						
							|  |  |  | 	return s.logger | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | func (s *Ethereum) ClientIdentity() p2p.ClientIdentity { | 
					
						
							|  |  |  | 	return s.clientIdentity | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (s *Ethereum) ChainManager() *core.ChainManager { | 
					
						
							|  |  |  | 	return s.chainManager | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-05 00:18:44 +01:00
										 |  |  | func (s *Ethereum) BlockProcessor() *core.BlockProcessor { | 
					
						
							|  |  |  | 	return s.blockProcessor | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (s *Ethereum) TxPool() *core.TxPool { | 
					
						
							|  |  |  | 	return s.txPool | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (s *Ethereum) BlockPool() *BlockPool { | 
					
						
							|  |  |  | 	return s.blockPool | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-15 17:09:14 +01:00
										 |  |  | func (s *Ethereum) Whisper() *whisper.Whisper { | 
					
						
							|  |  |  | 	return s.whisper | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 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 { | 
					
						
							| 
									
										
										
										
											2014-12-15 11:37:23 +01:00
										 |  |  | 	// XXX TODO | 
					
						
							|  |  |  | 	return false | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (s *Ethereum) PeerCount() int { | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 	return s.net.PeerCount() | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (s *Ethereum) Peers() []*p2p.Peer { | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 	return s.net.Peers() | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-15 13:00:09 +01:00
										 |  |  | func (s *Ethereum) MaxPeers() int { | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 	return s.net.MaxPeers | 
					
						
							| 
									
										
										
										
											2014-12-15 13:00:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | // Start the ethereum | 
					
						
							|  |  |  | func (s *Ethereum) Start(seed bool) error { | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 	err := s.net.Start() | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-05 17:10:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Start services | 
					
						
							|  |  |  | 	s.txPool.Start() | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 	s.blockPool.Start() | 
					
						
							| 
									
										
										
										
											2015-01-05 17:10:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if s.whisper != nil { | 
					
						
							|  |  |  | 		s.whisper.Start() | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// broadcast transactions | 
					
						
							|  |  |  | 	s.txSub = s.eventMux.Subscribe(core.TxPreEvent{}) | 
					
						
							|  |  |  | 	go s.txBroadcastLoop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// broadcast mined blocks | 
					
						
							|  |  |  | 	s.blockSub = s.eventMux.Subscribe(core.NewMinedBlockEvent{}) | 
					
						
							|  |  |  | 	go s.blockBroadcastLoop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// TODO: read peers here | 
					
						
							|  |  |  | 	if seed { | 
					
						
							|  |  |  | 		logger.Infof("Connect to seed node %v", seedNodeAddress) | 
					
						
							|  |  |  | 		if err := s.SuggestPeer(seedNodeAddress); err != nil { | 
					
						
							| 
									
										
										
										
											2015-01-19 11:20:12 +01:00
										 |  |  | 			logger.Infoln(err) | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	logger.Infoln("Server started") | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *Ethereum) SuggestPeer(addr string) error { | 
					
						
							|  |  |  | 	netaddr, err := net.ResolveTCPAddr("tcp", addr) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		logger.Errorf("couldn't resolve %s:", addr, err) | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 	self.net.SuggestPeer(netaddr.IP, netaddr.Port, nil) | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (s *Ethereum) Stop() { | 
					
						
							|  |  |  | 	// Close the database | 
					
						
							|  |  |  | 	defer s.db.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	close(s.quit) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	s.txSub.Unsubscribe()    // quits txBroadcastLoop | 
					
						
							|  |  |  | 	s.blockSub.Unsubscribe() // quits blockBroadcastLoop | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if s.RpcServer != nil { | 
					
						
							|  |  |  | 		s.RpcServer.Stop() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	s.txPool.Stop() | 
					
						
							|  |  |  | 	s.eventMux.Stop() | 
					
						
							|  |  |  | 	s.blockPool.Stop() | 
					
						
							| 
									
										
										
										
											2015-01-05 17:10:42 +01:00
										 |  |  | 	if s.whisper != nil { | 
					
						
							|  |  |  | 		s.whisper.Stop() | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	logger.Infoln("Server stopped") | 
					
						
							|  |  |  | 	close(s.shutdownChan) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // This function will wait for a shutdown and resumes main thread execution | 
					
						
							|  |  |  | func (s *Ethereum) WaitForShutdown() { | 
					
						
							|  |  |  | 	<-s.shutdownChan | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // now tx broadcasting is taken out of txPool | 
					
						
							|  |  |  | // handled here via subscription, efficiency? | 
					
						
							|  |  |  | func (self *Ethereum) txBroadcastLoop() { | 
					
						
							|  |  |  | 	// automatically stops if unsubscribe | 
					
						
							|  |  |  | 	for obj := range self.txSub.Chan() { | 
					
						
							|  |  |  | 		event := obj.(core.TxPreEvent) | 
					
						
							| 
									
										
										
										
											2015-01-05 17:10:42 +01:00
										 |  |  | 		self.net.Broadcast("eth", TxMsg, event.Tx.RlpData()) | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *Ethereum) blockBroadcastLoop() { | 
					
						
							|  |  |  | 	// automatically stops if unsubscribe | 
					
						
							| 
									
										
										
										
											2015-01-05 17:10:42 +01:00
										 |  |  | 	for obj := range self.blockSub.Chan() { | 
					
						
							| 
									
										
										
										
											2015-01-02 22:19:58 +01:00
										 |  |  | 		switch ev := obj.(type) { | 
					
						
							|  |  |  | 		case core.NewMinedBlockEvent: | 
					
						
							| 
									
										
										
										
											2015-01-05 17:10:42 +01:00
										 |  |  | 			self.net.Broadcast("eth", NewBlockMsg, ev.Block.RlpData(), ev.Block.Td) | 
					
						
							| 
									
										
										
										
											2015-01-02 22:19:58 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-12-14 18:03:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func saveProtocolVersion(db ethutil.Database) { | 
					
						
							|  |  |  | 	d, _ := db.Get([]byte("ProtocolVersion")) | 
					
						
							|  |  |  | 	protocolVersion := ethutil.NewValue(d).Uint() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if protocolVersion == 0 { | 
					
						
							|  |  |  | 		db.Put([]byte("ProtocolVersion"), ethutil.NewValue(ProtocolVersion).Bytes()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |