refactor(server::db): introduced newtype wrappers for entity id's in database

This commit is contained in:
Skipper
2026-04-27 13:07:12 +02:00
parent 3f801abdff
commit a773255935
18 changed files with 175 additions and 101 deletions

View File

@@ -22,3 +22,5 @@ run = '''
dart pub global activate protoc_plugin && \ dart pub global activate protoc_plugin && \
protoc --dart_out=grpc:useragent/lib/proto --proto_path=protobufs/ $(find protobufs -name '*.proto' | sort) protoc --dart_out=grpc:useragent/lib/proto --proto_path=protobufs/ $(find protobufs -name '*.proto' | sort)
''' '''
[tasks.generate_schema]

View File

@@ -43,13 +43,24 @@ create table if not exists arbiter_settings (
insert into arbiter_settings (id) values (1) on conflict do nothing; insert into arbiter_settings (id) values (1) on conflict do nothing;
-- ensure singleton row exists -- ensure singleton row exists
create table if not exists operator_client ( create table if not exists operator_identity (
id integer not null primary key, id integer not null primary key,
public_key blob not null, public_key blob not null,
created_at integer not null default(unixepoch ('now')), created_at integer not null default(unixepoch ('now')),
updated_at integer not null default(unixepoch ('now')) updated_at integer not null default(unixepoch ('now'))
) STRICT; ) STRICT;
create unique index if not exists uniq_operator_client_public_key on operator_client (public_key); create unique index if not exists uniq_operator_identity_public_key on operator_identity (public_key);
create table if not exists operator (
id integer primary key references operator_identity(id) on delete restrict, -- same id as operator_identity
share blob not null,
share_nonce blob not null,
created_at integer not null default(unixepoch ('now')),
updated_at integer not null default(unixepoch ('now'))
) STRICT;
create table if not exists client_metadata ( create table if not exists client_metadata (
id integer not null primary key, id integer not null primary key,

View File

@@ -48,7 +48,7 @@ impl Bootstrapper {
let row_count: i64 = { let row_count: i64 = {
let mut conn = db.get().await?; let mut conn = db.get().await?;
schema::operator_client::table schema::operator::table
.count() .count()
.get_result(&mut conn) .get_result(&mut conn)
.await? .await?

View File

@@ -3,7 +3,7 @@ use crate::{
crypto::integrity, crypto::integrity,
db::{ db::{
DatabaseError, DatabasePool, DatabaseError, DatabasePool,
models::{self}, models::{self, EvmWalletId},
schema, schema,
}, },
evm::{ evm::{
@@ -116,7 +116,7 @@ impl EvmActor {
} }
#[message] #[message]
pub async fn list_wallets(&self) -> Result<Vec<(i32, Address)>, Error> { pub async fn list_wallets(&self) -> Result<Vec<(EvmWalletId, Address)>, Error> {
let mut conn = self.db.get().await.map_err(DatabaseError::from)?; let mut conn = self.db.get().await.map_err(DatabaseError::from)?;
let rows: Vec<models::EvmWallet> = schema::evm_wallet::table let rows: Vec<models::EvmWallet> = schema::evm_wallet::table
.select(models::EvmWallet::as_select()) .select(models::EvmWallet::as_select())

View File

@@ -6,7 +6,7 @@ use crate::{
}, },
db::{ db::{
self, self,
models::{self, RootKeyHistory}, models::{self, RootKeyHistory, RootKeyHistoryId},
schema::{self}, schema::{self},
}, },
}; };
@@ -25,7 +25,6 @@ use strum::{EnumDiscriminants, IntoDiscriminant};
use tracing::{error, info}; use tracing::{error, info};
pub mod events { pub mod events {
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct Bootstrapped; pub struct Bootstrapped;
@@ -64,7 +63,7 @@ pub enum Error {
} }
struct Unsealed { struct Unsealed {
root_key_history_id: i32, root_key_history_id: RootKeyHistoryId,
root_key: KeyCell, root_key: KeyCell,
} }
@@ -73,8 +72,9 @@ struct Unsealed {
enum State { enum State {
#[default] #[default]
Unbootstrapped, Unbootstrapped,
Sealed { Sealed {
root_key_history_id: i32, root_key_history_id: RootKeyHistoryId,
}, },
Unsealed(Unsealed), Unsealed(Unsealed),
} }
@@ -115,7 +115,10 @@ impl Vault {
// Exclusive transaction to avoid race condtions if multiple vaults write // Exclusive transaction to avoid race condtions if multiple vaults write
// additional layer of protection against nonce-reuse // additional layer of protection against nonce-reuse
async fn get_new_nonce(pool: &db::DatabasePool, root_key_id: i32) -> Result<Nonce, Error> { async fn get_new_nonce(
pool: &db::DatabasePool,
root_key_id: RootKeyHistoryId,
) -> Result<Nonce, Error> {
let mut conn = pool.get().await?; let mut conn = pool.get().await?;
let nonce = conn let nonce = conn
@@ -128,7 +131,7 @@ impl Vault {
let mut nonce = Nonce::try_from(current_nonce.as_slice()).map_err(|()| { let mut nonce = Nonce::try_from(current_nonce.as_slice()).map_err(|()| {
error!( error!(
"Broken database: invalid nonce for root key history id={}", "Broken database: invalid nonce for root key history id={:#?}",
root_key_id root_key_id
); );
Error::BrokenDatabase Error::BrokenDatabase
@@ -184,7 +187,7 @@ impl Vault {
let data_encryption_nonce_bytes = data_encryption_nonce.to_vec(); let data_encryption_nonce_bytes = data_encryption_nonce.to_vec();
let root_key_history_id = conn let root_key_history_id = conn
.transaction(async |conn| { .transaction(async |conn| {
let root_key_history_id: i32 = insert_into(schema::root_key_history::table) let root_key_history_id = insert_into(schema::root_key_history::table)
.values(&models::NewRootKeyHistory { .values(&models::NewRootKeyHistory {
ciphertext: root_key_ciphertext.clone(), ciphertext: root_key_ciphertext.clone(),
tag: v1::ROOT_KEY_TAG.to_vec(), tag: v1::ROOT_KEY_TAG.to_vec(),
@@ -202,7 +205,9 @@ impl Vault {
.execute(&mut *conn) .execute(&mut *conn)
.await?; .await?;
Result::<_, diesel::result::Error>::Ok(root_key_history_id) Result::<_, diesel::result::Error>::Ok(RootKeyHistoryId::from_raw(
root_key_history_id,
))
}) })
.await?; .await?;
@@ -340,7 +345,10 @@ impl Vault {
} }
#[message] #[message]
pub fn sign_integrity(&mut self, mac_input: Vec<u8>) -> Result<(i32, Vec<u8>), Error> { pub fn sign_integrity(
&mut self,
mac_input: Vec<u8>,
) -> Result<(RootKeyHistoryId, Vec<u8>), Error> {
let Unsealed { let Unsealed {
root_key, root_key,
root_key_history_id, root_key_history_id,
@@ -352,7 +360,7 @@ impl Vault {
Ok(v) => v, Ok(v) => v,
Err(_) => unreachable!("HMAC accepts keys of any size"), Err(_) => unreachable!("HMAC accepts keys of any size"),
}); });
hmac.update(&root_key_history_id.to_be_bytes()); hmac.update(&root_key_history_id.to_raw().to_be_bytes());
hmac.update(&mac_input); hmac.update(&mac_input);
let mac = hmac.finalize().into_bytes().to_vec(); let mac = hmac.finalize().into_bytes().to_vec();
@@ -364,7 +372,7 @@ impl Vault {
&mut self, &mut self,
mac_input: Vec<u8>, mac_input: Vec<u8>,
expected_mac: Vec<u8>, expected_mac: Vec<u8>,
key_version: i32, key_version: RootKeyHistoryId,
) -> Result<bool, Error> { ) -> Result<bool, Error> {
let Unsealed { let Unsealed {
root_key, root_key,
@@ -381,7 +389,7 @@ impl Vault {
Ok(v) => v, Ok(v) => v,
Err(_) => unreachable!("HMAC accepts keys of any size"), Err(_) => unreachable!("HMAC accepts keys of any size"),
}); });
hmac.update(&key_version.to_be_bytes()); hmac.update(&key_version.to_raw().to_be_bytes());
hmac.update(&mac_input); hmac.update(&mac_input);
Ok(hmac.verify_slice(&expected_mac).is_ok()) Ok(hmac.verify_slice(&expected_mac).is_ok())
@@ -405,6 +413,7 @@ impl Vault {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::actors::GlobalActors; use crate::actors::GlobalActors;
use crate::db::models::RootKeyHistory;
use arbiter_crypto::safecell::SafeCellHandle as _; use arbiter_crypto::safecell::SafeCellHandle as _;
use super::*; use super::*;
@@ -440,8 +449,8 @@ mod tests {
assert!(n2.to_vec() > n1.to_vec(), "nonce must increase"); assert!(n2.to_vec() > n1.to_vec(), "nonce must increase");
let mut conn = db.get().await.unwrap(); let mut conn = db.get().await.unwrap();
let root_row: models::RootKeyHistory = schema::root_key_history::table let root_row: RootKeyHistory = schema::root_key_history::table
.select(models::RootKeyHistory::as_select()) .select(RootKeyHistory::as_select())
.first(&mut conn) .first(&mut conn)
.await .await
.unwrap(); .unwrap();

View File

@@ -79,10 +79,41 @@ pub mod types {
} }
} }
#[derive(Debug, FromSqlRow, AsExpression, Clone)] macro_rules! declare_id {
#[diesel(sql_type = Integer)] ($name:ident) => {
#[repr(transparent)] // hint compiler to optimize the wrapper struct away #[derive(Debug, FromSqlRow, AsExpression, Clone, Hash, Copy, PartialEq, Eq)]
pub struct ChainId(pub i32); #[diesel(sql_type = Integer)]
#[repr(transparent)] // hint compiler to optimize the wrapper struct away
pub struct $name(i32);
impl $name {
pub const fn to_raw(self) -> i32 {
self.0
}
pub const fn from_raw(raw: i32) -> Self {
Self(raw)
}
}
impl FromSql<Integer, Sqlite> for $name {
fn from_sql(
bytes: <Sqlite as diesel::backend::Backend>::RawValue<'_>,
) -> diesel::deserialize::Result<Self> {
FromSql::<Integer, Sqlite>::from_sql(bytes).map(Self)
}
}
impl ToSql<Integer, Sqlite> for $name {
fn to_sql<'b>(
&'b self,
out: &mut diesel::serialize::Output<'b, '_, Sqlite>,
) -> diesel::serialize::Result {
ToSql::<Integer, Sqlite>::to_sql(&self.0, out)
}
}
};
}
declare_id!(ChainId);
#[expect( #[expect(
clippy::cast_sign_loss, clippy::cast_sign_loss,
@@ -103,21 +134,13 @@ pub mod types {
} }
}; };
impl FromSql<Integer, Sqlite> for ChainId { declare_id!(OperatorId);
fn from_sql( declare_id!(OperatorIdentityId);
bytes: <Sqlite as diesel::backend::Backend>::RawValue<'_>, declare_id!(AeadEncryptedId);
) -> diesel::deserialize::Result<Self> { declare_id!(RootKeyHistoryId);
FromSql::<Integer, Sqlite>::from_sql(bytes).map(Self) declare_id!(TlsHistoryId);
} declare_id!(EvmWalletId);
} declare_id!(ClientId);
impl ToSql<Integer, Sqlite> for ChainId {
fn to_sql<'b>(
&'b self,
out: &mut diesel::serialize::Output<'b, '_, Sqlite>,
) -> diesel::serialize::Result {
ToSql::<Integer, Sqlite>::to_sql(&self.0, out)
}
}
} }
pub use types::*; pub use types::*;
@@ -130,12 +153,12 @@ pub use types::*;
)] )]
#[diesel(table_name = aead_encrypted, check_for_backend(Sqlite))] #[diesel(table_name = aead_encrypted, check_for_backend(Sqlite))]
pub struct AeadEncrypted { pub struct AeadEncrypted {
pub id: i32, pub id: AeadEncryptedId,
pub ciphertext: Vec<u8>, pub ciphertext: Vec<u8>,
pub tag: Vec<u8>, pub tag: Vec<u8>,
pub current_nonce: Vec<u8>, pub current_nonce: Vec<u8>,
pub schema_version: i32, pub schema_version: i32,
pub associated_root_key_id: i32, // references root_key_history.id pub associated_root_key_id: RootKeyHistoryId,
pub created_at: SqliteTimestamp, pub created_at: SqliteTimestamp,
} }
@@ -148,7 +171,7 @@ pub struct AeadEncrypted {
attributes_with = "deriveless" attributes_with = "deriveless"
)] )]
pub struct RootKeyHistory { pub struct RootKeyHistory {
pub id: i32, pub id: RootKeyHistoryId,
pub ciphertext: Vec<u8>, pub ciphertext: Vec<u8>,
pub tag: Vec<u8>, pub tag: Vec<u8>,
pub root_key_encryption_nonce: Vec<u8>, pub root_key_encryption_nonce: Vec<u8>,
@@ -166,7 +189,7 @@ pub struct RootKeyHistory {
attributes_with = "deriveless" attributes_with = "deriveless"
)] )]
pub struct TlsHistory { pub struct TlsHistory {
pub id: i32, pub id: TlsHistoryId,
pub cert: String, pub cert: String,
pub cert_key: String, // PEM Encoded private key pub cert_key: String, // PEM Encoded private key
pub ca_cert: String, // PEM Encoded certificate for cert signing pub ca_cert: String, // PEM Encoded certificate for cert signing
@@ -191,7 +214,7 @@ pub struct ArbiterSettings {
attributes_with = "deriveless" attributes_with = "deriveless"
)] )]
pub struct EvmWallet { pub struct EvmWallet {
pub id: i32, pub id: EvmWalletId,
pub address: Vec<u8>, pub address: Vec<u8>,
pub aead_encrypted_id: i32, pub aead_encrypted_id: i32,
pub created_at: SqliteTimestamp, pub created_at: SqliteTimestamp,
@@ -213,7 +236,7 @@ pub struct EvmWallet {
)] )]
pub struct EvmWalletAccess { pub struct EvmWalletAccess {
pub id: i32, pub id: i32,
pub wallet_id: i32, pub wallet_id: EvmWalletId,
pub client_id: i32, pub client_id: i32,
pub created_at: SqliteTimestamp, pub created_at: SqliteTimestamp,
} }
@@ -240,7 +263,7 @@ pub struct ProgramClientMetadataHistory {
#[derive(Models, Queryable, Debug, Insertable, Selectable)] #[derive(Models, Queryable, Debug, Insertable, Selectable)]
#[diesel(table_name = schema::program_client, check_for_backend(Sqlite))] #[diesel(table_name = schema::program_client, check_for_backend(Sqlite))]
pub struct ProgramClient { pub struct ProgramClient {
pub id: i32, pub id: ClientId,
pub public_key: Vec<u8>, pub public_key: Vec<u8>,
pub metadata_id: i32, pub metadata_id: i32,
pub created_at: SqliteTimestamp, pub created_at: SqliteTimestamp,
@@ -250,12 +273,22 @@ pub struct ProgramClient {
#[derive(Queryable, Debug)] #[derive(Queryable, Debug)]
#[diesel(table_name = schema::operator_client, check_for_backend(Sqlite))] #[diesel(table_name = schema::operator_client, check_for_backend(Sqlite))]
pub struct OperatorClient { pub struct OperatorClient {
pub id: i32, pub id: OperatorIdentityId,
pub public_key: Vec<u8>, pub public_key: Vec<u8>,
pub created_at: SqliteTimestamp, pub created_at: SqliteTimestamp,
pub updated_at: SqliteTimestamp, pub updated_at: SqliteTimestamp,
} }
#[derive(Queryable, Debug)]
#[diesel(table_name = schema::operator, check_for_backend(Sqlite))]
pub struct Operator {
pub id: OperatorId,
pub share: Vec<u8>,
pub share_nonce: Vec<u8>,
pub created_at: SqliteTimestamp,
pub updated_at: SqliteTimestamp,
}
#[derive(Models, Queryable, Debug, Insertable, Selectable)] #[derive(Models, Queryable, Debug, Insertable, Selectable)]
#[diesel(table_name = evm_ether_transfer_limit, check_for_backend(Sqlite))] #[diesel(table_name = evm_ether_transfer_limit, check_for_backend(Sqlite))]
#[view( #[view(
@@ -399,7 +432,7 @@ pub struct IntegrityEnvelope {
pub entity_kind: String, pub entity_kind: String,
pub entity_id: Vec<u8>, pub entity_id: Vec<u8>,
pub payload_version: i32, pub payload_version: i32,
pub key_version: i32, pub key_version: RootKeyHistoryId,
pub mac: Vec<u8>, pub mac: Vec<u8>,
pub signed_at: SqliteTimestamp, pub signed_at: SqliteTimestamp,
pub created_at: SqliteTimestamp, pub created_at: SqliteTimestamp,

View File

@@ -152,6 +152,25 @@ diesel::table! {
} }
} }
diesel::table! {
operator (id) {
id -> Nullable<Integer>,
share -> Binary,
share_nonce -> Binary,
created_at -> Integer,
updated_at -> Integer,
}
}
diesel::table! {
operator_identity (id) {
id -> Integer,
public_key -> Binary,
created_at -> Integer,
updated_at -> Integer,
}
}
diesel::table! { diesel::table! {
program_client (id) { program_client (id) {
id -> Integer, id -> Integer,
@@ -185,15 +204,6 @@ diesel::table! {
} }
} }
diesel::table! {
operator_client (id) {
id -> Integer,
public_key -> Binary,
created_at -> Integer,
updated_at -> Integer,
}
}
diesel::joinable!(aead_encrypted -> root_key_history (associated_root_key_id)); diesel::joinable!(aead_encrypted -> root_key_history (associated_root_key_id));
diesel::joinable!(arbiter_settings -> root_key_history (root_key_id)); diesel::joinable!(arbiter_settings -> root_key_history (root_key_id));
diesel::joinable!(arbiter_settings -> tls_history (tls_id)); diesel::joinable!(arbiter_settings -> tls_history (tls_id));
@@ -212,6 +222,7 @@ diesel::joinable!(evm_transaction_log -> evm_wallet_access (wallet_access_id));
diesel::joinable!(evm_wallet -> aead_encrypted (aead_encrypted_id)); diesel::joinable!(evm_wallet -> aead_encrypted (aead_encrypted_id));
diesel::joinable!(evm_wallet_access -> evm_wallet (wallet_id)); diesel::joinable!(evm_wallet_access -> evm_wallet (wallet_id));
diesel::joinable!(evm_wallet_access -> program_client (client_id)); diesel::joinable!(evm_wallet_access -> program_client (client_id));
diesel::joinable!(operator -> operator_identity (id));
diesel::joinable!(program_client -> client_metadata (metadata_id)); diesel::joinable!(program_client -> client_metadata (metadata_id));
diesel::allow_tables_to_appear_in_same_query!( diesel::allow_tables_to_appear_in_same_query!(
@@ -230,8 +241,9 @@ diesel::allow_tables_to_appear_in_same_query!(
evm_wallet, evm_wallet,
evm_wallet_access, evm_wallet_access,
integrity_envelope, integrity_envelope,
operator,
operator_identity,
program_client, program_client,
root_key_history, root_key_history,
tls_history, tls_history,
operator_client,
); );

View File

@@ -359,7 +359,8 @@ mod tests {
use crate::db::{ use crate::db::{
self, DatabaseConnection, self, DatabaseConnection,
models::{ models::{
EvmBasicGrant, EvmWalletAccess, NewEvmBasicGrant, NewEvmTransactionLog, SqliteTimestamp, EvmBasicGrant, EvmWalletAccess, EvmWalletId, NewEvmBasicGrant, NewEvmTransactionLog,
SqliteTimestamp,
}, },
schema::{evm_basic_grant, evm_transaction_log}, schema::{evm_basic_grant, evm_transaction_log},
}; };
@@ -377,7 +378,7 @@ mod tests {
EvalContext { EvalContext {
target: EvmWalletAccess { target: EvmWalletAccess {
id: WALLET_ACCESS_ID, id: WALLET_ACCESS_ID,
wallet_id: 10, wallet_id: EvmWalletId::from_raw(5),
client_id: 20, client_id: 20,
created_at: SqliteTimestamp(Utc::now()), created_at: SqliteTimestamp(Utc::now()),
}, },

View File

@@ -3,7 +3,8 @@ use crate::{
db::{ db::{
self, DatabaseConnection, self, DatabaseConnection,
models::{ models::{
EvmBasicGrant, EvmWalletAccess, NewEvmBasicGrant, NewEvmTransactionLog, SqliteTimestamp, EvmBasicGrant, EvmWalletAccess, EvmWalletId, NewEvmBasicGrant, NewEvmTransactionLog,
SqliteTimestamp,
}, },
schema::{evm_basic_grant, evm_transaction_log}, schema::{evm_basic_grant, evm_transaction_log},
}, },
@@ -31,7 +32,7 @@ fn ctx(to: Address, value: U256) -> EvalContext {
EvalContext { EvalContext {
target: EvmWalletAccess { target: EvmWalletAccess {
id: WALLET_ACCESS_ID, id: WALLET_ACCESS_ID,
wallet_id: 10, wallet_id: EvmWalletId::from_raw(10),
client_id: 20, client_id: 20,
created_at: SqliteTimestamp(Utc::now()), created_at: SqliteTimestamp(Utc::now()),
}, },

View File

@@ -2,7 +2,7 @@ use super::{Settings, TokenTransfer};
use crate::{ use crate::{
db::{ db::{
self, DatabaseConnection, self, DatabaseConnection,
models::{EvmBasicGrant, EvmWalletAccess, NewEvmBasicGrant, SqliteTimestamp}, models::{EvmBasicGrant, EvmWalletAccess, EvmWalletId, NewEvmBasicGrant, SqliteTimestamp},
schema::evm_basic_grant, schema::evm_basic_grant,
}, },
evm::{ evm::{
@@ -45,7 +45,7 @@ fn ctx(to: Address, calldata: Bytes) -> EvalContext {
EvalContext { EvalContext {
target: EvmWalletAccess { target: EvmWalletAccess {
id: WALLET_ACCESS_ID, id: WALLET_ACCESS_ID,
wallet_id: 10, wallet_id: EvmWalletId::from_raw(10),
client_id: 20, client_id: 20,
created_at: SqliteTimestamp(Utc::now()), created_at: SqliteTimestamp(Utc::now()),
}, },

View File

@@ -90,7 +90,7 @@ async fn handle_wallet_list(
.into_iter() .into_iter()
.map(|(id, address)| WalletEntry { .map(|(id, address)| WalletEntry {
address: address.to_vec(), address: address.to_vec(),
id, id: id.to_raw(),
}) })
.collect(), .collect(),
}), }),

View File

@@ -1,11 +1,10 @@
use crate::{ use crate::{
db::models::{CoreEvmWalletAccess, NewEvmWalletAccess}, db::models::{CoreEvmWalletAccess, EvmWalletId, NewEvmWalletAccess},
evm::policies::{ evm::policies::{
SharedGrantSettings, SpecificGrant, TransactionRateLimit, VolumeRateLimit, ether_transfer, SharedGrantSettings, SpecificGrant, TransactionRateLimit, VolumeRateLimit, ether_transfer,
token_transfers, token_transfers,
}, },
grpc::Convert, grpc::{Convert, TryConvert},
grpc::TryConvert,
}; };
use arbiter_proto::{ use arbiter_proto::{
proto::evm::{ proto::evm::{
@@ -150,7 +149,7 @@ impl Convert for WalletAccess {
fn convert(self) -> Self::Output { fn convert(self) -> Self::Output {
NewEvmWalletAccess { NewEvmWalletAccess {
wallet_id: self.wallet_id, wallet_id: EvmWalletId::from_raw(self.wallet_id),
client_id: self.sdk_client_id, client_id: self.sdk_client_id,
} }
} }
@@ -165,7 +164,7 @@ impl TryConvert for SdkClientWalletAccess {
return Err(Status::invalid_argument("Missing wallet access entry")); return Err(Status::invalid_argument("Missing wallet access entry"));
}; };
Ok(CoreEvmWalletAccess { Ok(CoreEvmWalletAccess {
wallet_id: access.wallet_id, wallet_id: EvmWalletId::from_raw(access.wallet_id),
client_id: access.sdk_client_id, client_id: access.sdk_client_id,
id: self.id, id: self.id,
}) })

View File

@@ -103,7 +103,7 @@ impl Convert for EvmWalletAccess {
Self::Output { Self::Output {
id: self.id, id: self.id,
access: Some(WalletAccess { access: Some(WalletAccess {
wallet_id: self.wallet_id, wallet_id: self.wallet_id.to_raw(),
sdk_client_id: self.client_id, sdk_client_id: self.client_id,
}), }),
} }

View File

@@ -2,7 +2,7 @@ use crate::{
db::models::NewEvmWalletAccess, db::models::NewEvmWalletAccess,
grpc::Convert, grpc::Convert,
peers::operator::{ peers::operator::{
OutOfBand, OperatorSession, OperatorSession, OutOfBand,
session::handlers::{ session::handlers::{
HandleGrantEvmWalletAccess, HandleListWalletAccess, HandleNewClientApprove, HandleGrantEvmWalletAccess, HandleListWalletAccess, HandleNewClientApprove,
HandleRevokeEvmWalletAccess, HandleSdkClientList, HandleRevokeEvmWalletAccess, HandleSdkClientList,
@@ -11,8 +11,8 @@ use crate::{
}; };
use arbiter_crypto::authn; use arbiter_crypto::authn;
use arbiter_proto::proto::{ use arbiter_proto::proto::{
shared::ClientInfo as ProtoClientMetadata,
operator::{ operator::{
operator_response::Payload as OperatorResponsePayload,
sdk_client::{ sdk_client::{
self as proto_sdk_client, ConnectionCancel as ProtoSdkClientConnectionCancel, self as proto_sdk_client, ConnectionCancel as ProtoSdkClientConnectionCancel,
ConnectionRequest as ProtoSdkClientConnectionRequest, ConnectionRequest as ProtoSdkClientConnectionRequest,
@@ -24,8 +24,8 @@ use arbiter_proto::proto::{
request::Payload as SdkClientRequestPayload, request::Payload as SdkClientRequestPayload,
response::Payload as SdkClientResponsePayload, response::Payload as SdkClientResponsePayload,
}, },
operator_response::Payload as OperatorResponsePayload,
}, },
shared::ClientInfo as ProtoClientMetadata,
}; };
use kameo::actor::ActorRef; use kameo::actor::ActorRef;
@@ -115,7 +115,7 @@ async fn handle_list(
clients: clients clients: clients
.into_iter() .into_iter()
.map(|(client, metadata)| ProtoSdkClientEntry { .map(|(client, metadata)| ProtoSdkClientEntry {
id: client.id, id: client.id.to_raw(),
pubkey: client.public_key.clone(), pubkey: client.public_key.clone(),
info: Some(ProtoClientMetadata { info: Some(ProtoClientMetadata {
name: metadata.name, name: metadata.name,

View File

@@ -4,7 +4,7 @@ use super::{
}; };
use crate::{ use crate::{
actors::bootstrap::ConsumeToken, actors::bootstrap::ConsumeToken,
db::{DatabasePool, schema::operator_client}, db::{DatabasePool, schema::operator_identity},
peers::operator::auth::Outbound, peers::operator::auth::Outbound,
}; };
use arbiter_crypto::authn::{self, AuthChallenge, OPERATOR_CONTEXT}; use arbiter_crypto::authn::{self, AuthChallenge, OPERATOR_CONTEXT};
@@ -44,9 +44,9 @@ async fn get_client_id(db: &DatabasePool, pubkey: &authn::PublicKey) -> Result<O
Error::internal("Database unavailable") Error::internal("Database unavailable")
})?; })?;
operator_client::table operator_identity::table
.filter(operator_client::public_key.eq(pubkey.to_bytes())) .filter(operator_identity::public_key.eq(pubkey.to_bytes()))
.select(operator_client::id) .select(operator_identity::id)
.first::<i32>(&mut conn) .first::<i32>(&mut conn)
.await .await
.optional() .optional()
@@ -63,9 +63,9 @@ async fn register_key(db: &DatabasePool, pubkey: &authn::PublicKey) -> Result<i3
Error::internal("Database unavailable") Error::internal("Database unavailable")
})?; })?;
let id: i32 = diesel::insert_into(operator_client::table) let id: i32 = diesel::insert_into(operator_identity::table)
.values((operator_client::public_key.eq(pubkey_bytes),)) .values((operator_identity::public_key.eq(pubkey_bytes),))
.returning(operator_client::id) .returning(operator_identity::id)
.get_result(&mut conn) .get_result(&mut conn)
.await .await
.map_err(|e| { .map_err(|e| {

View File

@@ -1,12 +1,16 @@
use super::{Error, OperatorSession}; use super::{Error, OperatorSession};
use crate::{ use crate::{
actors::evm::{ actors::{
ClientSignTransaction, Generate, ListWallets, OperatorCreateGrant, OperatorListGrants, evm::{
SignTransactionError as EvmSignError, ClientSignTransaction, Generate, ListWallets, OperatorCreateGrant, OperatorListGrants,
SignTransactionError as EvmSignError,
},
flow_coordinator::client_connect_approval::ClientApprovalAnswer,
vault::VaultState,
},
db::models::{
EvmWalletAccess, EvmWalletId, NewEvmWalletAccess, ProgramClient, ProgramClientMetadata,
}, },
actors::flow_coordinator::client_connect_approval::ClientApprovalAnswer,
actors::vault::VaultState,
db::models::{EvmWalletAccess, NewEvmWalletAccess, ProgramClient, ProgramClientMetadata},
evm::policies::{Grant, SpecificGrant}, evm::policies::{Grant, SpecificGrant},
}; };
use arbiter_crypto::authn; use arbiter_crypto::authn;
@@ -70,7 +74,9 @@ impl OperatorSession {
} }
#[message] #[message]
pub(crate) async fn handle_evm_wallet_list(&mut self) -> Result<Vec<(i32, Address)>, Error> { pub(crate) async fn handle_evm_wallet_list(
&mut self,
) -> Result<Vec<(EvmWalletId, Address)>, Error> {
match self.props.actors.evm.ask(ListWallets {}).await { match self.props.actors.evm.ask(ListWallets {}).await {
Ok(wallets) => Ok(wallets), Ok(wallets) => Ok(wallets),
Err(err) => { Err(err) => {

View File

@@ -86,8 +86,8 @@ async fn insert_bootstrap_sentinel_operator(db: &db::DatabasePool) {
.0 .0
.to_vec(); .to_vec();
insert_into(schema::operator_client::table) insert_into(schema::operator_identity::table)
.values((schema::operator_client::public_key.eq(sentinel_key),)) .values((schema::operator_identity::public_key.eq(sentinel_key),))
.execute(&mut conn) .execute(&mut conn)
.await .await
.unwrap(); .unwrap();

View File

@@ -206,8 +206,8 @@ pub async fn bootstrap_token_auth() {
task.await.unwrap().unwrap(); task.await.unwrap().unwrap();
let mut conn = db.get().await.unwrap(); let mut conn = db.get().await.unwrap();
let stored_pubkey: Vec<u8> = schema::operator_client::table let stored_pubkey: Vec<u8> = schema::operator_identity::table
.select(schema::operator_client::public_key) .select(schema::operator_identity::public_key)
.first::<Vec<u8>>(&mut conn) .first::<Vec<u8>>(&mut conn)
.await .await
.unwrap(); .unwrap();
@@ -259,7 +259,7 @@ pub async fn bootstrap_invalid_token_auth() {
)); ));
let mut conn = db.get().await.unwrap(); let mut conn = db.get().await.unwrap();
let count: i64 = schema::operator_client::table let count: i64 = schema::operator_identity::table
.count() .count()
.get_result::<i64>(&mut conn) .get_result::<i64>(&mut conn)
.await .await
@@ -285,9 +285,9 @@ pub async fn challenge_auth() {
{ {
let mut conn = db.get().await.unwrap(); let mut conn = db.get().await.unwrap();
let id: i32 = insert_into(schema::operator_client::table) let id: i32 = insert_into(schema::operator_identity::table)
.values((schema::operator_client::public_key.eq(pubkey_bytes.clone()),)) .values((schema::operator_identity::public_key.eq(pubkey_bytes.clone()),))
.returning(schema::operator_client::id) .returning(schema::operator_identity::id)
.get_result(&mut conn) .get_result(&mut conn)
.await .await
.unwrap(); .unwrap();
@@ -371,8 +371,8 @@ pub async fn challenge_auth_rejects_integrity_tag_mismatch_when_unsealed() {
{ {
let mut conn = db.get().await.unwrap(); let mut conn = db.get().await.unwrap();
insert_into(schema::operator_client::table) insert_into(schema::operator_identity::table)
.values((schema::operator_client::public_key.eq(pubkey_bytes.clone()),)) .values((schema::operator_identity::public_key.eq(pubkey_bytes.clone()),))
.execute(&mut conn) .execute(&mut conn)
.await .await
.unwrap(); .unwrap();
@@ -444,9 +444,9 @@ pub async fn challenge_auth_rejects_invalid_signature() {
{ {
let mut conn = db.get().await.unwrap(); let mut conn = db.get().await.unwrap();
let id: i32 = insert_into(schema::operator_client::table) let id: i32 = insert_into(schema::operator_identity::table)
.values((schema::operator_client::public_key.eq(pubkey_bytes.clone()),)) .values((schema::operator_identity::public_key.eq(pubkey_bytes.clone()),))
.returning(schema::operator_client::id) .returning(schema::operator_identity::id)
.get_result(&mut conn) .get_result(&mut conn)
.await .await
.unwrap(); .unwrap();