github.com/palisadeinc/bor@v0.0.0-20230615125219-ab7196213d15/internal/cli/command.go (about) 1 package cli 2 3 import ( 4 "fmt" 5 "os" 6 7 "github.com/ethereum/go-ethereum/accounts/keystore" 8 "github.com/ethereum/go-ethereum/internal/cli/flagset" 9 "github.com/ethereum/go-ethereum/internal/cli/server" 10 "github.com/ethereum/go-ethereum/internal/cli/server/proto" 11 "github.com/ethereum/go-ethereum/node" 12 13 "github.com/mitchellh/cli" 14 "github.com/ryanuber/columnize" 15 "google.golang.org/grpc" 16 ) 17 18 const ( 19 emptyPlaceHolder = "<none>" 20 ) 21 22 type MarkDownCommand interface { 23 MarkDown 24 cli.Command 25 } 26 27 type MarkDownCommandFactory func() (MarkDownCommand, error) 28 29 func Run(args []string) int { 30 commands := Commands() 31 32 mappedCommands := make(map[string]cli.CommandFactory) 33 34 for k, v := range commands { 35 // Declare a new v to limit the scope of v to inside the block, so the anonymous function below 36 // can get the "current" value of v, instead of the value of last v in the loop. 37 // See this post: https://stackoverflow.com/questions/10116507/go-transfer-var-into-anonymous-function for more explanation 38 v := v 39 mappedCommands[k] = func() (cli.Command, error) { 40 cmd, err := v() 41 return cmd.(cli.Command), err 42 } 43 } 44 45 cli := &cli.CLI{ 46 Name: "bor", 47 Args: args, 48 Commands: mappedCommands, 49 } 50 51 exitCode, err := cli.Run() 52 if err != nil { 53 fmt.Fprintf(os.Stderr, "Error executing CLI: %s\n", err.Error()) 54 return 1 55 } 56 57 return exitCode 58 } 59 60 func Commands() map[string]MarkDownCommandFactory { 61 ui := &cli.BasicUi{ 62 Reader: os.Stdin, 63 Writer: os.Stdout, 64 ErrorWriter: os.Stderr, 65 } 66 67 meta2 := &Meta2{ 68 UI: ui, 69 } 70 meta := &Meta{ 71 UI: ui, 72 } 73 74 return map[string]MarkDownCommandFactory{ 75 "server": func() (MarkDownCommand, error) { 76 return &server.Command{ 77 UI: ui, 78 }, nil 79 }, 80 "version": func() (MarkDownCommand, error) { 81 return &VersionCommand{ 82 UI: ui, 83 }, nil 84 }, 85 "dumpconfig": func() (MarkDownCommand, error) { 86 return &DumpconfigCommand{ 87 Meta2: meta2, 88 }, nil 89 }, 90 "debug": func() (MarkDownCommand, error) { 91 return &DebugCommand{ 92 UI: ui, 93 }, nil 94 }, 95 "debug pprof": func() (MarkDownCommand, error) { 96 return &DebugPprofCommand{ 97 Meta2: meta2, 98 }, nil 99 }, 100 "debug block": func() (MarkDownCommand, error) { 101 return &DebugBlockCommand{ 102 Meta2: meta2, 103 }, nil 104 }, 105 "chain": func() (MarkDownCommand, error) { 106 return &ChainCommand{ 107 UI: ui, 108 }, nil 109 }, 110 "chain watch": func() (MarkDownCommand, error) { 111 return &ChainWatchCommand{ 112 Meta2: meta2, 113 }, nil 114 }, 115 "chain sethead": func() (MarkDownCommand, error) { 116 return &ChainSetHeadCommand{ 117 Meta2: meta2, 118 }, nil 119 }, 120 "account": func() (MarkDownCommand, error) { 121 return &Account{ 122 UI: ui, 123 }, nil 124 }, 125 "account new": func() (MarkDownCommand, error) { 126 return &AccountNewCommand{ 127 Meta: meta, 128 }, nil 129 }, 130 "account import": func() (MarkDownCommand, error) { 131 return &AccountImportCommand{ 132 Meta: meta, 133 }, nil 134 }, 135 "account list": func() (MarkDownCommand, error) { 136 return &AccountListCommand{ 137 Meta: meta, 138 }, nil 139 }, 140 "peers": func() (MarkDownCommand, error) { 141 return &PeersCommand{ 142 UI: ui, 143 }, nil 144 }, 145 "peers add": func() (MarkDownCommand, error) { 146 return &PeersAddCommand{ 147 Meta2: meta2, 148 }, nil 149 }, 150 "peers remove": func() (MarkDownCommand, error) { 151 return &PeersRemoveCommand{ 152 Meta2: meta2, 153 }, nil 154 }, 155 "peers list": func() (MarkDownCommand, error) { 156 return &PeersListCommand{ 157 Meta2: meta2, 158 }, nil 159 }, 160 "peers status": func() (MarkDownCommand, error) { 161 return &PeersStatusCommand{ 162 Meta2: meta2, 163 }, nil 164 }, 165 "status": func() (MarkDownCommand, error) { 166 return &StatusCommand{ 167 Meta2: meta2, 168 }, nil 169 }, 170 "fingerprint": func() (MarkDownCommand, error) { 171 return &FingerprintCommand{ 172 UI: ui, 173 }, nil 174 }, 175 "attach": func() (MarkDownCommand, error) { 176 return &AttachCommand{ 177 UI: ui, 178 Meta: meta, 179 Meta2: meta2, 180 }, nil 181 }, 182 "bootnode": func() (MarkDownCommand, error) { 183 return &BootnodeCommand{ 184 UI: ui, 185 }, nil 186 }, 187 "removedb": func() (MarkDownCommand, error) { 188 return &RemoveDBCommand{ 189 Meta2: meta2, 190 }, nil 191 }, 192 "snapshot": func() (MarkDownCommand, error) { 193 return &SnapshotCommand{ 194 UI: ui, 195 }, nil 196 }, 197 "snapshot prune-state": func() (MarkDownCommand, error) { 198 return &PruneStateCommand{ 199 Meta: meta, 200 }, nil 201 }, 202 } 203 } 204 205 type Meta2 struct { 206 UI cli.Ui 207 208 addr string 209 } 210 211 func (m *Meta2) NewFlagSet(n string) *flagset.Flagset { 212 f := flagset.NewFlagSet(n) 213 214 f.StringFlag(&flagset.StringFlag{ 215 Name: "address", 216 Value: &m.addr, 217 Usage: "Address of the grpc endpoint", 218 Default: "127.0.0.1:3131", 219 }) 220 221 return f 222 } 223 224 func (m *Meta2) Conn() (*grpc.ClientConn, error) { 225 conn, err := grpc.Dial(m.addr, grpc.WithInsecure()) 226 if err != nil { 227 return nil, fmt.Errorf("failed to connect to server: %v", err) 228 } 229 230 return conn, nil 231 } 232 233 func (m *Meta2) BorConn() (proto.BorClient, error) { 234 conn, err := m.Conn() 235 if err != nil { 236 return nil, err 237 } 238 239 return proto.NewBorClient(conn), nil 240 } 241 242 // Meta is a helper utility for the commands 243 type Meta struct { 244 UI cli.Ui 245 246 dataDir string 247 keyStoreDir string 248 } 249 250 func (m *Meta) NewFlagSet(n string) *flagset.Flagset { 251 f := flagset.NewFlagSet(n) 252 253 f.StringFlag(&flagset.StringFlag{ 254 Name: "datadir", 255 Value: &m.dataDir, 256 Usage: "Path of the data directory to store information", 257 }) 258 f.StringFlag(&flagset.StringFlag{ 259 Name: "keystore", 260 Value: &m.keyStoreDir, 261 Usage: "Path of the data directory to store keys", 262 }) 263 264 return f 265 } 266 267 func (m *Meta) AskPassword() (string, error) { 268 return m.UI.AskSecret("Your new account is locked with a password. Please give a password. Do not forget this password") 269 } 270 271 func (m *Meta) GetKeystore() (*keystore.KeyStore, error) { 272 cfg := node.DefaultConfig 273 cfg.DataDir = m.dataDir 274 cfg.KeyStoreDir = m.keyStoreDir 275 276 stack, err := node.New(&cfg) 277 if err != nil { 278 return nil, err 279 } 280 281 keydir := stack.KeyStoreDir() 282 scryptN := keystore.StandardScryptN 283 scryptP := keystore.StandardScryptP 284 285 keys := keystore.NewKeyStore(keydir, scryptN, scryptP) 286 287 return keys, nil 288 } 289 290 func formatList(in []string) string { 291 columnConf := columnize.DefaultConfig() 292 columnConf.Empty = emptyPlaceHolder 293 294 return columnize.Format(in, columnConf) 295 } 296 297 func formatKV(in []string) string { 298 columnConf := columnize.DefaultConfig() 299 columnConf.Empty = emptyPlaceHolder 300 columnConf.Glue = " = " 301 302 return columnize.Format(in, columnConf) 303 }