merge upstream

This commit is contained in:
zelig 2014-07-21 13:30:37 +01:00
commit 4d5a890b46
19 changed files with 257 additions and 117 deletions

View File

@ -5,7 +5,7 @@ Ethereum
Ethereum Go Client © 2014 Jeffrey Wilcke. Ethereum Go Client © 2014 Jeffrey Wilcke.
Current state: Proof of Concept 0.5.16. Current state: Proof of Concept 0.5.17.
For the development package please see the [eth-go package](https://github.com/ethereum/eth-go). For the development package please see the [eth-go package](https://github.com/ethereum/eth-go).

View File

@ -86,7 +86,7 @@ ApplicationWindow {
TableView { TableView {
id: asmTableView id: asmTableView
width: 200 width: 200
TableViewColumn{ role: "value" ; title: "" ; width: 200 } TableViewColumn{ role: "value" ; title: "" ; width: asmTableView.width - 2 }
model: asmModel model: asmModel
} }

View File

@ -420,29 +420,53 @@ ApplicationWindow {
} }
Label { Label {
y: 7 y: 6
anchors.right: peerImage.left id: lastBlockLabel
objectName: "lastBlockLabel"
visible: true
text: ""
font.pixelSize: 10
anchors.right: peerGroup.left
anchors.rightMargin: 5 anchors.rightMargin: 5
}
ProgressBar {
id: syncProgressIndicator
visible: false
objectName: "syncProgressIndicator"
y: 3
width: 140
indeterminate: true
anchors.right: peerGroup.left
anchors.rightMargin: 5
}
RowLayout {
id: peerGroup
y: 7
anchors.right: parent.right
MouseArea {
onDoubleClicked: peerWindow.visible = true
anchors.fill: parent
}
Label {
id: peerLabel id: peerLabel
font.pixelSize: 8 font.pixelSize: 8
text: "0 / 0" text: "0 / 0"
} }
Image { Image {
y: 7
id: peerImage id: peerImage
anchors.right: parent.right
width: 10; height: 10 width: 10; height: 10
MouseArea {
onDoubleClicked: peerWindow.visible = true
anchors.fill: parent
}
source: "../network.png" source: "../network.png"
} }
} }
}
Window { Window {
id: popup id: popup
visible: false visible: false
//flags: Qt.CustomizeWindowHint | Qt.Tool | Qt.WindowCloseButtonHint
property var block property var block
width: root.width width: root.width
height: 300 height: 300
@ -460,7 +484,7 @@ ApplicationWindow {
Text { text: '<h3>Block details</h3>'; color: "#F2F2F2"} Text { text: '<h3>Block details</h3>'; color: "#F2F2F2"}
Text { text: '<b>Block number:</b> ' + number; color: "#F2F2F2"} Text { text: '<b>Block number:</b> ' + number; color: "#F2F2F2"}
Text { text: '<b>Hash:</b> ' + hash; color: "#F2F2F2"} Text { text: '<b>Hash:</b> ' + hash; color: "#F2F2F2"}
Text { text: '<b>Coinbase:</b> ' + coinbase; color: "#F2F2F2"} Text { text: '<b>Coinbase:</b> &lt;' + name + '&gt; ' + coinbase; color: "#F2F2F2"}
Text { text: '<b>Block found at:</b> ' + prettyTime; color: "#F2F2F2"} Text { text: '<b>Block found at:</b> ' + prettyTime; color: "#F2F2F2"}
Text { text: '<b>Gas used:</b> ' + gasUsed + " / " + gasLimit; color: "#F2F2F2"} Text { text: '<b>Gas used:</b> ' + gasUsed + " / " + gasLimit; color: "#F2F2F2"}
} }
@ -577,6 +601,7 @@ ApplicationWindow {
Window { Window {
id: addPeerWin id: addPeerWin
//flags: Qt.CustomizeWindowHint | Qt.Tool | Qt.WindowCloseButtonHint
visible: false visible: false
minimumWidth: 230 minimumWidth: 230
maximumWidth: 230 maximumWidth: 230
@ -686,9 +711,9 @@ ApplicationWindow {
} }
if(initial){ if(initial){
blockModel.append({number: block.number, gasLimit: block.gasLimit, gasUsed: block.gasUsed, coinbase: block.coinbase, hash: block.hash, txs: txs, txAmount: amount, time: block.time, prettyTime: convertToPretty(block.time)}) blockModel.append({number: block.number, name: block.name, gasLimit: block.gasLimit, gasUsed: block.gasUsed, coinbase: block.coinbase, hash: block.hash, txs: txs, txAmount: amount, time: block.time, prettyTime: convertToPretty(block.time)})
}else{ }else{
blockModel.insert(0, {number: block.number, gasLimit: block.gasLimit, gasUsed: block.gasUsed, coinbase: block.coinbase, hash: block.hash, txs: txs, txAmount: amount, time: block.time, prettyTime: convertToPretty(block.time)}) blockModel.insert(0, {number: block.number, name: block.name, gasLimit: block.gasLimit, gasUsed: block.gasUsed, coinbase: block.coinbase, hash: block.hash, txs: txs, txAmount: amount, time: block.time, prettyTime: convertToPretty(block.time)})
} }
} }
@ -743,6 +768,7 @@ ApplicationWindow {
// ****************************************** // ******************************************
Window { Window {
id: peerWindow id: peerWindow
//flags: Qt.CustomizeWindowHint | Qt.Tool | Qt.WindowCloseButtonHint
height: 200 height: 200
width: 700 width: 700
Rectangle { Rectangle {

@ -1 +0,0 @@
Subproject commit 944fbaa31d51328b522c0cd55113716630b4cbcb

View File

@ -17,6 +17,8 @@ type DebuggerWindow struct {
vm *ethchain.Vm vm *ethchain.Vm
Db *Debugger Db *Debugger
state *ethchain.State
} }
func NewDebuggerWindow(lib *UiLib) *DebuggerWindow { func NewDebuggerWindow(lib *UiLib) *DebuggerWindow {
@ -53,6 +55,7 @@ func (self *DebuggerWindow) SetCode(code string) {
func (self *DebuggerWindow) SetData(data string) { func (self *DebuggerWindow) SetData(data string) {
self.win.Set("dataText", data) self.win.Set("dataText", data)
} }
func (self *DebuggerWindow) SetAsm(data []byte) { func (self *DebuggerWindow) SetAsm(data []byte) {
self.win.Root().Call("clearAsm") self.win.Root().Call("clearAsm")

View File

@ -36,6 +36,7 @@ var LogLevel int
// flags specific to gui client // flags specific to gui client
var AssetPath string var AssetPath string
//TODO: If we re-use the one defined in cmd.go the binary osx image crashes. If somebody finds out why we can dry this up.
func defaultAssetPath() string { func defaultAssetPath() string {
var assetPath string var assetPath string
// If the current working directory is the go-ethereum dir // If the current working directory is the go-ethereum dir
@ -60,7 +61,6 @@ func defaultAssetPath() string {
} }
return assetPath return assetPath
} }
func defaultDataDir() string { func defaultDataDir() string {
usr, _ := user.Current() usr, _ := user.Current()
return path.Join(usr.HomeDir, ".ethereal") return path.Join(usr.HomeDir, ".ethereal")

View File

@ -7,6 +7,7 @@ import (
"github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethdb" "github.com/ethereum/eth-go/ethdb"
"github.com/ethereum/eth-go/ethlog" "github.com/ethereum/eth-go/ethlog"
"github.com/ethereum/eth-go/ethminer"
"github.com/ethereum/eth-go/ethpub" "github.com/ethereum/eth-go/ethpub"
"github.com/ethereum/eth-go/ethreact" "github.com/ethereum/eth-go/ethreact"
"github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethutil"
@ -14,6 +15,7 @@ import (
"github.com/ethereum/go-ethereum/utils" "github.com/ethereum/go-ethereum/utils"
"github.com/go-qml/qml" "github.com/go-qml/qml"
"math/big" "math/big"
"strconv"
"strings" "strings"
"time" "time"
) )
@ -41,6 +43,8 @@ type Gui struct {
Session string Session string
clientIdentity *ethwire.SimpleClientIdentity clientIdentity *ethwire.SimpleClientIdentity
config *ethutil.ConfigManager config *ethutil.ConfigManager
miner *ethminer.Miner
} }
// Create GUI, but doesn't start it // Create GUI, but doesn't start it
@ -125,6 +129,7 @@ func (gui *Gui) ToggleMining() {
txt = "Start mining" txt = "Start mining"
} else { } else {
utils.StartMining(gui.eth) utils.StartMining(gui.eth)
gui.miner = utils.GetMiner()
txt = "Stop mining" txt = "Stop mining"
} }
@ -244,7 +249,11 @@ func (gui *Gui) readPreviousTransactions() {
} }
func (gui *Gui) processBlock(block *ethchain.Block, initial bool) { func (gui *Gui) processBlock(block *ethchain.Block, initial bool) {
gui.win.Root().Call("addBlock", ethpub.NewPBlock(block), initial) name := ethpub.FindNameInNameReg(gui.eth.StateManager(), block.Coinbase)
b := ethpub.NewPBlock(block)
b.Name = name
gui.win.Root().Call("addBlock", b, initial)
} }
func (gui *Gui) setWalletValue(amount, unconfirmedFunds *big.Int) { func (gui *Gui) setWalletValue(amount, unconfirmedFunds *big.Int) {
@ -263,20 +272,32 @@ func (gui *Gui) setWalletValue(amount, unconfirmedFunds *big.Int) {
gui.win.Root().Call("setWalletValue", str) gui.win.Root().Call("setWalletValue", str)
} }
func (self *Gui) getObjectByName(objectName string) qml.Object {
return self.win.Root().ObjectByName(objectName)
}
// Simple go routine function that updates the list of peers in the GUI // Simple go routine function that updates the list of peers in the GUI
func (gui *Gui) update() { func (gui *Gui) update() {
reactor := gui.eth.Reactor()
blockChan := make(chan ethreact.Event, 1) var (
txChan := make(chan ethreact.Event, 1) blockChan = make(chan ethreact.Event, 1)
objectChan := make(chan ethreact.Event, 1) txChan = make(chan ethreact.Event, 1)
peerChan := make(chan ethreact.Event, 1) objectChan = make(chan ethreact.Event, 1)
ticker := time.NewTicker(5 * time.Second) peerChan = make(chan ethreact.Event, 1)
chainSyncChan = make(chan ethreact.Event, 1)
miningChan = make(chan ethreact.Event, 1)
)
peerUpdateTicker := time.NewTicker(5 * time.Second)
generalUpdateTicker := time.NewTicker(1 * time.Second)
state := gui.eth.StateManager().TransState() state := gui.eth.StateManager().TransState()
unconfirmedFunds := new(big.Int) unconfirmedFunds := new(big.Int)
gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetAccount(gui.address()).Amount))) gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetAccount(gui.address()).Amount)))
gui.getObjectByName("syncProgressIndicator").Set("visible", !gui.eth.IsUpToDate())
lastBlockLabel := gui.getObjectByName("lastBlockLabel")
go func() { go func() {
for { for {
@ -319,18 +340,43 @@ func (gui *Gui) update() {
state.UpdateStateObject(object) state.UpdateStateObject(object)
} }
case msg := <-chainSyncChan:
sync := msg.Resource.(bool)
gui.win.Root().ObjectByName("syncProgressIndicator").Set("visible", sync)
case <-objectChan: case <-objectChan:
gui.loadAddressBook() gui.loadAddressBook()
case <-peerChan: case <-peerChan:
gui.setPeerInfo() gui.setPeerInfo()
case <-ticker.C: case <-peerUpdateTicker.C:
gui.setPeerInfo() gui.setPeerInfo()
case msg := <-miningChan:
if msg.Name == "miner:start" {
gui.miner = msg.Resource.(*ethminer.Miner)
} else {
gui.miner = nil
}
case <-generalUpdateTicker.C:
statusText := "#" + gui.eth.BlockChain().CurrentBlock.Number.String()
if gui.miner != nil {
pow := gui.miner.GetPow()
if pow.GetHashrate() != 0 {
statusText = "Mining @ " + strconv.FormatInt(pow.GetHashrate(), 10) + "Khash - " + statusText
}
}
lastBlockLabel.Set("text", statusText)
} }
} }
}() }()
reactor := gui.eth.Reactor()
reactor.Subscribe("newBlock", blockChan) reactor.Subscribe("newBlock", blockChan)
reactor.Subscribe("newTx:pre", txChan) reactor.Subscribe("newTx:pre", txChan)
reactor.Subscribe("newTx:post", txChan) reactor.Subscribe("newTx:post", txChan)
reactor.Subscribe("chainSync", chainSyncChan)
reactor.Subscribe("miner:start", miningChan)
reactor.Subscribe("miner:stop", miningChan)
nameReg := ethpub.EthereumConfig(gui.eth.StateManager()).NameReg() nameReg := ethpub.EthereumConfig(gui.eth.StateManager()).NameReg()
if nameReg != nil { if nameReg != nil {
@ -357,7 +403,7 @@ func (gui *Gui) address() []byte {
} }
func (gui *Gui) RegisterName(name string) { func (gui *Gui) RegisterName(name string) {
name = fmt.Sprintf("\"%s\"", name) name = fmt.Sprintf("\"register\"\n\"%s\"", name)
gui.pub.Transact(gui.privateKey(), "NameReg", "", "10000", "10000000000000", name) gui.pub.Transact(gui.privateKey(), "NameReg", "", "10000", "10000000000000", name)
} }

View File

@ -10,7 +10,7 @@ import (
const ( const (
ClientIdentifier = "Ethereal" ClientIdentifier = "Ethereal"
Version = "0.5.16" Version = "0.5.17"
) )
func main() { func main() {

View File

@ -2,13 +2,14 @@ package main
import ( import (
"github.com/ethereum/eth-go" "github.com/ethereum/eth-go"
"github.com/ethereum/go-ethereum/ethereum/repl"
"github.com/ethereum/go-ethereum/utils" "github.com/ethereum/go-ethereum/utils"
"io/ioutil" "io/ioutil"
"os" "os"
) )
func InitJsConsole(ethereum *eth.Ethereum) { func InitJsConsole(ethereum *eth.Ethereum) {
repl := NewJSRepl(ethereum) repl := ethrepl.NewJSRepl(ethereum)
go repl.Start() go repl.Start()
utils.RegisterInterrupt(func(os.Signal) { utils.RegisterInterrupt(func(os.Signal) {
repl.Stop() repl.Stop()
@ -24,7 +25,7 @@ func ExecJsFile(ethereum *eth.Ethereum, InputFile string) {
if err != nil { if err != nil {
logger.Fatalln(err) logger.Fatalln(err)
} }
re := NewJSRE(ethereum) re := ethrepl.NewJSRE(ethereum)
utils.RegisterInterrupt(func(os.Signal) { utils.RegisterInterrupt(func(os.Signal) {
re.Stop() re.Stop()
}) })

View File

@ -12,6 +12,7 @@ import (
var Identifier string var Identifier string
var KeyRing string var KeyRing string
var DiffTool bool var DiffTool bool
var DiffType string
var KeyStore string var KeyStore string
var StartRpc bool var StartRpc bool
var RpcPort int var RpcPort int
@ -68,6 +69,7 @@ func Init() {
flag.StringVar(&DebugFile, "debug", "", "debug file (no debugging if not set)") 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.IntVar(&LogLevel, "loglevel", int(ethlog.InfoLevel), "loglevel: 0-5: silent,error,warn,info,debug,debug detail)")
flag.BoolVar(&DiffTool, "difftool", false, "creates output for diff'ing. Sets LogLevel=0") flag.BoolVar(&DiffTool, "difftool", false, "creates output for diff'ing. Sets LogLevel=0")
flag.StringVar(&DiffType, "diff", "all", "sets the level of diff output [vm, all]. Has no effect if difftool=false")
flag.BoolVar(&StartMining, "mine", false, "start dagger mining") flag.BoolVar(&StartMining, "mine", false, "start dagger mining")
flag.BoolVar(&StartJsConsole, "js", false, "launches javascript console") flag.BoolVar(&StartJsConsole, "js", false, "launches javascript console")

View File

@ -9,7 +9,7 @@ import (
const ( const (
ClientIdentifier = "Ethereum(G)" ClientIdentifier = "Ethereum(G)"
Version = "0.5.16" Version = "0.5.17"
) )
var logger = ethlog.NewLogger("CLI") var logger = ethlog.NewLogger("CLI")
@ -29,6 +29,7 @@ func main() {
utils.InitConfig(ConfigFile, Datadir, "ETH") utils.InitConfig(ConfigFile, Datadir, "ETH")
ethutil.Config.Diff = DiffTool ethutil.Config.Diff = DiffTool
ethutil.Config.DiffType = DiffType
utils.InitDataDir(Datadir) utils.InitDataDir(Datadir)

View File

@ -1,4 +1,4 @@
package main package ethrepl
import ( import (
"fmt" "fmt"

View File

@ -1,4 +1,4 @@
package main package ethrepl
const jsLib = ` const jsLib = `
function pp(object) { function pp(object) {

83
ethereum/repl/repl.go Normal file
View File

@ -0,0 +1,83 @@
package ethrepl
import (
"bufio"
"fmt"
"github.com/ethereum/eth-go"
"github.com/ethereum/eth-go/ethlog"
"github.com/ethereum/eth-go/ethutil"
"io"
"os"
"path"
)
var logger = ethlog.NewLogger("REPL")
type Repl interface {
Start()
Stop()
}
type JSRepl struct {
re *JSRE
prompt string
history *os.File
running bool
}
func NewJSRepl(ethereum *eth.Ethereum) *JSRepl {
hist, err := os.OpenFile(path.Join(ethutil.Config.ExecPath, "history"), os.O_RDWR|os.O_CREATE, os.ModePerm)
if err != nil {
panic(err)
}
return &JSRepl{re: NewJSRE(ethereum), prompt: "> ", history: hist}
}
func (self *JSRepl) Start() {
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])
}
self.read()
}
}
func (self *JSRepl) Stop() {
if self.running {
self.running = false
self.re.Stop()
logger.Infoln("exit JS Console")
self.history.Close()
}
}
func (self *JSRepl) parseInput(code string) {
defer func() {
if r := recover(); r != nil {
fmt.Println("[native] error", r)
}
}()
value, err := self.re.Run(code)
if err != nil {
fmt.Println(err)
return
}
self.PrintValue(value)
}

View File

@ -1,4 +1,4 @@
package main package ethrepl
// #cgo darwin CFLAGS: -I/usr/local/opt/readline/include // #cgo darwin CFLAGS: -I/usr/local/opt/readline/include
// #cgo darwin LDFLAGS: -L/usr/local/opt/readline/lib // #cgo darwin LDFLAGS: -L/usr/local/opt/readline/lib

View File

@ -1,4 +1,4 @@
package main package ethrepl
import ( import (
"bufio" "bufio"

View File

@ -1,84 +1,26 @@
package main package ethrepl
import ( import (
"bufio"
"fmt" "fmt"
"github.com/ethereum/eth-go"
"github.com/ethereum/eth-go/ethpub" "github.com/ethereum/eth-go/ethpub"
"github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethutil"
"github.com/obscuren/otto" "github.com/obscuren/otto"
"io"
"os"
"path"
) )
type Repl interface { type JSStateObject struct {
Start() *ethpub.PStateObject
Stop() eth *JSEthereum
} }
type JSRepl struct { func (self *JSStateObject) EachStorage(call otto.FunctionCall) otto.Value {
re *JSRE cb := call.Argument(0)
self.PStateObject.EachStorage(func(key string, value *ethutil.Value) {
value.Decode()
prompt string cb.Call(self.eth.toVal(self), self.eth.toVal(key), self.eth.toVal(ethutil.Bytes2Hex(value.Bytes())))
})
history *os.File return otto.UndefinedValue()
running bool
}
func NewJSRepl(ethereum *eth.Ethereum) *JSRepl {
hist, err := os.OpenFile(path.Join(ethutil.Config.ExecPath, "history"), os.O_RDWR|os.O_CREATE, os.ModePerm)
if err != nil {
panic(err)
}
return &JSRepl{re: NewJSRE(ethereum), prompt: "> ", history: hist}
}
func (self *JSRepl) Start() {
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])
}
self.read()
}
}
func (self *JSRepl) Stop() {
if self.running {
self.running = false
self.re.Stop()
logger.Infoln("exit JS Console")
self.history.Close()
}
}
func (self *JSRepl) parseInput(code string) {
defer func() {
if r := recover(); r != nil {
fmt.Println("[native] error", r)
}
}()
value, err := self.re.Run(code)
if err != nil {
fmt.Println(err)
return
}
self.PrintValue(value)
} }
// The JSEthereum object attempts to wrap the PEthereum object and returns // The JSEthereum object attempts to wrap the PEthereum object and returns
@ -110,7 +52,7 @@ func (self *JSEthereum) GetKey() otto.Value {
} }
func (self *JSEthereum) GetStateObject(addr string) otto.Value { func (self *JSEthereum) GetStateObject(addr string) otto.Value {
return self.toVal(self.PEthereum.GetStateObject(addr)) return self.toVal(&JSStateObject{self.PEthereum.GetStateObject(addr), self})
} }
func (self *JSEthereum) GetStateKeyVals(addr string) otto.Value { func (self *JSEthereum) GetStateKeyVals(addr string) otto.Value {

View File

@ -1,6 +1,7 @@
package utils package utils
import ( import (
"bitbucket.org/kardianos/osext"
"fmt" "fmt"
"github.com/ethereum/eth-go" "github.com/ethereum/eth-go"
"github.com/ethereum/eth-go/ethcrypto" "github.com/ethereum/eth-go/ethcrypto"
@ -16,6 +17,8 @@ import (
"os" "os"
"os/signal" "os/signal"
"path" "path"
"path/filepath"
"runtime"
"time" "time"
) )
@ -165,7 +168,34 @@ func NewKeyManager(KeyStore string, Datadir string, db ethutil.Database) *ethcry
return keyManager return keyManager
} }
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 "windows":
assetPath = "./assets"
default:
assetPath = "."
}
}
return assetPath
}
func KeyTasks(keyManager *ethcrypto.KeyManager, KeyRing string, GenAddr bool, SecretFile string, ExportDir string, NonInteractive bool) { func KeyTasks(keyManager *ethcrypto.KeyManager, KeyRing string, GenAddr bool, SecretFile string, ExportDir string, NonInteractive bool) {
ethcrypto.InitWords(DefaultAssetPath()) // Init mnemonic word list
var err error var err error
switch { switch {
case GenAddr: case GenAddr:
@ -205,7 +235,11 @@ func StartRpc(ethereum *eth.Ethereum, RpcPort int) {
} }
} }
var miner ethminer.Miner var miner *ethminer.Miner
func GetMiner() *ethminer.Miner {
return miner
}
func StartMining(ethereum *eth.Ethereum) bool { func StartMining(ethereum *eth.Ethereum) bool {
if !ethereum.Mining { if !ethereum.Mining {
@ -214,13 +248,14 @@ func StartMining(ethereum *eth.Ethereum) bool {
go func() { go func() {
logger.Infoln("Start mining") logger.Infoln("Start mining")
if miner == nil {
miner = ethminer.NewDefaultMiner(addr, ethereum) miner = ethminer.NewDefaultMiner(addr, ethereum)
}
// Give it some time to connect with peers // Give it some time to connect with peers
time.Sleep(3 * time.Second) time.Sleep(3 * time.Second)
for !ethereum.IsUpToDate() { for !ethereum.IsUpToDate() {
time.Sleep(5 * time.Second) time.Sleep(5 * time.Second)
} }
miner.Start() miner.Start()
}() }()
RegisterInterrupt(func(os.Signal) { RegisterInterrupt(func(os.Signal) {
@ -232,12 +267,14 @@ func StartMining(ethereum *eth.Ethereum) bool {
} }
func StopMining(ethereum *eth.Ethereum) bool { func StopMining(ethereum *eth.Ethereum) bool {
if ethereum.Mining { if ethereum.Mining && miner != nil {
miner.Stop() miner.Stop()
logger.Infoln("Stopped mining") logger.Infoln("Stopped mining")
ethereum.Mining = false ethereum.Mining = false
return true return true
} }
return false return false
} }