diff --git a/chain-signatures/Cargo.lock b/chain-signatures/Cargo.lock index 536419193..d0e492ac0 100644 --- a/chain-signatures/Cargo.lock +++ b/chain-signatures/Cargo.lock @@ -3756,7 +3756,6 @@ dependencies = [ "k256", "near-crypto 0.23.0", "near-gas", - "near-rng", "near-sdk", "near-workspaces", "rand 0.8.5", @@ -4542,12 +4541,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "near-rng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efd376ff92ef9c5ef550f808406056854815f10e046703ae97f61946ef53a12" - [[package]] name = "near-rpc-error-core" version = "0.20.1" diff --git a/chain-signatures/contract/Cargo.toml b/chain-signatures/contract/Cargo.toml index 690a0f1f8..12b80f8d6 100644 --- a/chain-signatures/contract/Cargo.toml +++ b/chain-signatures/contract/Cargo.toml @@ -15,7 +15,6 @@ schemars = "0.8" k256 = { version = "0.13.1", features = ["sha256", "ecdsa", "serde", "arithmetic", "expose-field"] } crypto-shared = { path = "../crypto-shared" } near-gas = { version = "0.2.5", features = ["serde", "borsh", "schemars"] } -near-rng = "0.1.1" thiserror = "1" [dev-dependencies] diff --git a/infra/.gitignore b/infra/.gitignore index 8cc2566e7..23a535390 100644 --- a/infra/.gitignore +++ b/infra/.gitignore @@ -20,6 +20,7 @@ crash.*.log !terraform-testnet-example.tfvars !backend.tfvars !terraform-mainnet-example.tfvars +secrets.txt # Ignore override files as they are usually used to override resources locally and so # are not checked in diff --git a/infra/multichain-mainnet/main.tf b/infra/multichain-mainnet/main.tf new file mode 100644 index 000000000..a3701d59e --- /dev/null +++ b/infra/multichain-mainnet/main.tf @@ -0,0 +1,233 @@ +provider "google" { + project = var.project_id +} +provider "google-beta" { + project = var.project_id +} +module "gce-container" { + count = length(var.node_configs) + source = "terraform-google-modules/container-vm/google" + version = "~> 3.0" + + container = { + image = var.image + args = ["start"] + port = "3000" + + env = concat(var.static_env, [ + { + name = "MPC_RECOVERY_NODE_ID" + value = "${count.index}" + }, + { + name = "MPC_RECOVERY_ACCOUNT_ID" + value = var.node_configs["${count.index}"].account + }, + { + name = "MPC_RECOVERY_CIPHER_PK" + value = var.node_configs["${count.index}"].cipher_pk + }, + { + name = "MPC_RECOVERY_ACCOUNT_SK" + value = data.google_secret_manager_secret_version.account_sk_secret_id[count.index].secret_data + }, + { + name = "MPC_RECOVERY_CIPHER_SK" + value = data.google_secret_manager_secret_version.cipher_sk_secret_id[count.index].secret_data + }, + { + name = "MPC_RECOVERY_SIGN_SK" + value = data.google_secret_manager_secret_version.sign_sk_secret_id[count.index] != null ? data.google_secret_manager_secret_version.sign_sk_secret_id[count.index].secret_data : data.google_secret_manager_secret_version.account_sk_secret_id[count.index].secret_data + }, + { + name = "AWS_ACCESS_KEY_ID" + value = data.google_secret_manager_secret_version.aws_access_key_secret_id.secret_data + }, + { + name = "AWS_SECRET_ACCESS_KEY" + value = data.google_secret_manager_secret_version.aws_secret_key_secret_id.secret_data + }, + { + name = "MPC_RECOVERY_LOCAL_ADDRESS" + value = "https://${var.node_configs[count.index].domain}" + }, + { + name = "MPC_RECOVERY_SK_SHARE_SECRET_ID" + value = var.node_configs["${count.index}"].sk_share_secret_id + }, + { + name = "MPC_RECOVERY_ENV", + value = var.env + } + ]) + } +} + +resource "google_service_account" "service_account" { + account_id = "multichain-partner-${var.env}" + display_name = "Multichain ${var.env} Account" +} + +resource "google_project_iam_member" "sa-roles" { + for_each = toset([ + "roles/datastore.user", + "roles/secretmanager.admin", + "roles/storage.objectAdmin", + "roles/iam.serviceAccountAdmin", + ]) + + role = each.key + member = "serviceAccount:${google_service_account.service_account.email}" + project = var.project_id +} + +resource "google_compute_global_address" "external_ips" { + count = length(var.node_configs) + name = "multichain-partner-mainnet-${count.index}" + address_type = "EXTERNAL" + + lifecycle { + prevent_destroy = true + } +} + +resource "google_compute_managed_ssl_certificate" "mainnet_ssl" { + count = length(var.node_configs) + name = "multichain-partner-mainnet-ssl-${count.index}" + + managed { + domains = [var.node_configs[count.index].domain] + } +} + +module "ig_template" { + count = length(var.node_configs) + source = "../modules/mig_template" + network = var.network + subnetwork = var.subnetwork + region = var.region + service_account = { + email = google_service_account.service_account.email, + scopes = ["cloud-platform"] + } + name_prefix = "multichain-partner-mainnet-${count.index}" + source_image_family = "cos-113-lts" + source_image_project = "cos-cloud" + machine_type = "n2d-standard-2" + + startup_script = "docker rm watchtower ; docker run -d --name watchtower -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --debug --interval 30" + + source_image = reverse(split("/", module.gce-container[count.index].source_image))[0] + metadata = merge(var.additional_metadata, { "gce-container-declaration" = module.gce-container["${count.index}"].metadata_value }) + tags = [ + "multichain", + "allow-ssh" + ] + labels = { + "container-vm" = module.gce-container[count.index].vm_container_label + } + + depends_on = [google_compute_global_address.external_ips] +} + + +module "instances" { + count = length(var.node_configs) + source = "../modules/instance-from-tpl" + region = var.region + project_id = var.project_id + hostname = "multichain-mainnet-partner-${count.index}" + network = var.network + subnetwork = var.subnetwork + + instance_template = module.ig_template[count.index].self_link_unique + +} + +resource "google_compute_health_check" "multichain_healthcheck" { + name = "multichain-mainnet-partner-healthcheck" + + http_health_check { + port = 3000 + request_path = "/" + } + +} + +resource "google_compute_global_forwarding_rule" "http_fw" { + count = length(var.node_configs) + name = "multichain-partner-mainnet-http-rule-${count.index}" + target = google_compute_target_http_proxy.default[count.index].id + port_range = "80" + ip_protocol = "TCP" + load_balancing_scheme = "EXTERNAL" + ip_address = google_compute_global_address.external_ips[count.index].address +} + +resource "google_compute_global_forwarding_rule" "https_fw" { + count = length(var.node_configs) + name = "multichain-partner-mainnet-https-rule-${count.index}" + target = google_compute_target_https_proxy.default_https[count.index].id + port_range = "443" + ip_protocol = "TCP" + load_balancing_scheme = "EXTERNAL" + ip_address = google_compute_global_address.external_ips[count.index].address +} + +resource "google_compute_target_http_proxy" "default" { + count = length(var.node_configs) + name = "multichain-partner-mainnet-http-target-proxy-${count.index}" + description = "a description" + url_map = google_compute_url_map.redirect_default[count.index].id +} + +resource "google_compute_target_https_proxy" "default_https" { + count = length(var.node_configs) + name = "multichain-partner-mainnet-https-target-proxy-${count.index}" + description = "a description" + ssl_certificates = [ google_compute_managed_ssl_certificate.mainnet_ssl[count.index].self_link ] + url_map = google_compute_url_map.default[count.index].id +} + +resource "google_compute_url_map" "default" { + count = length(var.node_configs) + name = "multichain-partner-mainnet-url-map-${count.index}" + default_service = google_compute_backend_service.multichain_backend[count.index].id +} + +resource "google_compute_url_map" "redirect_default" { + count = length(var.node_configs) + name = "multichain-partner-mainnet-redirect-url-map-${count.index}" + default_url_redirect { + strip_query = false + https_redirect = true + } +} + +resource "google_compute_backend_service" "multichain_backend" { + count = length(var.node_configs) + name = "multichain-partner-mainnet-backend-service-${count.index}" + load_balancing_scheme = "EXTERNAL" + + log_config { + enable = true + sample_rate = 0.5 + } + backend { + group = google_compute_instance_group.multichain_group[count.index].id + } + + health_checks = [google_compute_health_check.multichain_healthcheck.id] +} + +resource "google_compute_instance_group" "multichain_group" { + count = length(var.node_configs) + name = "multichain-partner-mainnet-instance-group-${count.index}" + instances = [module.instances[count.index].self_links[0]] + + zone = var.zone + named_port { + name = "http" + port = 3000 + } +} diff --git a/infra/multichain-mainnet/outputs.tf b/infra/multichain-mainnet/outputs.tf new file mode 100644 index 000000000..53ce33e08 --- /dev/null +++ b/infra/multichain-mainnet/outputs.tf @@ -0,0 +1,3 @@ +output "node_public_ip" { + value = google_compute_global_address.external_ips[*].address +} \ No newline at end of file diff --git a/infra/multichain-mainnet/resources.tf b/infra/multichain-mainnet/resources.tf new file mode 100644 index 000000000..6a2197d88 --- /dev/null +++ b/infra/multichain-mainnet/resources.tf @@ -0,0 +1,47 @@ +terraform { + backend "gcs" { + bucket = "terraform-prod-multichain" + prefix = "state/multichain-partner-vm-mainnet" + } + + required_providers { + google = { + source = "hashicorp/google" + version = "4.73.0" + } + } +} + +# These data blocks grab the values from your GCP secret manager, please adjust secret names as desired +data "google_secret_manager_secret_version" "account_sk_secret_id" { + count = length(var.node_configs) + secret = var.node_configs[0].account_sk_secret_id + project = var.project_id +} + +data "google_secret_manager_secret_version" "cipher_sk_secret_id" { + count = length(var.node_configs) + secret = var.node_configs[0].cipher_sk_secret_id + project = var.project_id +} + +data "google_secret_manager_secret_version" "sign_sk_secret_id" { + count = length(var.node_configs) + secret = var.node_configs[0].sign_sk_secret_id + project = var.project_id +} + +data "google_secret_manager_secret_version" "sk_share_secret_id" { + count = length(var.node_configs) + secret = var.node_configs[0].sk_share_secret_id + project = var.project_id +} + +# This is the AWS access key and secret key for our public S3 bucket with Lake data +data "google_secret_manager_secret_version" "aws_access_key_secret_id" { + secret = "multichain-indexer-aws-access-key" +} + +data "google_secret_manager_secret_version" "aws_secret_key_secret_id" { + secret = "multichain-indexer-aws-secret-key" +} diff --git a/infra/multichain-mainnet/variables.tf b/infra/multichain-mainnet/variables.tf new file mode 100644 index 000000000..580f5c20e --- /dev/null +++ b/infra/multichain-mainnet/variables.tf @@ -0,0 +1,132 @@ +variable "project_id" { + description = "The project ID to deploy resource into" + type = string +} + +variable "subnetwork" { + description = "The name of the subnetwork to deploy instances into" + type = string +} + +variable "mig_name" { + description = "The desired name to assign to the deployed managed instance group" + type = string + default = "mpc-mig" +} + +variable "image" { + description = "The Docker image to deploy to GCE instances. Note: This is a public image repository used for updating your nodes, please do not change this" + type = string + default = "us-east1-docker.pkg.dev/pagoda-discovery-platform-prod/multichain-public/multichain-mainnet:latest" +} + +variable "image_port" { + description = "The port the image exposes for HTTP requests" + type = number + default = 3000 +} + +variable "region" { + description = "The GCP region to deploy instances into" + type = string +} + +variable "zone" { + type = string +} + +variable "network" { + description = "The GCP network" + type = string +} + +variable "additional_metadata" { + type = map(any) + description = "Additional metadata to attach to the instance" + default = { + cos-update-strategy: "update_enabled" + } +} + +variable "service_account" { + type = object({ + email = string, + scopes = list(string) + }) + default = { + email = "" + scopes = ["cloud-platform"] + } +} + +variable "env_variables" { + type = map(any) + default = null +} + +variable "node_configs" { + type = list(object({ + account = string + cipher_pk = string + account_sk_secret_id = string + cipher_sk_secret_id = string + sign_sk_secret_id = string + sk_share_secret_id = string + domain = string + })) +} + +variable "env" { + type = string + default = "mainnet" +} + +variable "static_env" { + type = list(object({ + name = string + value = string + })) + default = [ + { + name = "MPC_RECOVERY_NEAR_RPC" + value = "https://rpc.mainnet.near.org" + }, + { + name = "MPC_RECOVERY_CONTRACT_ID" + value = "v1.signer.near" + }, + { + name = "MPC_RECOVERY_INDEXER_S3_BUCKET" + value = "near-lake-data-mainnet" + }, + { + name = "MPC_RECOVERY_INDEXER_START_BLOCK_HEIGHT" + value = 124092099 + }, + { + name = "AWS_DEFAULT_REGION" + value = "eu-central-1" + }, + { + name = "MPC_RECOVERY_GCP_PROJECT_ID" + value = "pagoda-discovery-platform-prod" + }, + { + name = "MPC_RECOVERY_WEB_PORT" + value = "3000" + }, + { + name = "RUST_LOG" + value = "mpc_recovery_node=debug" + }, + { + name = "MPC_RECOVERY_INDEXER_S3_REGION" + value = "eu-central-1" + } + ] +} + +variable "domain" { + description = "DNS name for your node" + default = null +} \ No newline at end of file diff --git a/infra/multichain-testnet/main.tf b/infra/multichain-testnet/main.tf index 56d00956c..6a474c004 100644 --- a/infra/multichain-testnet/main.tf +++ b/infra/multichain-testnet/main.tf @@ -72,7 +72,7 @@ resource "google_service_account" "service_account" { display_name = "Multichain ${var.env} Account" } -resource "google_project_iam_binding" "sa-roles" { +resource "google_project_iam_member" "sa-roles" { for_each = toset([ "roles/datastore.user", "roles/secretmanager.admin", @@ -80,10 +80,8 @@ resource "google_project_iam_binding" "sa-roles" { "roles/iam.serviceAccountAdmin", ]) - role = each.key - members = [ - "serviceAccount:${google_service_account.service_account.email}" - ] + role = each.key + member = "serviceAccount:${google_service_account.service_account.email}" project = var.project_id } diff --git a/infra/partner-mainnet/main.tf b/infra/partner-mainnet/main.tf index 40c4a232d..77faafe33 100644 --- a/infra/partner-mainnet/main.tf +++ b/infra/partner-mainnet/main.tf @@ -68,7 +68,7 @@ resource "google_service_account" "service_account" { display_name = "Multichain ${var.env} Account" } -resource "google_project_iam_binding" "sa-roles" { +resource "google_project_iam_member" "sa-roles" { for_each = toset([ "roles/datastore.user", "roles/secretmanager.admin", @@ -76,10 +76,8 @@ resource "google_project_iam_binding" "sa-roles" { "roles/iam.serviceAccountAdmin", ]) - role = each.key - members = [ - "serviceAccount:${google_service_account.service_account.email}" - ] + role = each.key + member = "serviceAccount:${google_service_account.service_account.email}" project = var.project_id } @@ -194,7 +192,7 @@ resource "google_compute_target_https_proxy" "default_https" { resource "google_compute_url_map" "default" { count = length(var.node_configs) name = "multichain-partner-mainnet-url-map-${count.index}" - default_service = google_compute_backend_service.multichain_backend.id + default_service = google_compute_backend_service.multichain_backend[count.index].id } resource "google_compute_url_map" "redirect_default" { @@ -207,11 +205,17 @@ resource "google_compute_url_map" "redirect_default" { } resource "google_compute_backend_service" "multichain_backend" { - name = "multichain-partner-mainnet-backend-service" + count = length(var.node_configs) + name = "multichain-partner-mainnet-backend-service-${count.index}" load_balancing_scheme = "EXTERNAL" + + log_config { + enable = true + sample_rate = 0.5 + } backend { - group = google_compute_instance_group.multichain_group.id + group = google_compute_instance_group.multichain_group[count.index].id } health_checks = [google_compute_health_check.multichain_healthcheck.id] diff --git a/infra/partner-mainnet/scripts/upload_secrets.sh b/infra/partner-mainnet/scripts/upload_secrets.sh index 36c769584..ad66fd17b 100755 --- a/infra/partner-mainnet/scripts/upload_secrets.sh +++ b/infra/partner-mainnet/scripts/upload_secrets.sh @@ -35,7 +35,7 @@ while read -r line || [ -n "$line" ]; do SECRET_VALUE=$(echo "$line" | cut -d '=' -f 2-) echo "Creating secret: $SECRET_NAME in project: $DEST_PROJECT" - echo "$SECRET_VALUE" | gcloud secrets create "$SECRET_NAME" --data-file=- --project="$DEST_PROJECT" --replication-policy="automatic" + printf "%s" "$SECRET_VALUE" | gcloud secrets create "$SECRET_NAME" --data-file=- --project="$DEST_PROJECT" --replication-policy="automatic" if [ $? -ne 0 ]; then echo "Failed to create secret: $SECRET_NAME in project: $DEST_PROJECT" diff --git a/integration-tests/chain-signatures/Cargo.lock b/integration-tests/chain-signatures/Cargo.lock index 07f73a2e5..7f5b20e6f 100644 --- a/integration-tests/chain-signatures/Cargo.lock +++ b/integration-tests/chain-signatures/Cargo.lock @@ -4244,7 +4244,6 @@ dependencies = [ "crypto-shared", "k256", "near-gas", - "near-rng", "near-sdk", "schemars", "serde", @@ -5043,12 +5042,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "near-rng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efd376ff92ef9c5ef550f808406056854815f10e046703ae97f61946ef53a12" - [[package]] name = "near-rpc-error-core" version = "0.20.1" diff --git a/load-tests/Cargo.lock b/load-tests/Cargo.lock index ea7cfcf5e..b771531d8 100644 --- a/load-tests/Cargo.lock +++ b/load-tests/Cargo.lock @@ -5364,6 +5364,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-format" version = "0.4.4" @@ -7977,13 +7983,14 @@ dependencies = [ [[package]] name = "time" -version = "0.3.31" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", "libc", + "num-conv", "num_threads", "powerfmt", "serde", @@ -7999,10 +8006,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ]