Skip to content

Commit f082c1b

Browse files
committed
Merge branch 'release/0.9.26'
2 parents 7086790 + d51d74e commit f082c1b

File tree

24 files changed

+779
-1986
lines changed

24 files changed

+779
-1986
lines changed

cmd/geth/admin.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,8 @@ func (js *jsre) setHead(call otto.FunctionCall) otto.Value {
262262
}
263263

264264
func (js *jsre) downloadProgress(call otto.FunctionCall) otto.Value {
265-
current, max := js.ethereum.Downloader().Stats()
266-
v, _ := call.Otto.ToValue(fmt.Sprintf("%d/%d", current, max))
265+
pending, cached := js.ethereum.Downloader().Stats()
266+
v, _ := call.Otto.ToValue(map[string]interface{}{"pending": pending, "cached": cached})
267267
return v
268268
}
269269

cmd/geth/blocktest.go renamed to cmd/geth/blocktestcmd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
"github.com/ethereum/go-ethereum/tests"
1313
)
1414

15-
var blocktestCmd = cli.Command{
15+
var blocktestCommand = cli.Command{
1616
Action: runBlockTest,
1717
Name: "blocktest",
1818
Usage: `loads a block test file`,

cmd/geth/chaincmd.go

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"path/filepath"
7+
"strconv"
8+
"time"
9+
10+
"github.com/codegangsta/cli"
11+
"github.com/ethereum/go-ethereum/cmd/utils"
12+
"github.com/ethereum/go-ethereum/common"
13+
"github.com/ethereum/go-ethereum/core"
14+
"github.com/ethereum/go-ethereum/core/state"
15+
"github.com/ethereum/go-ethereum/core/types"
16+
"github.com/ethereum/go-ethereum/logger/glog"
17+
)
18+
19+
var (
20+
importCommand = cli.Command{
21+
Action: importChain,
22+
Name: "import",
23+
Usage: `import a blockchain file`,
24+
}
25+
exportCommand = cli.Command{
26+
Action: exportChain,
27+
Name: "export",
28+
Usage: `export blockchain into file`,
29+
}
30+
upgradedbCommand = cli.Command{
31+
Action: upgradeDB,
32+
Name: "upgradedb",
33+
Usage: "upgrade chainblock database",
34+
}
35+
removedbCommand = cli.Command{
36+
Action: removeDB,
37+
Name: "removedb",
38+
Usage: "Remove blockchain and state databases",
39+
}
40+
dumpCommand = cli.Command{
41+
Action: dump,
42+
Name: "dump",
43+
Usage: `dump a specific block from storage`,
44+
Description: `
45+
The arguments are interpreted as block numbers or hashes.
46+
Use "ethereum dump 0" to dump the genesis block.
47+
`,
48+
}
49+
)
50+
51+
func importChain(ctx *cli.Context) {
52+
if len(ctx.Args()) != 1 {
53+
utils.Fatalf("This command requires an argument.")
54+
}
55+
chain, blockDB, stateDB, extraDB := utils.MakeChain(ctx)
56+
start := time.Now()
57+
err := utils.ImportChain(chain, ctx.Args().First())
58+
closeAll(blockDB, stateDB, extraDB)
59+
if err != nil {
60+
utils.Fatalf("Import error: %v", err)
61+
}
62+
fmt.Printf("Import done in %v", time.Since(start))
63+
}
64+
65+
func exportChain(ctx *cli.Context) {
66+
if len(ctx.Args()) != 1 {
67+
utils.Fatalf("This command requires an argument.")
68+
}
69+
chain, _, _, _ := utils.MakeChain(ctx)
70+
start := time.Now()
71+
if err := utils.ExportChain(chain, ctx.Args().First()); err != nil {
72+
utils.Fatalf("Export error: %v\n", err)
73+
}
74+
fmt.Printf("Export done in %v", time.Since(start))
75+
}
76+
77+
func removeDB(ctx *cli.Context) {
78+
confirm, err := utils.PromptConfirm("Remove local databases?")
79+
if err != nil {
80+
utils.Fatalf("%v", err)
81+
}
82+
83+
if confirm {
84+
fmt.Println("Removing chain and state databases...")
85+
start := time.Now()
86+
87+
os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "blockchain"))
88+
os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "state"))
89+
90+
fmt.Printf("Removed in %v\n", time.Since(start))
91+
} else {
92+
fmt.Println("Operation aborted")
93+
}
94+
}
95+
96+
func upgradeDB(ctx *cli.Context) {
97+
glog.Infoln("Upgrading blockchain database")
98+
99+
chain, blockDB, stateDB, extraDB := utils.MakeChain(ctx)
100+
v, _ := blockDB.Get([]byte("BlockchainVersion"))
101+
bcVersion := int(common.NewValue(v).Uint())
102+
if bcVersion == 0 {
103+
bcVersion = core.BlockChainVersion
104+
}
105+
106+
// Export the current chain.
107+
filename := fmt.Sprintf("blockchain_%d_%s.chain", bcVersion, time.Now().Format("20060102_150405"))
108+
exportFile := filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), filename)
109+
if err := utils.ExportChain(chain, exportFile); err != nil {
110+
utils.Fatalf("Unable to export chain for reimport %s", err)
111+
}
112+
closeAll(blockDB, stateDB, extraDB)
113+
os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "blockchain"))
114+
os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "state"))
115+
116+
// Import the chain file.
117+
chain, blockDB, stateDB, extraDB = utils.MakeChain(ctx)
118+
blockDB.Put([]byte("BlockchainVersion"), common.NewValue(core.BlockChainVersion).Bytes())
119+
err := utils.ImportChain(chain, exportFile)
120+
closeAll(blockDB, stateDB, extraDB)
121+
if err != nil {
122+
utils.Fatalf("Import error %v (a backup is made in %s, use the import command to import it)", err, exportFile)
123+
} else {
124+
os.Remove(exportFile)
125+
glog.Infoln("Import finished")
126+
}
127+
}
128+
129+
func dump(ctx *cli.Context) {
130+
chain, _, stateDB, _ := utils.MakeChain(ctx)
131+
for _, arg := range ctx.Args() {
132+
var block *types.Block
133+
if hashish(arg) {
134+
block = chain.GetBlock(common.HexToHash(arg))
135+
} else {
136+
num, _ := strconv.Atoi(arg)
137+
block = chain.GetBlockByNumber(uint64(num))
138+
}
139+
if block == nil {
140+
fmt.Println("{}")
141+
utils.Fatalf("block not found")
142+
} else {
143+
state := state.New(block.Root(), stateDB)
144+
fmt.Printf("%s\n", state.Dump())
145+
}
146+
}
147+
}
148+
149+
// hashish returns true for strings that look like hashes.
150+
func hashish(x string) bool {
151+
_, err := strconv.Atoi(x)
152+
return err != nil
153+
}
154+
155+
func closeAll(dbs ...common.Database) {
156+
for _, db := range dbs {
157+
db.Close()
158+
}
159+
}

