Skip to content

Commit f802a85

Browse files
committed
refactor(coprocessor): remove tenants notion from DB and related code
Replace with: * keys table - containing FHE keys * crs table - containing the CRS * host_chains table - containing host chain info Rationale is: * the fact that we now have only one FHE keychain (that can have multiple FHE keys) * CRS and keys can be changed independently via events from the GW * we want to support multiple host chains * we want to remove remains of previous design with tenants, IDs, tenant API keys, etc. We also simplify code where it no longer needs tenants, chain IDs, etc.
1 parent c93a604 commit f802a85

File tree

37 files changed

+925
-1013
lines changed

37 files changed

+925
-1013
lines changed

.devcontainer/post_create_command.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ set -euo pipefail
44

55
# Package manager dependencies.
66
sudo apt update
7-
sudo apt install -y protobuf-compiler build-essential libssl-dev pkg-config openssl vim git-lfs
7+
sudo apt install -y protobuf-compiler build-essential libssl-dev pkg-config openssl vim git-lfs postgresql-client
88

99
# Cargo dependencies.
1010
cargo install sqlx-cli

charts/coprocessor/values.yaml

Lines changed: 7 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,6 @@ config:
3030
name: coprocessor-key
3131
key: coprocessor.hex
3232

33-
# API key for tenant authentication
34-
apiKey:
35-
secret:
36-
name: coprocessor-api-key
37-
key: coprocessor-api-key
38-
3933
# Database connection configuration
4034
database:
4135
secret:
@@ -82,11 +76,13 @@ dbMigration:
8276
secretKeyRef:
8377
name: coprocessor-db-url
8478
key: coprocessor-db-url
85-
- name: TENANT_API_KEY
86-
valueFrom:
87-
secretKeyRef:
88-
name: coprocessor-api-key
89-
key: coprocessor-api-key
79+
# KMS public key URLs for cryptographic setup
80+
- name: PKS_URL
81+
value: "http://minio:9000/kms-public/kms/PUB/PublicKey/d74037feb1394aec0eb724afc4a690e16a0203eb1dc868de08179f2e4828f335"
82+
- name: SKS_URL
83+
value: "http://minio:9000/kms-public/kms/PUB/ServerKey/812b602c11693dda4bfa68db78269849972b6f1920a725a98fc78cf619a6ab5f"
84+
- name: PP_URL
85+
value: "http://minio:9000/kms-public/kms/PUB/CRS/e4e3f0deef6492bde2fac3f2c698112ace878d4a3656b272197ed332391c48fa"
9086

9187
serviceAccountName:
9288

@@ -130,16 +126,10 @@ hostListener:
130126
secretKeyRef:
131127
name: coprocessor-db-url
132128
key: coprocessor-db-url
133-
- name: TENANT_API_KEY
134-
valueFrom:
135-
secretKeyRef:
136-
name: coprocessor-api-key
137-
key: coprocessor-api-key
138129

139130
# Command line arguments for the host listener
140131
args:
141132
- --database-url=$(DATABASE_URL)
142-
- --coprocessor-api-key=$(TENANT_API_KEY)
143133
- --url=$(ETHEREUM_RPC_URL)
144134
- --acl-contract-address=$(ACL_CONTRACT_ADDRESS)
145135
- --tfhe-contract-address=$(FHEVM_EXECUTOR_CONTRACT_ADDRESS)
@@ -235,17 +225,11 @@ hostListenerPoller:
235225
secretKeyRef:
236226
name: coprocessor-db-url
237227
key: coprocessor-db-url
238-
- name: TENANT_API_KEY
239-
valueFrom:
240-
secretKeyRef:
241-
name: coprocessor-api-key
242-
key: coprocessor-api-key
243228

244229
# Command line arguments for the host listener poller
245230
args:
246231
### Required parameters
247232
- --database-url=$(DATABASE_URL)
248-
- --coprocessor-api-key=$(TENANT_API_KEY)
249233
- --url=$(ETHEREUM_RPC_HTTP_URL)
250234
- --acl-contract-address=$(ACL_CONTRACT_ADDRESS)
251235
- --tfhe-contract-address=$(FHEVM_EXECUTOR_CONTRACT_ADDRESS)
@@ -340,17 +324,11 @@ hostListenerCatchupOnly:
340324
secretKeyRef:
341325
name: coprocessor-db-url
342326
key: coprocessor-db-url
343-
- name: TENANT_API_KEY
344-
valueFrom:
345-
secretKeyRef:
346-
name: coprocessor-api-key
347-
key: coprocessor-api-key
348327

349328
# Command line arguments for the host listener catchup only mode
350329
# NOTE: --only-catchup-loop requires --end-at-block to be set
351330
args:
352331
- --database-url=$(DATABASE_URL)
353-
- --coprocessor-api-key=$(TENANT_API_KEY)
354332
- --url=$(ETHEREUM_RPC_URL)
355333
- --acl-contract-address=$(ACL_CONTRACT_ADDRESS)
356334
- --tfhe-contract-address=$(FHEVM_EXECUTOR_CONTRACT_ADDRESS)
@@ -535,11 +513,6 @@ tfheWorker:
535513
secretKeyRef:
536514
name: coprocessor-db-url
537515
key: coprocessor-db-url
538-
- name: TENANT_API_KEY
539-
valueFrom:
540-
secretKeyRef:
541-
name: coprocessor-api-key
542-
key: coprocessor-api-key
543516
- name: ACL_CONTRACT_ADDRESS
544517
value: "0x05fD9B5EFE0a996095f42Ed7e77c390810CF660c"
545518
- name: INPUT_VERIFIER_ADDRESS
@@ -794,16 +767,10 @@ snsWorker:
794767
secretKeyRef:
795768
name: coprocessor-db-url
796769
key: coprocessor-db-url
797-
- name: TENANT_API_KEY
798-
valueFrom:
799-
secretKeyRef:
800-
name: coprocessor-api-key
801-
key: coprocessor-api-key
802770

803771
# Command line arguments for SNS worker
804772
args:
805773
- --database-url=$(DATABASE_URL)
806-
- --tenant-api-key=$(TENANT_API_KEY)
807774
- --pg-listen-channels
808775
- event_pbs_computations
809776
- event_ciphertext_computed

coprocessor/docs/getting_started/fhevm/coprocessor/configuration.md

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,6 @@
22

33
## Coprocessor Backend
44

5-
### Database
6-
Some settings of the Coprocessor backend are configured by inserting entries in the PostgreSQL DB.
7-
8-
At the time of writing, we don't have a tool or automation for doing the configuration. The DB schema can be used as a reference, though: [schema](../../../../fhevm-engine/coprocessor/migrations/20240722111257_coprocessor.sql).
9-
10-
The `tenants` table contains a list of tenants that are using the Coprocessor backend. A tenant could be thought of as a separate blockchain (or a separate FHE key, i.e. using multiple FHE keys on a blockchain). The fields in `tenants` are:
11-
12-
| Field | Description |
13-
| -------------------------- | -------------------------------------------------- |
14-
| tenant_id | unique tenant identifier |
15-
| tenant_api_key | an API key that authenticates access to the server |
16-
| chain_id | the chain ID of the chain this tenant operates on |
17-
| verifying_contract_address | address of the InputVerifier contract |
18-
| acl_contract_address | address of the ACL contract |
19-
| pks_key | a serialization of the FHE public key |
20-
| sks_key | a serialization of the FHE server key |
21-
| public_params | a serialization of the CRS public params |
22-
| cks_key | optional secret FHE key, for debugging only |
23-
| is_admin | if tenant is an administrator |
24-
25-
265
### Command Line
276

287
You can use the `--help` command line switch on the coprocessor to get a help screen as follows:
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash
2+
3+
TABLE_NAME="$1"
4+
5+
psql $DATABASE_URL -P pager=off -c "\d+ $TABLE_NAME"
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
BEGIN;
2+
3+
-- Create the keys table.
4+
ALTER TABLE tenants RENAME TO keys;
5+
6+
-- Enforce that keys (or what we called tenants) has zero or one row.
7+
DO $$
8+
BEGIN
9+
IF (SELECT COUNT(*) FROM keys) > 1 THEN
10+
RAISE EXCEPTION 'Expected zero or one row in keys table, but found %', (SELECT COUNT(*) FROM keys);
11+
END IF;
12+
END $$;
13+
14+
ALTER TABLE keys DROP COLUMN tenant_api_key;
15+
ALTER TABLE keys DROP COLUMN is_admin;
16+
ALTER TABLE keys DROP COLUMN sns_sk;
17+
ALTER TABLE keys DROP COLUMN verifying_contract_address;;
18+
19+
-- key_id contains the key ID from the server key metadata (that is used in ciphertext metadata).
20+
ALTER TABLE keys ALTER COLUMN key_id SET NOT NULL;
21+
-- The current key_id for the existing key is empty.
22+
UPDATE keys SET key_id = ''::BYTEA;
23+
ALTER TABLE keys ADD CONSTRAINT unique_key_id UNIQUE (key_id);
24+
25+
--key_id_gw contains the key ID from the GW event (that could be different from key_id).
26+
ALTER TABLE keys ADD column key_id_gw BYTEA NOT NULL;
27+
ALTER TABLE keys ADD CONSTRAINT unique_key_id_gw UNIQUE (key_id_gw);
28+
29+
ALTER TABLE keys ADD COLUMN created_at TIMESTAMPTZ NOT NULL DEFAULT NOW();
30+
31+
-- Split CRS from keys.
32+
CREATE TABLE crs (
33+
-- The sequence number to identify the latest CRS.
34+
sequence_number BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
35+
crs_id BYTEA NOT NULL,
36+
crs BYTEA NOT NULL,
37+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
38+
CONSTRAINT unique_crs_id UNIQUE (crs_id)
39+
);
40+
41+
-- Move CRS from keys to crs.
42+
INSERT INTO crs (crs_id, crs)
43+
SELECT ''::BYTEA, public_params FROM keys;
44+
ALTER TABLE keys DROP COLUMN public_params;
45+
46+
-- Host chains.
47+
CREATE TABLE host_chains (
48+
chain_id BIGINT PRIMARY KEY NOT NULL CHECK (chain_id > 0),
49+
name TEXT NOT NULL,
50+
acl_contract_address TEXT NOT NULL,
51+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
52+
);
53+
54+
-- Move ACL contract address.
55+
INSERT INTO host_chains (chain_id, name, acl_contract_address)
56+
SELECT chain_id, 'ethereum', acl_contract_address FROM keys;
57+
ALTER TABLE keys DROP COLUMN acl_contract_address;
58+
59+
60+
-- allowed_handles.tenant_id no longer needed.
61+
ALTER TABLE allowed_handles DROP COLUMN tenant_id;
62+
ALTER TABLE allowed_handles ADD PRIMARY KEY (handle, account_address);
63+
64+
-- input_blobs.tenant_id no longer needed.
65+
ALTER TABLE input_blobs DROP CONSTRAINT input_blobs_pkey;
66+
ALTER TABLE input_blobs DROP COLUMN tenant_id;
67+
ALTER TABLE input_blobs ADD PRIMARY KEY (blob_hash);
68+
69+
-- ciphertext_digest.tenant_id no longer needed. Instead, put the host_chain_id there directly.
70+
ALTER TABLE ciphertext_digest ADD COLUMN host_chain_id BIGINT DEFAULT NULL;
71+
UPDATE ciphertext_digest SET host_chain_id = (SELECT chain_id FROM keys WHERE tenant_id = ciphertext_digest.tenant_id);
72+
ALTER TABLE ciphertext_digest ALTER COLUMN host_chain_id SET NOT NULL;
73+
ALTER TABLE ciphertext_digest ADD CONSTRAINT ciphertext_digest_host_chain_id_positive CHECK (host_chain_id > 0);
74+
ALTER TABLE ciphertext_digest DROP COLUMN tenant_id;
75+
ALTER TABLE ciphertext_digest ADD PRIMARY KEY (handle);
76+
ALTER TABLE ciphertext_digest ADD COLUMN key_id BYTEA NOT NULL; -- TODO for the future is to make this an index
77+
78+
-- ciphertexts.tenant_id no longer needed.
79+
ALTER TABLE ciphertexts DROP CONSTRAINT ciphertexts_pkey;
80+
ALTER TABLE ciphertexts DROP COLUMN tenant_id;
81+
ALTER TABLE ciphertexts ADD PRIMARY KEY (handle, ciphertext_version);
82+
83+
-- computations.tenant_id no longer needed.
84+
ALTER TABLE computations DROP CONSTRAINT computations_pkey;
85+
DROP INDEX IF EXISTS idx_computations_pk;
86+
ALTER TABLE computations DROP COLUMN tenant_id;
87+
ALTER TABLE computations ADD PRIMARY KEY (output_handle, transaction_id);
88+
89+
-- pbs_computations.tenant_id no longer needed.
90+
ALTER TABLE pbs_computations DROP CONSTRAINT pbs_computations_pkey;
91+
ALTER TABLE pbs_computations DROP COLUMN tenant_id;
92+
ALTER TABLE pbs_computations ADD PRIMARY KEY (handle);
93+
94+
-- We can now safely drop tenant_id and chain_id from keys.
95+
ALTER TABLE keys DROP COLUMN tenant_id;
96+
ALTER TABLE keys DROP COLUMN chain_id;
97+
-- The sequence_number can be used to identify the latest key.
98+
ALTER TABLE keys ADD COLUMN sequence_number BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY;
99+
100+
COMMIT;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use anyhow::Result;
2+
use sqlx::{PgPool, Row};
3+
use std::sync::Arc;
4+
use tfhe::zk::CompactPkeCrs;
5+
6+
use crate::utils::safe_deserialize_key;
7+
8+
pub type CrsId = Vec<u8>;
9+
10+
#[derive(Clone)]
11+
pub struct Crs {
12+
pub crs_id: CrsId,
13+
pub crs: CompactPkeCrs,
14+
}
15+
16+
#[derive(Clone, Default)]
17+
pub struct CrsCache {
18+
latest: Option<Arc<Crs>>,
19+
}
20+
21+
impl CrsCache {
22+
pub async fn load(pool: &PgPool) -> Result<Self> {
23+
let row = sqlx::query("SELECT crs_id, crs FROM crs ORDER BY sequence_number DESC LIMIT 1")
24+
.fetch_optional(pool)
25+
.await?;
26+
27+
let latest = row
28+
.map(|row| {
29+
Ok::<_, anyhow::Error>(Arc::new(Crs {
30+
crs_id: row.try_get("crs_id")?,
31+
crs: safe_deserialize_key(row.try_get("crs")?)?,
32+
}))
33+
})
34+
.transpose()?;
35+
36+
Ok(Self { latest })
37+
}
38+
39+
pub fn get_latest(&self) -> Option<&Crs> {
40+
self.latest.as_deref()
41+
}
42+
}

0 commit comments

Comments
 (0)