diff --git a/README.md b/README.md index ce6770d..c484b64 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ This package includes the following services: - Uses VictoriaMetrics to send performance metrics to a remote Pushgateway. - - Configuration is handled through templates in `/config/gnosis/`, and the main config file (`vmagent.yml`) is dynamically generated based on environment variables. + - Configuration is handled via the config file `/config/gnosis/vmagent.yml`, placehoders in that file are automatically picked up from the environment by vmagent. ### Configuration diff --git a/docker-compose.yml b/docker-compose.yml index 494d9ec..2fd5560 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,8 +13,8 @@ services: build: context: shutter args: - ASSETS_VERSION: shutter-gnosis-1000-set-1v2 # $NETWORK-10*$CHAIN_ID-set-$VERSION - UPSTREAM_VERSION: gnosis-v1.2.4b1 + ASSETS_VERSION: shutter-gnosis-1000-set1.3 # $NETWORK-10*$CHAIN_ID-set-$VERSION + UPSTREAM_VERSION: v1.2.5 KEYPER_CONFIG_DIR: /keyper/config SHUTTER_CHAIN_DIR: /chain STAKER_SCRIPTS_VERSION: v0.1.0 @@ -31,7 +31,7 @@ services: build: context: metrics args: - ASSETS_VERSION: shutter-gnosis-1000-set-1v2 # $NETWORK-10*$CHAIN_ID-set-$VERSION + ASSETS_VERSION: shutter-gnosis-1000-set1.3 # $NETWORK-10*$CHAIN_ID-set-$VERSION restart: on-failure environment: SHUTTER_PUSH_METRICS_ENABLED: false diff --git a/metrics/Dockerfile b/metrics/Dockerfile index 89d1b3e..a504f05 100644 --- a/metrics/Dockerfile +++ b/metrics/Dockerfile @@ -9,7 +9,6 @@ FROM victoriametrics/vmagent:v1.101.0 ARG NETWORK ENV ASSETS_DIR=/assets \ - TEMPLATE_CONFIG_FILE=/config/${NETWORK}/vmagent_template.yml \ CONFIG_FILE=/config/${NETWORK}/vmagent.yml \ USER_SETTINGS_FILE=/config/user/settings.env diff --git a/metrics/config/gnosis/vmagent_template.yml b/metrics/config/gnosis/vmagent.yml similarity index 55% rename from metrics/config/gnosis/vmagent_template.yml rename to metrics/config/gnosis/vmagent.yml index 93c87bc..8881610 100644 --- a/metrics/config/gnosis/vmagent_template.yml +++ b/metrics/config/gnosis/vmagent.yml @@ -6,18 +6,24 @@ scrape_configs: static_configs: - targets: ["shutter.shutter-gnosis.dappnode:9100"] labels: - instance: "%{KEYPER_NAME}" + instance: "kpr-%{KEYPER_NAME}" deployment: "%{_ASSETS_VERSION}" + deployment_type: "dappnode" + network: "%{_ASSETS_NETWORK}" - job_name: 'shuttermint' metrics_path: / static_configs: - targets: ["shutter.shutter-gnosis.dappnode:26660"] labels: - instance: "%{KEYPER_NAME}" + instance: "kpr-%{KEYPER_NAME}" deployment: "%{_ASSETS_VERSION}" + deployment_type: "dappnode" + network: "%{_ASSETS_NETWORK}" - job_name: 'vmagent' static_configs: - targets: ["localhost:8429"] labels: - instance: "%{KEYPER_NAME}" - deployment: "%{_ASSETS_VERSION}" \ No newline at end of file + instance: "kpr-%{KEYPER_NAME}" + deployment: "%{_ASSETS_VERSION}" + deployment_type: "dappnode" + network: "%{_ASSETS_NETWORK}" diff --git a/metrics/entrypoint.sh b/metrics/entrypoint.sh index d9284e1..2eb9f9c 100755 --- a/metrics/entrypoint.sh +++ b/metrics/entrypoint.sh @@ -62,11 +62,6 @@ source_user_settings() { fi } -replace_envs_in_yaml() { - echo "[INFO | metrics] Replacing environment variables in the configuration file" - sed "s|%{KEYPER_NAME}|$KEYPER_NAME|g; s|%{_ASSETS_VERSION}|$_ASSETS_VERSION|g" "$TEMPLATE_CONFIG_FILE" >"$CONFIG_FILE" -} - update_user_settings if [ "${SHUTTER_PUSH_METRICS_ENABLED}" = "false" ]; then @@ -78,8 +73,6 @@ source_assets_envs source_user_settings -replace_envs_in_yaml - exec /vmagent-prod \ -promscrape.config="${CONFIG_FILE}" \ -remoteWrite.url="${PUSHGATEWAY_URL}" \ diff --git a/shutter/Dockerfile b/shutter/Dockerfile index 5d86603..7fc6bc4 100644 --- a/shutter/Dockerfile +++ b/shutter/Dockerfile @@ -6,7 +6,7 @@ FROM ghcr.io/shutter-network/assets:${ASSETS_VERSION} as assets RUN rsync -aq --delete /assets-source/ /assets/ ARG UPSTREAM_VERSION -FROM ghcr.io/shutter-network/rolling-shutter:${UPSTREAM_VERSION} +FROM ghcr.io/shutter-network/keyper:${UPSTREAM_VERSION} ARG NETWORK ARG KEYPER_CONFIG_DIR diff --git a/shutter/go-shutter-settings/go.mod b/shutter/go-shutter-settings/go.mod index 5c9764e..a821639 100644 --- a/shutter/go-shutter-settings/go.mod +++ b/shutter/go-shutter-settings/go.mod @@ -5,3 +5,8 @@ go 1.21.0 require github.com/joho/godotenv v1.5.1 require github.com/pelletier/go-toml/v2 v2.2.3 + +require ( + github.com/google/go-cmp v0.5.9 // indirect + gotest.tools/v3 v3.5.1 // indirect +) diff --git a/shutter/go-shutter-settings/go.sum b/shutter/go-shutter-settings/go.sum index 8e1e558..c7db3dd 100644 --- a/shutter/go-shutter-settings/go.sum +++ b/shutter/go-shutter-settings/go.sum @@ -1,5 +1,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= @@ -10,3 +12,5 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= diff --git a/shutter/go-shutter-settings/settings/.gitignore b/shutter/go-shutter-settings/settings/.gitignore new file mode 100644 index 0000000..78cc7dc --- /dev/null +++ b/shutter/go-shutter-settings/settings/.gitignore @@ -0,0 +1 @@ +./test-assets/out.toml diff --git a/shutter/go-shutter-settings/settings/keyper.go b/shutter/go-shutter-settings/settings/keyper.go index a0310be..007c4ae 100644 --- a/shutter/go-shutter-settings/settings/keyper.go +++ b/shutter/go-shutter-settings/settings/keyper.go @@ -10,6 +10,8 @@ type KeyperConfig struct { InstanceID int `env:"_ASSETS_INSTANCE_ID"` DatabaseURL string `env:"SHUTTER_DATABASE_URL"` BeaconAPIURL string `env:"SHUTTER_BEACONAPIURL"` + HTTPEnabled bool `env:"SHUTTER_HTTP_ENABLED"` + HTTPListenAddress string `env:"SHUTTER_HTTP_LISTEN_ADDRESS"` MaxNumKeysPerMessage int `env:"_ASSETS_MAX_NUM_KEYS_PER_MESSAGE"` Gnosis struct { EncryptedGasLimit int `env:"_ASSETS_ENCRYPTED_GAS_LIMIT"` @@ -31,10 +33,15 @@ type KeyperConfig struct { } P2P struct { P2PKey string `env:"SHUTTER_P2P_KEY"` - ListenAddresses string `env:"SHUTTER_P2P_LISTENADDRESSES"` - AdvertiseAddresses string `env:"SHUTTER_P2P_ADVERTISEADDRESSES"` + ListenAddresses []string `env:"SHUTTER_P2P_LISTENADDRESSES"` + AdvertiseAddresses []string `env:"SHUTTER_P2P_ADVERTISEADDRESSES"` CustomBootstrapAddresses []string `env:"_ASSETS_CUSTOM_BOOTSTRAP_ADDRESSES"` DiscoveryNamespace string `env:"_ASSETS_DISCOVERY_NAME_PREFIX"` + FloodSubDiscovery struct { + Enabled bool `env:"SHUTTER_P2P_FLOODSUBDISCOVERY_ENABLED"` + Interval int `env:"SHUTTER_P2P_FLOODSUBDISCOVERY_INTERVAL"` + Topics []string `env:"SHUTTER_P2P_FLOODSUBDISCOVERY_TOPICS"` + } } Shuttermint struct { ShuttermintURL string `env:"SHUTTER_SHUTTERMINT_SHUTTERMINTURL"` @@ -44,7 +51,7 @@ type KeyperConfig struct { DKGStartBlockDelta int `env:"_ASSETS_DKG_START_BLOCK_DELTA"` } Metrics struct { - Enabled bool `env:"SHUTTER_ENABLED"` + Enabled bool `env:"SHUTTER_METRICS_ENABLED"` } } @@ -82,4 +89,4 @@ func AddSettingsToKeyper(generatedFilePath, configFilePath, outputFilePath strin fmt.Println("Keyper TOML file modified successfully and saved to", outputFilePath) return nil -} \ No newline at end of file +} diff --git a/shutter/go-shutter-settings/settings/keyper_test.go b/shutter/go-shutter-settings/settings/keyper_test.go new file mode 100644 index 0000000..80bb85f --- /dev/null +++ b/shutter/go-shutter-settings/settings/keyper_test.go @@ -0,0 +1,23 @@ +package settings + +import ( + "testing" + + "github.com/joho/godotenv" + "gotest.tools/v3/assert" +) + +func TestUnmarshal(t *testing.T) { + err := godotenv.Load("./test-assets/variables.env") + assert.NilError(t, err, "assets variables error") + var generatedConfig map[string]interface{} + err = UnmarshallFromFile("./test-assets/keyper.toml", &generatedConfig) + assert.NilError(t, err, "error unmarshalling") +} + +func TestAddSettings(t *testing.T) { + err := godotenv.Load("./test-assets/variables.env") + assert.NilError(t, err, "assets variables error") + err = AddSettingsToKeyper("./test-assets/generated.toml", "./test-assets/keyper.toml", "./test-assets/out.toml") + assert.NilError(t, err, "error") +} diff --git a/shutter/go-shutter-settings/settings/test-assets/generated.toml b/shutter/go-shutter-settings/settings/test-assets/generated.toml new file mode 100644 index 0000000..9797d6e --- /dev/null +++ b/shutter/go-shutter-settings/settings/test-assets/generated.toml @@ -0,0 +1,63 @@ +# Ethereum address: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +# Peer identity: /p2p/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + +InstanceID = 42 +# If it's empty, we use the standard PG_ environment variables +DatabaseURL = 'postgres://pguser:pgpassword@localhost:5432/shutter' +BeaconAPIURL = 'http://localhost:5052' +HTTPEnabled = false +HTTPListenAddress = ':3000' +MaxNumKeysPerMessage = 500 + +[Gnosis] +EncryptedGasLimit = 1000000 +MinGasPerTransaction = 21000 +MaxTxPointerAge = 5 +SecondsPerSlot = 5 +SlotsPerEpoch = 16 +GenesisSlotTimestamp = 1665410700 +SyncStartBlockNumber = 0 + +[Gnosis.Node] +PrivateKey = '0000000000000000000000000000000000000000000000000000000000000000' +# Contract source directory +DeploymentDir = './deployments/localhost/' +# The layer 1 JSON RPC endpoint +EthereumURL = 'http://127.0.0.1:8545/' + +[Gnosis.Contracts] +KeyperSetManager = '0x0000000000000000000000000000000000000000' +KeyBroadcastContract = '0x0000000000000000000000000000000000000000' +Sequencer = '0x0000000000000000000000000000000000000000' +ValidatorRegistry = '0x0000000000000000000000000000000000000000' + +[P2P] +P2PKey = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +ListenAddresses = ['/ip4/0.0.0.0/tcp/0', '/ip4/0.0.0.0/udp/0/quic-v1', '/ip4/0.0.0.0/udp/0/quic-v1/webtransport', '/ip6/::/tcp/0', '/ip6/::/udp/0/quic-v1', '/ip6/::/udp/0/quic-v1/webtransport'] +# Optional, addresses to be advertised to other peers instead of auto-detected ones. +AdvertiseAddresses = [] +# Overwrite p2p boostrap nodes +CustomBootstrapAddresses = ['/ip4/127.0.0.1/tcp/2001/p2p/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', '/ip4/127.0.0.1/tcp/2002/p2p/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'] +Environment = 'production' +# Must be unique for each instance id. +DiscoveryNamespace = 'shutter-42' +# Optional, to be set to true if running an access node +IsAccessNode = false + +[P2P.FloodSubDiscovery] +Enabled = false +Interval = 10 +Topics = [] + +[Shuttermint] +ShuttermintURL = 'http://localhost:26657' +ValidatorPublicKey = '8888888888888888888888888888888888888888888888888888888888888888' +EncryptionKey = '0000000000000000000000000000000000000000000000000000000000000000' +DKGPhaseLength = 30 +DKGStartBlockDelta = 200 + +[Metrics] +Enabled = false +Host = '[::]' +Port = 9100 \ No newline at end of file diff --git a/shutter/go-shutter-settings/settings/test-assets/keyper.toml b/shutter/go-shutter-settings/settings/test-assets/keyper.toml new file mode 100644 index 0000000..9797d6e --- /dev/null +++ b/shutter/go-shutter-settings/settings/test-assets/keyper.toml @@ -0,0 +1,63 @@ +# Ethereum address: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +# Peer identity: /p2p/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + +InstanceID = 42 +# If it's empty, we use the standard PG_ environment variables +DatabaseURL = 'postgres://pguser:pgpassword@localhost:5432/shutter' +BeaconAPIURL = 'http://localhost:5052' +HTTPEnabled = false +HTTPListenAddress = ':3000' +MaxNumKeysPerMessage = 500 + +[Gnosis] +EncryptedGasLimit = 1000000 +MinGasPerTransaction = 21000 +MaxTxPointerAge = 5 +SecondsPerSlot = 5 +SlotsPerEpoch = 16 +GenesisSlotTimestamp = 1665410700 +SyncStartBlockNumber = 0 + +[Gnosis.Node] +PrivateKey = '0000000000000000000000000000000000000000000000000000000000000000' +# Contract source directory +DeploymentDir = './deployments/localhost/' +# The layer 1 JSON RPC endpoint +EthereumURL = 'http://127.0.0.1:8545/' + +[Gnosis.Contracts] +KeyperSetManager = '0x0000000000000000000000000000000000000000' +KeyBroadcastContract = '0x0000000000000000000000000000000000000000' +Sequencer = '0x0000000000000000000000000000000000000000' +ValidatorRegistry = '0x0000000000000000000000000000000000000000' + +[P2P] +P2PKey = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +ListenAddresses = ['/ip4/0.0.0.0/tcp/0', '/ip4/0.0.0.0/udp/0/quic-v1', '/ip4/0.0.0.0/udp/0/quic-v1/webtransport', '/ip6/::/tcp/0', '/ip6/::/udp/0/quic-v1', '/ip6/::/udp/0/quic-v1/webtransport'] +# Optional, addresses to be advertised to other peers instead of auto-detected ones. +AdvertiseAddresses = [] +# Overwrite p2p boostrap nodes +CustomBootstrapAddresses = ['/ip4/127.0.0.1/tcp/2001/p2p/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', '/ip4/127.0.0.1/tcp/2002/p2p/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'] +Environment = 'production' +# Must be unique for each instance id. +DiscoveryNamespace = 'shutter-42' +# Optional, to be set to true if running an access node +IsAccessNode = false + +[P2P.FloodSubDiscovery] +Enabled = false +Interval = 10 +Topics = [] + +[Shuttermint] +ShuttermintURL = 'http://localhost:26657' +ValidatorPublicKey = '8888888888888888888888888888888888888888888888888888888888888888' +EncryptionKey = '0000000000000000000000000000000000000000000000000000000000000000' +DKGPhaseLength = 30 +DKGStartBlockDelta = 200 + +[Metrics] +Enabled = false +Host = '[::]' +Port = 9100 \ No newline at end of file diff --git a/shutter/go-shutter-settings/settings/test-assets/variables.env b/shutter/go-shutter-settings/settings/test-assets/variables.env new file mode 100644 index 0000000..abbc3fc --- /dev/null +++ b/shutter/go-shutter-settings/settings/test-assets/variables.env @@ -0,0 +1,22 @@ +# Enter variables that should be included in the assets container here, one per line, (ba)sh syntax. +# convention is to start the names with `_ASSETS_` to prevent accidental naming conflicts + +_ASSETS_DISCOVERY_NAME_PREFIX=shutter-gnosis + +_ASSETS_INSTANCE_ID=1000 +_ASSETS_MAX_NUM_KEYS_PER_MESSAGE=500 +_ASSETS_ENCRYPTED_GAS_LIMIT=1000000 +_ASSETS_GENESIS_SLOT_TIMESTAMP=1638993340 +_ASSETS_SYNC_START_BLOCK_NUMBER=34627113 +_ASSETS_KEYPER_SET_MANAGER=0x0000000000000000000000000000000000000000 +_ASSETS_KEY_BROADCAST_CONTRACT=0x0000000000000000000000000000000000000000 +_ASSETS_SEQUENCER=0x0000000000000000000000000000000000000000 +_ASSETS_VALIDATOR_REGISTRY=0x0000000000000000000000000000000000000000 +_ASSETS_CUSTOM_BOOTSTRAP_ADDRESSES='["/ip4/111.11.111.111/tcp/23003/p2p/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "/ip4/222.22.22.222/tcp/23003/p2p/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"]' +_ASSETS_DKG_PHASE_LENGTH=30 +_ASSETS_DKG_START_BLOCK_DELTA=1440 + +_ASSETS_SHUTTERMINT_SEED_NODES="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@111.11.111.111:26656,bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb@222.22.22.222:26656" + +_ASSETS_NETWORK=mainnet +_ASSETS_VERSION=shutter-gnosis-1000-set1.3 diff --git a/shutter/scripts/configure.sh b/shutter/scripts/configure.sh index d62aa04..1f0f305 100755 --- a/shutter/scripts/configure.sh +++ b/shutter/scripts/configure.sh @@ -31,7 +31,7 @@ init_keyper_db() { echo "[INFO | configure] Initializing keyper database..." - $SHUTTER_BIN gnosiskeyper initdb --config "$KEYPER_GENERATED_CONFIG_FILE" + $SHUTTER_BIN gnosiskeyper initdb --config "$KEYPER_CONFIG_FILE" } init_chain() { @@ -73,12 +73,12 @@ check_assets generate_keyper_config +configure_keyper + init_keyper_db init_chain -configure_keyper - configure_chain trigger_chain_start diff --git a/shutter/scripts/configure_keyper.sh b/shutter/scripts/configure_keyper.sh index fecaf01..8b0bced 100755 --- a/shutter/scripts/configure_keyper.sh +++ b/shutter/scripts/configure_keyper.sh @@ -10,11 +10,12 @@ echo "[INFO | configure] Calculating keyper configuration values..." SUPPORTED_NETWORKS="gnosis" -export SHUTTER_P2P_ADVERTISEADDRESSES="/ip4/${_DAPPNODE_GLOBAL_PUBLIC_IP}/tcp/${KEYPER_PORT}" -export SHUTTER_BEACONAPIURL=$(get_beacon_api_url_from_global_env "$NETWORK" "$SUPPORTED_NETWORKS") -export SHUTTER_GNOSIS_NODE_CONTRACTSURL=http://execution.gnosis.dncore.dappnode:8545 -export SHUTTER_GNOSIS_NODE_ETHEREUMURL=$(get_execution_ws_url_from_global_env "$NETWORK" "$SUPPORTED_NETWORKS") +export SHUTTER_P2P_ADVERTISEADDRESSES=["/ip4/${_DAPPNODE_GLOBAL_PUBLIC_IP}/tcp/${KEYPER_PORT}"] +export SHUTTER_BEACONAPIURL=http://${_DAPPNODE_GLOBAL_CONSENSUS_CLIENT_GNOSIS} +export SHUTTER_GNOSIS_NODE_CONTRACTSURL=ws://${_DAPPNODE_GLOBAL_EXECUTION_CLIENT_GNOSIS} +export SHUTTER_GNOSIS_NODE_ETHEREUMURL=ws://${_DAPPNODE_GLOBAL_EXECUTION_CLIENT_GNOSIS} export VALIDATOR_PUBLIC_KEY=$(cat "${SHUTTER_CHAIN_DIR}/config/priv_validator_pubkey.hex") +export SHUTTER_METRICS_ENABLED=${SHUTTER_PUSH_METRICS_ENABLED} echo "[INFO | configure] LISTEN: $SHUTTER_P2P_LISTENADDRESSES"