Skip to content

Commit e1e7335

Browse files
authored
Merge pull request #4 from AIBlockOfficial/v0.1.3
Merge v0.1.3 to Main
2 parents 887f8a1 + 933a8bc commit e1e7335

File tree

6 files changed

+274
-33
lines changed

6 files changed

+274
-33
lines changed

Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "valence_core"
3-
version = "0.1.2"
3+
version = "0.1.3"
44
edition = "2021"
55
license = "MIT"
66
keywords = ["blockchain", "L2", "peer-to-peer", "P2P"]
@@ -24,4 +24,6 @@ serde_json = "1.0.103"
2424
hex = "0.4.3"
2525
cuckoofilter = "0.5.0"
2626
tracing = "0.1.37"
27+
tracing-subscriber = "0.3.17"
28+
tracing-futures = "0.2.3"
2729
sha3 = "0.10.8"

src/api/utils.rs

+12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::convert::Infallible;
55
use warp::{Filter, Future, Rejection, Reply};
66

77
impl warp::reject::Reject for ApiErrorType {}
8+
use tracing::{debug, warn};
89

910
/// Clone component/struct to use in route
1011
///
@@ -61,27 +62,38 @@ pub fn sig_verify_middleware() -> impl Filter<Extract = ((),), Error = Rejection
6162
.and(warp::header::headers_cloned())
6263
.and_then(
6364
move |_: warp::path::FullPath, headers: warp::hyper::HeaderMap| {
65+
debug!("Validating signature");
66+
6467
async move {
6568
let public_key = headers
6669
.get("public_key")
6770
.and_then(|n| n.to_str().ok())
6871
.unwrap_or_default();
6972

73+
debug!("public_key: {:?}", public_key);
74+
7075
let address = headers
7176
.get("address")
7277
.and_then(|n| n.to_str().ok())
7378
.unwrap_or_default();
7479

80+
debug!("address: {:?}", address);
81+
7582
let signature = headers
7683
.get("signature")
7784
.and_then(|n| n.to_str().ok())
7885
.unwrap_or_default();
7986

87+
debug!("signature: {:?}", signature);
88+
8089
if validate_signature(public_key, address, signature) {
90+
debug!("Signature is valid");
91+
8192
// Proceed to the next filter/handler
8293
return Ok(());
8394
}
8495

96+
warn!("Invalid signature");
8597
Err(warp::reject::custom(ApiErrorType::InvalidSignature))
8698
}
8799
},

src/db/handler.rs

+26-2
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,36 @@ pub trait KvStoreConnection {
1919
///
2020
/// * `key` - Key of the data entry to set
2121
/// * `value` - Value of the data entry to set
22-
async fn set_data<T: Serialize + Send>(
22+
async fn set_data<T: Serialize + Send + DeserializeOwned>(
2323
&mut self,
2424
key: &str,
2525
value: T,
2626
) -> Result<(), Box<dyn std::error::Error + Send + Sync>>;
2727

28+
/// Sets a data entry in the cache with an expiration time
29+
///
30+
/// ### Arguments
31+
///
32+
/// * `key` - Key of the data entry to set
33+
/// * `value` - Value of the data entry to set
34+
/// * `seconds` - Number of seconds to expire the data entry in
35+
async fn set_data_with_expiry<T: Serialize + DeserializeOwned + Send>(
36+
&mut self,
37+
key: &str,
38+
value: T,
39+
seconds: usize,
40+
) -> Result<(), Box<dyn std::error::Error + Send + Sync>>;
41+
42+
/// Deletes a data entry from the cache
43+
///
44+
/// ### Arguments
45+
///
46+
/// * `key` - Key of the data entry to delete
47+
async fn delete_data(
48+
&mut self,
49+
key: &str,
50+
) -> Result<(), Box<dyn std::error::Error + Send + Sync>>;
51+
2852
/// Gets a data entry from the cache
2953
///
3054
/// ### Arguments
@@ -33,7 +57,7 @@ pub trait KvStoreConnection {
3357
async fn get_data<T: DeserializeOwned>(
3458
&mut self,
3559
key: &str,
36-
) -> Result<Option<T>, Box<dyn std::error::Error + Send + Sync>>;
60+
) -> Result<Option<Vec<T>>, Box<dyn std::error::Error + Send + Sync>>;
3761
}
3862

3963
#[async_trait]

src/db/mongo_db.rs

+148-21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use async_trait::async_trait;
2-
use mongodb::bson::{doc, Document};
2+
use mongodb::bson::{doc, DateTime, Document};
33
use mongodb::{options::ClientOptions, Client};
44
use serde::{de::DeserializeOwned, Serialize};
55
use tracing::{event, span, trace, warn, Level};
@@ -18,6 +18,31 @@ pub struct MongoDbConn {
1818
pub index: MongoDbIndex,
1919
}
2020

21+
impl MongoDbConn {
22+
/// Creates a TTL index on the expiry field.
23+
///
24+
/// NOTE: This function will need to be called in the main function when initialising a MongoDB connection.
25+
pub async fn create_ttl_index(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
26+
let collection = self
27+
.client
28+
.database(&self.index.db_name)
29+
.collection::<Document>(&self.index.coll_name);
30+
31+
// Create TTL index on the 'expiry' field
32+
let index_model = mongodb::IndexModel::builder()
33+
.keys(doc! { "expiry": 1 })
34+
.options(Some(
35+
mongodb::options::IndexOptions::builder()
36+
.expire_after(Some(std::time::Duration::from_secs(0)))
37+
.build(),
38+
))
39+
.build();
40+
41+
collection.create_index(index_model, None).await?;
42+
Ok(())
43+
}
44+
}
45+
2146
#[async_trait]
2247
impl KvStoreConnection for MongoDbConn {
2348
async fn init(url: &str) -> Result<Self, Box<dyn std::error::Error + Send + Sync>> {
@@ -47,7 +72,7 @@ impl KvStoreConnection for MongoDbConn {
4772
Ok(MongoDbConn { client, index })
4873
}
4974

50-
async fn set_data<T: Serialize + std::marker::Send>(
75+
async fn set_data<T: Serialize + std::marker::Send + DeserializeOwned>(
5176
&mut self,
5277
key: &str,
5378
value: T,
@@ -61,20 +86,32 @@ impl KvStoreConnection for MongoDbConn {
6186
.database(&self.index.db_name)
6287
.collection::<Document>(&self.index.coll_name);
6388

64-
let document = match mongodb::bson::to_document(&value) {
65-
Ok(document) => document,
66-
Err(e) => {
67-
event!(Level::ERROR, "Failed to serialize data with error: {e}");
68-
Document::new()
69-
}
89+
// Check if the document with the given key exists
90+
let filter = doc! { "_id": key };
91+
let existing_doc = collection.find_one(filter.clone(), None).await?;
92+
93+
let mut vec: Vec<T> = if let Some(doc) = existing_doc {
94+
// Deserialize the existing data
95+
mongodb::bson::from_bson(doc.get("data").unwrap().clone())?
96+
} else {
97+
Vec::new()
7098
};
7199

72-
let filter = doc! { "_id": key };
100+
// Append the new data to the vec
101+
vec.push(value);
102+
103+
// Serialize the vec back to a BSON array
104+
let serialized_vec = mongodb::bson::to_bson(&vec)?;
105+
106+
// Create or update the document
107+
let update = doc! {
108+
"$set": { "data": serialized_vec }
109+
};
73110
match collection
74-
.replace_one(
111+
.update_one(
75112
filter,
76-
document.clone(),
77-
mongodb::options::ReplaceOptions::builder()
113+
update,
114+
mongodb::options::UpdateOptions::builder()
78115
.upsert(true)
79116
.build(),
80117
)
@@ -86,32 +123,122 @@ impl KvStoreConnection for MongoDbConn {
86123
}
87124
};
88125

89-
trace!("Data set successfully");
126+
trace!("Data set successfully with expiry");
127+
128+
Ok(())
129+
}
130+
131+
async fn set_data_with_expiry<T: Serialize + std::marker::Send + DeserializeOwned>(
132+
&mut self,
133+
key: &str,
134+
value: T,
135+
seconds: usize,
136+
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
137+
// Tracing
138+
let span = span!(Level::TRACE, "MongoDbConn::set_data_with_expiry");
139+
let _enter = span.enter();
140+
141+
let collection = self
142+
.client
143+
.database(&self.index.db_name)
144+
.collection::<Document>(&self.index.coll_name);
145+
146+
// Check if the document with the given key exists
147+
let filter = doc! { "_id": key };
148+
let existing_doc = collection.find_one(filter.clone(), None).await?;
149+
150+
let mut vec: Vec<T> = if let Some(doc) = existing_doc {
151+
// Deserialize the existing data
152+
mongodb::bson::from_bson(doc.get("data").unwrap().clone())?
153+
} else {
154+
Vec::new()
155+
};
156+
157+
// Append the new data to the vec
158+
vec.push(value);
159+
160+
// Serialize the vec back to a BSON array
161+
let serialized_vec = mongodb::bson::to_bson(&vec)?;
162+
163+
// Calculate the expiry time
164+
let expiry_time = (seconds * 1000) as i64;
165+
let expiry_bson_datetime = DateTime::from_millis(expiry_time);
166+
167+
// Create or update the document with the new expiry time
168+
let update = doc! {
169+
"$set": {
170+
"data": serialized_vec,
171+
"expiry": expiry_bson_datetime,
172+
}
173+
};
174+
collection
175+
.update_one(
176+
filter,
177+
update,
178+
mongodb::options::UpdateOptions::builder()
179+
.upsert(true)
180+
.build(),
181+
)
182+
.await?;
183+
184+
trace!("Data set successfully with expiry");
185+
186+
Ok(())
187+
}
188+
189+
async fn delete_data(
190+
&mut self,
191+
key: &str,
192+
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
193+
// Tracing
194+
let span = span!(Level::TRACE, "MongoDbConn::delete_data");
195+
let _enter = span.enter();
196+
197+
let collection = self
198+
.client
199+
.database(&self.index.db_name)
200+
.collection::<Document>(&self.index.coll_name);
201+
202+
let filter = doc! { "_id": key };
203+
match collection.delete_one(filter, None).await {
204+
Ok(_) => (),
205+
Err(e) => {
206+
event!(Level::ERROR, "Failed to delete data with error: {e}");
207+
}
208+
};
209+
210+
trace!("Data deleted successfully");
90211

91212
Ok(())
92213
}
93214

94215
async fn get_data<T: DeserializeOwned>(
95216
&mut self,
96217
key: &str,
97-
) -> Result<Option<T>, Box<dyn std::error::Error + Send + Sync>> {
218+
) -> Result<Option<Vec<T>>, Box<dyn std::error::Error + Send + Sync>> {
98219
// Tracing
99220
let span = span!(Level::TRACE, "MongoDbConn::get_data");
100221
let _enter = span.enter();
101222

102223
let collection = self
103224
.client
104225
.database(&self.index.db_name)
105-
.collection::<Document>(&self.index.coll_name); // Change to your actual collection name
226+
.collection::<Document>(&self.index.coll_name);
106227

228+
// Check if the document with the given key exists
107229
let filter = doc! { "_id": key };
108-
let result = collection.find_one(filter, None).await?;
109-
110-
trace!("Data retrieved successfully");
230+
let doc_find = match collection.find_one(filter.clone(), None).await {
231+
Ok(doc) => doc,
232+
Err(e) => {
233+
event!(Level::ERROR, "Failed to get data with error: {e}");
234+
return Ok(None);
235+
}
236+
};
111237

112-
if let Some(document) = result {
113-
let deserialized: T = mongodb::bson::from_document(document)?;
114-
return Ok(Some(deserialized));
238+
if let Some(doc) = doc_find {
239+
// Deserialize the existing data
240+
let vec: Vec<T> = mongodb::bson::from_bson(doc.get("data").unwrap().clone())?;
241+
return Ok(Some(vec));
115242
}
116243

117244
warn!("Data unsuccessfully deserialized");

0 commit comments

Comments
 (0)