github.com/reapchain/go-reapchain@v0.2.15-0.20210609012950-9735c110c705/cmd/utils/cmd.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of go-ethereum. 3 // 4 // go-ethereum is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // go-ethereum is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package utils contains internal helper functions for go-ethereum commands. 18 package utils 19 20 import ( 21 "compress/gzip" 22 "fmt" 23 "io" 24 "os" 25 "os/signal" 26 "runtime" 27 "strings" 28 29 "github.com/ethereum/go-ethereum/core" 30 "github.com/ethereum/go-ethereum/core/types" 31 "github.com/ethereum/go-ethereum/internal/debug" 32 "github.com/ethereum/go-ethereum/log" 33 "github.com/ethereum/go-ethereum/node" 34 "github.com/ethereum/go-ethereum/rlp" 35 ) 36 37 const ( 38 importBatchSize = 2500 39 ) 40 41 // Fatalf formats a message to standard error and exits the program. 42 // The message is also printed to standard output if standard error 43 // is redirected to a different file. 44 func Fatalf(format string, args ...interface{}) { 45 w := io.MultiWriter(os.Stdout, os.Stderr) 46 if runtime.GOOS == "windows" { 47 // The SameFile check below doesn't work on Windows. 48 // stdout is unlikely to get redirected though, so just print there. 49 w = os.Stdout 50 } else { 51 outf, _ := os.Stdout.Stat() 52 errf, _ := os.Stderr.Stat() 53 if outf != nil && errf != nil && os.SameFile(outf, errf) { 54 w = os.Stderr 55 } 56 } 57 fmt.Fprintf(w, "Fatal: "+format+"\n", args...) 58 os.Exit(1) 59 } 60 61 func StartNode(stack *node.Node) { 62 63 if err := stack.Start(); err != nil { // Qmanager Enode 값을 읽어와서 노드 객체에 연결시킴. 64 // Temp disable : 65 fmt.Printf("Error starting protocol stack: %v", err) //not port no when run private : geth --localIP 1 66 } 67 go func() { 68 sigc := make(chan os.Signal, 1) 69 signal.Notify(sigc, os.Interrupt) 70 defer signal.Stop(sigc) 71 <-sigc 72 log.Info("Got interrupt, shutting down...") 73 go stack.Stop() 74 for i := 10; i > 0; i-- { 75 <-sigc 76 if i > 1 { 77 log.Warn("Already shutting down, interrupt more to panic.", "times", i-1) 78 } 79 } 80 debug.Exit() // ensure trace and CPU profile data is flushed. 81 debug.LoudPanic("boom") 82 }() 83 } 84 85 func ImportChain(chain *core.BlockChain, fn string) error { 86 // Watch for Ctrl-C while the import is running. 87 // If a signal is received, the import will stop at the next batch. 88 interrupt := make(chan os.Signal, 1) 89 stop := make(chan struct{}) 90 signal.Notify(interrupt, os.Interrupt) 91 defer signal.Stop(interrupt) 92 defer close(interrupt) 93 go func() { 94 if _, ok := <-interrupt; ok { 95 log.Info("Interrupted during import, stopping at next batch") 96 } 97 close(stop) 98 }() 99 checkInterrupt := func() bool { 100 select { 101 case <-stop: 102 return true 103 default: 104 return false 105 } 106 } 107 108 log.Info("Importing blockchain", "file", fn) 109 fh, err := os.Open(fn) 110 if err != nil { 111 return err 112 } 113 defer fh.Close() 114 115 var reader io.Reader = fh 116 if strings.HasSuffix(fn, ".gz") { 117 if reader, err = gzip.NewReader(reader); err != nil { 118 return err 119 } 120 } 121 122 stream := rlp.NewStream(reader, 0) 123 124 // Run actual the import. 125 blocks := make(types.Blocks, importBatchSize) 126 n := 0 127 for batch := 0; ; batch++ { 128 // Load a batch of RLP blocks. 129 if checkInterrupt() { 130 return fmt.Errorf("interrupted") 131 } 132 i := 0 133 for ; i < importBatchSize; i++ { 134 var b types.Block 135 if err := stream.Decode(&b); err == io.EOF { 136 break 137 } else if err != nil { 138 return fmt.Errorf("at block %d: %v", n, err) 139 } 140 // don't import first block 141 if b.NumberU64() == 0 { 142 i-- 143 continue 144 } 145 blocks[i] = &b 146 n++ 147 } 148 if i == 0 { 149 break 150 } 151 // Import the batch. 152 if checkInterrupt() { 153 return fmt.Errorf("interrupted") 154 } 155 if hasAllBlocks(chain, blocks[:i]) { 156 log.Info("Skipping batch as all blocks present", "batch", batch, "first", blocks[0].Hash(), "last", blocks[i-1].Hash()) 157 continue 158 } 159 160 if _, err := chain.InsertChain(blocks[:i]); err != nil { 161 return fmt.Errorf("invalid block %d: %v", n, err) 162 } 163 } 164 return nil 165 } 166 167 func hasAllBlocks(chain *core.BlockChain, bs []*types.Block) bool { 168 for _, b := range bs { 169 if !chain.HasBlock(b.Hash()) { 170 return false 171 } 172 } 173 return true 174 } 175 176 func ExportChain(blockchain *core.BlockChain, fn string) error { 177 log.Info("Exporting blockchain", "file", fn) 178 fh, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm) 179 if err != nil { 180 return err 181 } 182 defer fh.Close() 183 184 var writer io.Writer = fh 185 if strings.HasSuffix(fn, ".gz") { 186 writer = gzip.NewWriter(writer) 187 defer writer.(*gzip.Writer).Close() 188 } 189 190 if err := blockchain.Export(writer); err != nil { 191 return err 192 } 193 log.Info("Exported blockchain", "file", fn) 194 195 return nil 196 } 197 198 func ExportAppendChain(blockchain *core.BlockChain, fn string, first uint64, last uint64) error { 199 log.Info("Exporting blockchain", "file", fn) 200 // TODO verify mode perms 201 fh, err := os.OpenFile(fn, os.O_CREATE|os.O_APPEND|os.O_WRONLY, os.ModePerm) 202 if err != nil { 203 return err 204 } 205 defer fh.Close() 206 207 var writer io.Writer = fh 208 if strings.HasSuffix(fn, ".gz") { 209 writer = gzip.NewWriter(writer) 210 defer writer.(*gzip.Writer).Close() 211 } 212 213 if err := blockchain.ExportN(writer, first, last); err != nil { 214 return err 215 } 216 log.Info("Exported blockchain to", "file", fn) 217 return nil 218 }