tea_keyvalue_provider/
lib.rs

1//! tea-kvp-provider
2//!
3//! This WASCC provider is an enhanced version of Kevin Hoffman's original 
4//! [Key-Value Pair Provider example](https://github.com/wascc/examples/tree/master/keyvalue-provider)
5//!  with the following enhancedments:
6//! - Values are stored in Vec<u8> instead of String
7//! - New added Sorted Vec type. It will sort tuple values by the first element when insert.
8//!  
9
10//! 
11//! # About the Tea Project
12//! 
13//! Tea Project (Trusted Execution & Attestation) is a Wasm runtime build on top of RoT(Root of Trust)
14//! from both trusted hardware environment and blockchain technologies. Developer, Host and Consumer 
15//! do not have to trust any others to not only protecting privacy but also preventing cyber attacks. 
16//! The execution environment under remoted attestation can be verified by blockchain consensys. 
17//! Crypto economy is used as motivation that hosts are willing run trusted computing nodes. This 
18//! platform can be used by CDN providers, IPFS Nodes or existing cloud providers to enhance existing 
19//! infrastructure to be more secure and trustless.
20//! 
21//! Introduction [blog post](https://medium.com/@pushbar/0-of-n-cover-letter-of-the-trusted-webassembly-runtime-on-ipfs-12a4fd8c4338) 
22//! 
23//! Project [repo](http://github.com/tearust). More and more repo will be exposed soon. 
24//! 
25//! Yet to come //! project site [( not completed yet) http://www.t-rust.com/](http://www.t-rust.com/) 
26//! 
27//! Contact: kevin.zhang.canada_at_gmail_dot_com. 
28//! 
29//! We are just started, all kinds of help are welcome! 
30//! 
31
32
33#[macro_use]
34extern crate wascc_codec as codec;
35
36#[macro_use]
37extern crate log;
38
39
40mod kv;
41
42use crate::kv::KeyValueStore;
43use codec::capabilities::{CapabilityProvider, Dispatcher, NullDispatcher};
44use codec::core::{OP_BIND_ACTOR, OP_REMOVE_ACTOR};
45use tea_codec::keyvalue;
46use tea_codec::keyvalue::*;
47use wascc_codec::core::CapabilityConfiguration;
48use wascc_codec::{deserialize, serialize};
49
50use std::error::Error;
51use std::sync::RwLock;
52
53#[cfg(not(feature = "static_plugin"))]
54capability_provider!(KeyvalueProvider, KeyvalueProvider::new);
55
56const CAPABILITY_ID: &str = "tea:keyvalue";
57
58pub struct KeyvalueProvider {
59    dispatcher: RwLock<Box<dyn Dispatcher>>,
60    store: RwLock<KeyValueStore>,
61}
62
63impl Default for KeyvalueProvider {
64    fn default() -> Self {
65        match env_logger::try_init() {
66            Ok(_) => {}
67            Err(_) => {}
68        };
69        KeyvalueProvider {
70            dispatcher: RwLock::new(Box::new(NullDispatcher::new())),
71            store: RwLock::new(KeyValueStore::new()),
72        }
73    }
74}
75
76impl KeyvalueProvider {
77    pub fn new() -> Self {
78        Self::default()
79    }
80
81    fn configure(&self, _config: CapabilityConfiguration) -> Result<Vec<u8>, Box<dyn Error>> {
82        // Do nothing here
83        Ok(vec![])
84    }
85
86    fn remove_actor(&self, _config: CapabilityConfiguration) -> Result<Vec<u8>, Box<dyn Error>> {
87        // Do nothing here
88        Ok(vec![])
89    }
90
91    fn add(&self, _actor: &str, req: AddRequest) -> Result<Vec<u8>, Box<dyn Error>> {
92        let mut store = self.store.write().unwrap();
93        let res: i32 = store.incr(&req.key, req.value)?;
94        let resp = AddResponse { value: res };
95
96        Ok(serialize(resp)?)
97    }
98
99    fn del(&self, _actor: &str, req: DelRequest) -> Result<Vec<u8>, Box<dyn Error>> {
100        let mut store = self.store.write().unwrap();
101        store.del(&req.key)?;
102        let resp = DelResponse { key: req.key };
103
104        Ok(serialize(resp)?)
105    }
106
107    fn get(&self, _actor: &str, req: GetRequest) -> Result<Vec<u8>, Box<dyn Error>> {
108        let store = self.store.read().unwrap();
109        if !store.exists(&req.key)? {
110            Ok(serialize(GetResponse {
111                value: vec![],
112                exists: false,
113            })?)
114        } else {
115            let v = store.get(&req.key);
116            Ok(serialize(match v {
117                Ok(s) => GetResponse {
118                    value: s,
119                    exists: true,
120                },
121                Err(e) => {
122                    eprint!("GET for {} failed: {}", &req.key, e);
123                    GetResponse {
124                        value: vec![],
125                        exists: false,
126                    }
127                }
128            })?)
129        }
130    }
131
132    fn list_clear(&self, actor: &str, req: ListClearRequest) -> Result<Vec<u8>, Box<dyn Error>> {
133        self.del(actor, DelRequest { key: req.key })
134    }
135
136    fn list_range(&self, _actor: &str, req: ListRangeRequest) -> Result<Vec<u8>, Box<dyn Error>> {
137        let store = self.store.read().unwrap();
138        let result: Vec<Vec<u8>> = store.lrange(&req.key, req.start as _, req.stop as _)?;
139        Ok(serialize(ListRangeResponse { values: result })?)
140    }
141
142    fn list_push(&self, _actor: &str, req: ListPushRequest) -> Result<Vec<u8>, Box<dyn Error>> {
143        let mut store = self.store.write().unwrap();
144        let result: i32 = store.lpush(&req.key, req.value)?;
145        Ok(serialize(ListResponse { new_count: result })?)
146    }
147
148    fn set(&self, _actor: &str, req: SetRequest) -> Result<Vec<u8>, Box<dyn Error>> {
149        let mut store = self.store.write().unwrap();
150        store.set(&req.key, req.value.clone())?;
151        Ok(serialize(SetResponse { value: req.value })?)
152    }
153
154    fn list_del_item(
155        &self,
156        _actor: &str,
157        req: ListDelItemRequest,
158    ) -> Result<Vec<u8>, Box<dyn Error>> {
159        let mut store = self.store.write().unwrap();
160        let result: i32 = store.lrem(&req.key, req.value)?;
161        Ok(serialize(ListResponse { new_count: result })?)
162    }
163
164    fn set_add(&self, _actor: &str, req: SetAddRequest) -> Result<Vec<u8>, Box<dyn Error>> {
165        let mut store = self.store.write().unwrap();
166        let result: i32 = store.sadd(&req.key, req.value)?;
167        Ok(serialize(SetOperationResponse { new_count: result })?)
168    }
169
170    fn set_remove(&self, _actor: &str, req: SetRemoveRequest) -> Result<Vec<u8>, Box<dyn Error>> {
171        let mut store = self.store.write().unwrap();
172        let result: i32 = store.srem(&req.key, req.value)?;
173        Ok(serialize(SetOperationResponse { new_count: result })?)
174    }
175
176    fn set_union(&self, _actor: &str, req: SetUnionRequest) -> Result<Vec<u8>, Box<dyn Error>> {
177        let store = self.store.read().unwrap();
178        let result: Vec<Vec<u8>> = store.sunion(req.keys)?;
179        Ok(serialize(SetQueryResponse { values: result })?)
180    }
181
182    fn set_intersect(
183        &self,
184        _actor: &str,
185        req: SetIntersectionRequest,
186    ) -> Result<Vec<u8>, Box<dyn Error>> {
187        let store = self.store.read().unwrap();
188        let result: Vec<Vec<u8>> = store.sinter(req.keys)?;
189        Ok(serialize(SetQueryResponse { values: result })?)
190    }
191
192    fn set_query(&self, _actor: &str, req: SetQueryRequest) -> Result<Vec<u8>, Box<dyn Error>> {
193        let store = self.store.read().unwrap();
194        let result: Vec<Vec<u8>> = store.smembers(req.key)?;
195        Ok(serialize(SetQueryResponse { values: result })?)
196    }
197
198    fn exists(&self, _actor: &str, req: KeyExistsQuery) -> Result<Vec<u8>, Box<dyn Error>> {
199        let store = self.store.read().unwrap();
200        let result: bool = store.exists(&req.key)?;
201        Ok(serialize(GetResponse {
202            value: vec![],
203            exists: result,
204        })?)
205    }
206    fn sv_insert(&self, _actor:&str, req: KeyVecInsertQuery) -> Result<Vec<u8>, Box<dyn Error>>{
207        let mut store = self.store.write().unwrap();
208        let result: bool = store.sv_insert(&req.key, &req.value, req.overwrite)?;
209        Ok(serialize(KeyVecInsertResponse {
210           success:result,
211        })?)
212    }
213
214    fn sv_get(&self, _actor:&str, req: KeyVecGetQuery) -> Result<Vec<u8>, Box<dyn Error>>{
215        let store = self.store.read().unwrap();
216        let result: Vec<(i32, Vec<u8>)> = store.sv_into_vec(&req.key)?;
217        Ok(serialize(KeyVecGetResponse {
218            values: result,
219        })?)
220    }
221    fn sv_tail_off(&self, _actor:&str, req: KeyVecTailOffQuery) -> Result<Vec<u8>, Box<dyn Error>>{
222        let mut store = self.store.write().unwrap();
223        let result: usize = store.sv_tail_off(&req.key, req.remain)?;
224        Ok(serialize(KeyVecTailOffResponse {
225           len:result,
226        })?)
227    }
228}
229
230impl CapabilityProvider for KeyvalueProvider {
231    fn capability_id(&self) -> &'static str {
232        CAPABILITY_ID
233    }
234
235    // Invoked by the runtime host to give this provider plugin the ability to communicate
236    // with actors
237    fn configure_dispatch(&self, dispatcher: Box<dyn Dispatcher>) -> Result<(), Box<dyn Error>> {
238        trace!("Dispatcher received.");
239        let mut lock = self.dispatcher.write().unwrap();
240        *lock = dispatcher;
241
242        Ok(())
243    }
244
245    fn name(&self) -> &'static str {
246        "TEA Binary Key-Value Provider (In-Memory)"
247    }
248
249    // Invoked by host runtime to allow an actor to make use of the capability
250    // All providers MUST handle the "configure" message, even if no work will be done
251    fn handle_call(&self, actor: &str, op: &str, msg: &[u8]) -> Result<Vec<u8>, Box<dyn Error>> {
252        trace!("Received host call from {}, operation - {}", actor, op);
253
254        match op {
255            OP_BIND_ACTOR if actor == "system" => self.configure(deserialize(msg)?),
256            OP_REMOVE_ACTOR if actor == "system" => self.remove_actor(deserialize(msg)?),
257            keyvalue::OP_ADD => self.add(actor, deserialize(msg)?),
258            keyvalue::OP_DEL => self.del(actor, deserialize(msg)?),
259            keyvalue::OP_GET => self.get(actor, deserialize(msg)?),
260            keyvalue::OP_CLEAR => self.list_clear(actor, deserialize(msg)?),
261            keyvalue::OP_RANGE => self.list_range(actor, deserialize(msg)?),
262            keyvalue::OP_PUSH => self.list_push(actor, deserialize(msg)?),
263            keyvalue::OP_SET => self.set(actor, deserialize(msg)?),
264            keyvalue::OP_LIST_DEL => self.list_del_item(actor, deserialize(msg)?),
265            keyvalue::OP_SET_ADD => self.set_add(actor, deserialize(msg)?),
266            keyvalue::OP_SET_REMOVE => self.set_remove(actor, deserialize(msg)?),
267            keyvalue::OP_SET_UNION => self.set_union(actor, deserialize(msg)?),
268            keyvalue::OP_SET_INTERSECT => self.set_intersect(actor, deserialize(msg)?),
269            keyvalue::OP_SET_QUERY => self.set_query(actor, deserialize(msg)?),
270            keyvalue::OP_KEY_EXISTS => self.exists(actor, deserialize(msg)?),
271            keyvalue::OP_KEYVEC_INSERT => self.sv_insert(actor, deserialize(msg)?),
272            keyvalue::OP_KEYVEC_GET => self.sv_get(actor, deserialize(msg)?),
273            keyvalue::OP_KEYVEC_TAILOFF =>self.sv_tail_off(actor, deserialize(msg)?),
274            _ => Err("bad dispatch".into()),
275        }
276    }
277}