11use crate :: { get_blob, Message , PackageId , Request } ;
2- use alloy:: rpc:: types:: error;
32use serde:: { de:: DeserializeOwned , Deserialize , Serialize } ;
43use std:: marker:: PhantomData ;
54use 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 ) ]
1111pub 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 ) ]
2021pub 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 ) ]
5689pub 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 ) ]
76109pub 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 ) ]
117154pub 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