cmd/geth/js.go

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"fmt"
2323
"math/big"
2424
"os"
25+
"os/signal"
2526
"path/filepath"
2627
"strings"
2728

@@ -47,7 +48,8 @@ type dumbterm struct{ r *bufio.Reader }
4748

4849
func (r dumbterm) Prompt(p string) (string, error) {
4950
fmt.Print(p)
50-
return r.r.ReadString('\n')
51+
line, err := r.r.ReadString('\n')
52+
return strings.TrimSuffix(line, "\n"), err
5153
}
5254

5355
func (r dumbterm) PasswordPrompt(p string) (string, error) {
@@ -182,30 +184,52 @@ func (self *jsre) exec(filename string) error {
182184
}
183185

184186
func (self *jsre) interactive() {
185-
for {
186-
input, err := self.Prompt(self.ps1)
187-
if err != nil {
188-
break
187+
// Read input lines.
188+
prompt := make(chan string)
189+
inputln := make(chan string)
190+
go func() {
191+
defer close(inputln)
192+
for {
193+
line, err := self.Prompt(<-prompt)
194+
if err != nil {
195+
return
196+
}
197+
inputln <- line
189198
}
190-
if input == "" {
191-
continue
199+
}()
200+
// Wait for Ctrl-C, too.
201+
sig := make(chan os.Signal, 1)
202+
signal.Notify(sig, os.Interrupt)
203+
204+
defer func() {
205+
if self.atexit != nil {
206+
self.atexit()
192207
}
193-
str += input + "\n"
194-
self.setIndent()
195-
if indentCount <= 0 {
196-
if input == "exit" {
197-
break
208+
self.re.Stop(false)
209+
}()
210+
for {
211+
prompt <- self.ps1
212+
select {
213+
case <-sig:
214+
fmt.Println("caught interrupt, exiting")
215+
return
216+
case input, ok := <-inputln:
217+
if !ok || indentCount <= 0 && input == "exit" {
218+
return
219+
}
220+
if input == "" {
221+
continue
222+
}
223+
str += input + "\n"
224+
self.setIndent()
225+
if indentCount <= 0 {
226+
hist := str[:len(str)-1]
227+
self.AppendHistory(hist)
228+
self.parseInput(str)
229+
str = ""
198230
}
199-
hist := str[:len(str)-1]
200-
self.AppendHistory(hist)
201-
self.parseInput(str)
202-
str = ""
203231
}
204232
}
205-
if self.atexit != nil {
206-
self.atexit()
207-
}
208-
self.re.Stop(false)
209233
}
210234

211235
func (self *jsre) withHistory(op func(*os.File)) {

0 commit comments

Comments
 (0)