From 980ecf5596722c1809dcd4b100a2c5cef44c62ee Mon Sep 17 00:00:00 2001 From: Petar Ivanov <29689712+dartdart26@users.noreply.github.com> Date: Wed, 24 Sep 2025 15:17:55 +0300 Subject: [PATCH 1/2] feat(coprocessor): add copro context ID for input proofs Add support for a separate uin256 context ID in the event listened to by the gw-listener and using it to sign a `CiphertextVerification` in transaction-sender. Related to https://github.com/zama-ai/fhevm/pull/211 --- ...5_verify_proofs_coprocessor_context_id.sql | 8 ++ ...f6b78eb1966540df01871b27fe8383c0d52e.json} | 18 ++-- ...b351137d9561c952cceb0eb1fdf66c33c59d.json} | 5 +- .../contracts/InputVerification.sol | 3 + .../gw-listener/src/gw_listener.rs | 7 +- .../gw-listener/tests/gw_listener_tests.rs | 9 +- ...2c5cffb5284903adb757b4fda59b7fbe81d57.json | 6 ++ ...3974012524688114b5d313f9ce2da2ef1282.json} | 5 +- ...759ef15cf64f2da3fd3d3484b6dd74467e4a.json} | 22 +++-- ...b9a1d753b8650ed3367681ba30ed426799502.json | 6 ++ ...f8c304f534b50565504a96bd63ce63a6179d7.json | 6 ++ ...7e58590782ad965899b6dfdb284dc6d82b37.json} | 5 +- ...113ae7838d935e4462421fd796f5f7986dbbd.json | 6 ++ .../src/ops/verify_proof.rs | 14 ++- .../tests/verify_proof_tests.rs | 91 ++++++++++--------- 15 files changed, 142 insertions(+), 69 deletions(-) create mode 100644 coprocessor/fhevm-engine/db-migration/migrations/20250924120045_verify_proofs_coprocessor_context_id.sql rename coprocessor/fhevm-engine/gw-listener/.sqlx/{query-774d0833f523257d42044019619094083caf37a564283a97822f0efb309f2ea8.json => query-989cdc420a832541b7df7be83086f6b78eb1966540df01871b27fe8383c0d52e.json} (69%) rename coprocessor/fhevm-engine/gw-listener/.sqlx/{query-d1a294c48d897dc9685c95c8a59be64262d55e5d5b1dcbf40ae6d829fbc02970.json => query-a06d342308b9f63791f9fdfc1568b351137d9561c952cceb0eb1fdf66c33c59d.json} (50%) rename coprocessor/fhevm-engine/transaction-sender/.sqlx/{query-2611f503726ca2bd9cb05c62058395cf36c079ed4e0f7a9111e46e2b9a391b8c.json => query-1fcea613de0ee1b05fdc6dbbe1f33974012524688114b5d313f9ce2da2ef1282.json} (58%) rename coprocessor/fhevm-engine/transaction-sender/.sqlx/{query-50f019940b924bfc9f1a317b5b9ea97e02b9ef8646642042755b4fe7f2ddce5b.json => query-9d468cb6afef82b0206d4498ad03759ef15cf64f2da3fd3d3484b6dd74467e4a.json} (68%) rename coprocessor/fhevm-engine/transaction-sender/.sqlx/{query-7e4f6abc7e18549f31548130efa4bed4d267da6e28697ceb780a58d787e739f1.json => query-c3dd74257f8c441971693ab198eb7e58590782ad965899b6dfdb284dc6d82b37.json} (58%) diff --git a/coprocessor/fhevm-engine/db-migration/migrations/20250924120045_verify_proofs_coprocessor_context_id.sql b/coprocessor/fhevm-engine/db-migration/migrations/20250924120045_verify_proofs_coprocessor_context_id.sql new file mode 100644 index 0000000000..bfc3d79f6d --- /dev/null +++ b/coprocessor/fhevm-engine/db-migration/migrations/20250924120045_verify_proofs_coprocessor_context_id.sql @@ -0,0 +1,8 @@ +-- Use a default context ID of 1 as this is the first one used by the GW contract. +-- Note that if this migration is run after context ID has changed, the proof requests still pending would fail. +-- Therefore, we assume that this migration runs when either: +-- * the table is empty +-- * context ID is currently 1 +ALTER TABLE verify_proofs +ADD COLUMN IF NOT EXISTS coprocessor_context_id +BYTEA NOT NULL DEFAULT decode('0100000000000000000000000000000000000000000000000000000000000000', 'hex'); diff --git a/coprocessor/fhevm-engine/gw-listener/.sqlx/query-774d0833f523257d42044019619094083caf37a564283a97822f0efb309f2ea8.json b/coprocessor/fhevm-engine/gw-listener/.sqlx/query-989cdc420a832541b7df7be83086f6b78eb1966540df01871b27fe8383c0d52e.json similarity index 69% rename from coprocessor/fhevm-engine/gw-listener/.sqlx/query-774d0833f523257d42044019619094083caf37a564283a97822f0efb309f2ea8.json rename to coprocessor/fhevm-engine/gw-listener/.sqlx/query-989cdc420a832541b7df7be83086f6b78eb1966540df01871b27fe8383c0d52e.json index a2ea27f02a..6bffc5c525 100644 --- a/coprocessor/fhevm-engine/gw-listener/.sqlx/query-774d0833f523257d42044019619094083caf37a564283a97822f0efb309f2ea8.json +++ b/coprocessor/fhevm-engine/gw-listener/.sqlx/query-989cdc420a832541b7df7be83086f6b78eb1966540df01871b27fe8383c0d52e.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT zk_proof_id, chain_id, contract_address, user_address, input, extra_data\n FROM verify_proofs", + "query": "SELECT zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, input, extra_data\n FROM verify_proofs", "describe": { "columns": [ { @@ -10,26 +10,31 @@ }, { "ordinal": 1, + "name": "coprocessor_context_id", + "type_info": "Bytea" + }, + { + "ordinal": 2, "name": "chain_id", "type_info": "Int8" }, { - "ordinal": 2, + "ordinal": 3, "name": "contract_address", "type_info": "Text" }, { - "ordinal": 3, + "ordinal": 4, "name": "user_address", "type_info": "Text" }, { - "ordinal": 4, + "ordinal": 5, "name": "input", "type_info": "Bytea" }, { - "ordinal": 5, + "ordinal": 6, "name": "extra_data", "type_info": "Bytea" } @@ -42,9 +47,10 @@ false, false, false, + false, true, false ] }, - "hash": "774d0833f523257d42044019619094083caf37a564283a97822f0efb309f2ea8" + "hash": "989cdc420a832541b7df7be83086f6b78eb1966540df01871b27fe8383c0d52e" } diff --git a/coprocessor/fhevm-engine/gw-listener/.sqlx/query-d1a294c48d897dc9685c95c8a59be64262d55e5d5b1dcbf40ae6d829fbc02970.json b/coprocessor/fhevm-engine/gw-listener/.sqlx/query-a06d342308b9f63791f9fdfc1568b351137d9561c952cceb0eb1fdf66c33c59d.json similarity index 50% rename from coprocessor/fhevm-engine/gw-listener/.sqlx/query-d1a294c48d897dc9685c95c8a59be64262d55e5d5b1dcbf40ae6d829fbc02970.json rename to coprocessor/fhevm-engine/gw-listener/.sqlx/query-a06d342308b9f63791f9fdfc1568b351137d9561c952cceb0eb1fdf66c33c59d.json index cea05029f0..d1e19666c6 100644 --- a/coprocessor/fhevm-engine/gw-listener/.sqlx/query-d1a294c48d897dc9685c95c8a59be64262d55e5d5b1dcbf40ae6d829fbc02970.json +++ b/coprocessor/fhevm-engine/gw-listener/.sqlx/query-a06d342308b9f63791f9fdfc1568b351137d9561c952cceb0eb1fdf66c33c59d.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "WITH ins AS (\n INSERT INTO verify_proofs (zk_proof_id, chain_id, contract_address, user_address, input, extra_data)\n VALUES ($1, $2, $3, $4, $5, $6)\n ON CONFLICT(zk_proof_id) DO NOTHING\n )\n SELECT pg_notify($7, '')", + "query": "WITH ins AS (\n INSERT INTO verify_proofs (zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, input, extra_data)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n ON CONFLICT(zk_proof_id) DO NOTHING\n )\n SELECT pg_notify($8, '')", "describe": { "columns": [ { @@ -12,6 +12,7 @@ "parameters": { "Left": [ "Int8", + "Bytea", "Int8", "Text", "Text", @@ -24,5 +25,5 @@ null ] }, - "hash": "d1a294c48d897dc9685c95c8a59be64262d55e5d5b1dcbf40ae6d829fbc02970" + "hash": "a06d342308b9f63791f9fdfc1568b351137d9561c952cceb0eb1fdf66c33c59d" } diff --git a/coprocessor/fhevm-engine/gw-listener/contracts/InputVerification.sol b/coprocessor/fhevm-engine/gw-listener/contracts/InputVerification.sol index 0e12e4f9d5..c74e58ee01 100644 --- a/coprocessor/fhevm-engine/gw-listener/contracts/InputVerification.sol +++ b/coprocessor/fhevm-engine/gw-listener/contracts/InputVerification.sol @@ -6,6 +6,7 @@ pragma solidity ^0.8.28; contract InputVerification { event VerifyProofRequest( uint256 indexed zkProofId, + uint256 indexed coprocessorContextId, uint256 indexed contractChainId, address contractAddress, address userAddress, @@ -14,6 +15,7 @@ contract InputVerification { ); uint256 zkProofIdCounter = 0; + uint256 public coprocessorContextId = 7; function verifyProofRequest( uint256 contractChainId, @@ -26,6 +28,7 @@ contract InputVerification { zkProofIdCounter += 1; emit VerifyProofRequest( zkProofId, + coprocessorContextId, contractChainId, contractAddress, userAddress, diff --git a/coprocessor/fhevm-engine/gw-listener/src/gw_listener.rs b/coprocessor/fhevm-engine/gw-listener/src/gw_listener.rs index 4c32a90284..cbbcbdf677 100644 --- a/coprocessor/fhevm-engine/gw-listener/src/gw_listener.rs +++ b/coprocessor/fhevm-engine/gw-listener/src/gw_listener.rs @@ -136,12 +136,13 @@ impl + Clone + 'static> GatewayListener

{ // TODO: check if we can avoid the cast from u256 to i64 sqlx::query!( "WITH ins AS ( - INSERT INTO verify_proofs (zk_proof_id, chain_id, contract_address, user_address, input, extra_data) - VALUES ($1, $2, $3, $4, $5, $6) + INSERT INTO verify_proofs (zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, input, extra_data) + VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT(zk_proof_id) DO NOTHING ) - SELECT pg_notify($7, '')", + SELECT pg_notify($8, '')", request.zkProofId.to::(), + &request.coprocessorContextId.to_le_bytes::<32>(), request.contractChainId.to::(), request.contractAddress.to_string(), request.userAddress.to_string(), diff --git a/coprocessor/fhevm-engine/gw-listener/tests/gw_listener_tests.rs b/coprocessor/fhevm-engine/gw-listener/tests/gw_listener_tests.rs index 35cd254c97..9d7ca03bd3 100644 --- a/coprocessor/fhevm-engine/gw-listener/tests/gw_listener_tests.rs +++ b/coprocessor/fhevm-engine/gw-listener/tests/gw_listener_tests.rs @@ -101,15 +101,22 @@ async fn verify_proof_request_inserted_into_db() -> anyhow::Result<()> { let receipt = pending_txn.get_receipt().await?; assert!(receipt.status()); + let coprocessor_context_id = input_verification + .coprocessorContextId() + .call() + .await? + .to_le_bytes::<32>(); + loop { let rows = sqlx::query!( - "SELECT zk_proof_id, chain_id, contract_address, user_address, input, extra_data + "SELECT zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, input, extra_data FROM verify_proofs", ) .fetch_all(&env.db_pool) .await?; if !rows.is_empty() { let row = &rows[0]; + assert_eq!(row.coprocessor_context_id, coprocessor_context_id); assert_eq!(row.chain_id, 42); assert_eq!(row.contract_address, contract_address.to_string()); assert_eq!(row.user_address, user_address.to_string()); diff --git a/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-048212909e0bbe46633e404235d2c5cffb5284903adb757b4fda59b7fbe81d57.json b/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-048212909e0bbe46633e404235d2c5cffb5284903adb757b4fda59b7fbe81d57.json index f2f4786bf3..9f2c92382e 100644 --- a/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-048212909e0bbe46633e404235d2c5cffb5284903adb757b4fda59b7fbe81d57.json +++ b/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-048212909e0bbe46633e404235d2c5cffb5284903adb757b4fda59b7fbe81d57.json @@ -67,6 +67,11 @@ "ordinal": 12, "name": "extra_data", "type_info": "Bytea" + }, + { + "ordinal": 13, + "name": "coprocessor_context_id", + "type_info": "Bytea" } ], "parameters": { @@ -87,6 +92,7 @@ true, true, false, + false, false ] }, diff --git a/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-2611f503726ca2bd9cb05c62058395cf36c079ed4e0f7a9111e46e2b9a391b8c.json b/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-1fcea613de0ee1b05fdc6dbbe1f33974012524688114b5d313f9ce2da2ef1282.json similarity index 58% rename from coprocessor/fhevm-engine/transaction-sender/.sqlx/query-2611f503726ca2bd9cb05c62058395cf36c079ed4e0f7a9111e46e2b9a391b8c.json rename to coprocessor/fhevm-engine/transaction-sender/.sqlx/query-1fcea613de0ee1b05fdc6dbbe1f33974012524688114b5d313f9ce2da2ef1282.json index 47e91130b1..540659b71e 100644 --- a/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-2611f503726ca2bd9cb05c62058395cf36c079ed4e0f7a9111e46e2b9a391b8c.json +++ b/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-1fcea613de0ee1b05fdc6dbbe1f33974012524688114b5d313f9ce2da2ef1282.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "WITH ins AS (\n INSERT INTO verify_proofs (zk_proof_id, chain_id, contract_address, user_address, handles, verified)\n VALUES ($1, $2, $3, $4, $5, true)\n )\n SELECT pg_notify($6, '')", + "query": "WITH ins AS (\n INSERT INTO verify_proofs (zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, handles, verified)\n VALUES ($1, $2, $3, $4, $5, $6, true)\n )\n SELECT pg_notify($7, '')", "describe": { "columns": [ { @@ -12,6 +12,7 @@ "parameters": { "Left": [ "Int8", + "Bytea", "Int8", "Text", "Text", @@ -23,5 +24,5 @@ null ] }, - "hash": "2611f503726ca2bd9cb05c62058395cf36c079ed4e0f7a9111e46e2b9a391b8c" + "hash": "1fcea613de0ee1b05fdc6dbbe1f33974012524688114b5d313f9ce2da2ef1282" } diff --git a/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-50f019940b924bfc9f1a317b5b9ea97e02b9ef8646642042755b4fe7f2ddce5b.json b/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-9d468cb6afef82b0206d4498ad03759ef15cf64f2da3fd3d3484b6dd74467e4a.json similarity index 68% rename from coprocessor/fhevm-engine/transaction-sender/.sqlx/query-50f019940b924bfc9f1a317b5b9ea97e02b9ef8646642042755b4fe7f2ddce5b.json rename to coprocessor/fhevm-engine/transaction-sender/.sqlx/query-9d468cb6afef82b0206d4498ad03759ef15cf64f2da3fd3d3484b6dd74467e4a.json index 8e66848d28..de47e7e9b5 100644 --- a/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-50f019940b924bfc9f1a317b5b9ea97e02b9ef8646642042755b4fe7f2ddce5b.json +++ b/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-9d468cb6afef82b0206d4498ad03759ef15cf64f2da3fd3d3484b6dd74467e4a.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT zk_proof_id, chain_id, contract_address, user_address, handles, verified, retry_count, extra_data\n FROM verify_proofs\n WHERE verified IS NOT NULL AND retry_count < $1\n ORDER BY zk_proof_id\n LIMIT $2", + "query": "SELECT zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, handles, verified, retry_count, extra_data\n FROM verify_proofs\n WHERE verified IS NOT NULL AND retry_count < $1\n ORDER BY zk_proof_id\n LIMIT $2", "describe": { "columns": [ { @@ -10,36 +10,41 @@ }, { "ordinal": 1, + "name": "coprocessor_context_id", + "type_info": "Bytea" + }, + { + "ordinal": 2, "name": "chain_id", "type_info": "Int8" }, { - "ordinal": 2, + "ordinal": 3, "name": "contract_address", "type_info": "Text" }, { - "ordinal": 3, + "ordinal": 4, "name": "user_address", "type_info": "Text" }, { - "ordinal": 4, + "ordinal": 5, "name": "handles", "type_info": "Bytea" }, { - "ordinal": 5, + "ordinal": 6, "name": "verified", "type_info": "Bool" }, { - "ordinal": 6, + "ordinal": 7, "name": "retry_count", "type_info": "Int4" }, { - "ordinal": 7, + "ordinal": 8, "name": "extra_data", "type_info": "Bytea" } @@ -55,11 +60,12 @@ false, false, false, + false, true, true, false, false ] }, - "hash": "50f019940b924bfc9f1a317b5b9ea97e02b9ef8646642042755b4fe7f2ddce5b" + "hash": "9d468cb6afef82b0206d4498ad03759ef15cf64f2da3fd3d3484b6dd74467e4a" } diff --git a/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-b5b633e5812b7396037e2ab0a1db9a1d753b8650ed3367681ba30ed426799502.json b/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-b5b633e5812b7396037e2ab0a1db9a1d753b8650ed3367681ba30ed426799502.json index d34d2d615b..39383d9f17 100644 --- a/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-b5b633e5812b7396037e2ab0a1db9a1d753b8650ed3367681ba30ed426799502.json +++ b/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-b5b633e5812b7396037e2ab0a1db9a1d753b8650ed3367681ba30ed426799502.json @@ -67,6 +67,11 @@ "ordinal": 12, "name": "extra_data", "type_info": "Bytea" + }, + { + "ordinal": 13, + "name": "coprocessor_context_id", + "type_info": "Bytea" } ], "parameters": { @@ -87,6 +92,7 @@ true, true, false, + false, false ] }, diff --git a/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-be2b163e885ff2e4df27ae07c51f8c304f534b50565504a96bd63ce63a6179d7.json b/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-be2b163e885ff2e4df27ae07c51f8c304f534b50565504a96bd63ce63a6179d7.json index cd7e1df77c..7738819e9e 100644 --- a/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-be2b163e885ff2e4df27ae07c51f8c304f534b50565504a96bd63ce63a6179d7.json +++ b/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-be2b163e885ff2e4df27ae07c51f8c304f534b50565504a96bd63ce63a6179d7.json @@ -67,6 +67,11 @@ "ordinal": 12, "name": "extra_data", "type_info": "Bytea" + }, + { + "ordinal": 13, + "name": "coprocessor_context_id", + "type_info": "Bytea" } ], "parameters": { @@ -87,6 +92,7 @@ true, true, false, + false, false ] }, diff --git a/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-7e4f6abc7e18549f31548130efa4bed4d267da6e28697ceb780a58d787e739f1.json b/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-c3dd74257f8c441971693ab198eb7e58590782ad965899b6dfdb284dc6d82b37.json similarity index 58% rename from coprocessor/fhevm-engine/transaction-sender/.sqlx/query-7e4f6abc7e18549f31548130efa4bed4d267da6e28697ceb780a58d787e739f1.json rename to coprocessor/fhevm-engine/transaction-sender/.sqlx/query-c3dd74257f8c441971693ab198eb7e58590782ad965899b6dfdb284dc6d82b37.json index 8dd18252c5..3ce6b10df5 100644 --- a/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-7e4f6abc7e18549f31548130efa4bed4d267da6e28697ceb780a58d787e739f1.json +++ b/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-c3dd74257f8c441971693ab198eb7e58590782ad965899b6dfdb284dc6d82b37.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "WITH ins AS (\n INSERT INTO verify_proofs (zk_proof_id, chain_id, contract_address, user_address, handles, verified)\n VALUES ($1, $2, $3, $4, $5, false)\n )\n SELECT pg_notify($6, '')", + "query": "WITH ins AS (\n INSERT INTO verify_proofs (zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, handles, verified)\n VALUES ($1, $2, $3, $4, $5, $6, false)\n )\n SELECT pg_notify($7, '')", "describe": { "columns": [ { @@ -12,6 +12,7 @@ "parameters": { "Left": [ "Int8", + "Bytea", "Int8", "Text", "Text", @@ -23,5 +24,5 @@ null ] }, - "hash": "7e4f6abc7e18549f31548130efa4bed4d267da6e28697ceb780a58d787e739f1" + "hash": "c3dd74257f8c441971693ab198eb7e58590782ad965899b6dfdb284dc6d82b37" } diff --git a/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-eadec222d0154713dc15ea7ba1e113ae7838d935e4462421fd796f5f7986dbbd.json b/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-eadec222d0154713dc15ea7ba1e113ae7838d935e4462421fd796f5f7986dbbd.json index 13cfce8d10..be0469346b 100644 --- a/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-eadec222d0154713dc15ea7ba1e113ae7838d935e4462421fd796f5f7986dbbd.json +++ b/coprocessor/fhevm-engine/transaction-sender/.sqlx/query-eadec222d0154713dc15ea7ba1e113ae7838d935e4462421fd796f5f7986dbbd.json @@ -67,6 +67,11 @@ "ordinal": 12, "name": "extra_data", "type_info": "Bytea" + }, + { + "ordinal": 13, + "name": "coprocessor_context_id", + "type_info": "Bytea" } ], "parameters": { @@ -85,6 +90,7 @@ true, true, false, + false, false ] }, diff --git a/coprocessor/fhevm-engine/transaction-sender/src/ops/verify_proof.rs b/coprocessor/fhevm-engine/transaction-sender/src/ops/verify_proof.rs index 42469eca74..c846a3c1ab 100644 --- a/coprocessor/fhevm-engine/transaction-sender/src/ops/verify_proof.rs +++ b/coprocessor/fhevm-engine/transaction-sender/src/ops/verify_proof.rs @@ -23,6 +23,7 @@ sol! { address userAddress; address contractAddress; uint256 contractChainId; + uint256 coprocessorContextId; bytes extraData; } } @@ -242,7 +243,7 @@ where self.remove_proofs_by_retry_count().await?; } let rows = sqlx::query!( - "SELECT zk_proof_id, chain_id, contract_address, user_address, handles, verified, retry_count, extra_data + "SELECT zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, handles, verified, retry_count, extra_data FROM verify_proofs WHERE verified IS NOT NULL AND retry_count < $1 ORDER BY zk_proof_id @@ -270,6 +271,14 @@ where self.remove_proof_by_id(row.zk_proof_id).await?; continue; } + if row.coprocessor_context_id.len() != 32 { + error!( + coprocessor_context_id_len = row.coprocessor_context_id.len(), + "Bad coprocessor_context_id field, len is not 32" + ); + self.remove_proof_by_id(row.zk_proof_id).await?; + continue; + } let handles: Vec> = handles .chunks(32) .map(|chunk| { @@ -291,6 +300,9 @@ where .parse() .expect("invalid contract address"), contractChainId: U256::from(row.chain_id), + coprocessorContextId: U256::from_le_bytes::<32>( + row.coprocessor_context_id.as_slice().try_into()?, + ), extraData: row.extra_data.clone().into(), } .eip712_signing_hash(&domain); diff --git a/coprocessor/fhevm-engine/transaction-sender/tests/verify_proof_tests.rs b/coprocessor/fhevm-engine/transaction-sender/tests/verify_proof_tests.rs index 99f9931f80..777327bc55 100644 --- a/coprocessor/fhevm-engine/transaction-sender/tests/verify_proof_tests.rs +++ b/coprocessor/fhevm-engine/transaction-sender/tests/verify_proof_tests.rs @@ -1,9 +1,9 @@ use alloy::network::TxSigner; use alloy::primitives::FixedBytes; use alloy::primitives::U256; +use alloy::providers::ProviderBuilder; use alloy::providers::WsConnect; use alloy::signers::local::PrivateKeySigner; -use alloy::{providers::ProviderBuilder, sol}; use common::SignerType; use common::{CiphertextCommits, InputVerification, TestEnvironment}; use futures_util::StreamExt; @@ -18,15 +18,6 @@ use tokio::time::sleep; use transaction_sender::{FillersWithoutNonceManagement, NonceManagedProvider, TransactionSender}; mod common; -sol! { - struct CiphertextVerification { - bytes32[] ctHandles; - address userAddress; - address contractAddress; - uint256 contractChainId; - } -} - #[rstest] #[case::private_key(SignerType::PrivateKey)] #[case::aws_kms(SignerType::AwsKms)] @@ -97,11 +88,12 @@ async fn verify_proof_response_success(#[case] signer_type: SignerType) -> anyho // Insert a proof into the database and notify the sender. sqlx::query!( "WITH ins AS ( - INSERT INTO verify_proofs (zk_proof_id, chain_id, contract_address, user_address, handles, verified) - VALUES ($1, $2, $3, $4, $5, true) + INSERT INTO verify_proofs (zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, handles, verified) + VALUES ($1, $2, $3, $4, $5, $6, true) ) - SELECT pg_notify($6, '')", + SELECT pg_notify($7, '')", proof_id as i64, + &U256::from(42).to_le_bytes::<32>(), contract_chain_id as i64, env.contract_address.to_string(), env.user_address.to_string(), @@ -213,11 +205,12 @@ async fn verify_proof_response_empty_handles_success( // Insert a proof into the database and notify the sender. sqlx::query!( "WITH ins AS ( - INSERT INTO verify_proofs (zk_proof_id, chain_id, contract_address, user_address, handles, verified) - VALUES ($1, $2, $3, $4, $5, true) + INSERT INTO verify_proofs (zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, handles, verified) + VALUES ($1, $2, $3, $4, $5, $6, true) ) - SELECT pg_notify($6, '')", + SELECT pg_notify($7, '')", proof_id as i64, + &U256::from(42).to_le_bytes::<32>(), contract_chain_id as i64, env.contract_address.to_string(), env.user_address.to_string(), @@ -327,9 +320,10 @@ async fn verify_proof_response_concurrent_success( let contract_chain_id = 42u64; let mut query_builder = QueryBuilder::::new("WITH ins AS ( - INSERT INTO verify_proofs (zk_proof_id, chain_id, contract_address, user_address, handles, verified)"); + INSERT INTO verify_proofs (zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, handles, verified)"); query_builder.push_values(0..count, |mut b, i| { b.push_bind(i as i64); + b.push_bind(U256::from(i).to_le_bytes::<32>()); b.push_bind(contract_chain_id as i64); b.push_bind(env.contract_address.to_string()); b.push_bind(env.user_address.to_string()); @@ -446,11 +440,12 @@ async fn reject_proof_response_success(#[case] signer_type: SignerType) -> anyho sqlx::query!( "WITH ins AS ( - INSERT INTO verify_proofs (zk_proof_id, chain_id, contract_address, user_address, handles, verified) - VALUES ($1, $2, $3, $4, $5, false) + INSERT INTO verify_proofs (zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, handles, verified) + VALUES ($1, $2, $3, $4, $5, $6, false) ) - SELECT pg_notify($6, '')", + SELECT pg_notify($7, '')", proof_id as i64, + &U256::from(42).to_le_bytes::<32>(), 42 as i64, env.contract_address.to_string(), env.user_address.to_string(), @@ -545,11 +540,12 @@ async fn verify_proof_response_reversal_already_verified( // Insert a proof into the database and notify the sender. sqlx::query!( "WITH ins AS ( - INSERT INTO verify_proofs (zk_proof_id, chain_id, contract_address, user_address, handles, verified) - VALUES ($1, $2, $3, $4, $5, true) + INSERT INTO verify_proofs (zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, handles, verified) + VALUES ($1, $2, $3, $4, $5, $6, true) ) - SELECT pg_notify($6, '')", + SELECT pg_notify($7, '')", proof_id as i64, + &U256::from(42).to_le_bytes::<32>(), 42, env.contract_address.to_string(), env.user_address.to_string(), @@ -646,11 +642,12 @@ async fn reject_proof_response_reversal_already_rejected( sqlx::query!( "WITH ins AS ( - INSERT INTO verify_proofs (zk_proof_id, chain_id, contract_address, user_address, handles, verified) - VALUES ($1, $2, $3, $4, $5, false) + INSERT INTO verify_proofs (zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, handles, verified) + VALUES ($1, $2, $3, $4, $5, $6, false) ) - SELECT pg_notify($6, '')", + SELECT pg_notify($7, '')", proof_id as i64, + &U256::from(42).to_le_bytes::<32>(), 42, env.contract_address.to_string(), env.user_address.to_string(), @@ -744,11 +741,12 @@ async fn verify_proof_response_other_reversal( // Insert a proof into the database and notify the sender. sqlx::query!( "WITH ins AS ( - INSERT INTO verify_proofs (zk_proof_id, chain_id, contract_address, user_address, handles, verified) - VALUES ($1, $2, $3, $4, $5, true) + INSERT INTO verify_proofs (zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, handles, verified) + VALUES ($1, $2, $3, $4, $5, $6, true) ) - SELECT pg_notify($6, '')", + SELECT pg_notify($7, '')", proof_id as i64, + &U256::from(42).to_le_bytes::<32>(), 42, env.contract_address.to_string(), env.user_address.to_string(), @@ -842,11 +840,12 @@ async fn reject_proof_response_other_reversal( sqlx::query!( "WITH ins AS ( - INSERT INTO verify_proofs (zk_proof_id, chain_id, contract_address, user_address, handles, verified) - VALUES ($1, $2, $3, $4, $5, false) + INSERT INTO verify_proofs (zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, handles, verified) + VALUES ($1, $2, $3, $4, $5, $6, false) ) - SELECT pg_notify($6, '')", + SELECT pg_notify($7, '')", proof_id as i64, + &U256::from(42).to_le_bytes::<32>(), 42, env.contract_address.to_string(), env.user_address.to_string(), @@ -937,11 +936,12 @@ async fn verify_proof_response_other_reversal_gas_estimation( // Insert a proof into the database and notify the sender. sqlx::query!( "WITH ins AS ( - INSERT INTO verify_proofs (zk_proof_id, chain_id, contract_address, user_address, handles, verified) - VALUES ($1, $2, $3, $4, $5, true) + INSERT INTO verify_proofs (zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, handles, verified) + VALUES ($1, $2, $3, $4, $5, $6, true) ) - SELECT pg_notify($6, '')", + SELECT pg_notify($7, '')", proof_id as i64, + &U256::from(42).to_le_bytes::<32>(), 42, env.contract_address.to_string(), env.user_address.to_string(), @@ -1035,11 +1035,12 @@ async fn reject_proof_response_other_reversal_gas_estimation( // Insert a proof into the database and notify the sender. sqlx::query!( "WITH ins AS ( - INSERT INTO verify_proofs (zk_proof_id, chain_id, contract_address, user_address, handles, verified) - VALUES ($1, $2, $3, $4, $5, false) + INSERT INTO verify_proofs (zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, handles, verified) + VALUES ($1, $2, $3, $4, $5, $6, false) ) - SELECT pg_notify($6, '')", + SELECT pg_notify($7, '')", proof_id as i64, + &U256::from(42).to_le_bytes::<32>(), 42, env.contract_address.to_string(), env.user_address.to_string(), @@ -1135,11 +1136,12 @@ async fn verify_proof_max_retries_remove_entry( // Insert a proof into the database and notify the sender. sqlx::query!( "WITH ins AS ( - INSERT INTO verify_proofs (zk_proof_id, chain_id, contract_address, user_address, handles, verified) - VALUES ($1, $2, $3, $4, $5, true) + INSERT INTO verify_proofs (zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, handles, verified) + VALUES ($1, $2, $3, $4, $5, $6, true) ) - SELECT pg_notify($6, '')", + SELECT pg_notify($7, '')", proof_id as i64, + &U256::from(42).to_le_bytes::<32>(), 42, env.contract_address.to_string(), env.user_address.to_string(), @@ -1225,11 +1227,12 @@ async fn verify_proof_max_retries_do_not_remove_entry( // Insert a proof into the database and notify the sender. sqlx::query!( "WITH ins AS ( - INSERT INTO verify_proofs (zk_proof_id, chain_id, contract_address, user_address, handles, verified) - VALUES ($1, $2, $3, $4, $5, true) + INSERT INTO verify_proofs (zk_proof_id, coprocessor_context_id, chain_id, contract_address, user_address, handles, verified) + VALUES ($1, $2, $3, $4, $5, $6, true) ) - SELECT pg_notify($6, '')", + SELECT pg_notify($7, '')", proof_id as i64, + &U256::from(42).to_le_bytes::<32>(), 42, env.contract_address.to_string(), env.user_address.to_string(), From 92f278a1d28cb610138efcca04dfbb5b26bd54d1 Mon Sep 17 00:00:00 2001 From: Simon Eudeline Date: Tue, 2 Sep 2025 18:47:42 +0200 Subject: [PATCH 2/2] feat(kms-connector): retrieve s3 url in extra_data chore(kms-connector): update mock contract address chore(kms-connector): remove gw conn from kms-worker chore(kms-connector): update extra_data encoding fix(kms-connector): fix kms-worker health tests chore(kms-connector): adapt storage urls retrieval chore(kms-connector): s3 urls edge case handling --- ...1d893a88cdee93f4caa655e7c3b25e9347232.json | 4 - ...057b5ec1f2a64e2778551dffe0c88aa4de8fb.json | 4 - kms-connector/Cargo.lock | 255 ++++++++--------- kms-connector/Cargo.toml | 3 +- kms-connector/config/kms-worker.toml | 17 -- .../20250902144114_update_sns_ciphertext.sql | 2 + .../gw-listener/src/core/event_publisher.rs | 6 +- .../gw-listener/tests/integration_test.rs | 3 +- kms-connector/crates/kms-worker/Cargo.toml | 1 - .../kms-worker/src/core/config/parsed.rs | 43 +-- .../crates/kms-worker/src/core/config/raw.rs | 8 - .../src/core/event_processor/decryption.rs | 21 +- .../src/core/event_processor/processor.rs | 13 +- .../kms-worker/src/core/event_processor/s3.rs | 267 ++++-------------- .../crates/kms-worker/src/core/kms_worker.rs | 19 +- .../kms-worker/src/monitoring/health.rs | 17 +- .../kms-worker/tests/event_picker/parallel.rs | 35 +-- .../kms-worker/tests/event_picker/simple.rs | 42 +-- .../crates/kms-worker/tests/health.rs | 18 +- kms-connector/crates/kms-worker/tests/s3.rs | 11 +- kms-connector/crates/utils/src/tests/rand.rs | 14 +- .../crates/utils/src/tests/setup/gw.rs | 39 ++- .../crates/utils/src/tests/setup/instance.rs | 5 - kms-connector/crates/utils/src/types/db.rs | 41 ++- .../crates/utils/src/types/gw_event.rs | 14 +- kms-connector/tests/lib.rs | 1 - 26 files changed, 320 insertions(+), 583 deletions(-) create mode 100644 kms-connector/connector-db/migrations/20250902144114_update_sns_ciphertext.sql diff --git a/kms-connector/.sqlx/query-104ddb7d42e409798b340fe63281d893a88cdee93f4caa655e7c3b25e9347232.json b/kms-connector/.sqlx/query-104ddb7d42e409798b340fe63281d893a88cdee93f4caa655e7c3b25e9347232.json index 1fc49a4c7d..64afbad547 100644 --- a/kms-connector/.sqlx/query-104ddb7d42e409798b340fe63281d893a88cdee93f4caa655e7c3b25e9347232.json +++ b/kms-connector/.sqlx/query-104ddb7d42e409798b340fe63281d893a88cdee93f4caa655e7c3b25e9347232.json @@ -26,10 +26,6 @@ [ "sns_ciphertext_digest", "Bytea" - ], - [ - "coprocessor_tx_sender_addresses", - "ByteaArray" ] ] } diff --git a/kms-connector/.sqlx/query-ed6985b72be07dc05088337a387057b5ec1f2a64e2778551dffe0c88aa4de8fb.json b/kms-connector/.sqlx/query-ed6985b72be07dc05088337a387057b5ec1f2a64e2778551dffe0c88aa4de8fb.json index ab53bb5fe1..59bccab962 100644 --- a/kms-connector/.sqlx/query-ed6985b72be07dc05088337a387057b5ec1f2a64e2778551dffe0c88aa4de8fb.json +++ b/kms-connector/.sqlx/query-ed6985b72be07dc05088337a387057b5ec1f2a64e2778551dffe0c88aa4de8fb.json @@ -26,10 +26,6 @@ [ "sns_ciphertext_digest", "Bytea" - ], - [ - "coprocessor_tx_sender_addresses", - "ByteaArray" ] ] } diff --git a/kms-connector/Cargo.lock b/kms-connector/Cargo.lock index f610cd3147..c17a3c0b52 100644 --- a/kms-connector/Cargo.lock +++ b/kms-connector/Cargo.lock @@ -21,9 +21,9 @@ dependencies = [ [[package]] name = "actix-http" -version = "3.11.1" +version = "3.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cceded2fb55f3c4b67068fa64962e2ca59614edc5b03167de9ff82ae803da0" +checksum = "7926860314cbe2fb5d1f13731e387ab43bd32bca224e82e6e2db85de0a3dba49" dependencies = [ "actix-codec", "actix-rt", @@ -1033,9 +1033,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.20" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -1511,9 +1511,9 @@ dependencies = [ [[package]] name = "aws-credential-types" -version = "1.2.6" +version = "1.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d025db5d9f52cbc413b167136afb3d8aeea708c0d8884783cf6253be5e22f6f2" +checksum = "faf26925f4a5b59eb76722b63c2892b1d70d06fa053c72e4a100ec308c1d47bc" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", @@ -1547,9 +1547,9 @@ dependencies = [ [[package]] name = "aws-runtime" -version = "1.5.10" +version = "1.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c034a1bc1d70e16e7f4e4caf7e9f7693e4c9c24cd91cf17c2a0b21abaebc7c8b" +checksum = "bfa006bb32360ed90ac51203feafb9d02e3d21046e1fd3a450a404b90ea73e5d" dependencies = [ "aws-credential-types", "aws-sigv4", @@ -1593,9 +1593,9 @@ dependencies = [ [[package]] name = "aws-sdk-sso" -version = "1.84.0" +version = "1.86.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357a841807f6b52cb26123878b3326921e2a25faca412fabdd32bd35b7edd5d3" +checksum = "4a0abbfab841446cce6e87af853a3ba2cc1bc9afcd3f3550dd556c43d434c86d" dependencies = [ "aws-credential-types", "aws-runtime", @@ -1615,9 +1615,9 @@ dependencies = [ [[package]] name = "aws-sdk-ssooidc" -version = "1.86.0" +version = "1.88.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1cc7fb324aa12eb4404210e6381195c5b5e9d52c2682384f295f38716dd3c7" +checksum = "9a68d675582afea0e94d38b6ca9c5aaae4ca14f1d36faa6edb19b42e687e70d7" dependencies = [ "aws-credential-types", "aws-runtime", @@ -1637,9 +1637,9 @@ dependencies = [ [[package]] name = "aws-sdk-sts" -version = "1.86.0" +version = "1.88.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7d835f123f307cafffca7b9027c14979f1d403b417d8541d67cf252e8a21e35" +checksum = "d30990923f4f675523c51eb1c0dec9b752fb267b36a61e83cbc219c9d86da715" dependencies = [ "aws-credential-types", "aws-runtime", @@ -1660,9 +1660,9 @@ dependencies = [ [[package]] name = "aws-sigv4" -version = "1.3.4" +version = "1.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084c34162187d39e3740cb635acd73c4e3a551a36146ad6fe8883c929c9f876c" +checksum = "bffc03068fbb9c8dd5ce1c6fb240678a5cffb86fb2b7b1985c999c4b83c8df68" dependencies = [ "aws-credential-types", "aws-smithy-http", @@ -1682,9 +1682,9 @@ dependencies = [ [[package]] name = "aws-smithy-async" -version = "1.2.5" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e190749ea56f8c42bf15dd76c65e14f8f765233e6df9b0506d9d934ebef867c" +checksum = "127fcfad33b7dfc531141fda7e1c402ac65f88aca5511a4d31e2e3d2cd01ce9c" dependencies = [ "futures-util", "pin-project-lite", @@ -1693,9 +1693,9 @@ dependencies = [ [[package]] name = "aws-smithy-http" -version = "0.62.3" +version = "0.62.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c4dacf2d38996cf729f55e7a762b30918229917eca115de45dfa8dfb97796c9" +checksum = "3feafd437c763db26aa04e0cc7591185d0961e64c61885bece0fb9d50ceac671" dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", @@ -1713,9 +1713,9 @@ dependencies = [ [[package]] name = "aws-smithy-http-client" -version = "1.1.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147e8eea63a40315d704b97bf9bc9b8c1402ae94f89d5ad6f7550d963309da1b" +checksum = "1053b5e587e6fa40ce5a79ea27957b04ba660baa02b28b7436f64850152234f1" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", @@ -1743,27 +1743,27 @@ dependencies = [ [[package]] name = "aws-smithy-json" -version = "0.61.5" +version = "0.61.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaa31b350998e703e9826b2104dd6f63be0508666e1aba88137af060e8944047" +checksum = "cff418fc8ec5cadf8173b10125f05c2e7e1d46771406187b2c878557d4503390" dependencies = [ "aws-smithy-types", ] [[package]] name = "aws-smithy-observability" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9364d5989ac4dd918e5cc4c4bdcc61c9be17dcd2586ea7f69e348fc7c6cab393" +checksum = "2d1881b1ea6d313f9890710d65c158bdab6fb08c91ea825f74c1c8c357baf4cc" dependencies = [ "aws-smithy-runtime-api", ] [[package]] name = "aws-smithy-query" -version = "0.60.7" +version = "0.60.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fbd61ceb3fe8a1cb7352e42689cec5335833cd9f94103a61e98f9bb61c64bb" +checksum = "d28a63441360c477465f80c7abac3b9c4d075ca638f982e605b7dc2a2c7156c9" dependencies = [ "aws-smithy-types", "urlencoding", @@ -1771,9 +1771,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fa63ad37685ceb7762fa4d73d06f1d5493feb88e3f27259b9ed277f4c01b185" +checksum = "40ab99739082da5347660c556689256438defae3bcefd66c52b095905730e404" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -1795,9 +1795,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime-api" -version = "1.9.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07f5e0fc8a6b3f2303f331b94504bbf754d85488f402d6f1dd7a6080f99afe56" +checksum = "3683c5b152d2ad753607179ed71988e8cfd52964443b4f74fd8e552d0bbfeb46" dependencies = [ "aws-smithy-async", "aws-smithy-types", @@ -1812,9 +1812,9 @@ dependencies = [ [[package]] name = "aws-smithy-types" -version = "1.3.2" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d498595448e43de7f4296b7b7a18a8a02c61ec9349128c80a368f7c3b4ab11a8" +checksum = "9f5b3a7486f6690ba25952cabf1e7d75e34d69eaff5081904a47bc79074d6457" dependencies = [ "base64-simd", "bytes", @@ -1838,18 +1838,18 @@ dependencies = [ [[package]] name = "aws-smithy-xml" -version = "0.60.10" +version = "0.60.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db87b96cb1b16c024980f133968d52882ca0daaee3a086c6decc500f6c99728" +checksum = "e9c34127e8c624bc2999f3b657e749c1393bedc9cd97b92a804db8ced4d2e163" dependencies = [ "xmlparser", ] [[package]] name = "aws-types" -version = "1.3.8" +version = "1.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b069d19bf01e46298eaedd7c6f283fe565a59263e53eebec945f3e6398f42390" +checksum = "e2fd329bf0e901ff3f60425691410c69094dc2a1f34b331f37bfc4e9ac1565a1" dependencies = [ "aws-credential-types", "aws-smithy-async", @@ -2192,9 +2192,9 @@ checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" [[package]] name = "bytemuck" -version = "1.23.2" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" [[package]] name = "byteorder" @@ -2247,9 +2247,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.39" +version = "1.2.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f" +checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb" dependencies = [ "find-msvc-tools", "jobserver", @@ -2906,7 +2906,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -2983,7 +2983,7 @@ dependencies = [ [[package]] name = "fhevm_gateway_bindings" version = "0.1.0-rc14" -source = "git+https://github.com/zama-ai/fhevm.git?rev=70ccca7509de4e5ec9eb897943b861c679e56376#70ccca7509de4e5ec9eb897943b861c679e56376" +source = "git+https://github.com/zama-ai/fhevm.git?rev=08abc732fc9419f86c0896738b9f5f83367ceffb#08abc732fc9419f86c0896738b9f5f83367ceffb" dependencies = [ "alloy", "serde", @@ -3003,9 +3003,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" +checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3" [[package]] name = "fixed-hash" @@ -3027,9 +3027,9 @@ checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] name = "flate2" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9" dependencies = [ "crc32fast", "miniz_oxide", @@ -3626,7 +3626,7 @@ dependencies = [ "tokio", "tokio-rustls 0.26.4", "tower-service", - "webpki-roots 1.0.2", + "webpki-roots 1.0.3", ] [[package]] @@ -4030,7 +4030,6 @@ dependencies = [ "anyhow", "config", "connector-utils", - "dashmap", "fhevm_gateway_bindings", "kms-grpc", "prometheus", @@ -4081,7 +4080,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.53.4", + "windows-targets 0.53.5", ] [[package]] @@ -4098,7 +4097,7 @@ checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ "bitflags 2.9.4", "libc", - "redox_syscall 0.5.17", + "redox_syscall 0.5.18", ] [[package]] @@ -4142,11 +4141,10 @@ checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] @@ -4242,6 +4240,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", ] [[package]] @@ -4622,9 +4621,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -4632,15 +4631,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.17", + "redox_syscall 0.5.18", "smallvec", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -4697,12 +4696,11 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.2" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e0a3a33733faeaf8651dfee72dd0f388f0c8e5ad496a3478fa5a922f49cfa8" +checksum = "989e7521a040efde50c3ab6bbadafbe15ab6dc042686926be59ac35d74607df4" dependencies = [ "memchr", - "thiserror 2.0.12", "ucd-trie", ] @@ -5238,9 +5236,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.17" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ "bitflags 2.9.4", ] @@ -5343,7 +5341,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 1.0.2", + "webpki-roots 1.0.3", ] [[package]] @@ -5518,7 +5516,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -5544,7 +5542,7 @@ dependencies = [ "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.6", + "rustls-webpki 0.103.7", "subtle", "zeroize", ] @@ -5613,9 +5611,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.6" +version = "0.103.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8572f3c2cb9934231157b45499fc41e1f58c589fdfb81a844ba873265e80f8eb" +checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" dependencies = [ "aws-lc-rs", "ring", @@ -5631,9 +5629,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "rusty-fork" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" dependencies = [ "fnv", "quick-error", @@ -5671,7 +5669,7 @@ version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -5899,9 +5897,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.14.1" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c522100790450cf78eeac1507263d0a350d4d5b30df0c8e1fe051a10c22b376e" +checksum = "6093cd8c01b25262b84927e0f7151692158fab02d961e04c979d3903eba7ecc5" dependencies = [ "base64 0.22.1", "chrono", @@ -5910,8 +5908,7 @@ dependencies = [ "indexmap 2.11.4", "schemars 0.9.0", "schemars 1.0.4", - "serde", - "serde_derive", + "serde_core", "serde_json", "serde_with_macros", "time", @@ -5919,9 +5916,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.14.1" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327ada00f7d64abaac1e55a6911e90cf665aa051b9a561c7006c157f4633135e" +checksum = "a7e6c180db0816026a61afa1cff5344fb7ebded7e4d3062772179f2501481c27" dependencies = [ "darling", "proc-macro2", @@ -6053,6 +6050,12 @@ dependencies = [ "wide", ] +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "slab" version = "0.4.11" @@ -7195,9 +7198,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "ucd-trie" @@ -7505,14 +7508,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.2", + "webpki-roots 1.0.3", ] [[package]] name = "webpki-roots" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" +checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" dependencies = [ "rustls-pki-types", ] @@ -7561,9 +7564,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.62.1" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6844ee5416b285084d3d3fffd743b925a6c9385455f64f6d4fa3031c4c2749a9" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", @@ -7574,9 +7577,9 @@ dependencies = [ [[package]] name = "windows-implement" -version = "0.60.1" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edb307e42a74fb6de9bf3a02d9712678b22399c87e6fa869d6dfcd8c1b7754e0" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", @@ -7585,9 +7588,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.59.2" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0abd1ddbc6964ac14db11c7213d6532ef34bd9aa042c2e5935f59d7908b46a5" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", @@ -7596,24 +7599,24 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-result" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ "windows-link", ] [[package]] name = "windows-strings" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ "windows-link", ] @@ -7651,14 +7654,14 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.4", + "windows-targets 0.53.5", ] [[package]] name = "windows-sys" -version = "0.61.1" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ "windows-link", ] @@ -7696,19 +7699,19 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.4" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d42b7b7f66d2a06854650af09cfdf8713e427a439c97ad65a6375318033ac4b" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ "windows-link", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -7725,9 +7728,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" @@ -7743,9 +7746,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" @@ -7761,9 +7764,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" @@ -7773,9 +7776,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" @@ -7791,9 +7794,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" @@ -7809,9 +7812,9 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" @@ -7827,9 +7830,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" @@ -7845,9 +7848,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" diff --git a/kms-connector/Cargo.toml b/kms-connector/Cargo.toml index 41ef061c9f..f52e1eeb2a 100644 --- a/kms-connector/Cargo.toml +++ b/kms-connector/Cargo.toml @@ -18,7 +18,7 @@ gw-listener.path = "crates/gw-listener" kms-worker.path = "crates/kms-worker" tx-sender.path = "crates/tx-sender" connector-utils.path = "crates/utils" -fhevm_gateway_bindings = { git = "https://github.com/zama-ai/fhevm.git", rev = "70ccca7509de4e5ec9eb897943b861c679e56376", default-features = false } +fhevm_gateway_bindings = { git = "https://github.com/zama-ai/fhevm.git", rev = "08abc732fc9419f86c0896738b9f5f83367ceffb", default-features = false } kms-grpc = { git = "https://github.com/zama-ai/kms.git", tag = "v0.12.0", default-features = true } bc2wrap = { git = "https://github.com/zama-ai/kms.git", tag = "v0.12.0", default-features = true } tfhe = "=1.4.0-alpha.3" @@ -45,7 +45,6 @@ clap = { version = "=4.5.47", default-features = true, features = [ "derive", ] } config = { version = "=0.15.15", default-features = false, features = ["toml"] } -dashmap = { version = "=6.1.0", default-features = false } futures = { version = "=0.3.31", default-features = false } git-version = { version = "=0.3.9", default-features = false } opentelemetry = "=0.30.0" diff --git a/kms-connector/config/kms-worker.toml b/kms-connector/config/kms-worker.toml index 8d0b38cc4d..72c23b0496 100644 --- a/kms-connector/config/kms-worker.toml +++ b/kms-connector/config/kms-worker.toml @@ -15,10 +15,6 @@ chain_id = 54321 # Ex: KMS_CONNECTOR_KMS_CORE_ENDPOINTS="http://[::1]:50051,http://[::1]:50052" kms_core_endpoints = ["http://[::1]:50051"] -# Gateway WebSocket RPC URL endpoint (required) -# ENV: KMS_CONNECTOR_GATEWAY_URL -gateway_url = "ws://localhost:8545" - # URL of the KMS Connector internal database (required) # Format: see https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING-URIS # ENV: KMS_CONNECTOR_DATABASE_URL @@ -37,19 +33,6 @@ address = "0xF0bFB159C7381F7CB332586004d8247252C5b816" # ENV: KMS_CONNECTOR_DECRYPTION_DOMAIN_VERSION # domain_version = "1" -# Configuration of the GatewayConfig contract (required) -[gateway_config_contract] -# Address of the GatewayConfig contract (required) -# Format: hex string with 0x prefix -# ENV: KMS_CONNECTOR_GATEWAY_CONFIG_CONTRACT__ADDRESS -address = "0x5ffdaAB0373E62E2ea2944776209aEf29E631A64" -# EIP-712 domain name for GatewayConfig contract (optional, defaults to "GatewayConfig") -# ENV: KMS_CONNECTOR_GATEWAY_CONFIG_CONTRACT__DOMAIN_NAME -# domain_name = "GatewayConfig" -# EIP-712 domain version for GatewayConfig contract (optional, defaults to "1") -# ENV: KMS_CONNECTOR_GATEWAY_CONFIG_CONTRACT__DOMAIN_VERSION -# domain_version = "1" - # Configuration of the KMSGeneration contract (required) [kms_generation_contract] # Address of the KMSGeneration contract (required) diff --git a/kms-connector/connector-db/migrations/20250902144114_update_sns_ciphertext.sql b/kms-connector/connector-db/migrations/20250902144114_update_sns_ciphertext.sql new file mode 100644 index 0000000000..185230e90e --- /dev/null +++ b/kms-connector/connector-db/migrations/20250902144114_update_sns_ciphertext.sql @@ -0,0 +1,2 @@ +ALTER TYPE sns_ciphertext_material DROP ATTRIBUTE coprocessor_tx_sender_addresses CASCADE; +ALTER TYPE sns_ciphertext_material ADD ATTRIBUTE storage_urls TEXT[] CASCADE; diff --git a/kms-connector/crates/gw-listener/src/core/event_publisher.rs b/kms-connector/crates/gw-listener/src/core/event_publisher.rs index 12b5ad0e2b..df7a16c3da 100644 --- a/kms-connector/crates/gw-listener/src/core/event_publisher.rs +++ b/kms-connector/crates/gw-listener/src/core/event_publisher.rs @@ -58,7 +58,8 @@ impl DbEventPublisher { let sns_ciphertexts_db = request .snsCtMaterials .iter() - .map(SnsCiphertextMaterialDbItem::from) + .zip(request.storageUrls) + .map(|(sns_ct, url)| SnsCiphertextMaterialDbItem::new(sns_ct, url)) .collect::>(); sqlx::query!( @@ -79,7 +80,8 @@ impl DbEventPublisher { let sns_ciphertexts_db = request .snsCtMaterials .iter() - .map(SnsCiphertextMaterialDbItem::from) + .zip(request.storageUrls) + .map(|(sns_ct, url)| SnsCiphertextMaterialDbItem::new(sns_ct, url)) .collect::>(); sqlx::query!( diff --git a/kms-connector/crates/gw-listener/tests/integration_test.rs b/kms-connector/crates/gw-listener/tests/integration_test.rs index e6368bdf84..ff5787ac58 100644 --- a/kms-connector/crates/gw-listener/tests/integration_test.rs +++ b/kms-connector/crates/gw-listener/tests/integration_test.rs @@ -229,7 +229,7 @@ async fn test_publish_keygen() -> anyhow::Result<()> { let prep_id = U256::from_le_bytes(row.try_get::<[u8; 32], _>("prep_keygen_id")?); let key_id = U256::from_le_bytes(row.try_get::<[u8; 32], _>("key_id")?); assert_eq!(prep_id, rand_prep_id); - assert_eq!(key_id, KEY_COUNTER + U256::ONE); + assert_eq!(key_id, U256::ZERO); info!("Event successfully stored! Stopping GatewayListener..."); cancel_token.cancel(); @@ -407,6 +407,7 @@ const PREP_KEY_COUNTER: U256 = U256::from_be_bytes([ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); +#[allow(dead_code)] const KEY_COUNTER: U256 = U256::from_be_bytes([ 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); diff --git a/kms-connector/crates/kms-worker/Cargo.toml b/kms-connector/crates/kms-worker/Cargo.toml index 891f57a96e..105b36c310 100644 --- a/kms-connector/crates/kms-worker/Cargo.toml +++ b/kms-connector/crates/kms-worker/Cargo.toml @@ -14,7 +14,6 @@ actix-web.workspace = true alloy.workspace = true anyhow.workspace = true config.workspace = true -dashmap.workspace = true kms-grpc.workspace = true prometheus.workspace = true serde.workspace = true diff --git a/kms-connector/crates/kms-worker/src/core/config/parsed.rs b/kms-connector/crates/kms-worker/src/core/config/parsed.rs index f265baeb42..e74ab1e568 100644 --- a/kms-connector/crates/kms-worker/src/core/config/parsed.rs +++ b/kms-connector/crates/kms-worker/src/core/config/parsed.rs @@ -19,16 +19,12 @@ pub struct Config { pub database_pool_size: u32, /// The timeout for polling the database for events. pub database_polling_timeout: Duration, - /// The Gateway RPC endpoint. - pub gateway_url: String, /// The KMS Core endpoints. pub kms_core_endpoints: Vec, /// The Chain ID of the Gateway. pub chain_id: u64, /// The `Decryption` contract configuration. pub decryption_contract: ContractConfig, - /// The `GatewayConfig` contract configuration. - pub gateway_config_contract: ContractConfig, /// The `KMSGeneration` contract configuration. pub kms_generation_contract: ContractConfig, /// The service name used for tracing. @@ -86,16 +82,9 @@ impl Config { .map_err(|e| Error::InvalidConfig(e.to_string()))?; let decryption_contract = ContractConfig::parse("Decryption", raw_config.decryption_contract)?; - let gateway_config_contract = - ContractConfig::parse("GatewayConfig", raw_config.gateway_config_contract)?; let kms_generation_contract = ContractConfig::parse("KMSGeneration", raw_config.kms_generation_contract)?; - // Validate critical configuration parts - if raw_config.gateway_url.is_empty() { - return Err(Error::EmptyField("Gateway URL".to_string())); - } - let kms_core_endpoints; if raw_config.kms_core_endpoints.is_empty() { if let Some(kms_core_endpoint) = raw_config.kms_core_endpoint { @@ -121,11 +110,9 @@ impl Config { database_url: raw_config.database_url, database_pool_size: raw_config.database_pool_size, database_polling_timeout, - gateway_url: raw_config.gateway_url, kms_core_endpoints, chain_id: raw_config.chain_id, decryption_contract, - gateway_config_contract, kms_generation_contract, service_name: raw_config.service_name, events_batch_size: raw_config.events_batch_size, @@ -162,11 +149,9 @@ mod tests { fn cleanup_env_vars() { unsafe { env::remove_var("KMS_CONNECTOR_DATABASE_URL"); - env::remove_var("KMS_CONNECTOR_GATEWAY_URL"); env::remove_var("KMS_CONNECTOR_KMS_CORE_ENDPOINTS"); env::remove_var("KMS_CONNECTOR_CHAIN_ID"); env::remove_var("KMS_CONNECTOR_DECRYPTION_CONTRACT__ADDRESS"); - env::remove_var("KMS_CONNECTOR_GATEWAY_CONFIG_CONTRACT__ADDRESS"); env::remove_var("KMS_CONNECTOR_KMS_GENERATION_CONTRACT__ADDRESS"); env::remove_var("KMS_CONNECTOR_SERVICE_NAME"); env::remove_var("KMS_CONNECTOR_S3_CONFIG__REGION"); @@ -192,7 +177,6 @@ mod tests { let config = Config::from_env_and_file(Some(temp_file.path())).unwrap(); // Compare fields - assert_eq!(raw_config.gateway_url, config.gateway_url); assert_eq!(raw_config.kms_core_endpoints, config.kms_core_endpoints); assert_eq!(raw_config.chain_id, config.chain_id); assert_eq!( @@ -200,8 +184,8 @@ mod tests { config.decryption_contract.address, ); assert_eq!( - Address::from_str(&raw_config.gateway_config_contract.address).unwrap(), - config.gateway_config_contract.address, + Address::from_str(&raw_config.kms_generation_contract.address).unwrap(), + config.kms_generation_contract.address, ); assert_eq!(raw_config.kms_core_endpoints, config.kms_core_endpoints); assert_eq!(raw_config.service_name, config.service_name); @@ -225,14 +209,6 @@ mod tests { raw_config.decryption_contract.domain_version.unwrap(), config.decryption_contract.domain_version, ); - assert_eq!( - raw_config.gateway_config_contract.domain_name.unwrap(), - config.gateway_config_contract.domain_name, - ); - assert_eq!( - raw_config.gateway_config_contract.domain_version.unwrap(), - config.gateway_config_contract.domain_version, - ); assert_eq!(raw_config.s3_config, config.s3_config); } @@ -247,7 +223,6 @@ mod tests { "KMS_CONNECTOR_DATABASE_URL", "postgres://postgres:postgres@localhost", ); - env::set_var("KMS_CONNECTOR_GATEWAY_URL", "ws://localhost:9545"); env::set_var( "KMS_CONNECTOR_KMS_CORE_ENDPOINTS", "http://localhost:50053,http://localhost:50054", @@ -257,10 +232,6 @@ mod tests { "KMS_CONNECTOR_DECRYPTION_CONTRACT__ADDRESS", "0x5fbdb2315678afecb367f032d93f642f64180aa3", ); - env::set_var( - "KMS_CONNECTOR_GATEWAY_CONFIG_CONTRACT__ADDRESS", - "0x5fbdb2315678afecb367f032d93f642f64180aa3", - ); env::set_var( "KMS_CONNECTOR_KMS_GENERATION_CONTRACT__ADDRESS", "0x5fbdb2315678afecb367f032d93f642f64180aa3", @@ -279,7 +250,6 @@ mod tests { let config = Config::from_env_and_file::<&str>(None).unwrap(); // Verify values - assert_eq!(config.gateway_url, "ws://localhost:9545"); assert_eq!( config.kms_core_endpoints, vec!["http://localhost:50053", "http://localhost:50054"] @@ -289,10 +259,6 @@ mod tests { config.decryption_contract.address, Address::from_str("0x5fbdb2315678afecb367f032d93f642f64180aa3").unwrap() ); - assert_eq!( - config.gateway_config_contract.address, - Address::from_str("0x5fbdb2315678afecb367f032d93f642f64180aa3").unwrap() - ); assert_eq!( config.kms_generation_contract.address, Address::from_str("0x5fbdb2315678afecb367f032d93f642f64180aa3").unwrap() @@ -337,9 +303,6 @@ mod tests { assert_eq!(config.s3_config.as_ref().unwrap().region, "test-region"); assert_eq!(config.s3_config.as_ref().unwrap().bucket, "test-bucket"); - // File values should be used for non-overridden fields - assert_eq!(config.gateway_url, "ws://localhost:8545"); - cleanup_env_vars(); } @@ -351,7 +314,7 @@ mod tests { address: "0x0000".to_string(), ..Default::default() }, - gateway_config_contract: RawContractConfig { + kms_generation_contract: RawContractConfig { address: "0x000010".to_string(), ..Default::default() }, diff --git a/kms-connector/crates/kms-worker/src/core/config/raw.rs b/kms-connector/crates/kms-worker/src/core/config/raw.rs index 330d67aca1..dadf46aedc 100644 --- a/kms-connector/crates/kms-worker/src/core/config/raw.rs +++ b/kms-connector/crates/kms-worker/src/core/config/raw.rs @@ -31,13 +31,11 @@ pub struct RawConfig { pub database_pool_size: u32, #[serde(default = "default_database_polling_timeout_secs")] pub database_polling_timeout_secs: u64, - pub gateway_url: String, #[serde(default)] pub kms_core_endpoints: Vec, pub kms_core_endpoint: Option, pub chain_id: u64, pub decryption_contract: RawContractConfig, - pub gateway_config_contract: RawContractConfig, pub kms_generation_contract: RawContractConfig, #[serde(default = "default_service_name")] pub service_name: String, @@ -139,7 +137,6 @@ impl Default for RawConfig { database_url: "postgres://postgres:postgres@localhost".to_string(), database_pool_size: 16, database_polling_timeout_secs: default_database_polling_timeout_secs(), - gateway_url: "ws://localhost:8545".to_string(), kms_core_endpoints: vec!["http://localhost:50052".to_string()], kms_core_endpoint: None, chain_id: 1, @@ -148,11 +145,6 @@ impl Default for RawConfig { domain_name: Some("Decryption".to_string()), domain_version: Some("1".to_string()), }, - gateway_config_contract: RawContractConfig { - address: "0x0000000000000000000000000000000000000000".to_string(), - domain_name: Some("GatewayConfig".to_string()), - domain_version: Some("1".to_string()), - }, kms_generation_contract: RawContractConfig { address: "0x0000000000000000000000000000000000000000".to_string(), domain_name: Some("KMSGeneration".to_string()), diff --git a/kms-connector/crates/kms-worker/src/core/event_processor/decryption.rs b/kms-connector/crates/kms-worker/src/core/event_processor/decryption.rs index 09778e3a6c..5a436474f8 100644 --- a/kms-connector/crates/kms-worker/src/core/event_processor/decryption.rs +++ b/kms-connector/crates/kms-worker/src/core/event_processor/decryption.rs @@ -8,7 +8,6 @@ use crate::core::{ use alloy::{ hex, primitives::{Address, Bytes, U256}, - providers::Provider, sol_types::Eip712Domain, }; use anyhow::anyhow; @@ -22,19 +21,17 @@ use tracing::info; #[derive(Clone)] /// The struct responsible of processing incoming decryption requests. -pub struct DecryptionProcessor { +pub struct DecryptionProcessor { /// The EIP712 domain of the `Decryption` contract. domain: Eip712Domain, /// The entity used to collect ciphertexts from S3 buckets. - s3_service: S3Service

, + s3_service: S3Service, } -impl

