Merge branch 'ethersphere-feature/logging' into develop
This commit is contained in:
		
						commit
						91bdf9e801
					
				
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -9,5 +9,6 @@ | ||||
| *un~ | ||||
| .DS_Store | ||||
| */**/.DS_Store | ||||
| ./ethereum/ethereum | ||||
| ethereum/ethereum | ||||
| ethereal/ethereal | ||||
| 
 | ||||
|  | ||||
| @ -319,7 +319,7 @@ ApplicationWindow { | ||||
| 
 | ||||
| 					Slider { | ||||
| 						id: logLevelSlider | ||||
| 						value: 1 | ||||
| 						value: eth.getLogLevelInt() | ||||
| 						anchors { | ||||
| 							right: parent.right | ||||
| 							top: parent.top | ||||
| @ -332,7 +332,7 @@ ApplicationWindow { | ||||
| 						} | ||||
| 
 | ||||
| 						orientation: Qt.Vertical | ||||
| 						maximumValue: 3 | ||||
| 						maximumValue: 5 | ||||
| 						stepSize: 1 | ||||
| 
 | ||||
| 						onValueChanged: { | ||||
|  | ||||
| @ -1,43 +0,0 @@ | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"flag" | ||||
| ) | ||||
| 
 | ||||
| var Identifier string | ||||
| 
 | ||||
| //var StartMining bool
 | ||||
| var StartRpc bool | ||||
| var RpcPort int | ||||
| var UseUPnP bool | ||||
| var OutboundPort string | ||||
| var ShowGenesis bool | ||||
| var AddPeer string | ||||
| var MaxPeer int | ||||
| var GenAddr bool | ||||
| var UseSeed bool | ||||
| var ImportKey string | ||||
| var ExportKey bool | ||||
| var AssetPath string | ||||
| 
 | ||||
| var Datadir string | ||||
| 
 | ||||
| func Init() { | ||||
| 	flag.StringVar(&Identifier, "id", "", "Custom client identifier") | ||||
| 	flag.StringVar(&OutboundPort, "port", "30303", "listening port") | ||||
| 	flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support") | ||||
| 	flag.IntVar(&MaxPeer, "maxpeer", 10, "maximum desired peers") | ||||
| 	flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on") | ||||
| 	flag.BoolVar(&StartRpc, "rpc", false, "start rpc server") | ||||
| 	flag.StringVar(&AssetPath, "asset_path", "", "absolute path to GUI assets directory") | ||||
| 
 | ||||
| 	flag.BoolVar(&ShowGenesis, "genesis", false, "prints genesis header and exits") | ||||
| 	flag.BoolVar(&UseSeed, "seed", true, "seed peers") | ||||
| 	flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key") | ||||
| 	flag.BoolVar(&ExportKey, "export", false, "export private key") | ||||
| 	flag.StringVar(&ImportKey, "import", "", "imports the given private key (hex)") | ||||
| 
 | ||||
| 	flag.StringVar(&Datadir, "datadir", ".ethereal", "specifies the datadir to use. Takes precedence over config file.") | ||||
| 
 | ||||
| 	flag.Parse() | ||||
| } | ||||
| @ -1,142 +0,0 @@ | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/ethereum/eth-go" | ||||
| 	"github.com/ethereum/eth-go/ethutil" | ||||
| 	"github.com/ethereum/go-ethereum/ethereal/ui" | ||||
| 	"github.com/ethereum/go-ethereum/utils" | ||||
| 	"github.com/go-qml/qml" | ||||
| 	"github.com/rakyll/globalconf" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"os/signal" | ||||
| 	"path" | ||||
| 	"runtime" | ||||
| ) | ||||
| 
 | ||||
| const Debug = true | ||||
| 
 | ||||
| // Register interrupt handlers so we can stop the ethereum
 | ||||
| func RegisterInterupts(s *eth.Ethereum) { | ||||
| 	// Buffered chan of one is enough
 | ||||
| 	c := make(chan os.Signal, 1) | ||||
| 	// Notify about interrupts for now
 | ||||
| 	signal.Notify(c, os.Interrupt) | ||||
| 	go func() { | ||||
| 		for sig := range c { | ||||
| 			fmt.Printf("Shutting down (%v) ... \n", sig) | ||||
| 
 | ||||
| 			s.Stop() | ||||
| 		} | ||||
| 	}() | ||||
| } | ||||
| 
 | ||||
| func main() { | ||||
| 	Init() | ||||
| 
 | ||||
| 	qml.Init(nil) | ||||
| 
 | ||||
| 	runtime.GOMAXPROCS(runtime.NumCPU()) | ||||
| 
 | ||||
| 	g, err := globalconf.NewWithOptions(&globalconf.Options{ | ||||
| 		Filename: path.Join(ethutil.ApplicationFolder(Datadir), "conf.ini"), | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		fmt.Println(err) | ||||
| 	} else { | ||||
| 		g.ParseAll() | ||||
| 	} | ||||
| 	ethutil.ReadConfig(Datadir, ethutil.LogFile|ethutil.LogStd, g, Identifier) | ||||
| 
 | ||||
| 	// Instantiated a eth stack
 | ||||
| 	ethereum, err := eth.New(eth.CapDefault, UseUPnP) | ||||
| 	if err != nil { | ||||
| 		log.Println("eth start err:", err) | ||||
| 		return | ||||
| 	} | ||||
| 	ethereum.Port = OutboundPort | ||||
| 
 | ||||
| 	if GenAddr { | ||||
| 		fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") | ||||
| 
 | ||||
| 		var r string | ||||
| 		fmt.Scanln(&r) | ||||
| 		for ; ; fmt.Scanln(&r) { | ||||
| 			if r == "n" || r == "y" { | ||||
| 				break | ||||
| 			} else { | ||||
| 				fmt.Printf("Yes or no?", r) | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if r == "y" { | ||||
| 			utils.CreateKeyPair(true) | ||||
| 		} | ||||
| 		os.Exit(0) | ||||
| 	} else { | ||||
| 		if len(ImportKey) > 0 { | ||||
| 			fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") | ||||
| 			var r string | ||||
| 			fmt.Scanln(&r) | ||||
| 			for ; ; fmt.Scanln(&r) { | ||||
| 				if r == "n" || r == "y" { | ||||
| 					break | ||||
| 				} else { | ||||
| 					fmt.Printf("Yes or no?", r) | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			if r == "y" { | ||||
| 				utils.ImportPrivateKey(ImportKey) | ||||
| 				os.Exit(0) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if ExportKey { | ||||
| 		keyPair := ethutil.GetKeyRing().Get(0) | ||||
| 		fmt.Printf(` | ||||
| Generating new address and keypair. | ||||
| Please keep your keys somewhere save. | ||||
| 
 | ||||
| ++++++++++++++++ KeyRing +++++++++++++++++++ | ||||
| addr: %x | ||||
| prvk: %x | ||||
| pubk: %x | ||||
| ++++++++++++++++++++++++++++++++++++++++++++ | ||||
| save these words so you can restore your account later: %s | ||||
| `, keyPair.Address(), keyPair.PrivateKey, keyPair.PublicKey) | ||||
| 
 | ||||
| 		os.Exit(0) | ||||
| 	} | ||||
| 
 | ||||
| 	if ShowGenesis { | ||||
| 		fmt.Println(ethereum.BlockChain().Genesis()) | ||||
| 		os.Exit(0) | ||||
| 	} | ||||
| 
 | ||||
| 	/* | ||||
| 		if StartMining { | ||||
| 			utils.DoMining(ethereum) | ||||
| 		} | ||||
| 	*/ | ||||
| 
 | ||||
| 	if StartRpc { | ||||
| 		utils.DoRpc(ethereum, RpcPort) | ||||
| 	} | ||||
| 
 | ||||
| 	log.Printf("Starting Ethereum GUI v%s\n", ethutil.Config.Ver) | ||||
| 
 | ||||
| 	// Set the max peers
 | ||||
| 	ethereum.MaxPeers = MaxPeer | ||||
| 
 | ||||
| 	gui := ethui.New(ethereum) | ||||
| 
 | ||||
| 	ethereum.Start(UseSeed) | ||||
| 
 | ||||
| 	gui.Start(AssetPath) | ||||
| 
 | ||||
| 	// Wait for shutdown
 | ||||
| 	ethereum.WaitForShutdown() | ||||
| } | ||||
							
								
								
									
										95
									
								
								ethereal/flags.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								ethereal/flags.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,95 @@ | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"bitbucket.org/kardianos/osext" | ||||
| 	"flag" | ||||
| 	"fmt" | ||||
| 	"github.com/ethereum/eth-go/ethlog" | ||||
| 	"os" | ||||
| 	"os/user" | ||||
| 	"path" | ||||
| 	"path/filepath" | ||||
| 	"runtime" | ||||
| ) | ||||
| 
 | ||||
| var Identifier string | ||||
| var StartRpc bool | ||||
| var RpcPort int | ||||
| var UseUPnP bool | ||||
| var OutboundPort string | ||||
| var ShowGenesis bool | ||||
| var AddPeer string | ||||
| var MaxPeer int | ||||
| var GenAddr bool | ||||
| var UseSeed bool | ||||
| var ImportKey string | ||||
| var ExportKey bool | ||||
| var NonInteractive bool | ||||
| var Datadir string | ||||
| var LogFile string | ||||
| var ConfigFile string | ||||
| var DebugFile string | ||||
| var LogLevel int | ||||
| 
 | ||||
| // flags specific to gui client
 | ||||
| var AssetPath string | ||||
| 
 | ||||
| func defaultAssetPath() string { | ||||
| 	var assetPath string | ||||
| 	// If the current working directory is the go-ethereum dir
 | ||||
| 	// assume a debug build and use the source directory as
 | ||||
| 	// asset directory.
 | ||||
| 	pwd, _ := os.Getwd() | ||||
| 	if pwd == path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "ethereal") { | ||||
| 		assetPath = path.Join(pwd, "assets") | ||||
| 	} else { | ||||
| 		switch runtime.GOOS { | ||||
| 		case "darwin": | ||||
| 			// Get Binary Directory
 | ||||
| 			exedir, _ := osext.ExecutableFolder() | ||||
| 			assetPath = filepath.Join(exedir, "../Resources") | ||||
| 		case "linux": | ||||
| 			assetPath = "/usr/share/ethereal" | ||||
| 		case "window": | ||||
| 			fallthrough | ||||
| 		default: | ||||
| 			assetPath = "." | ||||
| 		} | ||||
| 	} | ||||
| 	return assetPath | ||||
| } | ||||
| 
 | ||||
| func defaultDataDir() string { | ||||
| 	usr, _ := user.Current() | ||||
| 	return path.Join(usr.HomeDir, ".ethereal") | ||||
| } | ||||
| 
 | ||||
| var defaultConfigFile = path.Join(defaultDataDir(), "conf.ini") | ||||
| 
 | ||||
| func Init() { | ||||
| 	flag.Usage = func() { | ||||
| 		fmt.Fprintf(os.Stderr, "%s [options] [filename]:\noptions precedence: default < config file < environment variables < command line\n", os.Args[0]) | ||||
| 		flag.PrintDefaults() | ||||
| 	} | ||||
| 
 | ||||
| 	flag.StringVar(&Identifier, "id", "", "Custom client identifier") | ||||
| 	flag.StringVar(&OutboundPort, "port", "30303", "listening port") | ||||
| 	flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support") | ||||
| 	flag.IntVar(&MaxPeer, "maxpeer", 10, "maximum desired peers") | ||||
| 	flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on") | ||||
| 	flag.BoolVar(&StartRpc, "rpc", false, "start rpc server") | ||||
| 	flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)") | ||||
| 	flag.BoolVar(&UseSeed, "seed", true, "seed peers") | ||||
| 	flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key") | ||||
| 	flag.BoolVar(&ExportKey, "export", false, "export private key") | ||||
| 	flag.StringVar(&LogFile, "logfile", "", "log file (defaults to standard output)") | ||||
| 	flag.StringVar(&ImportKey, "import", "", "imports the given private key (hex)") | ||||
| 	flag.StringVar(&Datadir, "datadir", defaultDataDir(), "specifies the datadir to use") | ||||
| 	flag.StringVar(&ConfigFile, "conf", defaultConfigFile, "config file") | ||||
| 	flag.StringVar(&DebugFile, "debug", "", "debug file (no debugging if not set)") | ||||
| 	flag.IntVar(&LogLevel, "loglevel", int(ethlog.InfoLevel), "loglevel: 0-5: silent,error,warn,info,debug,debug detail)") | ||||
| 
 | ||||
| 	flag.StringVar(&AssetPath, "asset_path", defaultAssetPath(), "absolute path to GUI assets directory") | ||||
| 
 | ||||
| 	flag.Parse() | ||||
| } | ||||
							
								
								
									
										61
									
								
								ethereal/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								ethereal/main.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/ethereum/eth-go/ethlog" | ||||
| 	"github.com/ethereum/go-ethereum/ethereal/ui" | ||||
| 	"github.com/ethereum/go-ethereum/utils" | ||||
| 	"github.com/go-qml/qml" | ||||
| 	"os" | ||||
| 	"runtime" | ||||
| ) | ||||
| 
 | ||||
| func main() { | ||||
| 	runtime.GOMAXPROCS(runtime.NumCPU()) | ||||
| 
 | ||||
| 	qml.Init(nil) | ||||
| 
 | ||||
| 	var interrupted = false | ||||
| 	utils.RegisterInterrupt(func(os.Signal) { | ||||
| 		interrupted = true | ||||
| 	}) | ||||
| 
 | ||||
| 	utils.HandleInterrupt() | ||||
| 
 | ||||
| 	// precedence: code-internal flag default < config file < environment variables < command line
 | ||||
| 	Init() // parsing command line
 | ||||
| 	utils.InitConfig(ConfigFile, Datadir, Identifier, "ETH") | ||||
| 
 | ||||
| 	utils.InitDataDir(Datadir) | ||||
| 
 | ||||
| 	utils.InitLogging(Datadir, LogFile, LogLevel, DebugFile) | ||||
| 
 | ||||
| 	ethereum := utils.NewEthereum(UseUPnP, OutboundPort, MaxPeer) | ||||
| 
 | ||||
| 	// create, import, export keys
 | ||||
| 	utils.KeyTasks(GenAddr, ImportKey, ExportKey, NonInteractive) | ||||
| 
 | ||||
| 	if ShowGenesis { | ||||
| 		utils.ShowGenesis(ethereum) | ||||
| 	} | ||||
| 
 | ||||
| 	if StartRpc { | ||||
| 		utils.StartRpc(ethereum, RpcPort) | ||||
| 	} | ||||
| 
 | ||||
| 	gui := ethui.New(ethereum, LogLevel) | ||||
| 
 | ||||
| 	utils.RegisterInterrupt(func(os.Signal) { | ||||
| 		gui.Stop() | ||||
| 	}) | ||||
| 	utils.StartEthereum(ethereum, UseSeed) | ||||
| 	// gui blocks the main thread
 | ||||
| 	gui.Start(AssetPath) | ||||
| 	// we need to run the interrupt callbacks in case gui is closed
 | ||||
| 	// this skips if we got here by actual interrupt stopping the GUI
 | ||||
| 	if !interrupted { | ||||
| 		utils.RunInterruptCallbacks(os.Interrupt) | ||||
| 	} | ||||
| 	// this blocks the thread
 | ||||
| 	ethereum.WaitForShutdown() | ||||
| 	ethlog.Flush() | ||||
| } | ||||
| @ -6,6 +6,7 @@ import ( | ||||
| 	"github.com/ethereum/eth-go" | ||||
| 	"github.com/ethereum/eth-go/ethchain" | ||||
| 	"github.com/ethereum/eth-go/ethdb" | ||||
| 	"github.com/ethereum/eth-go/ethlog" | ||||
| 	"github.com/ethereum/eth-go/ethpub" | ||||
| 	"github.com/ethereum/eth-go/ethutil" | ||||
| 	"github.com/ethereum/go-ethereum/utils" | ||||
| @ -15,6 +16,8 @@ import ( | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| var logger = ethlog.NewLogger("GUI") | ||||
| 
 | ||||
| type Gui struct { | ||||
| 	// The main application window
 | ||||
| 	win *qml.Window | ||||
| @ -32,11 +35,13 @@ type Gui struct { | ||||
| 
 | ||||
| 	addr []byte | ||||
| 
 | ||||
| 	pub *ethpub.PEthereum | ||||
| 	pub      *ethpub.PEthereum | ||||
| 	logLevel ethlog.LogLevel | ||||
| 	open     bool | ||||
| } | ||||
| 
 | ||||
| // Create GUI, but doesn't start it
 | ||||
| func New(ethereum *eth.Ethereum) *Gui { | ||||
| func New(ethereum *eth.Ethereum, logLevel int) *Gui { | ||||
| 	lib := &EthLib{stateManager: ethereum.StateManager(), blockChain: ethereum.BlockChain(), txPool: ethereum.TxPool()} | ||||
| 	db, err := ethdb.NewLDBDatabase("tx_database") | ||||
| 	if err != nil { | ||||
| @ -52,7 +57,7 @@ func New(ethereum *eth.Ethereum) *Gui { | ||||
| 
 | ||||
| 	pub := ethpub.NewPEthereum(ethereum) | ||||
| 
 | ||||
| 	return &Gui{eth: ethereum, lib: lib, txDb: db, addr: addr, pub: pub} | ||||
| 	return &Gui{eth: ethereum, lib: lib, txDb: db, addr: addr, pub: pub, logLevel: ethlog.LogLevel(logLevel), open: false} | ||||
| } | ||||
| 
 | ||||
| func (gui *Gui) Start(assetPath string) { | ||||
| @ -86,25 +91,39 @@ func (gui *Gui) Start(assetPath string) { | ||||
| 
 | ||||
| 	var win *qml.Window | ||||
| 	var err error | ||||
| 	var addlog = false | ||||
| 	if len(data) == 0 { | ||||
| 		win, err = gui.showKeyImport(context) | ||||
| 	} else { | ||||
| 		win, err = gui.showWallet(context) | ||||
| 
 | ||||
| 		ethutil.Config.Log.AddLogSystem(gui) | ||||
| 		addlog = true | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		ethutil.Config.Log.Infoln("FATAL: asset not found: you can set an alternative asset path on on the command line using option 'asset_path'", err) | ||||
| 		logger.Errorln("asset not found: you can set an alternative asset path on the command line using option 'asset_path'", err) | ||||
| 
 | ||||
| 		panic(err) | ||||
| 	} | ||||
| 
 | ||||
| 	ethutil.Config.Log.Infoln("[GUI] Starting GUI") | ||||
| 
 | ||||
| 	logger.Infoln("Starting GUI") | ||||
| 	gui.open = true | ||||
| 	win.Show() | ||||
| 	// only add the gui logger after window is shown otherwise slider wont be shown
 | ||||
| 	if addlog { | ||||
| 		ethlog.AddLogSystem(gui) | ||||
| 	} | ||||
| 	win.Wait() | ||||
| 	// need to silence gui logger after window closed otherwise logsystem hangs
 | ||||
| 	gui.SetLogLevel(ethlog.Silence) | ||||
| 	gui.open = false | ||||
| } | ||||
| 
 | ||||
| 	gui.eth.Stop() | ||||
| func (gui *Gui) Stop() { | ||||
| 	if gui.open { | ||||
| 		gui.SetLogLevel(ethlog.Silence) | ||||
| 		gui.open = false | ||||
| 		gui.win.Hide() | ||||
| 	} | ||||
| 	logger.Infoln("Stopped") | ||||
| } | ||||
| 
 | ||||
| func (gui *Gui) ToggleMining() { | ||||
| @ -311,22 +330,6 @@ func (gui *Gui) setPeerInfo() { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Logging functions that log directly to the GUI interface
 | ||||
| func (gui *Gui) Println(v ...interface{}) { | ||||
| 	str := strings.TrimRight(fmt.Sprintln(v...), "\n") | ||||
| 	lines := strings.Split(str, "\n") | ||||
| 	for _, line := range lines { | ||||
| 		gui.win.Root().Call("addLog", line) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (gui *Gui) Printf(format string, v ...interface{}) { | ||||
| 	str := strings.TrimRight(fmt.Sprintf(format, v...), "\n") | ||||
| 	lines := strings.Split(str, "\n") | ||||
| 	for _, line := range lines { | ||||
| 		gui.win.Root().Call("addLog", line) | ||||
| 	} | ||||
| } | ||||
| func (gui *Gui) RegisterName(name string) { | ||||
| 	keyPair := ethutil.GetKeyRing().Get(0) | ||||
| 	name = fmt.Sprintf("\"%s\"\n1", name) | ||||
| @ -353,6 +356,34 @@ func (gui *Gui) ClientId() string { | ||||
| 	return ethutil.Config.Identifier | ||||
| } | ||||
| 
 | ||||
| func (gui *Gui) SetLogLevel(level int) { | ||||
| 	ethutil.Config.Log.SetLevel(level) | ||||
| // functions that allow Gui to implement interface ethlog.LogSystem
 | ||||
| func (gui *Gui) SetLogLevel(level ethlog.LogLevel) { | ||||
| 	gui.logLevel = level | ||||
| } | ||||
| 
 | ||||
| func (gui *Gui) GetLogLevel() ethlog.LogLevel { | ||||
| 	return gui.logLevel | ||||
| } | ||||
| 
 | ||||
| // this extra function needed to give int typecast value to gui widget
 | ||||
| // that sets initial loglevel to default
 | ||||
| func (gui *Gui) GetLogLevelInt() int { | ||||
| 	return int(gui.logLevel) | ||||
| } | ||||
| 
 | ||||
| func (gui *Gui) Println(v ...interface{}) { | ||||
| 	gui.printLog(fmt.Sprintln(v...)) | ||||
| } | ||||
| 
 | ||||
| func (gui *Gui) Printf(format string, v ...interface{}) { | ||||
| 	gui.printLog(fmt.Sprintf(format, v...)) | ||||
| } | ||||
| 
 | ||||
| // Print function that logs directly to the GUI
 | ||||
| func (gui *Gui) printLog(s string) { | ||||
| 	str := strings.TrimRight(s, "\n") | ||||
| 	lines := strings.Split(str, "\n") | ||||
| 	for _, line := range lines { | ||||
| 		gui.win.Root().Call("addLog", line) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -96,11 +96,11 @@ func (app *HtmlApplication) NewWatcher(quitChan chan bool) { | ||||
| 				app.watcher.Close() | ||||
| 				break out | ||||
| 			case <-app.watcher.Event: | ||||
| 				//ethutil.Config.Log.Debugln("Got event:", ev)
 | ||||
| 				//logger.Debugln("Got event:", ev)
 | ||||
| 				app.webView.Call("reload") | ||||
| 			case err := <-app.watcher.Error: | ||||
| 				// TODO: Do something here
 | ||||
| 				ethutil.Config.Log.Infoln("Watcher error:", err) | ||||
| 				logger.Infoln("Watcher error:", err) | ||||
| 			} | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| @ -22,7 +22,7 @@ func NewQmlApplication(path string, lib *UiLib) *QmlApplication { | ||||
| func (app *QmlApplication) Create() error { | ||||
| 	component, err := app.engine.LoadFile(app.path) | ||||
| 	if err != nil { | ||||
| 		ethutil.Config.Log.Debugln(err) | ||||
| 		logger.Warnln(err) | ||||
| 	} | ||||
| 	app.win = component.CreateWindow(nil) | ||||
| 
 | ||||
|  | ||||
| @ -1,14 +1,10 @@ | ||||
| package ethui | ||||
| 
 | ||||
| import ( | ||||
| 	"bitbucket.org/kardianos/osext" | ||||
| 	"github.com/ethereum/eth-go" | ||||
| 	"github.com/ethereum/eth-go/ethutil" | ||||
| 	"github.com/go-qml/qml" | ||||
| 	"os" | ||||
| 	"path" | ||||
| 	"path/filepath" | ||||
| 	"runtime" | ||||
| ) | ||||
| 
 | ||||
| type memAddr struct { | ||||
| @ -29,9 +25,6 @@ type UiLib struct { | ||||
| } | ||||
| 
 | ||||
| func NewUiLib(engine *qml.Engine, eth *eth.Ethereum, assetPath string) *UiLib { | ||||
| 	if assetPath == "" { | ||||
| 		assetPath = DefaultAssetPath() | ||||
| 	} | ||||
| 	return &UiLib{engine: engine, eth: eth, assetPath: assetPath} | ||||
| } | ||||
| 
 | ||||
| @ -52,7 +45,7 @@ func (ui *UiLib) OpenHtml(path string) { | ||||
| func (ui *UiLib) Muted(content string) { | ||||
| 	component, err := ui.engine.LoadFile(ui.AssetPath("qml/muted.qml")) | ||||
| 	if err != nil { | ||||
| 		ethutil.Config.Log.Debugln(err) | ||||
| 		logger.Debugln(err) | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| @ -81,6 +74,7 @@ func (ui *UiLib) ConnectToPeer(addr string) { | ||||
| func (ui *UiLib) AssetPath(p string) string { | ||||
| 	return path.Join(ui.assetPath, p) | ||||
| } | ||||
| 
 | ||||
| func (self *UiLib) StartDbWithContractAndData(contractHash, data string) { | ||||
| 	dbWindow := NewDebuggerWindow(self) | ||||
| 	object := self.eth.StateManager().CurrentState().GetStateObject(ethutil.FromHex(contractHash)) | ||||
| @ -104,29 +98,3 @@ func (self *UiLib) StartDebugger() { | ||||
| 
 | ||||
| 	dbWindow.Show() | ||||
| } | ||||
| 
 | ||||
| func DefaultAssetPath() string { | ||||
| 	var base string | ||||
| 	// If the current working directory is the go-ethereum dir
 | ||||
| 	// assume a debug build and use the source directory as
 | ||||
| 	// asset directory.
 | ||||
| 	pwd, _ := os.Getwd() | ||||
| 	if pwd == path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "ethereal") { | ||||
| 		base = path.Join(pwd, "assets") | ||||
| 	} else { | ||||
| 		switch runtime.GOOS { | ||||
| 		case "darwin": | ||||
| 			// Get Binary Directory
 | ||||
| 			exedir, _ := osext.ExecutableFolder() | ||||
| 			base = filepath.Join(exedir, "../Resources") | ||||
| 		case "linux": | ||||
| 			base = "/usr/share/ethereal" | ||||
| 		case "window": | ||||
| 			fallthrough | ||||
| 		default: | ||||
| 			base = "." | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return base | ||||
| } | ||||
|  | ||||
							
								
								
									
										32
									
								
								ethereum/cmd.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								ethereum/cmd.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/ethereum/eth-go" | ||||
| 	"github.com/ethereum/go-ethereum/utils" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| ) | ||||
| 
 | ||||
| func InitJsConsole(ethereum *eth.Ethereum) { | ||||
| 	repl := NewJSRepl(ethereum) | ||||
| 	go repl.Start() | ||||
| 	utils.RegisterInterrupt(func(os.Signal) { | ||||
| 		repl.Stop() | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func ExecJsFile(ethereum *eth.Ethereum, InputFile string) { | ||||
| 	file, err := os.Open(InputFile) | ||||
| 	if err != nil { | ||||
| 		logger.Fatalln(err) | ||||
| 	} | ||||
| 	content, err := ioutil.ReadAll(file) | ||||
| 	if err != nil { | ||||
| 		logger.Fatalln(err) | ||||
| 	} | ||||
| 	re := NewJSRE(ethereum) | ||||
| 	utils.RegisterInterrupt(func(os.Signal) { | ||||
| 		re.Stop() | ||||
| 	}) | ||||
| 	re.Run(string(content)) | ||||
| } | ||||
| @ -1,193 +0,0 @@ | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/ethereum/eth-go" | ||||
| 	"github.com/ethereum/eth-go/ethutil" | ||||
| 	"github.com/ethereum/go-ethereum/utils" | ||||
| 	"github.com/rakyll/globalconf" | ||||
| 	"io/ioutil" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"os/signal" | ||||
| 	"path" | ||||
| 	"runtime" | ||||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| const Debug = true | ||||
| 
 | ||||
| func RegisterInterrupt(cb func(os.Signal)) { | ||||
| 	go func() { | ||||
| 		// Buffered chan of one is enough
 | ||||
| 		c := make(chan os.Signal, 1) | ||||
| 		// Notify about interrupts for now
 | ||||
| 		signal.Notify(c, os.Interrupt) | ||||
| 
 | ||||
| 		for sig := range c { | ||||
| 			cb(sig) | ||||
| 		} | ||||
| 	}() | ||||
| } | ||||
| 
 | ||||
| func confirm(message string) bool { | ||||
| 	fmt.Println(message, "Are you sure? (y/n)") | ||||
| 	var r string | ||||
| 	fmt.Scanln(&r) | ||||
| 	for ; ; fmt.Scanln(&r) { | ||||
| 		if r == "n" || r == "y" { | ||||
| 			break | ||||
| 		} else { | ||||
| 			fmt.Printf("Yes or no?", r) | ||||
| 		} | ||||
| 	} | ||||
| 	return r == "y" | ||||
| } | ||||
| 
 | ||||
| func main() { | ||||
| 	Init() | ||||
| 
 | ||||
| 	runtime.GOMAXPROCS(runtime.NumCPU()) | ||||
| 
 | ||||
| 	// set logger
 | ||||
| 	var logSys *log.Logger | ||||
| 	flags := log.LstdFlags | ||||
| 
 | ||||
| 	var lt ethutil.LoggerType | ||||
| 	if StartJsConsole || len(InputFile) > 0 { | ||||
| 		lt = ethutil.LogFile | ||||
| 	} else { | ||||
| 		lt = ethutil.LogFile | ethutil.LogStd | ||||
| 	} | ||||
| 
 | ||||
| 	g, err := globalconf.NewWithOptions(&globalconf.Options{ | ||||
| 		Filename: path.Join(ethutil.ApplicationFolder(Datadir), "conf.ini"), | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		fmt.Println(err) | ||||
| 	} else { | ||||
| 		g.ParseAll() | ||||
| 	} | ||||
| 	ethutil.ReadConfig(Datadir, lt, g, Identifier) | ||||
| 
 | ||||
| 	logger := ethutil.Config.Log | ||||
| 
 | ||||
| 	if LogFile != "" { | ||||
| 		logfile, err := os.OpenFile(LogFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) | ||||
| 		if err != nil { | ||||
| 			panic(fmt.Sprintf("error opening log file '%s': %v", LogFile, err)) | ||||
| 		} | ||||
| 		defer logfile.Close() | ||||
| 		log.SetOutput(logfile) | ||||
| 		logSys = log.New(logfile, "", flags) | ||||
| 		logger.AddLogSystem(logSys) | ||||
| 	} else { | ||||
| 		logSys = log.New(os.Stdout, "", flags) | ||||
| 	} | ||||
| 
 | ||||
| 	// Instantiated a eth stack
 | ||||
| 	ethereum, err := eth.New(eth.CapDefault, UseUPnP) | ||||
| 	if err != nil { | ||||
| 		log.Println("eth start err:", err) | ||||
| 		return | ||||
| 	} | ||||
| 	ethereum.Port = OutboundPort | ||||
| 
 | ||||
| 	// bookkeeping tasks
 | ||||
| 	switch { | ||||
| 	case GenAddr: | ||||
| 		if NonInteractive || confirm("This action overwrites your old private key.") { | ||||
| 			utils.CreateKeyPair(true) | ||||
| 		} | ||||
| 		os.Exit(0) | ||||
| 	case len(ImportKey) > 0: | ||||
| 		if NonInteractive || confirm("This action overwrites your old private key.") { | ||||
| 			mnemonic := strings.Split(ImportKey, " ") | ||||
| 			if len(mnemonic) == 24 { | ||||
| 				logSys.Println("Got mnemonic key, importing.") | ||||
| 				key := ethutil.MnemonicDecode(mnemonic) | ||||
| 				utils.ImportPrivateKey(key) | ||||
| 			} else if len(mnemonic) == 1 { | ||||
| 				logSys.Println("Got hex key, importing.") | ||||
| 				utils.ImportPrivateKey(ImportKey) | ||||
| 			} else { | ||||
| 				logSys.Println("Did not recognise format, exiting.") | ||||
| 			} | ||||
| 		} | ||||
| 		os.Exit(0) | ||||
| 	case ExportKey: | ||||
| 		keyPair := ethutil.GetKeyRing().Get(0) | ||||
| 		fmt.Printf(` | ||||
| Generating new address and keypair. | ||||
| Please keep your keys somewhere save. | ||||
| 
 | ||||
| ++++++++++++++++ KeyRing +++++++++++++++++++ | ||||
| addr: %x | ||||
| prvk: %x | ||||
| pubk: %x | ||||
| ++++++++++++++++++++++++++++++++++++++++++++ | ||||
| save these words so you can restore your account later: %s | ||||
| `, keyPair.Address(), keyPair.PrivateKey, keyPair.PublicKey) | ||||
| 
 | ||||
| 		os.Exit(0) | ||||
| 	case ShowGenesis: | ||||
| 		logSys.Println(ethereum.BlockChain().Genesis()) | ||||
| 		os.Exit(0) | ||||
| 	default: | ||||
| 		// Creates a keypair if non exists
 | ||||
| 		utils.CreateKeyPair(false) | ||||
| 	} | ||||
| 
 | ||||
| 	// client
 | ||||
| 	logger.Infoln(fmt.Sprintf("Starting Ethereum v%s", ethutil.Config.Ver)) | ||||
| 
 | ||||
| 	// Set the max peers
 | ||||
| 	ethereum.MaxPeers = MaxPeer | ||||
| 
 | ||||
| 	// Set Mining status
 | ||||
| 	ethereum.Mining = StartMining | ||||
| 
 | ||||
| 	if StartMining { | ||||
| 		utils.DoMining(ethereum) | ||||
| 	} | ||||
| 
 | ||||
| 	if StartJsConsole { | ||||
| 		repl := NewJSRepl(ethereum) | ||||
| 
 | ||||
| 		go repl.Start() | ||||
| 
 | ||||
| 		RegisterInterrupt(func(os.Signal) { | ||||
| 			repl.Stop() | ||||
| 		}) | ||||
| 	} else if len(InputFile) > 0 { | ||||
| 		file, err := os.Open(InputFile) | ||||
| 		if err != nil { | ||||
| 			ethutil.Config.Log.Fatal(err) | ||||
| 		} | ||||
| 
 | ||||
| 		content, err := ioutil.ReadAll(file) | ||||
| 		if err != nil { | ||||
| 			ethutil.Config.Log.Fatal(err) | ||||
| 		} | ||||
| 
 | ||||
| 		re := NewJSRE(ethereum) | ||||
| 		RegisterInterrupt(func(os.Signal) { | ||||
| 			re.Stop() | ||||
| 		}) | ||||
| 		re.Run(string(content)) | ||||
| 	} | ||||
| 
 | ||||
| 	if StartRpc { | ||||
| 		utils.DoRpc(ethereum, RpcPort) | ||||
| 	} | ||||
| 
 | ||||
| 	RegisterInterrupt(func(sig os.Signal) { | ||||
| 		fmt.Printf("Shutting down (%v) ... \n", sig) | ||||
| 		ethereum.Stop() | ||||
| 	}) | ||||
| 
 | ||||
| 	ethereum.Start(UseSeed) | ||||
| 
 | ||||
| 	// Wait for shutdown
 | ||||
| 	ethereum.WaitForShutdown() | ||||
| } | ||||
| @ -3,11 +3,13 @@ package main | ||||
| import ( | ||||
| 	"flag" | ||||
| 	"fmt" | ||||
| 	"github.com/ethereum/eth-go/ethlog" | ||||
| 	"os" | ||||
| 	"os/user" | ||||
| 	"path" | ||||
| ) | ||||
| 
 | ||||
| var Identifier string | ||||
| var StartMining bool | ||||
| var StartRpc bool | ||||
| var RpcPort int | ||||
| var UseUPnP bool | ||||
| @ -19,16 +21,28 @@ var GenAddr bool | ||||
| var UseSeed bool | ||||
| var ImportKey string | ||||
| var ExportKey bool | ||||
| var LogFile string | ||||
| var NonInteractive bool | ||||
| var Datadir string | ||||
| var LogFile string | ||||
| var ConfigFile string | ||||
| var DebugFile string | ||||
| var LogLevel int | ||||
| 
 | ||||
| // flags specific to cli client
 | ||||
| var StartMining bool | ||||
| var StartJsConsole bool | ||||
| var InputFile string | ||||
| 
 | ||||
| var Datadir string | ||||
| func defaultDataDir() string { | ||||
| 	usr, _ := user.Current() | ||||
| 	return path.Join(usr.HomeDir, ".ethereum") | ||||
| } | ||||
| 
 | ||||
| var defaultConfigFile = path.Join(defaultDataDir(), "conf.ini") | ||||
| 
 | ||||
| func Init() { | ||||
| 	flag.Usage = func() { | ||||
| 		fmt.Fprintf(os.Stderr, "%s [options] [filename]:\n", os.Args[0]) | ||||
| 		fmt.Fprintf(os.Stderr, "%s [options] [filename]:\noptions precedence: default < config file < environment variables < command line\n", os.Args[0]) | ||||
| 		flag.PrintDefaults() | ||||
| 	} | ||||
| 
 | ||||
| @ -38,17 +52,19 @@ func Init() { | ||||
| 	flag.IntVar(&MaxPeer, "maxpeer", 10, "maximum desired peers") | ||||
| 	flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on") | ||||
| 	flag.BoolVar(&StartRpc, "rpc", false, "start rpc server") | ||||
| 	flag.BoolVar(&StartJsConsole, "js", false, "exp") | ||||
| 
 | ||||
| 	flag.BoolVar(&StartMining, "mine", false, "start dagger mining") | ||||
| 	flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)") | ||||
| 	flag.BoolVar(&UseSeed, "seed", true, "seed peers") | ||||
| 	flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key") | ||||
| 	flag.BoolVar(&ExportKey, "export", false, "export private key") | ||||
| 	flag.StringVar(&LogFile, "logfile", "", "log file (defaults to standard output)") | ||||
| 	flag.StringVar(&ImportKey, "import", "", "imports the given private key (hex)") | ||||
| 	flag.StringVar(&Datadir, "datadir", defaultDataDir(), "specifies the datadir to use") | ||||
| 	flag.StringVar(&ConfigFile, "conf", defaultConfigFile, "config file") | ||||
| 	flag.StringVar(&DebugFile, "debug", "", "debug file (no debugging if not set)") | ||||
| 	flag.IntVar(&LogLevel, "loglevel", int(ethlog.InfoLevel), "loglevel: 0-5: silent,error,warn,info,debug,debug detail)") | ||||
| 
 | ||||
| 	flag.StringVar(&Datadir, "datadir", ".ethereum", "specifies the datadir to use. Takes precedence over config file.") | ||||
| 	flag.BoolVar(&StartMining, "mine", false, "start dagger mining") | ||||
| 	flag.BoolVar(&StartJsConsole, "js", false, "launches javascript console") | ||||
| 
 | ||||
| 	flag.Parse() | ||||
| 
 | ||||
| @ -4,6 +4,7 @@ import ( | ||||
| 	"fmt" | ||||
| 	"github.com/ethereum/eth-go" | ||||
| 	"github.com/ethereum/eth-go/ethchain" | ||||
| 	"github.com/ethereum/eth-go/ethlog" | ||||
| 	"github.com/ethereum/eth-go/ethpub" | ||||
| 	"github.com/ethereum/eth-go/ethutil" | ||||
| 	"github.com/ethereum/go-ethereum/utils" | ||||
| @ -14,6 +15,8 @@ import ( | ||||
| 	"path/filepath" | ||||
| ) | ||||
| 
 | ||||
| var jsrelogger = ethlog.NewLogger("JSRE") | ||||
| 
 | ||||
| type JSRE struct { | ||||
| 	ethereum *eth.Ethereum | ||||
| 	vm       *otto.Otto | ||||
| @ -31,7 +34,7 @@ func (jsre *JSRE) LoadExtFile(path string) { | ||||
| 	if err == nil { | ||||
| 		jsre.vm.Run(result) | ||||
| 	} else { | ||||
| 		ethutil.Config.Log.Debugln("Could not load file:", path) | ||||
| 		jsrelogger.Debugln("Could not load file:", path) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -65,6 +68,8 @@ func NewJSRE(ethereum *eth.Ethereum) *JSRE { | ||||
| 
 | ||||
| 	re.initStdFuncs() | ||||
| 
 | ||||
| 	jsrelogger.Infoln("started") | ||||
| 
 | ||||
| 	return re | ||||
| } | ||||
| 
 | ||||
| @ -99,6 +104,7 @@ func (self *JSRE) Stop() { | ||||
| 	close(self.blockChan) | ||||
| 	close(self.quitChan) | ||||
| 	close(self.changeChan) | ||||
| 	jsrelogger.Infoln("stopped") | ||||
| } | ||||
| 
 | ||||
| func (self *JSRE) mainLoop() { | ||||
|  | ||||
							
								
								
									
										53
									
								
								ethereum/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								ethereum/main.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/ethereum/eth-go/ethlog" | ||||
| 	"github.com/ethereum/go-ethereum/utils" | ||||
| 	"runtime" | ||||
| ) | ||||
| 
 | ||||
| var logger = ethlog.NewLogger("CLI") | ||||
| 
 | ||||
| func main() { | ||||
| 	runtime.GOMAXPROCS(runtime.NumCPU()) | ||||
| 
 | ||||
| 	utils.HandleInterrupt() | ||||
| 
 | ||||
| 	// precedence: code-internal flag default < config file < environment variables < command line
 | ||||
| 	Init() // parsing command line
 | ||||
| 	utils.InitConfig(ConfigFile, Datadir, Identifier, "ETH") | ||||
| 
 | ||||
| 	utils.InitDataDir(Datadir) | ||||
| 
 | ||||
| 	utils.InitLogging(Datadir, LogFile, LogLevel, DebugFile) | ||||
| 
 | ||||
| 	ethereum := utils.NewEthereum(UseUPnP, OutboundPort, MaxPeer) | ||||
| 
 | ||||
| 	// create, import, export keys
 | ||||
| 	utils.KeyTasks(GenAddr, ImportKey, ExportKey, NonInteractive) | ||||
| 
 | ||||
| 	if ShowGenesis { | ||||
| 		utils.ShowGenesis(ethereum) | ||||
| 	} | ||||
| 
 | ||||
| 	if StartMining { | ||||
| 		utils.StartMining(ethereum) | ||||
| 	} | ||||
| 
 | ||||
| 	// better reworked as cases
 | ||||
| 	if StartJsConsole { | ||||
| 		InitJsConsole(ethereum) | ||||
| 	} else if len(InputFile) > 0 { | ||||
| 		ExecJsFile(ethereum, InputFile) | ||||
| 	} | ||||
| 
 | ||||
| 	if StartRpc { | ||||
| 		utils.StartRpc(ethereum, RpcPort) | ||||
| 	} | ||||
| 
 | ||||
| 	utils.StartEthereum(ethereum, UseSeed) | ||||
| 
 | ||||
| 	// this blocks the thread
 | ||||
| 	ethereum.WaitForShutdown() | ||||
| 	ethlog.Flush() | ||||
| } | ||||
| @ -23,6 +23,8 @@ type JSRepl struct { | ||||
| 	prompt string | ||||
| 
 | ||||
| 	history *os.File | ||||
| 
 | ||||
| 	running bool | ||||
| } | ||||
| 
 | ||||
| func NewJSRepl(ethereum *eth.Ethereum) *JSRepl { | ||||
| @ -35,24 +37,32 @@ func NewJSRepl(ethereum *eth.Ethereum) *JSRepl { | ||||
| } | ||||
| 
 | ||||
| func (self *JSRepl) Start() { | ||||
| 	reader := bufio.NewReader(self.history) | ||||
| 	for { | ||||
| 		line, err := reader.ReadString('\n') | ||||
| 		if err != nil && err == io.EOF { | ||||
| 			break | ||||
| 		} else if err != nil { | ||||
| 			fmt.Println("error reading history", err) | ||||
| 			break | ||||
| 		} | ||||
| 	if !self.running { | ||||
| 		self.running = true | ||||
| 		logger.Infoln("init JS Console") | ||||
| 		reader := bufio.NewReader(self.history) | ||||
| 		for { | ||||
| 			line, err := reader.ReadString('\n') | ||||
| 			if err != nil && err == io.EOF { | ||||
| 				break | ||||
| 			} else if err != nil { | ||||
| 				fmt.Println("error reading history", err) | ||||
| 				break | ||||
| 			} | ||||
| 
 | ||||
| 		addHistory(line[:len(line)-1]) | ||||
| 			addHistory(line[:len(line)-1]) | ||||
| 		} | ||||
| 		self.read() | ||||
| 	} | ||||
| 	self.read() | ||||
| } | ||||
| 
 | ||||
| func (self *JSRepl) Stop() { | ||||
| 	self.re.Stop() | ||||
| 	self.history.Close() | ||||
| 	if self.running { | ||||
| 		self.running = false | ||||
| 		self.re.Stop() | ||||
| 		logger.Infoln("exit JS Console") | ||||
| 		self.history.Close() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (self *JSRepl) parseInput(code string) { | ||||
|  | ||||
							
								
								
									
										236
									
								
								utils/cmd.go
									
									
									
									
									
								
							
							
						
						
									
										236
									
								
								utils/cmd.go
									
									
									
									
									
								
							| @ -3,18 +3,184 @@ package utils | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/ethereum/eth-go" | ||||
| 	"github.com/ethereum/eth-go/ethlog" | ||||
| 	"github.com/ethereum/eth-go/ethminer" | ||||
| 	"github.com/ethereum/eth-go/ethpub" | ||||
| 	"github.com/ethereum/eth-go/ethrpc" | ||||
| 	"github.com/ethereum/eth-go/ethutil" | ||||
| 	"io" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"os/signal" | ||||
| 	"path" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| func DoRpc(ethereum *eth.Ethereum, RpcPort int) { | ||||
| var logger = ethlog.NewLogger("CLI") | ||||
| var interruptCallbacks = []func(os.Signal){} | ||||
| 
 | ||||
| // Register interrupt handlers callbacks
 | ||||
| func RegisterInterrupt(cb func(os.Signal)) { | ||||
| 	interruptCallbacks = append(interruptCallbacks, cb) | ||||
| } | ||||
| 
 | ||||
| // go routine that call interrupt handlers in order of registering
 | ||||
| func HandleInterrupt() { | ||||
| 	c := make(chan os.Signal, 1) | ||||
| 	go func() { | ||||
| 		signal.Notify(c, os.Interrupt) | ||||
| 		for sig := range c { | ||||
| 			logger.Errorf("Shutting down (%v) ... \n", sig) | ||||
| 			RunInterruptCallbacks(sig) | ||||
| 		} | ||||
| 	}() | ||||
| } | ||||
| 
 | ||||
| func RunInterruptCallbacks(sig os.Signal) { | ||||
| 	for _, cb := range interruptCallbacks { | ||||
| 		cb(sig) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func AbsolutePath(Datadir string, filename string) string { | ||||
| 	if path.IsAbs(filename) { | ||||
| 		return filename | ||||
| 	} | ||||
| 	return path.Join(Datadir, filename) | ||||
| } | ||||
| 
 | ||||
| func openLogFile(Datadir string, filename string) *os.File { | ||||
| 	path := AbsolutePath(Datadir, filename) | ||||
| 	file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) | ||||
| 	if err != nil { | ||||
| 		panic(fmt.Sprintf("error opening log file '%s': %v", filename, err)) | ||||
| 	} | ||||
| 	return file | ||||
| } | ||||
| 
 | ||||
| func confirm(message string) bool { | ||||
| 	fmt.Println(message, "Are you sure? (y/n)") | ||||
| 	var r string | ||||
| 	fmt.Scanln(&r) | ||||
| 	for ; ; fmt.Scanln(&r) { | ||||
| 		if r == "n" || r == "y" { | ||||
| 			break | ||||
| 		} else { | ||||
| 			fmt.Printf("Yes or no?", r) | ||||
| 		} | ||||
| 	} | ||||
| 	return r == "y" | ||||
| } | ||||
| 
 | ||||
| func InitDataDir(Datadir string) { | ||||
| 	_, err := os.Stat(Datadir) | ||||
| 	if err != nil { | ||||
| 		if os.IsNotExist(err) { | ||||
| 			fmt.Printf("Debug logging directory '%s' doesn't exist, creating it\n", Datadir) | ||||
| 			os.Mkdir(Datadir, 0777) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func InitLogging(Datadir string, LogFile string, LogLevel int, DebugFile string) { | ||||
| 	var writer io.Writer | ||||
| 	if LogFile == "" { | ||||
| 		writer = os.Stdout | ||||
| 	} else { | ||||
| 		writer = openLogFile(Datadir, LogFile) | ||||
| 	} | ||||
| 	ethlog.AddLogSystem(ethlog.NewStdLogSystem(writer, log.LstdFlags, ethlog.LogLevel(LogLevel))) | ||||
| 	if DebugFile != "" { | ||||
| 		writer = openLogFile(Datadir, DebugFile) | ||||
| 		ethlog.AddLogSystem(ethlog.NewStdLogSystem(writer, log.LstdFlags, ethlog.DebugLevel)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func InitConfig(ConfigFile string, Datadir string, Identifier string, EnvPrefix string) { | ||||
| 	InitDataDir(Datadir) | ||||
| 	ethutil.ReadConfig(ConfigFile, Datadir, Identifier, EnvPrefix) | ||||
| 	ethutil.Config.Set("rpcport", "700") | ||||
| } | ||||
| 
 | ||||
| func exit(status int) { | ||||
| 	ethlog.Flush() | ||||
| 	os.Exit(status) | ||||
| } | ||||
| 
 | ||||
| func NewEthereum(UseUPnP bool, OutboundPort string, MaxPeer int) *eth.Ethereum { | ||||
| 	ethereum, err := eth.New(eth.CapDefault, UseUPnP) | ||||
| 	if err != nil { | ||||
| 		logger.Fatalln("eth start err:", err) | ||||
| 	} | ||||
| 	ethereum.Port = OutboundPort | ||||
| 	ethereum.MaxPeers = MaxPeer | ||||
| 	return ethereum | ||||
| } | ||||
| 
 | ||||
| func StartEthereum(ethereum *eth.Ethereum, UseSeed bool) { | ||||
| 	logger.Infof("Starting Ethereum v%s", ethutil.Config.Ver) | ||||
| 	ethereum.Start(UseSeed) | ||||
| 	RegisterInterrupt(func(sig os.Signal) { | ||||
| 		ethereum.Stop() | ||||
| 		ethlog.Flush() | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func ShowGenesis(ethereum *eth.Ethereum) { | ||||
| 	logger.Infoln(ethereum.BlockChain().Genesis()) | ||||
| 	exit(0) | ||||
| } | ||||
| 
 | ||||
| func KeyTasks(GenAddr bool, ImportKey string, ExportKey bool, NonInteractive bool) { | ||||
| 	switch { | ||||
| 	case GenAddr: | ||||
| 		if NonInteractive || confirm("This action overwrites your old private key.") { | ||||
| 			CreateKeyPair(true) | ||||
| 		} | ||||
| 		exit(0) | ||||
| 	case len(ImportKey) > 0: | ||||
| 		if NonInteractive || confirm("This action overwrites your old private key.") { | ||||
| 			// import should be from file
 | ||||
| 			mnemonic := strings.Split(ImportKey, " ") | ||||
| 			if len(mnemonic) == 24 { | ||||
| 				logger.Infoln("Got mnemonic key, importing.") | ||||
| 				key := ethutil.MnemonicDecode(mnemonic) | ||||
| 				ImportPrivateKey(key) | ||||
| 			} else if len(mnemonic) == 1 { | ||||
| 				logger.Infoln("Got hex key, importing.") | ||||
| 				ImportPrivateKey(ImportKey) | ||||
| 			} else { | ||||
| 				logger.Errorln("Did not recognise format, exiting.") | ||||
| 			} | ||||
| 		} | ||||
| 		exit(0) | ||||
| 	case ExportKey: // this should be exporting to a filename
 | ||||
| 		keyPair := ethutil.GetKeyRing().Get(0) | ||||
| 		fmt.Printf(` | ||||
| Generating new address and keypair. | ||||
| Please keep your keys somewhere save. | ||||
| 
 | ||||
| ++++++++++++++++ KeyRing +++++++++++++++++++ | ||||
| addr: %x | ||||
| prvk: %x | ||||
| pubk: %x | ||||
| ++++++++++++++++++++++++++++++++++++++++++++ | ||||
| save these words so you can restore your account later: %s | ||||
| `, keyPair.Address(), keyPair.PrivateKey, keyPair.PublicKey) | ||||
| 
 | ||||
| 		exit(0) | ||||
| 	default: | ||||
| 		// Creates a keypair if none exists
 | ||||
| 		CreateKeyPair(false) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func StartRpc(ethereum *eth.Ethereum, RpcPort int) { | ||||
| 	var err error | ||||
| 	ethereum.RpcServer, err = ethrpc.NewJsonRpcServer(ethpub.NewPEthereum(ethereum), RpcPort) | ||||
| 	if err != nil { | ||||
| 		ethutil.Config.Log.Infoln("Could not start RPC interface:", err) | ||||
| 		logger.Errorf("Could not start RPC interface (port %v): %v", RpcPort, err) | ||||
| 	} else { | ||||
| 		go ethereum.RpcServer.Start() | ||||
| 	} | ||||
| @ -22,57 +188,41 @@ func DoRpc(ethereum *eth.Ethereum, RpcPort int) { | ||||
| 
 | ||||
| var miner ethminer.Miner | ||||
| 
 | ||||
| func DoMining(ethereum *eth.Ethereum) { | ||||
| 	// Set Mining status
 | ||||
| 	ethereum.Mining = true | ||||
| func StartMining(ethereum *eth.Ethereum) bool { | ||||
| 	if !ethereum.Mining { | ||||
| 		ethereum.Mining = true | ||||
| 
 | ||||
| 	if ethutil.GetKeyRing().Len() == 0 { | ||||
| 		ethutil.Config.Log.Infoln("No address found, can't start mining") | ||||
| 		return | ||||
| 		if ethutil.GetKeyRing().Len() == 0 { | ||||
| 			logger.Errorln("No address found, can't start mining") | ||||
| 			ethereum.Mining = false | ||||
| 			return true //????
 | ||||
| 		} | ||||
| 		keyPair := ethutil.GetKeyRing().Get(0) | ||||
| 		addr := keyPair.Address() | ||||
| 
 | ||||
| 		go func() { | ||||
| 			miner = ethminer.NewDefaultMiner(addr, ethereum) | ||||
| 			// Give it some time to connect with peers
 | ||||
| 			time.Sleep(3 * time.Second) | ||||
| 			logger.Infoln("Miner started") | ||||
| 			miner := ethminer.NewDefaultMiner(addr, ethereum) | ||||
| 			miner.Start() | ||||
| 		}() | ||||
| 		RegisterInterrupt(func(os.Signal) { | ||||
| 			StopMining(ethereum) | ||||
| 		}) | ||||
| 		return true | ||||
| 	} | ||||
| 	keyPair := ethutil.GetKeyRing().Get(0) | ||||
| 	addr := keyPair.Address() | ||||
| 
 | ||||
| 	go func() { | ||||
| 		miner = ethminer.NewDefaultMiner(addr, ethereum) | ||||
| 
 | ||||
| 		// Give it some time to connect with peers
 | ||||
| 		time.Sleep(3 * time.Second) | ||||
| 
 | ||||
| 		/* | ||||
| 			for ethereum.IsUpToDate() == false { | ||||
| 				time.Sleep(5 * time.Second) | ||||
| 			} | ||||
| 		*/ | ||||
| 
 | ||||
| 		ethutil.Config.Log.Infoln("Miner started") | ||||
| 
 | ||||
| 		miner := ethminer.NewDefaultMiner(addr, ethereum) | ||||
| 		miner.Start() | ||||
| 	}() | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func StopMining(ethereum *eth.Ethereum) bool { | ||||
| 	if ethereum.Mining { | ||||
| 		miner.Stop() | ||||
| 
 | ||||
| 		ethutil.Config.Log.Infoln("Miner stopped") | ||||
| 
 | ||||
| 		logger.Infoln("Miner stopped") | ||||
| 		ethereum.Mining = false | ||||
| 
 | ||||
| 		return true | ||||
| 	} | ||||
| 
 | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func StartMining(ethereum *eth.Ethereum) bool { | ||||
| 	if !ethereum.Mining { | ||||
| 		DoMining(ethereum) | ||||
| 
 | ||||
| 		return true | ||||
| 	} | ||||
| 
 | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user