diff --git a/package-lock.json b/package-lock.json index 9dfb7f4adf..462b96d01a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25607,7 +25607,7 @@ "dependencies": { "@fhevm/solidity": "*", "@openzeppelin/contracts": "^5.3.0", - "@zama-fhe/relayer-sdk": "^0.3.0-6", + "@zama-fhe/relayer-sdk": "0.4.0-4", "bigint-buffer": "^1.1.5", "dotenv": "^16.0.3", "encrypted-types": "^0.0.4" @@ -27423,9 +27423,9 @@ } }, "test-suite/e2e/node_modules/@zama-fhe/relayer-sdk": { - "version": "0.3.0-6", - "resolved": "https://registry.npmjs.org/@zama-fhe/relayer-sdk/-/relayer-sdk-0.3.0-6.tgz", - "integrity": "sha512-lrnor1yIsC2ePHWo5XCxSsFkBr8JuaI7FvRk1azpglxkBVNECvuMD23ky04A8F6k53NDBvlh71MvHI+qvAOaQQ==", + "version": "0.4.0-4", + "resolved": "https://registry.npmjs.org/@zama-fhe/relayer-sdk/-/relayer-sdk-0.4.0-4.tgz", + "integrity": "sha512-F4B4QQesRcYeUzpLSyZ+P5x9y2ALwkVL/xTSt3nsFknp33YpyDkV9BhGNz4qt8C5XQh15OvwbYyVPXuv7cggDA==", "license": "BSD-3-Clause-Clear", "dependencies": { "commander": "^14.0.0", diff --git a/test-suite/e2e/.env.example b/test-suite/e2e/.env.example index 2ad53a6b91..d25c278c80 100644 --- a/test-suite/e2e/.env.example +++ b/test-suite/e2e/.env.example @@ -1,6 +1,7 @@ MNEMONIC="adapt mosquito move limb mobile illegal tree voyage juice mosquito burger raise father hope layer" # Gateway CHAIN_ID_GATEWAY="54321" +CHAIN_ID_HOST="12345" INPUT_VERIFICATION_ADDRESS="0x35760912360E875DA50D40a74305575c23D55783" DECRYPTION_ADDRESS="0xc9bAE822fE6793e3B456144AdB776D5A318CB71e" # Host diff --git a/test-suite/e2e/package.json b/test-suite/e2e/package.json index 8d563c57eb..eed8d8448d 100644 --- a/test-suite/e2e/package.json +++ b/test-suite/e2e/package.json @@ -16,9 +16,9 @@ "dependencies": { "@fhevm/solidity": "*", "@openzeppelin/contracts": "^5.3.0", - "@zama-fhe/relayer-sdk": "^0.3.0-6", + "@zama-fhe/relayer-sdk": "0.4.0-4", "bigint-buffer": "^1.1.5", "dotenv": "^16.0.3", "encrypted-types": "^0.0.4" } -} +} \ No newline at end of file diff --git a/test-suite/e2e/test/instance.ts b/test-suite/e2e/test/instance.ts index da1cc08b79..e560131dd9 100644 --- a/test-suite/e2e/test/instance.ts +++ b/test-suite/e2e/test/instance.ts @@ -8,6 +8,7 @@ const kmsAdd = process.env.KMS_VERIFIER_CONTRACT_ADDRESS; const aclAdd = process.env.ACL_CONTRACT_ADDRESS; const inputAdd = process.env.INPUT_VERIFIER_CONTRACT_ADDRESS; const gatewayChainID = +process.env.CHAIN_ID_GATEWAY!; +const hostChainID = +process.env.CHAIN_ID_HOST!; const verifyingContractAddressDecryption = process.env.DECRYPTION_ADDRESS!; const verifyingContractAddressInputVerification = process.env.INPUT_VERIFICATION_ADDRESS!; const relayerUrl = process.env.RELAYER_URL!; @@ -34,7 +35,8 @@ export const createInstance = async () => { aclContractAddress: aclAdd, network: network.config.url, relayerUrl: relayerUrl, - gatewayChainId: gatewayChainID, + gatewayChainId: Number(gatewayChainID), + chainId: Number(hostChainID), }); return instance; }; diff --git a/test-suite/e2e/test/pausedProtocol/pausedGateway.ts b/test-suite/e2e/test/pausedProtocol/pausedGateway.ts index 2ce6f0bca2..fa8d29462a 100644 --- a/test-suite/e2e/test/pausedProtocol/pausedGateway.ts +++ b/test-suite/e2e/test/pausedProtocol/pausedGateway.ts @@ -37,7 +37,7 @@ describe('Paused gateway', function () { ); inputAlice.add64(18446744073709550042n); - await expect(inputAlice.encrypt()).to.be.rejectedWith(new RegExp('Input request failed')); + await expect(inputAlice.encrypt()).to.be.rejectedWith(new RegExp('Could not estimate gas')); }); // The following test case should cover the Decryption.userDecryptionRequest method calling. @@ -53,7 +53,7 @@ describe('Paused gateway', function () { privateKey, publicKey, ), - ).to.be.rejectedWith(new RegExp('User decrypt failed')); + ).to.be.rejectedWith(new RegExp('Could not estimate gas')); }); // The following test case should cover the Decryption.publicDecryptionRequest method calling. @@ -62,7 +62,7 @@ describe('Paused gateway', function () { const handleAddress = await this.httpPublicDecryptContract.xAddress(); const handle32 = await this.httpPublicDecryptContract.xUint32(); await expect(this.instances.alice.publicDecrypt([handleAddress, handle32, handleBool])).to.be.rejectedWith( - new RegExp('Public decrypt failed'), + new RegExp('Could not estimate gas'), ); }); }); diff --git a/test-suite/e2e/test/userDecryption/userDecryption.ts b/test-suite/e2e/test/userDecryption/userDecryption.ts index 9c27a18f99..84d0bf4593 100644 --- a/test-suite/e2e/test/userDecryption/userDecryption.ts +++ b/test-suite/e2e/test/userDecryption/userDecryption.ts @@ -57,8 +57,8 @@ describe('User decryption', function () { contractAddress: this.signers.alice.address, // this should be impossible, as expected by this test }, ]; - const startTimeStamp = Math.floor(Date.now() / 1000).toString(); - const durationDays = '10'; // String for consistency + const startTimeStamp = Math.floor(Date.now() / 1000); + const durationDays = 10; const contractAddresses = [this.signers.alice.address]; // this should be impossible, as expected by this test // Use the new createEIP712 function @@ -199,8 +199,8 @@ describe('User decryption', function () { }, ]; const { publicKey, privateKey } = this.instances.alice.generateKeypair(); - const startTimeStamp = (BigInt(Math.floor(Date.now() / 1000)) - 20n * 86400n).toString(); - const durationDays = '10'; // String for consistency + const startTimeStamp = Number(BigInt(Math.floor(Date.now() / 1000)) - 20n * 86400n); + const durationDays = 10; const contractAddresses = [this.contractAddress]; // Use the new createEIP712 function diff --git a/test-suite/e2e/test/utils.ts b/test-suite/e2e/test/utils.ts index 750fd8c2b6..b9d33071eb 100644 --- a/test-suite/e2e/test/utils.ts +++ b/test-suite/e2e/test/utils.ts @@ -112,8 +112,8 @@ export const userDecryptSingleHandle = async ( contractAddress: contractAddress, }, ]; - const startTimeStamp = Math.floor(Date.now() / 1000).toString(); - const durationDays = '10'; // String for consistency + const startTimeStamp = Math.floor(Date.now() / 1000); + const durationDays = 10; // Relayer-sdk expects numbers from now on const contractAddresses = [contractAddress]; // Use the new createEIP712 function diff --git a/test-suite/fhevm/config/relayer/local.yaml b/test-suite/fhevm/config/relayer/local.yaml index 9535275dfb..b5f6eca112 100644 --- a/test-suite/fhevm/config/relayer/local.yaml +++ b/test-suite/fhevm/config/relayer/local.yaml @@ -1,23 +1,72 @@ -environment: development gateway: + blockchain_rpc: + ws_url: "ws://localhost:8757" + http_url: "http://localhost:8757" + chain_id: 654321 + ws_health_check_timeout_secs: 5 + http_health_check_timeout_secs: 5 listener: + # Optional: set the starting block number for event subscriptions + # last_block_number: null ws_reconnect_config: max_attempts: 20 retry_interval_ms: 500 + # Number of parallel listener instances (1-3) + listener_instances: 3 + # TTL for event deduplication cache in seconds (1-10) + dedup_ttl_seconds: 5 + dedup_max_capacity: 100000 tx_engine: private_key: GATEWAY_PRIVATE_KEY max_concurrency: 100 retry: max_attempts: 100 retry_interval_ms: 500 + tx_throttlers: + input_proof: + per_seconds: 20 + capacity: 11000 + safety_margin: 1000 + user_decrypt: + per_seconds: 20 + capacity: 11000 + safety_margin: 1000 + public_decrypt: + per_seconds: 20 + capacity: 11000 + safety_margin: 1000 readiness_checker: - max_concurrency: 100 retry: max_attempts: 30 - # The time is treated as seconds in code, even the config name has _ms suffix. - # This will be fixed in next rc, until then treat the value as seconds. - retry_interval_ms: 2 + retry_interval_ms: 2000 + public_decrypt: + max_concurrency: 250 + capacity: 11000 + safety_margin: 1000 + user_decrypt: + max_concurrency: 250 + capacity: 11000 + safety_margin: 1000 + contracts: + decryption_address: "0xB8Ae44365c45A7C5256b14F607CaE23BC040c354" + input_verification_address: "0xE61cff9C581c7c91AEF682c2C10e8632864339ab" + user_decrypt_shares_threshold: 9 +log: + + format: "compact" # compact, pretty, or json + show_file_line: true + show_thread_ids: true + show_timestamp: true + show_target: true + +keyurl: + fhe_public_key: + data_id: "fhe-public-key-data-id" + url: "http://0.0.0.0:3001/publicKey.bin" + crs: + data_id: "crs-data-id" + url: "http://0.0.0.0:3001/crs2048.bin" http: endpoint: "0.0.0.0:3000" @@ -27,20 +76,43 @@ http: retry_after_seconds: 5 jitter_max_ms: 2000 metrics: - histogram_buckets: [0, 0.5, 1, 1.25, 1.5, 1.75, 2, 2.5, 3, 3.5, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 25, 30] - -log: - format: "compact" - show_file_line: true - show_thread_ids: false - show_timestamp: true - show_target: true + histogram_buckets: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 40] + api_retry_after_seconds: 4 + metrics: endpoint: "0.0.0.0:9898" + query_duration_histogram_bucket: [0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0] + pool_wait_duration_seconds_histogram_bucket: [0.0001, 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0, 3.0] + request_status_duration_histogram_bucket: [0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0, 30.0, 60.0, 300.0, 600.0, 1800.0, 3600.0] + transaction_duration_secs_histogram_bucket: [0.01, 0.1, 0.25, 0.50, 0.75, 1.0, 1.25, 1.5, 2.0, 5.0, 10.0] storage: - db_path_rocksdb: "./.database" - -development: - verbose_errors: true \ No newline at end of file + sql_database_url: "postgresql://postgres:postgres@localhost:5433/relayer_db" + app_pool: + max_connections: 10 + min_connections: 2 + acquire_timeout_secs: 10 + idle_timeout_secs: 300 + max_lifetime_secs: 900 + cron_pool: + max_connections: 5 + min_connections: 1 + acquire_timeout_secs: 30 + idle_timeout_secs: 600 + max_lifetime_secs: 1800 + sql_health_check_timeout_secs: 5 + cron: + # 60s for interval check + timeout_cron_interval: "60s" + # 30 mins timeout logic + public_decrypt_timeout: "30m" + user_decrypt_timeout: "30m" + input_proof_timeout: "30m" + # 1 hour interval for cleanup check + expiry_cron_interval: "5m" + # Retention Policies + public_decrypt_expiry: "365d" # 1 year + user_decrypt_expiry: "7d" + input_proof_expiry: "7d" + cron_startup_delay_after_recovery: "30s" \ No newline at end of file diff --git a/test-suite/fhevm/docker-compose/relayer-docker-compose.yml b/test-suite/fhevm/docker-compose/relayer-docker-compose.yml index c7b5fc7d7a..15937c76b0 100644 --- a/test-suite/fhevm/docker-compose/relayer-docker-compose.yml +++ b/test-suite/fhevm/docker-compose/relayer-docker-compose.yml @@ -1,4 +1,36 @@ services: + relayer-db: + container_name: fhevm-relayer-db + platform: linux/amd64 + image: postgres:17 + environment: + POSTGRES_DB: relayer_db + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 10s + timeout: 5s + retries: 5 + ports: + - "5433:5432" + volumes: + - relayer_postgres_data:/var/lib/postgresql/data + + relayer-db-migration: + container_name: relayer-db-migration + platform: linux/amd64 + image: ghcr.io/zama-ai/console/relayer-migrate:${RELAYER_MIGRATE_VERSION} + env_file: + - ../env/staging/.env.relayer.local + command: + - /bin/server + ports: + - "3001:3001" + depends_on: + relayer-db: + condition: service_healthy + relayer: container_name: fhevm-relayer platform: linux/amd64 @@ -12,3 +44,11 @@ services: - ../config/relayer/local.yaml:/app/config/local.yaml ports: - "3000:3000" + depends_on: + relayer-db: + condition: service_healthy + relayer-db-migration: + condition: service_started + +volumes: + relayer_postgres_data: diff --git a/test-suite/fhevm/env/staging/.env.relayer b/test-suite/fhevm/env/staging/.env.relayer index c78f4b1dc5..44fe50272a 100644 --- a/test-suite/fhevm/env/staging/.env.relayer +++ b/test-suite/fhevm/env/staging/.env.relayer @@ -1,3 +1,10 @@ +# ============================================================================= +# DATABASE CONFIGURATION - SENSITIVE +# ============================================================================= +# IMPORTANT: For testing only - move to secure storage in production +DATABASE_URL=postgres://postgres:postgres@relayer-db:5432/relayer_db +MAX_ATTEMPTS=20 + # ============================================================================= # WALLET CONFIGURATION - SENSITIVE # ============================================================================= @@ -21,4 +28,7 @@ APP_GATEWAY__CONTRACTS__DECRYPTION_ADDRESS=0x35760912360E875DA50D40a74305575c23D APP_GATEWAY__CONTRACTS__INPUT_VERIFICATION_ADDRESS=0x1ceFA8E3F3271358218B52c33929Cf76078004c1 APP_GATEWAY__CONTRACTS__USER_DECRYPT_SHARES_THRESHOLD=1 -RUST_LOG=info +# Storage configuration: +APP_STORAGE__SQL_DATABASE_URL=postgres://postgres:postgres@relayer-db:5432/relayer_db + +RUST_LOG=debug diff --git a/test-suite/fhevm/env/staging/.env.test-suite b/test-suite/fhevm/env/staging/.env.test-suite index 0959e8260a..e695fa1776 100644 --- a/test-suite/fhevm/env/staging/.env.test-suite +++ b/test-suite/fhevm/env/staging/.env.test-suite @@ -8,6 +8,7 @@ MNEMONIC=adapt mosquito move limb mobile illegal tree voyage juice mosquito burg # NETWORK CONFIGURATION # ============================================================================= CHAIN_ID_GATEWAY=54321 +CHAIN_ID_HOST=12345 RPC_URL=http://host-node:8545 # ============================================================================= @@ -29,4 +30,4 @@ FHEVM_EXECUTOR_CONTRACT_ADDRESS=0xcCAe95fF1d11656358E782570dF0418F59fA40e1 # ============================================================================= # SERVICE ENDPOINTS # ============================================================================= -RELAYER_URL=http://fhevm-relayer:3000 \ No newline at end of file +RELAYER_URL=http://fhevm-relayer:3000/v2 \ No newline at end of file diff --git a/test-suite/fhevm/fhevm-cli b/test-suite/fhevm/fhevm-cli index 0eaba112a2..59ddd3fdaf 100755 --- a/test-suite/fhevm/fhevm-cli +++ b/test-suite/fhevm/fhevm-cli @@ -37,10 +37,11 @@ export HOST_VERSION=${HOST_VERSION:-"v0.10.5"} # Other services. export CORE_VERSION=${CORE_VERSION:-"v0.12.7"} -export RELAYER_VERSION=${RELAYER_VERSION:-"v0.6.0"} +export RELAYER_VERSION=${RELAYER_VERSION:-"v0.8.4"} +export RELAYER_MIGRATE_VERSION=${RELAYER_MIGRATE_VERSION:-"v0.8.3"} # Test-suite docker image cannot be updated with 0.10.x releases because of the introduction a # breaking change in delegate user decryption tests in https://github.com/zama-ai/fhevm/pull/1092 -export TEST_SUITE_VERSION=${TEST_SUITE_VERSION:-"1c70735"} +export TEST_SUITE_VERSION=${TEST_SUITE_VERSION:-"ebb1a48"} function print_logo() {