DecryptionProcessor

-where - P: Provider, -{ - pub fn new(config: &Config, s3_service: S3Service

) -> Self { +impl DecryptionProcessor { + pub fn new(config: &Config, s3_service: S3Service) -> Self { + // Create EIP-712 domain using alloy primitives let domain = Eip712Domain { name: Some(Cow::Owned(config.decryption_contract.domain_name.clone())), version: Some(Cow::Owned( @@ -52,6 +49,7 @@ where &self, decryption_id: U256, sns_materials: Vec, + storage_urls: Vec>, extra_data: Vec, user_decrypt_data: Option, ) -> anyhow::Result { @@ -64,7 +62,9 @@ where })?; info!("Extracted key_id {key_id} from snsCtMaterials[0]"); - let ciphertexts = self.prepare_ciphertexts(&key_id, sns_materials).await?; + let ciphertexts = self + .prepare_ciphertexts(&key_id, sns_materials, storage_urls) + .await?; let domain_msg = alloy_to_protobuf_domain(&self.domain)?; info!("Eip712Domain constructed: {domain_msg:?}",); @@ -108,10 +108,11 @@ where &self, key_id: &str, sns_materials: Vec, + storage_urls: Vec>, ) -> anyhow::Result> { let sns_ciphertext_materials = self .s3_service - .retrieve_sns_ciphertext_materials(sns_materials) + .retrieve_sns_ciphertext_materials(sns_materials, storage_urls) .await; if sns_ciphertext_materials.is_empty() { diff --git a/kms-connector/crates/kms-worker/src/core/event_processor/processor.rs b/kms-connector/crates/kms-worker/src/core/event_processor/processor.rs index 0541bfa5b7..3474d981ac 100644 --- a/kms-connector/crates/kms-worker/src/core/event_processor/processor.rs +++ b/kms-connector/crates/kms-worker/src/core/event_processor/processor.rs @@ -3,7 +3,6 @@ use crate::core::event_processor::{ decryption::{DecryptionProcessor, UserDecryptionExtraData}, kms::KMSGenerationProcessor, }; -use alloy::providers::Provider; use anyhow::anyhow; use connector_utils::types::{GatewayEvent, KmsGrpcRequest, KmsResponse}; use sqlx::{Pool, Postgres}; @@ -23,12 +22,12 @@ pub trait EventProcessor: Send { /// Struct that processes Gateway's events coming from a `Postgres` database. #[derive(Clone)] -pub struct DbEventProcessor { +pub struct DbEventProcessor { /// The GRPC client used to communicate with the KMS Core. kms_client: KmsClient, /// The entity used to process decryption requests. - decryption_processor: DecryptionProcessor

, + decryption_processor: DecryptionProcessor, /// The entity used to process key management requests. kms_generation_processor: KMSGenerationProcessor, @@ -37,7 +36,7 @@ pub struct DbEventProcessor { db_pool: Pool, } -impl EventProcessor for DbEventProcessor

{ +impl EventProcessor for DbEventProcessor { type Event = GatewayEvent; #[tracing::instrument(skip_all)] @@ -68,10 +67,10 @@ pub enum ProcessingError { Recoverable(anyhow::Error), } -impl DbEventProcessor

{ +impl DbEventProcessor { pub fn new( kms_client: KmsClient, - decryption_processor: DecryptionProcessor

, + decryption_processor: DecryptionProcessor, kms_generation_processor: KMSGenerationProcessor, db_pool: Pool, ) -> Self { @@ -95,6 +94,7 @@ impl DbEventProcessor

{ .prepare_decryption_request( req.decryptionId, req.snsCtMaterials, + req.storageUrls, req.extraData.into(), None, ) @@ -105,6 +105,7 @@ impl DbEventProcessor

{ .prepare_decryption_request( req.decryptionId, req.snsCtMaterials, + req.storageUrls, req.extraData.into(), Some(UserDecryptionExtraData::new(req.userAddress, req.publicKey)), ) diff --git a/kms-connector/crates/kms-worker/src/core/event_processor/s3.rs b/kms-connector/crates/kms-worker/src/core/event_processor/s3.rs index b720dbbc98..5989fd4b14 100644 --- a/kms-connector/crates/kms-worker/src/core/event_processor/s3.rs +++ b/kms-connector/crates/kms-worker/src/core/event_processor/s3.rs @@ -2,31 +2,21 @@ use crate::{ core::config::{Config, S3Config}, monitoring::metrics::{S3_CIPHERTEXT_RETRIEVAL_COUNTER, S3_CIPHERTEXT_RETRIEVAL_ERRORS}, }; -use alloy::{hex, primitives::Address, providers::Provider, transports::http::reqwest}; +use alloy::{hex, transports::http::reqwest}; use anyhow::anyhow; use connector_utils::types::fhe::extract_fhe_type_from_handle; -use dashmap::DashMap; -use fhevm_gateway_bindings::{ - decryption::Decryption::SnsCiphertextMaterial, - gateway_config::GatewayConfig::{self, GatewayConfigInstance}, -}; +use fhevm_gateway_bindings::decryption::Decryption::SnsCiphertextMaterial; use kms_grpc::kms::v1::{CiphertextFormat, TypedCiphertext}; use sha3::{Digest, Keccak256}; -use std::{sync::LazyLock, time::Duration}; +use std::time::Duration; use tracing::{debug, error, info, warn}; -/// Global cache for coprocessor S3 bucket URLs. -static S3_BUCKET_CACHE: LazyLock> = LazyLock::new(DashMap::new); - /// The header used to retrieve the ciphertext format from the S3 HTTP response. const CT_FORMAT_HEADER: &str = "x-amz-meta-Ct-Format"; /// Struct used to fetch ciphertext from S3 buckets. #[derive(Clone)] -pub struct S3Service { - /// The instance of the `GatewayConfig` contract. - gateway_config_contract: GatewayConfigInstance

, - +pub struct S3Service { /// An optional S3 bucket fallback configuration. fallback_config: Option, @@ -37,208 +27,47 @@ pub struct S3Service { s3_connect_timeout: Duration, } -impl

S3Service

-where - P: Provider, -{ - pub fn new(config: &Config, provider: P) -> Self { - let gateway_config_contract = - GatewayConfig::new(config.gateway_config_contract.address, provider); - +impl S3Service { + pub fn new(config: &Config) -> Self { Self { - gateway_config_contract, fallback_config: config.s3_config.clone(), s3_ciphertext_retrieval_retries: config.s3_ciphertext_retrieval_retries, s3_connect_timeout: config.s3_connect_timeout, } } - /// Retrieves the S3 bucket URL for a coprocessor from the GatewayConfig contract. - async fn get_s3_url(&self, copro_addr: Address) -> Option { - info!( - "Attempting to get S3 bucket URL for coprocessor {:?}", - copro_addr - ); - - // Try to find a cached S3 bucket URL for any of the coprocessors - if let Some(url) = S3_BUCKET_CACHE.get(&copro_addr) { - info!( - "CACHE HIT: Using cached S3 bucket URL for coprocessor {:?}: {}", - copro_addr, - url.value() - ); - return Some(url.value().clone()); - } - - // If no cached URL found, query the GatewayConfig contract for the first available coprocessor - info!( - "CACHE MISS: Querying GatewayConfig contract for coprocessor {:?} S3 bucket URL", - copro_addr - ); - - // Call getCoprocessor method to retrieve S3 bucket URL of the coprocessor - let s3_bucket_url = match self - .gateway_config_contract - .getCoprocessor(copro_addr) - .call() - .await - { - Ok(coprocessor) => coprocessor.s3BucketUrl.to_string(), - Err(e) => { - warn!( - "GatewayConfig contract call failed for coprocessor {:?}: {}", - copro_addr, e - ); - return None; - } - }; - - if s3_bucket_url.is_empty() { - warn!("Coprocessor {:?} returned empty S3 bucket URL", copro_addr); - return None; - } - - // Cache the URL for future use - info!( - "CACHE UPDATE: Adding S3 bucket URL for coprocessor {:?}: {}", - copro_addr, s3_bucket_url - ); - S3_BUCKET_CACHE.insert(copro_addr, s3_bucket_url.clone()); - - // Log the updated cache state - log_cache("S3 cache state after insert"); - - info!( - "Successfully retrieved and cached S3 bucket URL for coprocessor {:?}: {}", - copro_addr, s3_bucket_url - ); - Some(s3_bucket_url) - } - - /// Prefetches and caches S3 bucket URLs to return a list of coprocessor s3 urls. - async fn prefetch_coprocessor_buckets( - &self, - coprocessor_addresses: Vec

, - ) -> Vec { - info!( - "S3 PREFETCH START: Prefetching S3 bucket URLs for {} coprocessors", - coprocessor_addresses.len() - ); - log_cache("S3 cache state before prefetching"); - - let mut s3_urls = Vec::new(); - let mut success_count = 0; - let mut cache_hit_count = 0; - let mut cache_miss_count = 0; - let mut fallback_used = false; - - for (idx, address) in coprocessor_addresses.iter().enumerate() { - info!( - "Processing coprocessor {}/{}: {:?}", - idx + 1, - coprocessor_addresses.len(), - address - ); - - // Add the cached URL to our result list - if let Some(url) = S3_BUCKET_CACHE.get(address) { - info!( - "CACHE HIT: S3 bucket URL for coprocessor {:?} already cached", - address - ); - cache_hit_count += 1; - success_count += 1; - - s3_urls.push(url.value().clone()); - continue; - } - - cache_miss_count += 1; - info!( - "CACHE MISS: Fetching S3 bucket URL for coprocessor {:?}", - address - ); - - match self.get_s3_url(*address).await { - Some(s3_url) => { - info!( - "Successfully fetched S3 bucket URL for coprocessor {:?}: {}", - address, s3_url - ); - success_count += 1; - s3_urls.push(s3_url); - } - None => { - warn!( - "Failed to prefetch S3 bucket URL for coprocessor {:?}", - address - ); - } - }; - } - log_cache("S3 cache state after prefetching"); - - // If we couldn't get any URLs but have a fallback config, use it - if s3_urls.is_empty() { - if let Some(config) = &self.fallback_config { - if !config.bucket.is_empty() { - let fallback_url = format!( - "https://s3.{}.amazonaws.com/{}", - config.region, config.bucket - ); - warn!( - "All S3 URL retrievals failed. Using global fallback S3 URL: {}", - fallback_url - ); - s3_urls.push(fallback_url); - success_count += 1; - fallback_used = true; - } else { - warn!( - "All S3 URL retrievals failed and fallback bucket is empty. No URLs available." - ); - } - } else { - warn!( - "All S3 URL retrievals failed and no fallback configuration available. No URLs available." - ); - } - } - - info!( - "S3 PREFETCH COMPLETE: Successfully prefetched {}/{} S3 bucket URLs (cache hits: {}, cache misses: {}, fallback used: {})", - success_count, - coprocessor_addresses.len(), - cache_hit_count, - cache_miss_count, - fallback_used - ); - s3_urls - } - /// Helper method to retrieve ciphertext materials from S3. pub async fn retrieve_sns_ciphertext_materials( &self, sns_materials: Vec, + mut s3_urls_matrix: Vec>, ) -> Vec { - let mut sns_ciphertext_materials = Vec::new(); + fill_urls_if_needed( + &sns_materials, + &mut s3_urls_matrix, + self.fallback_config.as_ref(), + ); - for sns_material in sns_materials { - // Get S3 URL and retrieve ciphertext + let mut sns_ciphertext_materials = Vec::new(); + for (sns_material, mut s3_urls) in sns_materials.into_iter().zip(s3_urls_matrix) { // 1. For each SNS material, we try to retrieve its ciphertext from multiple possible S3 URLs - // 1.1. We try to fetch the ciphertext for `self.s3_ct_retrieval_retries` times for each S3 URL + // 1.1. We try to fetch the ciphertext for `self.s3_ciphertext_retrieval_retries` times for each S3 URL // 2. Once we successfully retrieve a ciphertext from any of those URLs, we break out of the S3 URLs loop // 3. Then we continue processing the next SNS material in the outer loop - let s3_urls = self - .prefetch_coprocessor_buckets(sns_material.coprocessorTxSenderAddresses) - .await; let handle = sns_material.ctHandle.to_vec(); let ct_digest = sns_material.snsCiphertextDigest.as_slice(); let ct_digest_hex = hex::encode(ct_digest); if s3_urls.is_empty() { - warn!("No S3 URLs found for ciphertext digest {ct_digest_hex}",); - continue; + if let Some(fallback_s3_config) = &self.fallback_config { + warn!( + "No S3 URLs found for ciphertext digest {ct_digest_hex}, using S3 fallback config" + ); + s3_urls.push(extract_fallback_url(fallback_s3_config)); + } else { + warn!("No S3 URLs found for ciphertext digest {ct_digest_hex}"); + continue; + } } match self @@ -255,7 +84,7 @@ where sns_ciphertext_materials } - /// Retrieves a ciphertext from S3 with `self.s3_ct_retrieval_retries` retries. + /// Retrieves a ciphertext from S3 with `self.s3_ciphertext_retrieval_retries` retries. pub async fn retrieve_s3_ciphertext_with_retry( &self, s3_urls: Vec, @@ -382,20 +211,6 @@ where } } -/// Logs the current state of the S3 bucket cache. -fn log_cache(prefix: &str) { - let cache_size = S3_BUCKET_CACHE.len(); - info!("{prefix}: {cache_size} entries"); - - if cache_size > 0 { - let mut cache_entries = Vec::new(); - for entry in S3_BUCKET_CACHE.iter() { - cache_entries.push(format!("{:?}: {}", entry.key(), entry.value())); - } - debug!("S3_BUCKET_CACHE contents: {}", cache_entries.join(", ")); - } -} - /// Computes Keccak256 digest of a byte array. pub fn compute_digest(ct: &[u8]) -> Vec { debug!("Computing Keccak256 digest for {} bytes of data", ct.len()); @@ -406,6 +221,38 @@ pub fn compute_digest(ct: &[u8]) -> Vec { result } +fn fill_urls_if_needed( + sns_materials: &[SnsCiphertextMaterial], + s3_urls_matrix: &mut Vec>, + fallback_config: Option<&S3Config>, +) { + if sns_materials.len() > s3_urls_matrix.len() { + warn!( + "Not enough URL entries ({}) compared to ciphertexts ({}). Will try to use default config...", + s3_urls_matrix.len(), + sns_materials.len(), + ); + + s3_urls_matrix.extend(vec![ + fallback_config + .map(|c| vec![extract_fallback_url(c)]) + .unwrap_or_default(); + sns_materials.len() - s3_urls_matrix.len() + ]); + } +} + +pub fn extract_fallback_url(s3_config: &S3Config) -> String { + if let Some(fallback_s3_endpoint) = s3_config.endpoint.clone() { + fallback_s3_endpoint + } else { + format!( + "https://s3.{}.amazonaws.com/{}", + s3_config.region, s3_config.bucket + ) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/kms-connector/crates/kms-worker/src/core/kms_worker.rs b/kms-connector/crates/kms-worker/src/core/kms_worker.rs index 25e983b61d..67743997f3 100644 --- a/kms-connector/crates/kms-worker/src/core/kms_worker.rs +++ b/kms-connector/crates/kms-worker/src/core/kms_worker.rs @@ -11,10 +11,7 @@ use crate::{ }, monitoring::health::{KmsHealthClient, State}, }; -use connector_utils::{ - conn::{GatewayProvider, connect_to_db, connect_to_gateway}, - tasks::spawn_with_limit, -}; +use connector_utils::{conn::connect_to_db, tasks::spawn_with_limit}; use std::fmt::Display; use tokio_util::sync::CancellationToken; use tracing::{error, info, warn}; @@ -93,17 +90,16 @@ where } } -impl KmsWorker, DbKmsResponsePublisher> { +impl KmsWorker { /// Creates a new `KmsWorker` instance from a valid `Config`. - pub async fn from_config(config: Config) -> anyhow::Result<(Self, State)> { + pub async fn from_config(config: Config) -> anyhow::Result<(Self, State)> { let db_pool = connect_to_db(&config.database_url, config.database_pool_size).await?; - let provider = connect_to_gateway(&config.gateway_url, config.chain_id).await?; let kms_client = KmsClient::connect(&config).await?; let kms_health_client = KmsHealthClient::connect(&config.kms_core_endpoints).await?; let event_picker = DbEventPicker::connect(db_pool.clone(), &config).await?; - let s3_service = S3Service::new(&config, provider.clone()); + let s3_service = S3Service::new(&config); let decryption_processor = DecryptionProcessor::new(&config, s3_service); let kms_generation_processor = KMSGenerationProcessor::new(&config); let event_processor = DbEventProcessor::new( @@ -114,12 +110,7 @@ impl KmsWorker, DbKmsResponsePu ); let response_publisher = DbKmsResponsePublisher::new(db_pool.clone()); - let state = State::new( - db_pool, - provider, - kms_health_client, - config.healthcheck_timeout, - ); + let state = State::new(db_pool, kms_health_client, config.healthcheck_timeout); let kms_worker = KmsWorker::new(event_picker, event_processor, response_publisher); Ok((kms_worker, state)) } diff --git a/kms-connector/crates/kms-worker/src/monitoring/health.rs b/kms-connector/crates/kms-worker/src/monitoring/health.rs index 9dfedf3724..e383cc60bb 100644 --- a/kms-connector/crates/kms-worker/src/monitoring/health.rs +++ b/kms-connector/crates/kms-worker/src/monitoring/health.rs @@ -1,6 +1,5 @@ use actix_web::http::StatusCode; -use alloy::providers::Provider; -use connector_utils::monitoring::health::{Healthcheck, database_healthcheck, gateway_healthcheck}; +use connector_utils::monitoring::health::{Healthcheck, database_healthcheck}; use serde::{Deserialize, Serialize}; use sqlx::{Pool, Postgres}; use std::time::Duration; @@ -13,36 +12,31 @@ use tonic_health::pb::{HealthCheckRequest, HealthCheckResponse, health_client::H #[derive(Clone)] /// The struct used to monitor the state of the `KmsWorker`. -pub struct State

{ +pub struct State { db_pool: Pool, - provider: P, kms_health_client: KmsHealthClient, healthcheck_timeout: Duration, } -impl State

{ +impl State { pub fn new( db_pool: Pool, - provider: P, kms_health_client: KmsHealthClient, healthcheck_timeout: Duration, ) -> Self { Self { db_pool, - provider, kms_health_client, healthcheck_timeout, } } } -impl Healthcheck for State

{ +impl Healthcheck for State { async fn healthcheck(&self) -> actix_web::HttpResponse { let mut errors = vec![]; let database_connected = database_healthcheck(&self.db_pool, self.healthcheck_timeout, &mut errors).await; - let gateway_connected = - gateway_healthcheck(&self.provider, self.healthcheck_timeout, &mut errors).await; let mut kms_core_connected = true; let kms_healtcheck_results = self.kms_health_client.check(self.healthcheck_timeout).await; @@ -69,7 +63,6 @@ impl Healthcheck for State

{ let status = HealthStatus { healthy, database_connected, - gateway_connected, kms_core_connected, details: errors.join("; "), }; @@ -89,8 +82,6 @@ pub struct HealthStatus { pub healthy: bool, /// Database connection status. pub database_connected: bool, - /// Gateway provider connection status. - pub gateway_connected: bool, /// KMS Core connections status. pub kms_core_connected: bool, /// Details about any issues encountered during healthcheck. diff --git a/kms-connector/crates/kms-worker/tests/event_picker/parallel.rs b/kms-connector/crates/kms-worker/tests/event_picker/parallel.rs index c3098cac5c..556b4e2431 100644 --- a/kms-connector/crates/kms-worker/tests/event_picker/parallel.rs +++ b/kms-connector/crates/kms-worker/tests/event_picker/parallel.rs @@ -1,5 +1,3 @@ -use std::time::Duration; - use alloy::primitives::U256; use connector_utils::{ tests::{rand::rand_sns_ct, setup::TestInstanceBuilder}, @@ -7,6 +5,7 @@ use connector_utils::{ }; use fhevm_gateway_bindings::decryption::Decryption::PublicDecryptionRequest; use kms_worker::core::{Config, DbEventPicker, EventPicker}; +use std::time::Duration; use tokio::time::timeout; #[tokio::test] @@ -18,11 +17,7 @@ async fn test_parallel_event_picker_one_events() -> anyhow::Result<()> { let mut event_picker1 = DbEventPicker::connect(test_instance.db().clone(), &config).await?; let id0 = U256::ZERO; - let sns_ct = vec![rand_sns_ct()]; - let sns_ciphertexts_db = sns_ct - .iter() - .map(SnsCiphertextMaterialDbItem::from) - .collect::>(); + let sns_ciphertexts_db = vec![rand_sns_ct()]; println!("Inserting only one PublicDecryptionRequest for two event picker..."); sqlx::query!( @@ -47,7 +42,11 @@ async fn test_parallel_event_picker_one_events() -> anyhow::Result<()> { events0, vec![GatewayEvent::PublicDecryption(PublicDecryptionRequest { decryptionId: id0, - snsCtMaterials: sns_ct.clone(), + storageUrls: sns_ciphertexts_db + .iter() + .map(|s| s.storage_urls.clone()) + .collect(), + snsCtMaterials: sns_ciphertexts_db.iter().map(|s| s.into()).collect(), extraData: vec![].into() })] ); @@ -68,11 +67,7 @@ async fn test_parallel_event_picker_two_events() -> anyhow::Result<()> { let id0 = U256::ZERO; let id1 = U256::ONE; - let sns_ct = vec![rand_sns_ct()]; - let sns_ciphertexts_db = sns_ct - .iter() - .map(SnsCiphertextMaterialDbItem::from) - .collect::>(); + let sns_ciphertexts_db = vec![rand_sns_ct()]; println!("Inserting two PublicDecryptionRequest for two event picker..."); sqlx::query!( @@ -86,7 +81,7 @@ async fn test_parallel_event_picker_two_events() -> anyhow::Result<()> { sqlx::query!( "INSERT INTO public_decryption_requests VALUES ($1, $2, $3) ON CONFLICT DO NOTHING", id1.as_le_slice(), - sns_ciphertexts_db as Vec, + sns_ciphertexts_db.clone() as Vec, vec![], ) .execute(test_instance.db()) @@ -101,7 +96,11 @@ async fn test_parallel_event_picker_two_events() -> anyhow::Result<()> { events0, vec![GatewayEvent::PublicDecryption(PublicDecryptionRequest { decryptionId: id0, - snsCtMaterials: sns_ct.clone(), + storageUrls: sns_ciphertexts_db + .iter() + .map(|s| s.storage_urls.clone()) + .collect(), + snsCtMaterials: sns_ciphertexts_db.iter().map(|s| s.into()).collect(), extraData: vec![].into(), })] ); @@ -109,7 +108,11 @@ async fn test_parallel_event_picker_two_events() -> anyhow::Result<()> { events1, vec![GatewayEvent::PublicDecryption(PublicDecryptionRequest { decryptionId: id1, - snsCtMaterials: sns_ct, + storageUrls: sns_ciphertexts_db + .iter() + .map(|s| s.storage_urls.clone()) + .collect(), + snsCtMaterials: sns_ciphertexts_db.iter().map(|s| s.into()).collect(), extraData: vec![].into(), })] ); diff --git a/kms-connector/crates/kms-worker/tests/event_picker/simple.rs b/kms-connector/crates/kms-worker/tests/event_picker/simple.rs index e44f58e3dc..cd148c4d51 100644 --- a/kms-connector/crates/kms-worker/tests/event_picker/simple.rs +++ b/kms-connector/crates/kms-worker/tests/event_picker/simple.rs @@ -24,17 +24,13 @@ async fn test_pick_public_decryption() -> anyhow::Result<()> { DbEventPicker::connect(test_instance.db().clone(), &Config::default()).await?; let decryption_id = rand_u256(); - let sns_ct = vec![rand_sns_ct()]; - let sns_ciphertexts_db = sns_ct - .iter() - .map(SnsCiphertextMaterialDbItem::from) - .collect::>(); + let sns_ciphertexts_db = vec![rand_sns_ct()]; info!("Triggering Postgres notification with PublicDecryptionRequest insertion..."); sqlx::query!( "INSERT INTO public_decryption_requests VALUES ($1, $2, $3) ON CONFLICT DO NOTHING", decryption_id.as_le_slice(), - sns_ciphertexts_db as Vec, + sns_ciphertexts_db.clone() as Vec, vec![], ) .execute(test_instance.db()) @@ -48,7 +44,11 @@ async fn test_pick_public_decryption() -> anyhow::Result<()> { events, vec![GatewayEvent::PublicDecryption(PublicDecryptionRequest { decryptionId: decryption_id, - snsCtMaterials: sns_ct, + storageUrls: sns_ciphertexts_db + .iter() + .map(|s| s.storage_urls.clone()) + .collect(), + snsCtMaterials: sns_ciphertexts_db.iter().map(|s| s.into()).collect(), extraData: vec![].into(), })] ); @@ -64,19 +64,15 @@ async fn test_pick_user_decryption() -> anyhow::Result<()> { DbEventPicker::connect(test_instance.db().clone(), &Config::default()).await?; let decryption_id = rand_u256(); - let sns_ct = vec![rand_sns_ct()]; + let sns_ciphertexts_db = vec![rand_sns_ct()]; let user_address = rand_address(); let public_key = rand_public_key(); - let sns_ciphertexts_db = sns_ct - .iter() - .map(SnsCiphertextMaterialDbItem::from) - .collect::>(); info!("Triggering Postgres notification with UserDecryptionRequest insertion..."); sqlx::query!( "INSERT INTO user_decryption_requests VALUES ($1, $2, $3, $4, $5) ON CONFLICT DO NOTHING", decryption_id.as_le_slice(), - sns_ciphertexts_db as Vec, + sns_ciphertexts_db.clone() as Vec, user_address.as_slice(), &public_key, vec![], @@ -92,7 +88,11 @@ async fn test_pick_user_decryption() -> anyhow::Result<()> { events, vec![GatewayEvent::UserDecryption(UserDecryptionRequest { decryptionId: decryption_id, - snsCtMaterials: sns_ct, + storageUrls: sns_ciphertexts_db + .iter() + .map(|s| s.storage_urls.clone()) + .collect(), + snsCtMaterials: sns_ciphertexts_db.iter().map(|s| s.into()).collect(), userAddress: user_address, publicKey: public_key.into(), extraData: vec![].into(), @@ -215,16 +215,12 @@ async fn test_polling_backup() -> anyhow::Result<()> { let test_instance = TestInstanceBuilder::db_setup().await?; let decryption_id = rand_u256(); - let sns_ct = vec![rand_sns_ct()]; - let sns_ciphertexts_db = sns_ct - .iter() - .map(SnsCiphertextMaterialDbItem::from) - .collect::>(); + let sns_ciphertexts_db = vec![rand_sns_ct()]; info!("Inserting PublicDecryptionRequest before starting the event picker..."); sqlx::query!( "INSERT INTO public_decryption_requests VALUES ($1, $2, $3) ON CONFLICT DO NOTHING", decryption_id.as_le_slice(), - sns_ciphertexts_db as Vec, + sns_ciphertexts_db.clone() as Vec, vec![], ) .execute(test_instance.db()) @@ -244,7 +240,11 @@ async fn test_polling_backup() -> anyhow::Result<()> { events, vec![GatewayEvent::PublicDecryption(PublicDecryptionRequest { decryptionId: decryption_id, - snsCtMaterials: sns_ct, + storageUrls: sns_ciphertexts_db + .iter() + .map(|s| s.storage_urls.clone()) + .collect(), + snsCtMaterials: sns_ciphertexts_db.iter().map(|s| s.into()).collect(), extraData: vec![].into(), })] ); diff --git a/kms-connector/crates/kms-worker/tests/health.rs b/kms-connector/crates/kms-worker/tests/health.rs index 3c9b3ef7f1..d0a4aa928a 100644 --- a/kms-connector/crates/kms-worker/tests/health.rs +++ b/kms-connector/crates/kms-worker/tests/health.rs @@ -1,7 +1,4 @@ -use alloy::{ - providers::RootProvider, - transports::http::reqwest::{self, StatusCode, Url}, -}; +use alloy::transports::http::reqwest::{self, StatusCode, Url}; use connector_utils::{ monitoring::{ health::{Healthcheck, query_healthcheck_endpoint}, @@ -23,7 +20,6 @@ async fn test_healthcheck_endpoints() -> anyhow::Result<()> { KmsHealthClient::connect(&[test_instance.kms_url().to_string()]).await?; let state = State::new( test_instance.db().clone(), - test_instance.provider().clone(), kms_health_client, Duration::from_secs(5), ); @@ -61,7 +57,7 @@ async fn test_healthcheck_endpoints() -> anyhow::Result<()> { assert_eq!( response.json::().await?, VersionResponse { - name: State::::service_name().to_string(), + name: State::service_name().to_string(), version: env!("CARGO_PKG_VERSION").to_string(), build: GIT_COMMIT_HASH.to_string(), } @@ -80,16 +76,6 @@ async fn test_healthcheck_endpoints() -> anyhow::Result<()> { // Test everything is fine query_healthcheck_endpoint::(monitoring_url.clone()).await?; - // Pause Gateway and verify healthcheck failure - test_instance.anvil_container().pause().await?; - query_healthcheck_endpoint::(monitoring_url.clone()) - .await - .unwrap_err(); - test_instance.anvil_container().unpause().await?; - - // Test everything is fine - query_healthcheck_endpoint::(monitoring_url.clone()).await?; - // Pause KMS Core and verify healthcheck failure test_instance.kms_container().pause().await?; query_healthcheck_endpoint::(monitoring_url) diff --git a/kms-connector/crates/kms-worker/tests/s3.rs b/kms-connector/crates/kms-worker/tests/s3.rs index 3dda962c8b..0f167cea17 100644 --- a/kms-connector/crates/kms-worker/tests/s3.rs +++ b/kms-connector/crates/kms-worker/tests/s3.rs @@ -1,7 +1,4 @@ -use alloy::{ - hex, - providers::{ProviderBuilder, mock::Asserter}, -}; +use alloy::hex; use connector_utils::tests::{ rand::rand_u256, setup::{S3_CT, S3Instance, TestInstance}, @@ -14,11 +11,10 @@ async fn test_get_ciphertext_from_s3() -> anyhow::Result<()> { .with_s3(S3Instance::setup().await?) .build(); let config = Config::default(); - let mock_provider = ProviderBuilder::new().connect_mocked_client(Asserter::new()); let handle = rand_u256().to_be_bytes_vec(); // dummy handle let bucket_url = format!("{}/ct128", test_instance.s3_url()); - let s3_service = S3Service::new(&config, mock_provider); + let s3_service = S3Service::new(&config); s3_service .retrieve_s3_ciphertext_with_retry(vec![bucket_url], &handle, &hex::decode(S3_CT)?, S3_CT) .await @@ -42,11 +38,10 @@ async fn test_get_unstored_s3_ciphertext() -> anyhow::Result<()> { .with_s3(S3Instance::setup().await?) .build(); let config = Config::default(); - let mock_provider = ProviderBuilder::new().connect_mocked_client(Asserter::new()); let handle = rand_u256().to_be_bytes_vec(); // dummy handle let bucket_url = format!("{}/ct128", test_instance.s3_url()); - let s3_service = S3Service::new(&config, mock_provider); + let s3_service = S3Service::new(&config); if let Some(ct) = s3_service .retrieve_s3_ciphertext_with_retry( vec![bucket_url], diff --git a/kms-connector/crates/utils/src/tests/rand.rs b/kms-connector/crates/utils/src/tests/rand.rs index 4938cd33d2..2878bf2bb3 100644 --- a/kms-connector/crates/utils/src/tests/rand.rs +++ b/kms-connector/crates/utils/src/tests/rand.rs @@ -1,5 +1,5 @@ +use crate::types::db::SnsCiphertextMaterialDbItem; use alloy::primitives::{Address, FixedBytes, U256}; -use fhevm_gateway_bindings::decryption::Decryption::SnsCiphertextMaterial; use rand::Rng; pub fn rand_u256() -> U256 { @@ -22,11 +22,11 @@ pub fn rand_digest() -> FixedBytes<32> { rand::rng().random::<[u8; 32]>().into() } -pub fn rand_sns_ct() -> SnsCiphertextMaterial { - SnsCiphertextMaterial { - keyId: rand_u256(), - ctHandle: rand::rng().random::<[u8; 32]>().into(), - snsCiphertextDigest: rand::rng().random::<[u8; 32]>().into(), - coprocessorTxSenderAddresses: vec![rand_address()], +pub fn rand_sns_ct() -> SnsCiphertextMaterialDbItem { + SnsCiphertextMaterialDbItem { + key_id: rand::rng().random::<[u8; 32]>(), + ct_handle: rand::rng().random::<[u8; 32]>(), + sns_ciphertext_digest: rand::rng().random::<[u8; 32]>(), + storage_urls: vec!["http://localhost:9000/ct/128".to_string()], } } diff --git a/kms-connector/crates/utils/src/tests/setup/gw.rs b/kms-connector/crates/utils/src/tests/setup/gw.rs index 82f87212f7..7fb65f4d81 100644 --- a/kms-connector/crates/utils/src/tests/setup/gw.rs +++ b/kms-connector/crates/utils/src/tests/setup/gw.rs @@ -3,34 +3,28 @@ use crate::{ conn::WalletGatewayProvider, provider::{FillersWithoutNonceManagement, NonceManagedProvider}, tests::setup::{ROOT_CARGO_TOML, pick_free_port}, - // tests::setup::{ROOT_CARGO_TOML, pick_free_port}, }; use alloy::{ - primitives::{Address, ChainId, FixedBytes}, + primitives::{Address, ChainId, address}, providers::{ProviderBuilder, WsConnect}, }; use fhevm_gateway_bindings::{ decryption::Decryption::{self, DecryptionInstance}, - gateway_config::GatewayConfig::{self, GatewayConfigInstance}, kms_generation::KMSGeneration::{self, KMSGenerationInstance}, }; -use std::{sync::LazyLock, time::Duration}; +use std::{str::from_utf8, sync::LazyLock, time::Duration}; use testcontainers::{ ContainerAsync, GenericImage, ImageExt, core::{WaitFor, client::docker_client_instance}, runners::AsyncRunner, }; -use tracing::info; - -pub const DECRYPTION_MOCK_ADDRESS: Address = Address(FixedBytes([ - 184, 174, 68, 54, 92, 69, 167, 197, 37, 107, 20, 246, 7, 202, 226, 59, 192, 64, 195, 84, -])); -pub const GATEWAY_CONFIG_MOCK_ADDRESS: Address = Address(FixedBytes([ - 159, 167, 153, 249, 90, 114, 37, 140, 4, 21, 223, 237, 216, 207, 118, 210, 97, 60, 117, 15, -])); -pub const KMS_GENERATION_MOCK_ADDRESS: Address = Address(FixedBytes([ - 200, 27, 227, 169, 24, 21, 210, 212, 9, 109, 174, 8, 26, 113, 22, 201, 250, 123, 223, 8, -])); +use tracing::{debug, info}; + +pub const DECRYPTION_MOCK_ADDRESS: Address = address!("0x9FA799F95A72258c0415DFEdd8Cf76D2613c750f"); +pub const GATEWAY_CONFIG_MOCK_ADDRESS: Address = + address!("0xE61cff9C581c7c91AEF682c2C10e8632864339ab"); +pub const KMS_GENERATION_MOCK_ADDRESS: Address = + address!("0x286f5339934279C74df10123bDbeEF3CaE932c22"); pub const TEST_MNEMONIC: &str = "coyote sketch defense hover finger envelope celery urge panther venue verb cheese"; @@ -45,7 +39,6 @@ const ANVIL_PORT: u16 = 8545; pub struct GatewayInstance { pub provider: WalletGatewayProvider, pub decryption_contract: DecryptionInstance, - pub gateway_config_contract: GatewayConfigInstance, pub kms_generation_contract: KMSGenerationInstance, pub anvil: ContainerAsync, pub anvil_host_port: u16, @@ -60,15 +53,12 @@ impl GatewayInstance { block_time: u64, ) -> Self { let decryption_contract = Decryption::new(DECRYPTION_MOCK_ADDRESS, provider.clone()); - let gateway_config_contract = - GatewayConfig::new(GATEWAY_CONFIG_MOCK_ADDRESS, provider.clone()); let kms_generation_contract = KMSGeneration::new(KMS_GENERATION_MOCK_ADDRESS, provider.clone()); GatewayInstance { provider, decryption_contract, - gateway_config_contract, kms_generation_contract, anvil, anvil_host_port, @@ -151,7 +141,7 @@ pub async fn setup_anvil_gateway( info!("Deploying Gateway mock contracts..."); let version = ROOT_CARGO_TOML.get_gateway_bindings_version(); - let _deploy_mock_container = + let deploy_mock_container = GenericImage::new("ghcr.io/zama-ai/fhevm/gateway-contracts", &version) .with_wait_for(WaitFor::message_on_stdout("Mock contract deployment done!")) .with_env_var("HARDHAT_NETWORK", "staging") @@ -173,6 +163,15 @@ pub async fn setup_anvil_gateway( .with_cmd(["npx hardhat task:deployGatewayMockContracts"]) .start() .await?; + + let stdout = deploy_mock_container.stdout_to_vec().await; + let stderr = deploy_mock_container.stderr_to_vec().await; + if let Ok(Ok(stdout)) = stdout.as_deref().map(from_utf8) { + debug!("Stdout: {stdout}"); + } + if let Ok(Ok(stderr)) = stderr.as_deref().map(from_utf8) { + debug!("Stderr: {stderr}"); + } info!("Mock contract successfully deployed on Anvil!"); Ok(anvil) diff --git a/kms-connector/crates/utils/src/tests/setup/instance.rs b/kms-connector/crates/utils/src/tests/setup/instance.rs index a29a0bdd6d..fce6970c29 100644 --- a/kms-connector/crates/utils/src/tests/setup/instance.rs +++ b/kms-connector/crates/utils/src/tests/setup/instance.rs @@ -6,7 +6,6 @@ use crate::{ }; use fhevm_gateway_bindings::{ decryption::Decryption::DecryptionInstance, - gateway_config::GatewayConfig::GatewayConfigInstance, kms_generation::KMSGeneration::KMSGenerationInstance, }; use sqlx::{Pool, Postgres}; @@ -87,10 +86,6 @@ impl TestInstance { &self.gateway().decryption_contract } - pub fn gateway_config_contract(&self) -> &GatewayConfigInstance { - &self.gateway().gateway_config_contract - } - pub fn kms_generation_contract(&self) -> &KMSGenerationInstance { &self.gateway().kms_generation_contract } diff --git a/kms-connector/crates/utils/src/types/db.rs b/kms-connector/crates/utils/src/types/db.rs index 3f88ca790e..cd010c18a4 100644 --- a/kms-connector/crates/utils/src/types/db.rs +++ b/kms-connector/crates/utils/src/types/db.rs @@ -1,4 +1,4 @@ -use alloy::primitives::{Address, U256}; +use alloy::primitives::U256; use anyhow::anyhow; use fhevm_gateway_bindings::{ decryption::Decryption::SnsCiphertextMaterial, kms_generation::IKMSGeneration::KeyDigest, @@ -9,25 +9,10 @@ use std::str::FromStr; #[derive(sqlx::Type, Clone, Debug, Default, PartialEq)] #[sqlx(type_name = "sns_ciphertext_material")] pub struct SnsCiphertextMaterialDbItem { - ct_handle: [u8; 32], - key_id: [u8; 32], - sns_ciphertext_digest: [u8; 32], - coprocessor_tx_sender_addresses: Vec<[u8; 20]>, -} - -impl From<&SnsCiphertextMaterial> for SnsCiphertextMaterialDbItem { - fn from(value: &SnsCiphertextMaterial) -> Self { - Self { - ct_handle: *value.ctHandle, - key_id: value.keyId.to_le_bytes(), - sns_ciphertext_digest: *value.snsCiphertextDigest, - coprocessor_tx_sender_addresses: value - .coprocessorTxSenderAddresses - .iter() - .map(|a| *a.0) - .collect(), - } - } + pub ct_handle: [u8; 32], + pub key_id: [u8; 32], + pub sns_ciphertext_digest: [u8; 32], + pub storage_urls: Vec, } impl From<&SnsCiphertextMaterialDbItem> for SnsCiphertextMaterial { @@ -36,11 +21,17 @@ impl From<&SnsCiphertextMaterialDbItem> for SnsCiphertextMaterial { ctHandle: value.ct_handle.into(), keyId: U256::from_le_bytes(value.key_id), snsCiphertextDigest: value.sns_ciphertext_digest.into(), - coprocessorTxSenderAddresses: value - .coprocessor_tx_sender_addresses - .iter() - .map(Address::from) - .collect(), + } + } +} + +impl SnsCiphertextMaterialDbItem { + pub fn new(sns_ct: &SnsCiphertextMaterial, storage_urls: Vec) -> Self { + Self { + ct_handle: *sns_ct.ctHandle, + key_id: sns_ct.keyId.to_le_bytes(), + sns_ciphertext_digest: *sns_ct.snsCiphertextDigest, + storage_urls, } } } diff --git a/kms-connector/crates/utils/src/types/gw_event.rs b/kms-connector/crates/utils/src/types/gw_event.rs index bb767d0f9b..c5b66f4ba3 100644 --- a/kms-connector/crates/utils/src/types/gw_event.rs +++ b/kms-connector/crates/utils/src/types/gw_event.rs @@ -26,29 +26,31 @@ pub enum GatewayEvent { impl GatewayEvent { pub fn from_public_decryption_row(row: &PgRow) -> Result { - let sns_ct_materials = row + let (sns_ct_materials, storage_urls) = row .try_get::, _>("sns_ct_materials")? - .iter() - .map(SnsCiphertextMaterial::from) + .into_iter() + .map(|s| (SnsCiphertextMaterial::from(&s), s.storage_urls)) .collect(); Ok(GatewayEvent::PublicDecryption(PublicDecryptionRequest { decryptionId: U256::from_le_bytes(row.try_get::<[u8; 32], _>("decryption_id")?), snsCtMaterials: sns_ct_materials, + storageUrls: storage_urls, extraData: row.try_get::, _>("extra_data")?.into(), })) } pub fn from_user_decryption_row(row: &PgRow) -> Result { - let sns_ct_materials = row + let (sns_ct_materials, storage_urls) = row .try_get::, _>("sns_ct_materials")? - .iter() - .map(SnsCiphertextMaterial::from) + .into_iter() + .map(|s| (SnsCiphertextMaterial::from(&s), s.storage_urls)) .collect(); Ok(GatewayEvent::UserDecryption(UserDecryptionRequest { decryptionId: U256::from_le_bytes(row.try_get::<[u8; 32], _>("decryption_id")?), snsCtMaterials: sns_ct_materials, + storageUrls: storage_urls, userAddress: row.try_get::<[u8; 20], _>("user_address")?.into(), publicKey: row.try_get::, _>("public_key")?.into(), extraData: row.try_get::, _>("extra_data")?.into(), diff --git a/kms-connector/tests/lib.rs b/kms-connector/tests/lib.rs index cfe158c95b..9409cc2e6b 100644 --- a/kms-connector/tests/lib.rs +++ b/kms-connector/tests/lib.rs @@ -113,7 +113,6 @@ impl KmsConnector { ..Default::default() }; kms_worker_conf.decryption_contract.address = DECRYPTION_MOCK_ADDRESS; - kms_worker_conf.gateway_config_contract.address = GATEWAY_CONFIG_MOCK_ADDRESS; let (kms_worker, _) = KmsWorker::from_config(kms_worker_conf).await?; let mut tx_sender_conf = tx_sender::core::Config::default().await;