diff options
-rw-r--r-- | cmd/geth/admin.go | 6 | ||||
-rw-r--r-- | cmd/geth/main.go | 47 | ||||
-rw-r--r-- | cmd/utils/cmd.go | 52 | ||||
-rw-r--r-- | core/block_processor.go | 37 | ||||
-rw-r--r-- | miner/agent.go | 25 | ||||
-rw-r--r-- | rpc/http.go | 3 |
6 files changed, 113 insertions, 57 deletions
diff --git a/cmd/geth/admin.go b/cmd/geth/admin.go index ebdf3512a..53dd0e6ad 100644 --- a/cmd/geth/admin.go +++ b/cmd/geth/admin.go @@ -383,7 +383,7 @@ func (js *jsre) unlock(call otto.FunctionCall) otto.Value { var passphrase string if arg.IsUndefined() { fmt.Println("Please enter a passphrase now.") - passphrase, err = readPassword("Passphrase: ", true) + passphrase, err = utils.PromptPassword("Passphrase: ", true) if err != nil { fmt.Println(err) return otto.FalseValue() @@ -410,12 +410,12 @@ func (js *jsre) newAccount(call otto.FunctionCall) otto.Value { if arg.IsUndefined() { fmt.Println("The new account will be encrypted with a passphrase.") fmt.Println("Please enter a passphrase now.") - auth, err := readPassword("Passphrase: ", true) + auth, err := utils.PromptPassword("Passphrase: ", true) if err != nil { fmt.Println(err) return otto.FalseValue() } - confirm, err := readPassword("Repeat Passphrase: ", false) + confirm, err := utils.PromptPassword("Repeat Passphrase: ", false) if err != nil { fmt.Println(err) return otto.FalseValue() diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 817337e20..df0af3e79 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -21,7 +21,6 @@ package main import ( - "bufio" "fmt" "io" "io/ioutil" @@ -44,13 +43,12 @@ import ( "github.com/ethereum/go-ethereum/logger" "github.com/mattn/go-colorable" "github.com/mattn/go-isatty" - "github.com/peterh/liner" ) import _ "net/http/pprof" const ( ClientIdentifier = "Geth" - Version = "0.9.21.1" + Version = "0.9.22" ) var ( @@ -230,6 +228,11 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso Name: "upgradedb", Usage: "upgrade chainblock database", }, + { + Action: removeDb, + Name: "removedb", + Usage: "Remove blockchain and state databases", + }, } app.Flags = []cli.Flag{ utils.IdentityFlag, @@ -421,12 +424,12 @@ func getPassPhrase(ctx *cli.Context, desc string, confirmation bool) (passphrase passfile := ctx.GlobalString(utils.PasswordFileFlag.Name) if len(passfile) == 0 { fmt.Println(desc) - auth, err := readPassword("Passphrase: ", true) + auth, err := utils.PromptPassword("Passphrase: ", true) if err != nil { utils.Fatalf("%v", err) } if confirmation { - confirm, err := readPassword("Repeat Passphrase: ", false) + confirm, err := utils.PromptPassword("Repeat Passphrase: ", false) if err != nil { utils.Fatalf("%v", err) } @@ -543,6 +546,25 @@ func exportchain(ctx *cli.Context) { return } +func removeDb(ctx *cli.Context) { + confirm, err := utils.PromptConfirm("Remove local databases?") + if err != nil { + utils.Fatalf("%v", err) + } + + if confirm { + fmt.Println("Removing chain and state databases...") + start := time.Now() + + os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "blockchain")) + os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "state")) + + fmt.Printf("Removed in %v\n", time.Since(start)) + } else { + fmt.Println("Operation aborted") + } +} + func upgradeDb(ctx *cli.Context) { fmt.Println("Upgrade blockchain DB") @@ -666,18 +688,3 @@ func hashish(x string) bool { _, err := strconv.Atoi(x) return err != nil } - -func readPassword(prompt string, warnTerm bool) (string, error) { - if liner.TerminalSupported() { - lr := liner.NewLiner() - defer lr.Close() - return lr.PasswordPrompt(prompt) - } - if warnTerm { - fmt.Println("!! Unsupported terminal, password will be echoed.") - } - fmt.Print(prompt) - input, err := bufio.NewReader(os.Stdin).ReadString('\n') - fmt.Println() - return input, err -} diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index fb55a64af..39b4e46da 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -22,11 +22,13 @@ package utils import ( + "bufio" "fmt" "io" "os" "os/signal" "regexp" + "strings" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" @@ -35,6 +37,7 @@ import ( "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/rlp" + "github.com/peterh/liner" ) var interruptCallbacks = []func(os.Signal){} @@ -71,18 +74,45 @@ func openLogFile(Datadir string, filename string) *os.File { 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? (%s)", r) - } +func PromptConfirm(prompt string) (bool, error) { + var ( + input string + err error + ) + prompt = prompt + " [y/N] " + + if liner.TerminalSupported() { + lr := liner.NewLiner() + defer lr.Close() + input, err = lr.Prompt(prompt) + } else { + fmt.Print(prompt) + input, err = bufio.NewReader(os.Stdin).ReadString('\n') + fmt.Println() + } + + if len(input) > 0 && strings.ToUpper(input[:1]) == "Y" { + return true, nil + } else { + return false, nil + } + + return false, err +} + +func PromptPassword(prompt string, warnTerm bool) (string, error) { + if liner.TerminalSupported() { + lr := liner.NewLiner() + defer lr.Close() + return lr.PasswordPrompt(prompt) + } + if warnTerm { + fmt.Println("!! Unsupported terminal, password will be echoed.") } - return r == "y" + fmt.Print(prompt) + input, err := bufio.NewReader(os.Stdin).ReadString('\n') + fmt.Println() + return input, err } func initDataDir(Datadir string) { diff --git a/core/block_processor.go b/core/block_processor.go index a021086c0..20e6722a4 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -15,7 +15,6 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/pow" "github.com/ethereum/go-ethereum/rlp" - "gopkg.in/fatih/set.v0" ) const ( @@ -331,32 +330,50 @@ func AccumulateRewards(statedb *state.StateDB, block *types.Block) { } func (sm *BlockProcessor) VerifyUncles(statedb *state.StateDB, block, parent *types.Block) error { - ancestors := set.New() - uncles := set.New() + //ancestors := set.New() + //uncles := set.New() + ancestors := make(map[common.Hash]struct{}) + uncles := make(map[common.Hash]struct{}) ancestorHeaders := make(map[common.Hash]*types.Header) for _, ancestor := range sm.bc.GetAncestors(block, 7) { ancestorHeaders[ancestor.Hash()] = ancestor.Header() - ancestors.Add(ancestor.Hash()) + //ancestors.Add(ancestor.Hash()) + ancestors[ancestor.Hash()] = struct{}{} // Include ancestors uncles in the uncle set. Uncles must be unique. for _, uncle := range ancestor.Uncles() { - uncles.Add(uncle.Hash()) + //uncles.Add(uncle.Hash()) + uncles[uncle.Hash()] = struct{}{} } } - uncles.Add(block.Hash()) + //uncles.Add(block.Hash()) + uncles[block.Hash()] = struct{}{} for i, uncle := range block.Uncles() { hash := uncle.Hash() - if uncles.Has(hash) { + //if uncles.Has(hash) { + if _, has := uncles[hash]; has { // Error not unique return UncleError("uncle[%d](%x) not unique", i, hash[:4]) } - uncles.Add(hash) + uncles[hash] = struct{}{} + + //if ancestors.Has(hash) { + if _, has := ancestors[hash]; has { + var branch string + //ancestors.Each(func(item interface{}) bool { + for hash := range ancestors { + branch += fmt.Sprintf(" O - %x\n |\n", hash) + //return true + } + //}) + branch += fmt.Sprintf(" O - %x\n |\n", block.Hash()) + glog.Infoln(branch) - if ancestors.Has(hash) { return UncleError("uncle[%d](%x) is ancestor", i, hash[:4]) } - if !ancestors.Has(uncle.ParentHash) { + //if !ancestors.Has(uncle.ParentHash) { + if _, has := ancestors[uncle.ParentHash]; !has { return UncleError("uncle[%d](%x)'s parent unknown (%x)", i, hash[:4], uncle.ParentHash[0:4]) } diff --git a/miner/agent.go b/miner/agent.go index da2a2008d..3ed3ba839 100644 --- a/miner/agent.go +++ b/miner/agent.go @@ -40,7 +40,6 @@ func (self *CpuAgent) Stop() { defer self.mu.Unlock() close(self.quit) - close(self.quitCurrentOp) } func (self *CpuAgent) Start() { @@ -50,7 +49,6 @@ func (self *CpuAgent) Start() { self.quit = make(chan struct{}) // creating current op ch makes sure we're not closing a nil ch // later on - self.quitCurrentOp = make(chan struct{}) self.workCh = make(chan *types.Block, 1) go self.update() @@ -62,11 +60,19 @@ out: select { case block := <-self.workCh: self.mu.Lock() - close(self.quitCurrentOp) + if self.quitCurrentOp != nil { + close(self.quitCurrentOp) + } + self.quitCurrentOp = make(chan struct{}) + go self.mine(block, self.quitCurrentOp) self.mu.Unlock() - - go self.mine(block) case <-self.quit: + self.mu.Lock() + if self.quitCurrentOp != nil { + close(self.quitCurrentOp) + self.quitCurrentOp = nil + } + self.mu.Unlock() break out } } @@ -84,16 +90,11 @@ done: } } -func (self *CpuAgent) mine(block *types.Block) { +func (self *CpuAgent) mine(block *types.Block, stop <- chan struct{}) { glog.V(logger.Debug).Infof("(re)started agent[%d]. mining...\n", self.index) - // Reset the channel - self.mu.Lock() - self.quitCurrentOp = make(chan struct{}) - self.mu.Unlock() - // Mine - nonce, mixDigest := self.pow.Search(block, self.quitCurrentOp) + nonce, mixDigest := self.pow.Search(block, stop) if nonce != 0 { block.SetNonce(nonce) block.Header().MixDigest = common.BytesToHash(mixDigest) diff --git a/rpc/http.go b/rpc/http.go index 9b3fa5142..f37e102f5 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -6,6 +6,7 @@ import ( "io" "io/ioutil" "net/http" + "strings" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" @@ -39,7 +40,7 @@ func Start(pipe *xeth.XEth, config RpcConfig) error { if len(config.CorsDomain) > 0 { var opts cors.Options opts.AllowedMethods = []string{"POST"} - opts.AllowedOrigins = []string{config.CorsDomain} + opts.AllowedOrigins = strings.Split(config.CorsDomain, " ") c := cors.New(opts) handler = newStoppableHandler(c.Handler(JSONRPC(pipe)), l.stop) |