github.com/elastos/Elastos.ELA.SideChain.ETH@v0.2.2/chainbridge-core/config/config.go (about) 1 // Copyright 2020 ChainSafe Systems 2 // SPDX-License-Identifier: LGPL-3.0-only 3 4 package config 5 6 import ( 7 "encoding/json" 8 "fmt" 9 "os" 10 "path/filepath" 11 12 "github.com/elastos/Elastos.ELA.SideChain.ESC/chainbridge-core/bridgelog" 13 "github.com/elastos/Elastos.ELA.SideChain.ESC/chainbridge-core/crypto/secp256k1" 14 ) 15 16 var ( 17 DefaultConfigDir = "./chainbridge/config/chain_bridge.json" 18 KeystoreFlagName = "./data/keystore/" 19 BlockstoreFlagName = "./chainbridge/blockstore" 20 FreshStartFlagName = "fresh" 21 LatestBlockFlagName = "latest" 22 ) 23 24 type GeneralChainConfig struct { 25 Name string `json:"name"` // Human-readable chain name 26 Id uint64 `json:"id"` //ChainID 27 Endpoint string `json:"endpoint"` // url for rpc endpoint 28 From string `json:"from"` // address of key to use 29 KeystorePath string // Location of key files 30 Insecure bool // Indicated whether the test keyring should be used 31 BlockstorePath string // Location of blockstore 32 FreshStart bool // If true, blockstore is ignored at start. 33 LatestBlock bool // If true, overrides blockstore or latest block in config and starts from current block 34 Opts OpsConfig 35 Kp *secp256k1.Keypair 36 } 37 38 func (c *GeneralChainConfig) Validate() error { 39 // viper defaults to 0 for not specified ints, but we must have a valid chain id 40 // Previous method of checking used a string cast like below 41 //chainId := string(c.Id) 42 if c.Id == 0 { 43 return fmt.Errorf("required field chain.Id empty for chain %v", c.Id) 44 } 45 if c.Endpoint == "" { 46 return fmt.Errorf("required field chain.Endpoint empty for chain %v", c.Id) 47 } 48 if c.Name == "" { 49 return fmt.Errorf("required field chain.Name empty for chain %v", c.Id) 50 } 51 if err := c.Opts.Validate(); err != nil { 52 return err 53 } 54 return nil 55 } 56 57 type BridgeConfig struct { 58 Chains []GeneralChainConfig `json:"chains"` 59 } 60 61 func NewConfig() *BridgeConfig { 62 return &BridgeConfig{ 63 Chains: []GeneralChainConfig{}, 64 } 65 } 66 67 func (c *BridgeConfig) validateAndParse() error { 68 for _, chain := range c.Chains { 69 err := chain.Validate() 70 if err != nil { 71 return err 72 } 73 ops, err := chain.Opts.ParseConfig() 74 if err != nil { 75 return err 76 } 77 chain.Opts = *ops 78 } 79 return nil 80 } 81 82 func GetConfig(path string) (*BridgeConfig, error) { 83 var fig = NewConfig() 84 if path == "" { 85 path = DefaultConfigDir 86 } 87 88 err := loadConfig(path, fig) 89 if err != nil { 90 bridgelog.Warn("err loading json file", "err", err.Error()) 91 return fig, err 92 } 93 94 err = fig.validateAndParse() 95 if err != nil { 96 return nil, err 97 } 98 return fig, nil 99 } 100 101 func loadConfig(file string, config *BridgeConfig) error { 102 ext := filepath.Ext(file) 103 fp, err := filepath.Abs(file) 104 if err != nil { 105 return err 106 } 107 f, err := os.Open(filepath.Clean(fp)) 108 if err != nil { 109 return err 110 } 111 112 if ext == ".json" { 113 if err = json.NewDecoder(f).Decode(&config); err != nil { 114 return err 115 } 116 } else { 117 return fmt.Errorf("unrecognized extention: %s", ext) 118 } 119 return nil 120 }