| 
									
										
										
										
											2015-01-06 12:13:57 +01:00
										 |  |  | /* | 
					
						
							|  |  |  | 	This file is part of go-ethereum | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	go-ethereum is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | 	it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  | 	the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | 	(at your option) any later version. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	go-ethereum is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | 	but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | 	GNU General Public License for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | 	along with go-ethereum.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @authors | 
					
						
							|  |  |  |  * 	Jeffrey Wilcke <i@jev.io> | 
					
						
							|  |  |  |  * 	Viktor Tron <viktor@ethdev.com> | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-05-14 12:41:30 +02:00
										 |  |  | package utils | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2014-06-26 18:41:36 +01:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2015-03-18 13:36:48 +01:00
										 |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2014-08-15 01:07:40 +02:00
										 |  |  | 	"os" | 
					
						
							|  |  |  | 	"os/signal" | 
					
						
							| 
									
										
										
										
											2014-08-15 13:16:07 +02:00
										 |  |  | 	"regexp" | 
					
						
							| 
									
										
										
										
											2014-08-15 01:07:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-18 13:36:48 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/core" | 
					
						
							| 
									
										
										
										
											2014-12-23 15:37:03 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/core/types" | 
					
						
							| 
									
										
										
										
											2014-12-14 18:26:13 +00:00
										 |  |  | 	"github.com/ethereum/go-ethereum/eth" | 
					
						
							| 
									
										
										
										
											2014-10-31 12:56:05 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/logger" | 
					
						
							| 
									
										
										
										
											2015-04-07 14:57:04 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/logger/glog" | 
					
						
							| 
									
										
										
										
											2014-12-23 15:37:03 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/rlp" | 
					
						
							| 
									
										
										
										
											2014-05-14 12:41:30 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 10:47:45 +01:00
										 |  |  | var interruptCallbacks = []func(os.Signal){} | 
					
						
							| 
									
										
										
										
											2014-06-23 12:20:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 10:47:45 +01:00
										 |  |  | // Register interrupt handlers callbacks | 
					
						
							| 
									
										
										
										
											2014-06-23 12:20:59 +01:00
										 |  |  | func RegisterInterrupt(cb func(os.Signal)) { | 
					
						
							| 
									
										
										
										
											2014-06-26 18:41:36 +01:00
										 |  |  | 	interruptCallbacks = append(interruptCallbacks, cb) | 
					
						
							| 
									
										
										
										
											2014-06-26 10:47:45 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // go routine that call interrupt handlers in order of registering | 
					
						
							|  |  |  | func HandleInterrupt() { | 
					
						
							| 
									
										
										
										
											2014-06-26 18:41:36 +01:00
										 |  |  | 	c := make(chan os.Signal, 1) | 
					
						
							|  |  |  | 	go func() { | 
					
						
							|  |  |  | 		signal.Notify(c, os.Interrupt) | 
					
						
							|  |  |  | 		for sig := range c { | 
					
						
							| 
									
										
										
										
											2015-04-07 14:57:04 +02:00
										 |  |  | 			glog.V(logger.Error).Infof("Shutting down (%v) ... \n", sig) | 
					
						
							| 
									
										
										
										
											2014-06-26 18:41:36 +01:00
										 |  |  | 			RunInterruptCallbacks(sig) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2014-05-14 13:32:49 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 16:26:14 +01:00
										 |  |  | func RunInterruptCallbacks(sig os.Signal) { | 
					
						
							| 
									
										
										
										
											2014-06-26 18:41:36 +01:00
										 |  |  | 	for _, cb := range interruptCallbacks { | 
					
						
							|  |  |  | 		cb(sig) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-06-26 16:26:14 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-26 18:41:36 +01:00
										 |  |  | func openLogFile(Datadir string, filename string) *os.File { | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	path := common.AbsolutePath(Datadir, filename) | 
					
						
							| 
									
										
										
										
											2014-06-26 18:41:36 +01:00
										 |  |  | 	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 { | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 			fmt.Printf("Yes or no? (%s)", r) | 
					
						
							| 
									
										
										
										
											2014-06-26 18:41:36 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return r == "y" | 
					
						
							| 
									
										
										
										
											2014-06-23 12:20:59 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-05-22 00:25:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | func initDataDir(Datadir string) { | 
					
						
							| 
									
										
										
										
											2014-06-26 18:41:36 +01:00
										 |  |  | 	_, err := os.Stat(Datadir) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		if os.IsNotExist(err) { | 
					
						
							| 
									
										
										
										
											2014-06-29 13:43:27 +01:00
										 |  |  | 			fmt.Printf("Data directory '%s' doesn't exist, creating it\n", Datadir) | 
					
						
							| 
									
										
										
										
											2014-06-26 18:41:36 +01:00
										 |  |  | 			os.Mkdir(Datadir, 0777) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 18:39:13 +01:00
										 |  |  | func exit(err error) { | 
					
						
							|  |  |  | 	status := 0 | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-03-10 15:42:25 +01:00
										 |  |  | 		fmt.Fprintln(os.Stderr, "Fatal:", err) | 
					
						
							| 
									
										
										
										
											2014-06-29 18:39:13 +01:00
										 |  |  | 		status = 1 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-10-31 12:56:05 +01:00
										 |  |  | 	logger.Flush() | 
					
						
							| 
									
										
										
										
											2014-06-26 18:41:36 +01:00
										 |  |  | 	os.Exit(status) | 
					
						
							| 
									
										
										
										
											2014-05-14 12:41:30 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-05-22 00:25:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | // Fatalf formats a message to standard output and exits the program. | 
					
						
							|  |  |  | func Fatalf(format string, args ...interface{}) { | 
					
						
							|  |  |  | 	fmt.Fprintf(os.Stderr, "Fatal: "+format+"\n", args...) | 
					
						
							|  |  |  | 	logger.Flush() | 
					
						
							|  |  |  | 	os.Exit(1) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-07 00:38:36 +01:00
										 |  |  | func StartEthereum(ethereum *eth.Ethereum) { | 
					
						
							| 
									
										
										
										
											2015-04-07 14:57:04 +02:00
										 |  |  | 	glog.V(logger.Info).Infoln("Starting ", ethereum.Name()) | 
					
						
							| 
									
										
										
										
											2015-02-07 00:38:36 +01:00
										 |  |  | 	if err := ethereum.Start(); err != nil { | 
					
						
							| 
									
										
										
										
											2015-01-05 17:12:52 +01:00
										 |  |  | 		exit(err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-06-26 18:41:36 +01:00
										 |  |  | 	RegisterInterrupt(func(sig os.Signal) { | 
					
						
							|  |  |  | 		ethereum.Stop() | 
					
						
							| 
									
										
										
										
											2014-10-31 12:56:05 +01:00
										 |  |  | 		logger.Flush() | 
					
						
							| 
									
										
										
										
											2014-06-26 18:41:36 +01:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2014-06-23 12:20:59 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-05-22 00:25:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 03:25:57 +01:00
										 |  |  | func StartEthereumForTest(ethereum *eth.Ethereum) { | 
					
						
							| 
									
										
										
										
											2015-04-07 14:57:04 +02:00
										 |  |  | 	glog.V(logger.Info).Infoln("Starting ", ethereum.Name()) | 
					
						
							| 
									
										
										
										
											2015-03-06 03:25:57 +01:00
										 |  |  | 	ethereum.StartForTest() | 
					
						
							|  |  |  | 	RegisterInterrupt(func(sig os.Signal) { | 
					
						
							|  |  |  | 		ethereum.Stop() | 
					
						
							|  |  |  | 		logger.Flush() | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-15 13:16:07 +02:00
										 |  |  | func FormatTransactionData(data string) []byte { | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	d := common.StringToByteFunc(data, func(s string) (ret []byte) { | 
					
						
							| 
									
										
										
										
											2014-08-15 13:16:07 +02:00
										 |  |  | 		slice := regexp.MustCompile("\\n|\\s").Split(s, 1000000000) | 
					
						
							|  |  |  | 		for _, dataItem := range slice { | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 			d := common.FormatData(dataItem) | 
					
						
							| 
									
										
										
										
											2014-08-15 13:16:07 +02:00
										 |  |  | 			ret = append(ret, d...) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return d | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-08 22:44:48 +07:00
										 |  |  | func ImportChain(chainmgr *core.ChainManager, fn string) error { | 
					
						
							|  |  |  | 	fmt.Printf("importing blockchain '%s'\n", fn) | 
					
						
							| 
									
										
										
										
											2014-12-23 15:37:03 +01:00
										 |  |  | 	fh, err := os.OpenFile(fn, os.O_RDONLY, os.ModePerm) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer fh.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-08 22:44:48 +07:00
										 |  |  | 	chainmgr.Reset() | 
					
						
							| 
									
										
										
										
											2015-03-18 13:36:48 +01:00
										 |  |  | 	stream := rlp.NewStream(fh) | 
					
						
							| 
									
										
										
										
											2015-04-13 10:13:52 +02:00
										 |  |  | 	var i, n int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	batchSize := 2500 | 
					
						
							|  |  |  | 	blocks := make(types.Blocks, batchSize) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-18 13:36:48 +01:00
										 |  |  | 	for ; ; i++ { | 
					
						
							|  |  |  | 		var b types.Block | 
					
						
							| 
									
										
										
										
											2015-03-18 14:04:19 +01:00
										 |  |  | 		if err := stream.Decode(&b); err == io.EOF { | 
					
						
							| 
									
										
										
										
											2015-03-18 13:36:48 +01:00
										 |  |  | 			break | 
					
						
							|  |  |  | 		} else if err != nil { | 
					
						
							|  |  |  | 			return fmt.Errorf("at block %d: %v", i, err) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-04-13 10:13:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		blocks[n] = &b | 
					
						
							|  |  |  | 		n++ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if n == batchSize { | 
					
						
							|  |  |  | 			if err := chainmgr.InsertChain(blocks); err != nil { | 
					
						
							|  |  |  | 				return fmt.Errorf("invalid block %v", err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			n = 0 | 
					
						
							|  |  |  | 			blocks = make(types.Blocks, batchSize) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if n > 0 { | 
					
						
							|  |  |  | 		if err := chainmgr.InsertChain(blocks[:n]); err != nil { | 
					
						
							|  |  |  | 			return fmt.Errorf("invalid block %v", err) | 
					
						
							| 
									
										
										
										
											2015-03-18 13:36:48 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-12-23 15:37:03 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-13 10:13:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-18 13:36:48 +01:00
										 |  |  | 	fmt.Printf("imported %d blocks\n", i) | 
					
						
							| 
									
										
										
										
											2014-12-23 15:37:03 +01:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-03-08 22:44:48 +07:00
										 |  |  | 
 | 
					
						
							|  |  |  | func ExportChain(chainmgr *core.ChainManager, fn string) error { | 
					
						
							|  |  |  | 	fmt.Printf("exporting blockchain '%s'\n", fn) | 
					
						
							| 
									
										
										
										
											2015-03-18 14:04:19 +01:00
										 |  |  | 	fh, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm) | 
					
						
							| 
									
										
										
										
											2015-03-18 13:36:48 +01:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer fh.Close() | 
					
						
							|  |  |  | 	if err := chainmgr.Export(fh); err != nil { | 
					
						
							| 
									
										
										
										
											2015-03-08 22:44:48 +07:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	fmt.Printf("exported blockchain\n") | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } |