Skip to content

Commit bf89fd6

Browse files
authored
Merge pull request #129 from kinode-dao/dr/kv-overhaul
kv: new types from runtime
2 parents ef78f0e + b086d98 commit bf89fd6

File tree

1 file changed

+96
-59
lines changed

1 file changed

+96
-59
lines changed

src/kv.rs

Lines changed: 96 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,119 +1,156 @@
11
use crate::{get_blob, Message, PackageId, Request};
2-
use alloy::rpc::types::error;
32
use serde::{de::DeserializeOwned, Deserialize, Serialize};
43
use std::marker::PhantomData;
54
use thiserror::Error;
65

7-
/// Actions are sent to a specific key value database, `db` is the name,
8-
/// `package_id` is the [`PackageId`]. Capabilities are checked, you can access another process's
9-
/// database if it has given you the [`crate::Capability`].
10-
#[derive(Debug, Serialize, Deserialize)]
6+
/// Actions are sent to a specific key value database. `db` is the name,
7+
/// `package_id` is the [`PackageId`] that created the database. Capabilities
8+
/// are checked: you can access another process's database if it has given
9+
/// you the read and/or write capability to do so.
10+
#[derive(Clone, Debug, Serialize, Deserialize)]
1111
pub struct KvRequest {
1212
pub package_id: PackageId,
1313
pub db: String,
1414
pub action: KvAction,
1515
}
1616

17-
/// IPC Action format, representing operations that can be performed on the key-value runtime module.
18-
/// These actions are included in a KvRequest sent to the kv:distro:sys runtime module.
19-
#[derive(Debug, Serialize, Deserialize, Clone)]
17+
/// IPC Action format representing operations that can be performed on the
18+
/// key-value runtime module. These actions are included in a [`KvRequest`]
19+
/// sent to the `kv:distro:sys` runtime module.
20+
#[derive(Clone, Debug, Serialize, Deserialize)]
2021
pub enum KvAction {
2122
/// Opens an existing key-value database or creates a new one if it doesn't exist.
23+
/// Requires `package_id` in [`KvRequest`] to match the package ID of the sender.
24+
/// The sender will own the database and can remove it with [`KvAction::RemoveDb`].
25+
///
26+
/// A successful open will respond with [`KvResponse::Ok`]. Any error will be
27+
/// contained in the [`KvResponse::Err`] variant.
2228
Open,
2329
/// Permanently deletes the entire key-value database.
30+
/// Requires `package_id` in [`KvRequest`] to match the package ID of the sender.
31+
/// Only the owner can remove the database.
32+
///
33+
/// A successful remove will respond with [`KvResponse::Ok`]. Any error will be
34+
/// contained in the [`KvResponse::Err`] variant.
2435
RemoveDb,
2536
/// Sets a value for the specified key in the database.
2637
///
2738
/// # Parameters
2839
/// * `key` - The key as a byte vector
2940
/// * `tx_id` - Optional transaction ID if this operation is part of a transaction
41+
/// * blob: [`Vec<u8>`] - Byte vector to store for the key
42+
///
43+
/// Using this action requires the sender to have the write capability
44+
/// for the database.
45+
///
46+
/// A successful set will respond with [`KvResponse::Ok`]. Any error will be
47+
/// contained in the [`KvResponse::Err`] variant.
3048
Set { key: Vec<u8>, tx_id: Option<u64> },
3149
/// Deletes a key-value pair from the database.
3250
///
3351
/// # Parameters
3452
/// * `key` - The key to delete as a byte vector
3553
/// * `tx_id` - Optional transaction ID if this operation is part of a transaction
54+
///
55+
/// Using this action requires the sender to have the write capability
56+
/// for the database.
57+
///
58+
/// A successful delete will respond with [`KvResponse::Ok`]. Any error will be
59+
/// contained in the [`KvResponse::Err`] variant.
3660
Delete { key: Vec<u8>, tx_id: Option<u64> },
3761
/// Retrieves the value associated with the specified key.
3862
///
3963
/// # Parameters
40-
/// * `key` - The key to look up as a byte vector
41-
Get { key: Vec<u8> },
64+
/// * The key to look up as a byte vector
65+
///
66+
/// Using this action requires the sender to have the read capability
67+
/// for the database.
68+
///
69+
/// A successful get will respond with [`KvResponse::Get`], where the response blob
70+
/// contains the value associated with the key if any. Any error will be
71+
/// contained in the [`KvResponse::Err`] variant.
72+
Get(Vec<u8>),
4273
/// Begins a new transaction for atomic operations.
74+
///
75+
/// Sending this will prompt a [`KvResponse::BeginTx`] response with the
76+
/// transaction ID. Any error will be contained in the [`KvResponse::Err`] variant.
4377
BeginTx,
4478
/// Commits all operations in the specified transaction.
4579
///
4680
/// # Parameters
4781
/// * `tx_id` - The ID of the transaction to commit
82+
///
83+
/// A successful commit will respond with [`KvResponse::Ok`]. Any error will be
84+
/// contained in the [`KvResponse::Err`] variant.
4885
Commit { tx_id: u64 },
49-
/// Creates a backup of the database.
50-
Backup,
5186
}
5287

53-
/// Response types for key-value store operations.
54-
/// These responses are returned after processing a KvAction request.
55-
#[derive(Debug, Serialize, Deserialize)]
88+
#[derive(Clone, Debug, Serialize, Deserialize)]
5689
pub enum KvResponse {
5790
/// Indicates successful completion of an operation.
91+
/// Sent in response to actions Open, RemoveDb, Set, Delete, and Commit.
5892
Ok,
5993
/// Returns the transaction ID for a newly created transaction.
6094
///
6195
/// # Fields
6296
/// * `tx_id` - The ID of the newly created transaction
6397
BeginTx { tx_id: u64 },
64-
/// Returns the key that was retrieved from the database.
98+
/// Returns the value for the key that was retrieved from the database.
6599
///
66-
/// # Fields
67-
/// * `key` - The retrieved key as a byte vector
68-
Get { key: Vec<u8> },
100+
/// # Parameters
101+
/// * The retrieved key as a byte vector
102+
/// * blob: [`Vec<u8>`] - Byte vector associated with the key
103+
Get(Vec<u8>),
69104
/// Indicates an error occurred during the operation.
70105
Err(KvError),
71106
}
72107

73-
/// Errors that can occur during key-value store operations.
74-
/// These errors are returned as part of `KvResponse::Err` when an operation fails.
75-
#[derive(Debug, Serialize, Deserialize, Error)]
108+
#[derive(Clone, Debug, Serialize, Deserialize, Error)]
76109
pub enum KvError {
77-
/// The requested database does not exist.
78-
#[error("kv: DbDoesNotExist")]
79-
NoDb,
80-
/// The requested key was not found in the database.
81-
#[error("kv: KeyNotFound")]
110+
#[error("db [{0}, {1}] does not exist")]
111+
NoDb(PackageId, String),
112+
#[error("key not found")]
82113
KeyNotFound,
83-
/// No active transaction found for the given transaction ID.
84-
#[error("kv: no Tx found")]
85-
NoTx,
86-
/// The operation requires capabilities that the caller doesn't have.
87-
///
88-
/// # Fields
89-
/// * `error` - Description of the missing capability or permission
90-
#[error("kv: No capability: {error}")]
91-
NoCap { error: String },
92-
/// An internal RocksDB error occurred during the operation.
93-
///
94-
/// # Fields
95-
/// * `action` - The operation that was being performed
96-
/// * `error` - The specific error message from RocksDB
97-
#[error("kv: rocksdb internal error: {error}")]
98-
RocksDBError { action: String, error: String },
99-
/// Error parsing or processing input data.
100-
///
101-
/// # Fields
102-
/// * `error` - Description of what was invalid about the input
103-
#[error("kv: input bytes/json/key error: {error}")]
104-
InputError { error: String },
105-
/// An I/O error occurred during the operation.
106-
///
107-
/// # Fields
108-
/// * `error` - Description of the I/O error
109-
#[error("kv: IO error: {error}")]
110-
IOError { error: String },
114+
#[error("no transaction {0} found")]
115+
NoTx(u64),
116+
#[error("no write capability for requested DB")]
117+
NoWriteCap,
118+
#[error("no read capability for requested DB")]
119+
NoReadCap,
120+
#[error("request to open or remove DB with mismatching package ID")]
121+
MismatchingPackageId,
122+
#[error("failed to generate capability for new DB")]
123+
AddCapFailed,
124+
#[error("kv got a malformed request that either failed to deserialize or was missing a required blob")]
125+
MalformedRequest,
126+
#[error("RocksDB internal error: {0}")]
127+
RocksDBError(String),
128+
#[error("IO error: {0}")]
129+
IOError(String),
130+
}
131+
132+
/// The JSON parameters contained in all capabilities issued by `kv:distro:sys`.
133+
///
134+
/// # Fields
135+
/// * `kind` - The kind of capability, either [`KvCapabilityKind::Read`] or [`KvCapabilityKind::Write`]
136+
/// * `db_key` - The database key, a tuple of the [`PackageId`] that created the database and the database name
137+
#[derive(Clone, Debug, Serialize, Deserialize)]
138+
pub struct KvCapabilityParams {
139+
pub kind: KvCapabilityKind,
140+
pub db_key: (PackageId, String),
141+
}
142+
143+
#[derive(Clone, Debug, Serialize, Deserialize)]
144+
#[serde(rename_all = "lowercase")]
145+
pub enum KvCapabilityKind {
146+
Read,
147+
Write,
111148
}
112149

113150
/// Kv helper struct for a db.
114151
/// Opening or creating a kv will give you a `Result<Kv>`.
115152
/// You can call it's impl functions to interact with it.
116-
#[derive(Debug, Clone, Serialize, Deserialize)]
153+
#[derive(Clone, Debug, Serialize, Deserialize)]
117154
pub struct Kv<K, V> {
118155
pub package_id: PackageId,
119156
pub db: String,
@@ -134,7 +171,7 @@ where
134171
.body(serde_json::to_vec(&KvRequest {
135172
package_id: self.package_id.clone(),
136173
db: self.db.clone(),
137-
action: KvAction::Get { key },
174+
action: KvAction::Get(key),
138175
})?)
139176
.send_and_await_response(self.timeout)?;
140177

@@ -171,7 +208,7 @@ where
171208
.body(serde_json::to_vec(&KvRequest {
172209
package_id: self.package_id.clone(),
173210
db: self.db.clone(),
174-
action: KvAction::Get { key },
211+
action: KvAction::Get(key),
175212
})?)
176213
.send_and_await_response(self.timeout)?;
177214

@@ -373,7 +410,7 @@ impl Kv<Vec<u8>, Vec<u8>> {
373410
.body(serde_json::to_vec(&KvRequest {
374411
package_id: self.package_id.clone(),
375412
db: self.db.clone(),
376-
action: KvAction::Get { key: key.to_vec() },
413+
action: KvAction::Get(key.to_vec()),
377414
})?)
378415
.send_and_await_response(self.timeout)?;
379416

0 commit comments

Comments
 (0)