forked from ChainSafe/ChainBridge
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathconfig.go
134 lines (116 loc) · 3.11 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Copyright 2020 ChainSafe Systems
// SPDX-License-Identifier: LGPL-3.0-only
package config
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"github.com/ethereum/go-ethereum/log"
"github.com/urfave/cli/v2"
)
const DefaultConfigPath = "./config.json"
const DefaultKeystorePath = "./keys"
const DefaultBlockTimeout = int64(180) // 3 minutes
type Config struct {
Chains []RawChainConfig `json:"chains"`
KeystorePath string `json:"keystorePath,omitempty"`
}
// RawChainConfig is parsed directly from the config file and should be using to construct the core.ChainConfig
type RawChainConfig struct {
Name string `json:"name"`
Type string `json:"type"`
Id string `json:"id"` // ChainID
Endpoint string `json:"endpoint"` // url for rpc endpoint
From string `json:"from"` // address of key to use
Opts map[string]string `json:"opts"`
}
func NewConfig() *Config {
return &Config{
Chains: []RawChainConfig{},
}
}
func (c *Config) ToJSON(file string) *os.File {
var (
newFile *os.File
err error
)
var raw []byte
if raw, err = json.Marshal(*c); err != nil {
log.Warn("error marshalling json", "err", err)
os.Exit(1)
}
newFile, err = os.Create(file)
if err != nil {
log.Warn("error creating config file", "err", err)
}
_, err = newFile.Write(raw)
if err != nil {
log.Warn("error writing to config file", "err", err)
}
if err := newFile.Close(); err != nil {
log.Warn("error closing file", "err", err)
}
return newFile
}
func (c *Config) validate() error {
for _, chain := range c.Chains {
if chain.Type == "" {
return fmt.Errorf("required field chain.Type empty for chain %s", chain.Id)
}
if chain.Endpoint == "" {
return fmt.Errorf("required field chain.Endpoint empty for chain %s", chain.Id)
}
if chain.Name == "" {
return fmt.Errorf("required field chain.Name empty for chain %s", chain.Id)
}
if chain.Id == "" {
return fmt.Errorf("required field chain.Id empty for chain %s", chain.Id)
}
if chain.From == "" {
return fmt.Errorf("required field chain.From empty for chain %s", chain.Id)
}
}
return nil
}
func GetConfig(ctx *cli.Context) (*Config, error) {
var fig Config
path := DefaultConfigPath
if file := ctx.String(ConfigFileFlag.Name); file != "" {
path = file
}
err := loadConfig(path, &fig)
if err != nil {
log.Warn("err loading json file", "err", err.Error())
return &fig, err
}
if ksPath := ctx.String(KeystorePathFlag.Name); ksPath != "" {
fig.KeystorePath = ksPath
}
log.Debug("Loaded config", "path", path)
err = fig.validate()
if err != nil {
return nil, err
}
return &fig, nil
}
func loadConfig(file string, config *Config) error {
ext := filepath.Ext(file)
fp, err := filepath.Abs(file)
if err != nil {
return err
}
log.Debug("Loading configuration", "path", filepath.Clean(fp))
f, err := os.Open(filepath.Clean(fp))
if err != nil {
return err
}
if ext == ".json" {
if err = json.NewDecoder(f).Decode(&config); err != nil {
return err
}
} else {
return fmt.Errorf("unrecognized extention: %s", ext)
}
return nil
}