Skip to content

Commit d7b3713

Browse files
authored
Use go to keep config (#2)
* First approach * Update go settings * Fix metrics envs * Remove noisy logging
1 parent 8da9ce3 commit d7b3713

File tree

13 files changed

+437
-63
lines changed

13 files changed

+437
-63
lines changed

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ services:
1414
context: shutter
1515
args:
1616
ASSETS_VERSION: shutter-gnosis-1000-set-1v2 # $NETWORK-10*$CHAIN_ID-set-$VERSION
17-
UPSTREAM_VERSION: gnosis-v1.2.1
17+
UPSTREAM_VERSION: gnosis-v1.2.4b1
1818
KEYPER_CONFIG_DIR: /keyper/config
1919
SHUTTER_CHAIN_DIR: /chain
2020
STAKER_SCRIPTS_VERSION: v0.1.0

metrics/entrypoint.sh

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ update_user_setting() {
1919

2020
if [ -z "$value" ]; then
2121
echo "[INFO | metrics] Skipped updating $key in user settings file (empty value)"
22-
return 1
22+
return 0
2323
fi
2424

2525
if grep -q "^$key=" "$USER_SETTINGS_FILE"; then
@@ -33,7 +33,7 @@ update_user_setting() {
3333
fi
3434
}
3535

36-
source_envs() {
36+
source_assets_envs() {
3737
set -a # Export all variables
3838

3939
# shellcheck disable=SC1091
@@ -49,12 +49,19 @@ source_envs() {
4949
_ASSETS_VERSION="$(cat /assets/version)"
5050
fi
5151

52-
# shellcheck disable=SC1090
53-
. "$USER_SETTINGS_FILE"
54-
5552
set +a
5653
}
5754

55+
source_user_settings() {
56+
# Ensure user settings file exists
57+
if [ -f "$USER_SETTINGS_FILE" ]; then
58+
set -a
59+
# shellcheck disable=SC1090
60+
. "$USER_SETTINGS_FILE"
61+
set +a
62+
fi
63+
}
64+
5865
replace_envs_in_yaml() {
5966
echo "[INFO | metrics] Replacing environment variables in the configuration file"
6067
sed "s|%{KEYPER_NAME}|$KEYPER_NAME|g; s|%{_ASSETS_VERSION}|$_ASSETS_VERSION|g" "$TEMPLATE_CONFIG_FILE" >"$CONFIG_FILE"
@@ -67,7 +74,9 @@ if [ "${SHUTTER_PUSH_METRICS_ENABLED}" = "false" ]; then
6774
exit 0
6875
fi
6976

70-
source_envs
77+
source_assets_envs
78+
79+
source_user_settings
7180

7281
replace_envs_in_yaml
7382

package_variants/gnosis/docker-compose.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ services:
44
args:
55
NETWORK: gnosis
66
CHAIN_PORT: 26656
7-
PROMETHEUS_LISTEN_PORT: 26660
87
KEYPER_PORT: 23003
98
KEYPER_METRICS_PORT: 9100
109

@@ -17,4 +16,4 @@ services:
1716
- "23003:23003/tcp"
1817
- "26656:26656"
1918
- "26660:26660"
20-
- "9100:9100"
19+
- "9100:9100"

shutter/Dockerfile

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ ARG KEYPER_CONFIG_DIR
1313
ARG SHUTTER_CHAIN_DIR
1414
ARG KEYPER_PORT
1515
ARG CHAIN_PORT
16-
ARG PROMETHEUS_LISTEN_PORT
1716
ARG STAKER_SCRIPTS_VERSION
1817

1918
RUN apt-get update && \
@@ -24,22 +23,27 @@ RUN apt-get update && \
2423
ENV SHUTTER_GNOSIS_SM_BLOCKTIME=10 \
2524
SHUTTER_GNOSIS_GENESIS_KEYPER=0x440Dc6F164e9241F04d282215ceF2780cd0B755e \
2625
SHUTTER_GNOSIS_MAXTXPOINTERAGE=5 \
27-
SHUTTER_DATABASEURL=postgres://[email protected]${NETWORK}.dappnode:5432/keyper \
26+
SHUTTER_DATABASE_URL=postgres://[email protected]${NETWORK}.dappnode:5432/keyper \
2827
SHUTTER_SHUTTERMINT_SHUTTERMINTURL=http://localhost:26657 \
2928
CHAIN_LISTEN_PORT=26657 \
3029
SHUTTER_BIN=/rolling-shutter \
3130
SHUTTER_ENV_FILE=/shutter.env \
3231
KEYPER_GENERATED_CONFIG_FILE=${KEYPER_CONFIG_DIR}/generated.toml \
3332
KEYPER_CONFIG_FILE=${KEYPER_CONFIG_DIR}/keyper.toml \
3433
SHUTTER_CHAIN_DIR=${SHUTTER_CHAIN_DIR} \
34+
KEYPER_PORT=${KEYPER_PORT} \
3535
SHUTTER_CHAIN_CONFIG_FILE=${SHUTTER_CHAIN_DIR}/config/config.toml \
3636
ASSETS_DIR=/assets \
37+
SHUTTER_SETTINGS_SRC_DIR=/usr/src/go-shutter-settings \
3738
STAKER_SCRIPTS_URL=https://github.com/dappnode/staker-package-scripts/releases/download/${STAKER_SCRIPTS_VERSION}
3839

3940
ADD ${STAKER_SCRIPTS_URL}/dvt_lsd_tools.sh /etc/profile.d/
4041

42+
COPY go-shutter-settings ${SHUTTER_SETTINGS_SRC_DIR}
4143
COPY supervisord.conf /etc/supervisord.conf
4244

45+
RUN go build -C ${SHUTTER_SETTINGS_SRC_DIR} -o /usr/local/bin/go_shutter_settings
46+
4347
RUN mkdir -p ${KEYPER_CONFIG_DIR} ${SHUTTER_CHAIN_DIR} ${ASSETS_DIR} /opt/supervisor && \
4448
chmod +rx /etc/profile.d/dvt_lsd_tools.sh
4549

@@ -48,8 +52,7 @@ COPY --from=assets ${ASSETS_DIR}/ ${ASSETS_DIR}/
4852

4953
# Placed here to rebuild less layers
5054
ENV CHAIN_PORT=${CHAIN_PORT} \
51-
SHUTTER_P2P_LISTENADDRESSES=/ip4/0.0.0.0/tcp/${KEYPER_PORT} \
52-
PROMETHEUS_LISTEN_PORT=${PROMETHEUS_LISTEN_PORT} \
55+
SHUTTER_P2P_LISTENADDRESSES="/ip4/0.0.0.0/tcp/${KEYPER_PORT}" \
5356
NETWORK=${NETWORK}
5457

5558
ENTRYPOINT ["supervisord", "-c", "/etc/supervisord.conf"]

shutter/go-shutter-settings/go.mod

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module go-shutter-settings
2+
3+
go 1.21.0
4+
5+
require github.com/joho/godotenv v1.5.1
6+
7+
require github.com/pelletier/go-toml/v2 v2.2.3

shutter/go-shutter-settings/go.sum

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
2+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3+
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
4+
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
5+
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
6+
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
7+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
8+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
9+
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
10+
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
11+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
12+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"fmt"
6+
"go-shutter-settings/settings"
7+
"log"
8+
"os"
9+
10+
"github.com/joho/godotenv"
11+
)
12+
13+
func main() {
14+
var generatedFilePath, configFilePath, outputFilePath string
15+
16+
// Define flags for the generated, config, and output paths
17+
flag.StringVar(&generatedFilePath, "generated", "", "Path to the generated file where settings will be included")
18+
flag.StringVar(&configFilePath, "config", "", "Path to the config file where the settings will be read")
19+
flag.StringVar(&outputFilePath, "output", "", "Path where the modified settings will be saved")
20+
21+
// Parse the flags
22+
flag.Parse()
23+
24+
// Load environment variables from the .env file
25+
err := godotenv.Load(os.Getenv("ASSETS_DIR") + "/variables.env")
26+
if err != nil {
27+
log.Fatalf("Error loading .env file: %v", err)
28+
}
29+
30+
// Check for additional arguments, e.g., keyper or chain
31+
if len(flag.Args()) < 1 {
32+
fmt.Println("Error: missing argument. Use 'include-keyper-settings' or 'include-chain-settings'.")
33+
os.Exit(1)
34+
}
35+
36+
// Read the argument passed to the program
37+
argument := flag.Arg(0)
38+
39+
// Call appropriate function based on the command
40+
switch argument {
41+
case "include-keyper-settings":
42+
// Ensure generated, config, and output paths are provided
43+
if generatedFilePath == "" || configFilePath == "" || outputFilePath == "" {
44+
fmt.Println("Error: --generated, --config, and --output flags must be provided for keyper settings.")
45+
flag.Usage()
46+
os.Exit(1)
47+
}
48+
49+
// Call the function to configure keyper
50+
err := settings.AddSettingsToKeyper(generatedFilePath, configFilePath, outputFilePath)
51+
if err != nil {
52+
log.Fatalf("Failed to configure keyper: %v", err)
53+
}
54+
55+
case "include-chain-settings":
56+
// Ensure config and output paths are provided
57+
if generatedFilePath == "" || outputFilePath == "" {
58+
fmt.Println("Error: --config and --output flags must be provided for chain settings.")
59+
flag.Usage()
60+
os.Exit(1)
61+
}
62+
63+
// Call the function to configure chain
64+
err := settings.AddSettingsToChain(generatedFilePath, outputFilePath)
65+
if err != nil {
66+
log.Fatalf("Failed to configure chain: %v", err)
67+
}
68+
69+
default:
70+
fmt.Println("Invalid argument. Use 'include-keyper-settings' or 'include-chain-settings'.")
71+
os.Exit(1)
72+
}
73+
74+
fmt.Println("Configuration completed successfully!")
75+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package settings
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"reflect"
7+
"strings"
8+
)
9+
10+
type ChainConfig struct {
11+
Moniker string `env:"KEYPER_NAME"`
12+
Genesis_file string `env:"ASSETS_GENESIS_FILE"`
13+
P2P struct {
14+
Seeds string `env:"_ASSETS_SHUTTERMINT_SEED_NODES"`
15+
External_address string `env:"SHUTTER_EXTERNAL_ADDRESS"`
16+
Addr_book_strict bool `env:"SHUTTER_ADDR_BOOK_STRICT"`
17+
Pex bool `env:"SHUTTER_P2P_PEX"`
18+
}
19+
Instrumentation struct {
20+
Prometheus bool `env:"SHUTTER_PUSH_METRICS_ENABLED"`
21+
Prometheus_listen_addr string `env:"SHUTTER_PROMETHEUS_LISTEN_ADDR"`
22+
}
23+
}
24+
25+
func AddSettingsToChain(generatedFilePath, outputFilePath string) error {
26+
var generatedConfig map[string]interface{}
27+
28+
fmt.Println("Adding user settings to chain...")
29+
30+
if _, err := os.Stat(generatedFilePath); os.IsNotExist(err) {
31+
return fmt.Errorf("generated file does not exist: %s", generatedFilePath)
32+
}
33+
34+
// Read and unmarshal the keyper config file
35+
if err := UnmarshallFromFile(generatedFilePath, &generatedConfig); err != nil {
36+
return err
37+
}
38+
39+
chainConfig := getChainConfigFromEnvs()
40+
41+
// ToLower is used because chain cofig file fields are lower case, but the struct
42+
// fields are upper case to be exported
43+
ApplyConfigToGenerated(reflect.ValueOf(chainConfig), &generatedConfig, strings.ToLower)
44+
45+
MarshalToFile(outputFilePath, generatedConfig)
46+
47+
fmt.Println("Chain TOML file modified successfully and saved to", outputFilePath)
48+
49+
return nil
50+
}
51+
52+
func getChainConfigFromEnvs() ChainConfig {
53+
chainConfig := ChainConfig{}
54+
PopulateFromEnv(&chainConfig)
55+
return chainConfig
56+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package settings
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"reflect"
7+
)
8+
9+
type KeyperConfig struct {
10+
InstanceID int `env:"_ASSETS_INSTANCE_ID"`
11+
DatabaseURL string `env:"SHUTTER_DATABASE_URL"`
12+
BeaconAPIURL string `env:"SHUTTER_BEACONAPIURL"`
13+
MaxNumKeysPerMessage int `env:"_ASSETS_MAX_NUM_KEYS_PER_MESSAGE"`
14+
Gnosis struct {
15+
EncryptedGasLimit int `env:"_ASSETS_ENCRYPTED_GAS_LIMIT"`
16+
MaxTxPointerAge int `env:"_ASSETS_MAX_TX_POINTER_AGE"`
17+
GenesisSlotTimestamp int `env:"_ASSETS_GENESIS_SLOT_TIMESTAMP"`
18+
SyncStartBlockNumber int `env:"_ASSETS_SYNC_START_BLOCK_NUMBER"`
19+
Node struct {
20+
PrivateKey string `env:"SHUTTER_GNOSIS_NODE_PRIVATEKEY"`
21+
ContractsURL string `env:"SHUTTER_GNOSIS_NODE_CONTRACTSURL"`
22+
DeploymentDir string `env:"SHUTTER_DEPLOYMENT_DIR"` // Unused
23+
EthereumURL string `env:"SHUTTER_GNOSIS_NODE_ETHEREUMURL"`
24+
}
25+
Contracts struct {
26+
KeyperSetManager string `env:"_ASSETS_KEYPER_SET_MANAGER"`
27+
KeyBroadcastContract string `env:"_ASSETS_KEY_BROADCAST_CONTRACT"`
28+
Sequencer string `env:"_ASSETS_SEQUENCER"`
29+
ValidatorRegistry string `env:"_ASSETS_VALIDATOR_REGISTRY"`
30+
}
31+
}
32+
P2P struct {
33+
P2PKey string `env:"SHUTTER_P2P_KEY"`
34+
ListenAddresses string `env:"SHUTTER_P2P_LISTENADDRESSES"`
35+
AdvertiseAddresses string `env:"SHUTTER_P2P_ADVERTISEADDRESSES"`
36+
CustomBootstrapAddresses []string `env:"_ASSETS_CUSTOM_BOOTSTRAP_ADDRESSES"`
37+
DiscoveryNamespace string `env:"_ASSETS_DISCOVERY_NAME_PREFIX"`
38+
}
39+
Shuttermint struct {
40+
ShuttermintURL string `env:"SHUTTER_SHUTTERMINT_SHUTTERMINTURL"`
41+
ValidatorPublicKey string `env:"VALIDATOR_PUBLIC_KEY"`
42+
EncryptionKey string `env:"SHUTTER_SHUTTERMINT_ENCRYPTION_PUBLIC_KEY"`
43+
DKGPhaseLength int `env:"_ASSETS_DKG_PHASE_LENGTH"`
44+
DKGStartBlockDelta int `env:"_ASSETS_DKG_START_BLOCK_DELTA"`
45+
}
46+
Metrics struct {
47+
Enabled bool `env:"SHUTTER_ENABLED"`
48+
}
49+
}
50+
51+
// AddSettingsToKeyper modifies the keyper settings by combining the generated, config, and environment variables.
52+
func AddSettingsToKeyper(generatedFilePath, configFilePath, outputFilePath string) error {
53+
var keyperConfig KeyperConfig
54+
var generatedConfig map[string]interface{}
55+
56+
fmt.Println("Adding user settings to keyper...")
57+
58+
if _, err := os.Stat(generatedFilePath); os.IsNotExist(err) {
59+
return fmt.Errorf("generated file does not exist: %s", generatedFilePath)
60+
}
61+
62+
if _, err := os.Stat(configFilePath); os.IsNotExist(err) {
63+
return fmt.Errorf("config file does not exist: %s", configFilePath)
64+
}
65+
66+
// Read and unmarshal the keyper config file
67+
if err := UnmarshallFromFile(configFilePath, &keyperConfig); err != nil {
68+
return err
69+
}
70+
71+
PopulateFromEnv(&keyperConfig)
72+
73+
// Read and unmarshal the generated file
74+
if err := UnmarshallFromFile(generatedFilePath, &generatedConfig); err != nil {
75+
return err
76+
}
77+
78+
ApplyConfigToGenerated(reflect.ValueOf(keyperConfig), &generatedConfig, nil)
79+
80+
MarshalToFile(outputFilePath, generatedConfig)
81+
82+
fmt.Println("Keyper TOML file modified successfully and saved to", outputFilePath)
83+
84+
return nil
85+
}

0 commit comments

Comments
 (0)