ceremonyclient/node/config/config.go

251 lines
20 KiB
Go
Raw Normal View History

2023-08-21 03:50:38 +00:00
package config
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/hex"
"fmt"
"io/fs"
"os"
"path/filepath"
"github.com/cloudflare/circl/sign/ed448"
"github.com/libp2p/go-libp2p/core/crypto"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
)
type Config struct {
Key *KeyConfig `yaml:"key"`
P2P *P2PConfig `yaml:"p2p"`
Engine *EngineConfig `yaml:"engine"`
DB *DBConfig `yaml:"db"`
ListenGRPCMultiaddr string `yaml:"listenGrpcMultiaddr"`
ListenRestMultiaddr string `yaml:"listenRESTMultiaddr"`
LogFile string `yaml:"logFile"`
2023-08-21 03:50:38 +00:00
}
func NewConfig(configPath string) (*Config, error) {
file, err := os.Open(configPath)
if err != nil {
return nil, err
}
defer file.Close()
d := yaml.NewDecoder(file)
config := &Config{}
if err := d.Decode(&config); err != nil {
return nil, err
}
return config, nil
}
func LoadConfig(configPath string, proverKey string) (*Config, error) {
info, err := os.Stat(configPath)
if os.IsNotExist(err) {
fmt.Println("Creating config directory " + configPath)
if err = os.Mkdir(configPath, fs.FileMode(0700)); err != nil {
panic(err)
}
} else {
if err != nil {
panic(err)
}
if !info.IsDir() {
panic(configPath + " is not a directory")
}
}
file, err := os.Open(filepath.Join(configPath, "config.yml"))
saveDefaults := false
if err != nil {
if errors.Is(err, os.ErrNotExist) {
saveDefaults = true
} else {
return nil, err
}
}
2023-09-25 02:43:35 +00:00
bootstrapPeers := []string{
"/dns/bootstrap.quilibrium.com/udp/8336/quic/p2p/QmUhm9iZVruSxyavjoPLCfuoRG94SGQEkfxEEoukEZmD5B",
"/dns/quaalude.quilibrium.com/udp/8336/quic/p2p/QmcKQjpQmLpbDsiif2MuakhHFyxWvqYauPsJDaXnLav7PJ",
"/dns/quecifer.quilibrium.com/udp/8336/quic/p2p/QmQkyqziNCycUDdeBypkikMZWH2bBmmxfK7cbJFJmyyQdQ",
"/dns/quantum.quilibrium.com/udp/8336/quic/p2p/QmXaSyf9Gaq5ddcHysefDpuE7SJqzdg1surQ5wac55ysJV",
2023-09-25 02:43:35 +00:00
"/ip4/204.186.74.47/udp/8317/quic/p2p/Qmd233pLUDvcDW3ama27usfbG1HxKNh1V9dmWVW1SXp1pd",
"/ip4/204.186.74.46/udp/8316/quic/p2p/QmeqBjm3iX7sdTieyto1gys5ruQrQNPKfaTGcVQQWJPYDV",
"/ip4/186.233.184.181/udp/8336/quic/p2p/QmW6QDvKuYqJYYMP5tMZSp12X3nexywK28tZNgqtqNpEDL",
"/dns/quil.zanshindojo.org/udp/8336/quic/p2p/QmXbbmtS5D12rEc4HWiHWr6e83SCE4jeThPP4VJpAQPvXq",
"/ip4/185.209.178.115/udp/8336/quic/p2p/Qmekz5obb9qCRP5CrZ4D8Tmabbr5mJf6mgBJHTaitrx7Fx",
"/ip4/186.233.187.185/udp/8336/quic/p2p/QmR7jT9NKL3yZ1iRjLxPJjAVNbk38HAfDtAKF5SCZmHdpK",
"/ip4/149.86.224.152/udp/8336/quic/p2p/QmaVaJ93mKaaqDnsYbHGEUBzEtbWhb3s4DAutt6JeJC5Wz",
2023-09-25 02:43:35 +00:00
"/ip4/144.76.104.93/udp/8336/quic/p2p/QmZejZ8DBGQ6foX9recW73GA6TqL6hCMX9ETWWW1Fb8xtx",
"/ip4/65.109.17.13/udp/8336/quic/p2p/Qmc35n99eojSvW3PkbfBczJoSX92WmnnKh3Fg114ok3oo4",
"/ip4/65.108.194.84/udp/8336/quic/p2p/QmP8C7g9ZRiWzhqN2AgFu5onS6HwHzR6Vv1TCHxAhnCSnq",
2023-09-25 02:43:35 +00:00
"/ip4/207.246.81.38/udp/8336/quic/p2p/QmPBYgDy7snHon7PAn8nv1shApQBQz1iHb2sBBS8QSgQwW",
"/dns/abyssia.fr/udp/8336/quic/p2p/QmS7C1UhN8nvzLJgFFf1uspMRrXjJqThHNN6AyEXp6oVUB",
"/ip4/51.15.18.247/udp/8336/quic/p2p/QmYVaHXdFmHFeTa6oPixgjMVag6Ex7gLjE559ejJddwqzu",
"/dns/quil.dfcnodes.eu/udp/8336/quic/p2p/QmQaFmbYVrKSwoen5UQdaqyDq4QhXfSSLDVnYpYD4SF9tX",
2024-03-16 09:29:39 +00:00
"/ip4/103.219.168.169/udp/8336/quic/p2p/Qme2LDknxE5z8AnECTjJ6ZmTkSYmoQ8phegaD5vEcZM9uB",
2024-03-17 21:14:13 +00:00
"/ip4/87.98.167.207/udp/8336/quic/p2p/QmafiAXLu1JWktyfzDtD67i78GRBYCfQ4doTfq7pp7wfQ1",
"/ip4/216.244.76.122/udp/8336/quic/p2p/QmUSbMytVBUYiiGE266aZHrHrP17vLx5UJFd7o74HkDoaV",
"/ip4/185.177.126.200/udp/8336/quic/p2p/QmQn3bWk5aqaNSv9dwPjBg4qdeGBGNEB72tvuhgEc64Ki5",
2023-09-25 02:43:35 +00:00
}
genesisSeed := "5768656e20696e2074686520436f75727365206f6620746563686e6f6c6f676963616c206576656e74732c206974206265636f6d6573206e656365737361727920666f72206f6e65206e6574776f726b0a746f20646973736f6c766520746865202070726f746f636f6c2062616e647320776869636820206861766520636f6e6e6563746564207468656d20207769746820616e6f746865722c20616e6420746f0a617373756d6520616d6f6e672074686520706f77657273206f6620746865207765622c202074686520736570617261746520616e6420657175616c2073746174696f6e20746f207768696368207468650a4c617773206f6620546563686e6f6c6f677920616e6420206f6620546563686e6f6c6f6779277320537465776172647320656e7469746c65207468656d2c20206120646563656e7420726573706563740a746f20746865206f70696e696f6e73206f6620416c6c20726571756972657320207468617420746865792073686f756c64206465636c617265207468652063617573657320776869636820696d70656c0a7468656d20746f207468652073657061726174696f6e2e0a0a576520686f6c642074686573652074727574687320746f2062652073656c662d65766964656e742c207468617420616c6c20636f676e697469766520656e7469746965732061726520637265617465640a657175616c2c2074686174202074686579206172652020656e646f7765642062792020746865206f7264657220206f66206c696665202077697468206365727461696e2020756e616c69656e61626c650a5269676874732c2020746861742020616d6f6e6720207468657365202061726520204c6966652c20204c6962657274792c2020507269766163792020616e64202050726f70657274792e2020546861740a686973746f726963616c6c7920746f20207365637572652020746865736520207269676874732c202050726f746f636f6c7320206861766520206265656e2020696e737469747574656420616d6f6e670a656e7469746965732c2020617320476f7665726e6d656e74732068617665206265656e2020696e737469747574656420616d6f6e67204d656e2c2020686176696e6720646572697665642074686569720a6a75737420706f776572732066726f6d2074686520636f6e73656e74206f662074686520676f7665726e65642c2054686174207768656e6576657220616e7920466f726d206f662050726f746f636f6c0a6265636f6d6573206465737472756374697665206f6620746865736520656e64732c20697420697320746865205269676874206f6620416c6c20746f20616c746572206f7220746f2061626f6c6973680a69742c20616e6420746f20696e73746974757465206e65772050726f746f636f6c732c206c6179696e672069747320666f756e646174696f6e206f6e2073756368207072696e6369706c657320616e640a6f7267616e697a696e672069747320706f7765727320696e207375636820666f726d2c2020617320746f207468656d207368616c6c207365656d206d6f7374206c696b656c7920746f206566666563740a74686569722053616665747920616e642048617070696e6573732e2050727564656e63652c2020696e646565642c202077696c6c206469637461746520746861742050726f746f636f6c73206c6f6e670a65737461626c6973686564202073686f756c6420206e6f742020626520206368616e6765642020666f7220206c696768742020616e6420207472616e7369656e7420206361757365733b202020616e640a6163636f7264696e676c7920616c6c20657870657269656e6365206861746820736865776e2c2074686174206d616e6b696e6420617265206d6f726520646973706f73656420746f207375666665722c0a7768696c65206576696c73206172652073756666657261626c652c207468616e20746f20207269676874207468656d73656c7665732062792061626f6c697368696e672074686520666f726d7320746f0a776869636820746865792020617265206163637573746f6d65642e2020427574207768656e202061206c6f6e6720747261696e20206f66206162757365732020616e642075737572706174696f6e732c0a7075727375696e672020696e7661726961626c7920207468652073616d6520204f626a656374206576696e6365732020612064657369676e2020746f2072656475636520207468656d2020756e6465720a6162736f6c7574652020446573706f7469736d2c20206974206973202074686569722072696768742c202069742069732020746865697220647574792c2020746f207468726f77206f666620737563680a50726f746f636f6c732c2020616e6420746f2070726f76696465206e6577204775617264732020666f72207468656972206675747572652073656375726974792e20205375636820686173206265656e0a746865202070617469656e742020737566666572616e636520206f66202074686520207765623b2020616e6420207375636820697320206e6f772074686520206e6563657373697479202077686963680a636f6e73747261696e73207468656d20746f20616c74657220746865697220666f726d65722053797374656d73206f66204e6574776f726b696e672e202054686520686973746f7279206f66207468650a70726573656e7420496e7465726e6574206973206120686973746f727920206f6620726570656174656420696e6a757269657320616e642075737572706174696f6e732c2020
2023-08-21 03:50:38 +00:00
config := &Config{
DB: &DBConfig{
Path: configPath + "/store",
},
Key: &KeyConfig{
KeyStore: KeyManagerTypeFile,
KeyStoreFile: &KeyStoreFileConfig{
Path: filepath.Join(configPath, "keys.yml"),
},
},
P2P: &P2PConfig{
ListenMultiaddr: "/ip4/0.0.0.0/udp/8336/quic",
2023-09-25 02:43:35 +00:00
BootstrapPeers: bootstrapPeers,
PeerPrivKey: "",
2023-08-21 03:50:38 +00:00
},
Engine: &EngineConfig{
ProvingKeyId: "default-proving-key",
Filter: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
2023-09-25 02:43:35 +00:00
GenesisSeed: genesisSeed,
2023-08-21 03:50:38 +00:00
MaxFrames: -1,
PendingCommitWorkers: 4,
},
}
if saveDefaults {
fmt.Println("Generating default config...")
fmt.Println("Generating random host key...")
privkey, _, err := crypto.GenerateEd448Key(rand.Reader)
if err != nil {
panic(err)
}
hostKey, err := privkey.Raw()
if err != nil {
panic(err)
}
config.P2P.PeerPrivKey = hex.EncodeToString(hostKey)
fmt.Println("Generating keystore key...")
keystoreKey := make([]byte, 32)
if _, err := rand.Read(keystoreKey); err != nil {
panic(err)
}
config.Key.KeyStoreFile.EncryptionKey = hex.EncodeToString(keystoreKey)
if multiAddr := os.Getenv("DEFAULT_LISTEN_GRPC_MULTIADDR"); multiAddr != "" {
config.ListenGRPCMultiaddr = multiAddr
config.ListenRestMultiaddr = os.Getenv("DEFAULT_LISTEN_REST_MULTIADDR")
}
if multiAddr := os.Getenv("DEFAULT_STATS_MULTIADDR"); multiAddr != "" {
config.Engine.StatsMultiaddr = multiAddr
}
2023-08-21 03:50:38 +00:00
fmt.Println("Saving config...")
if err = SaveConfig(configPath, config); err != nil {
panic(err)
}
keyfile, err := os.OpenFile(
filepath.Join(configPath, "keys.yml"),
os.O_CREATE|os.O_RDWR,
fs.FileMode(0600),
2023-08-21 03:50:38 +00:00
)
if err != nil {
panic(err)
}
if proverKey != "" {
provingKey, err := hex.DecodeString(proverKey)
if err != nil {
panic(err)
}
iv := [12]byte{}
rand.Read(iv[:])
aesCipher, err := aes.NewCipher(keystoreKey)
if err != nil {
return nil, errors.Wrap(err, "could not construct cipher")
}
gcm, err := cipher.NewGCM(aesCipher)
if err != nil {
return nil, errors.Wrap(err, "could not construct block")
}
ciphertext := gcm.Seal(nil, iv[:], provingKey, nil)
ciphertext = append(append([]byte{}, iv[:]...), ciphertext...)
provingPubKey := ed448.PrivateKey(provingKey).Public().(ed448.PublicKey)
keyfile.Write([]byte(
"default-proving-key:\n id: default-proving-key\n" +
" type: 0\n privateKey: " + hex.EncodeToString(ciphertext) + "\n" +
" publicKey: " + hex.EncodeToString(provingPubKey) + "\n"))
} else {
keyfile.Write([]byte("null:\n"))
}
keyfile.Close()
if file, err = os.Open(
filepath.Join(configPath, "config.yml"),
); err != nil {
panic(err)
}
}
defer file.Close()
d := yaml.NewDecoder(file)
if err := d.Decode(&config); err != nil {
return nil, err
}
2023-09-25 02:43:35 +00:00
if config.Engine.GenesisSeed == "00" {
config.Engine.GenesisSeed = genesisSeed
}
// Slight trick here to get people on the latest bootstrap list
// if it's empty, always use latest, if it has the Q bootstrap node, always
// use latest.
if len(config.P2P.BootstrapPeers) == 0 ||
config.P2P.BootstrapPeers[0] == bootstrapPeers[0] {
2023-09-25 02:43:35 +00:00
config.P2P.BootstrapPeers = bootstrapPeers
}
2023-08-21 03:50:38 +00:00
return config, nil
}
func SaveConfig(configPath string, config *Config) error {
file, err := os.OpenFile(
filepath.Join(configPath, "config.yml"),
os.O_CREATE|os.O_RDWR,
os.FileMode(0600),
)
if err != nil {
return err
}
defer file.Close()
d := yaml.NewEncoder(file)
if err := d.Encode(config); err != nil {
return err
}
return nil
}