mirror of
https://github.com/talaia-labs/rust-teos.git
synced 2026-08-13 12:33:22 +02:00
Removes JSON serde, moves slots computation logic to appointment.rs
The JSON serialization logic was added to deal with data storage. Given won't be using LevelDB for this implementation, but a SQL database, all that serialization logic in unnecessary.
This commit is contained in:
parent
66868fd0b1
commit
b5da110cbb
6 changed files with 39 additions and 188 deletions
|
|
@ -7,8 +7,6 @@ edition = "2018"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
serde = {version = "1.0.126", features = ["derive"]}
|
||||
serde_json = "1.0"
|
||||
uuid = { version = "0.8", features = ["serde", "v4"] }
|
||||
hex = "0.4.3"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
use hex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{Error as JSONError, Value};
|
||||
use std::fmt;
|
||||
|
||||
use bitcoin::Txid;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone, Hash)]
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
|
||||
pub struct Locator([u8; 16]);
|
||||
|
||||
impl Locator {
|
||||
|
|
@ -15,19 +13,30 @@ impl Locator {
|
|||
Locator(raw_locator)
|
||||
}
|
||||
|
||||
pub fn to_vec(&self) -> Vec<u8> {
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
self.0.to_vec()
|
||||
}
|
||||
|
||||
pub fn deserialize(data: Vec<u8>) -> Result<Self, ()> {
|
||||
if data.len() == 16 {
|
||||
let mut raw_locator = [0; 16];
|
||||
raw_locator.copy_from_slice(&data);
|
||||
Ok(Self(raw_locator))
|
||||
} else {
|
||||
// TODO: Maybe add a more expressive error?
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Locator {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", hex::encode(self.to_vec()))
|
||||
write!(f, "{}", hex::encode(self.serialize()))
|
||||
}
|
||||
}
|
||||
|
||||
/// Contains data regarding an appointment between a client and the Watchtower. An appointment is requested for every new channel update.
|
||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub struct Appointment {
|
||||
pub locator: Locator,
|
||||
pub encrypted_blob: Vec<u8>,
|
||||
|
|
@ -50,14 +59,6 @@ impl Appointment {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn from_json(data: &str) -> Result<Self, JSONError> {
|
||||
serde_json::from_str::<Appointment>(data)
|
||||
}
|
||||
|
||||
pub fn to_json(self) -> Value {
|
||||
serde_json::to_value(&self).unwrap()
|
||||
}
|
||||
|
||||
/// Serializes an appointment to be signed.
|
||||
/// The serialization follows the same ordering as the fields in the appointment:
|
||||
///
|
||||
|
|
@ -65,44 +66,9 @@ impl Appointment {
|
|||
///
|
||||
/// All values are big endian.
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
let mut result = self.locator.to_vec();
|
||||
let mut result = self.locator.serialize();
|
||||
result.extend(&self.encrypted_blob);
|
||||
result.extend(self.to_self_delay.to_be_bytes().to_vec());
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn test_from_json() {
|
||||
let locator = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
|
||||
let encrypted_blob = [1, 2, 3, 4].to_vec();
|
||||
let to_self_delay = 21;
|
||||
let appointment = Appointment::new(locator, encrypted_blob.clone(), to_self_delay);
|
||||
|
||||
let data = json!(appointment).to_string();
|
||||
let a = Appointment::from_json(&data).unwrap();
|
||||
|
||||
assert_eq!(a.locator, Locator(locator));
|
||||
assert_eq!(a.encrypted_blob, encrypted_blob);
|
||||
assert_eq!(a.to_self_delay, to_self_delay);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_json() {
|
||||
let locator = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
|
||||
let encrypted_blob = [1, 2, 3, 4].to_vec();
|
||||
let to_self_delay = 21;
|
||||
let appointment = Appointment::new(locator, encrypted_blob.clone(), to_self_delay);
|
||||
|
||||
let a_json = appointment.to_json();
|
||||
|
||||
assert_eq!(a_json["locator"], json!(locator));
|
||||
assert_eq!(a_json["encrypted_blob"], json!(encrypted_blob));
|
||||
assert_eq!(a_json["to_self_delay"], json!(to_self_delay));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,65 +3,17 @@ pub mod constants;
|
|||
pub mod cryptography;
|
||||
pub mod receipts;
|
||||
|
||||
use serde::de::{self, SeqAccess, Unexpected, Visitor};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use std::fmt;
|
||||
|
||||
use bitcoin::secp256k1::PublicKey;
|
||||
use bitcoin::secp256k1::{Error, PublicKey};
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||
pub struct UserId(pub PublicKey);
|
||||
|
||||
struct UserIdVisitor;
|
||||
impl UserId {
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
self.0.serialize().to_vec()
|
||||
}
|
||||
|
||||
impl Serialize for UserId {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_bytes(&self.0.serialize())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Visitor<'de> for UserIdVisitor {
|
||||
type Value = UserId;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(formatter, "a 33-byte long array or sequence")
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
match PublicKey::from_slice(v) {
|
||||
Ok(pk) => Ok(UserId(pk)),
|
||||
Err(_) => Err(de::Error::invalid_value(Unexpected::Bytes(v), &self)),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
let mut vec = Vec::new();
|
||||
|
||||
while let Some(elem) = seq.next_element()? {
|
||||
vec.push(elem);
|
||||
}
|
||||
|
||||
match PublicKey::from_slice(&vec) {
|
||||
Ok(pk) => Ok(UserId(pk)),
|
||||
Err(_) => Err(de::Error::invalid_value(Unexpected::Seq, &self)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for UserId {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_bytes(UserIdVisitor)
|
||||
pub fn deserialize(data: &[u8]) -> Result<Self, Error> {
|
||||
Ok(UserId(PublicKey::from_slice(data)?))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ base64 = "0.13.0"
|
|||
futures = "0.3"
|
||||
log = "0.4"
|
||||
simple_logger = "1.12.1"
|
||||
serde = "1.0.126"
|
||||
serde_json = "1.0"
|
||||
tokio = { version = "1.5", features = [ "io-util", "macros", "rt", "rt-multi-thread", "sync", "net", "time" ] }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{Error as JSONError, Value};
|
||||
use std::fmt;
|
||||
|
||||
use bitcoin::hashes::{ripemd160, Hash};
|
||||
|
|
@ -7,15 +5,19 @@ use bitcoin::hashes::{ripemd160, Hash};
|
|||
use teos_common::appointment::{Appointment, Locator};
|
||||
use teos_common::UserId;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, Eq, PartialEq, Hash)]
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||
pub struct UUID(pub [u8; 20]);
|
||||
|
||||
impl UUID {
|
||||
pub fn new(locator: &Locator, user_id: &UserId) -> Self {
|
||||
let mut uuid_data = locator.to_vec();
|
||||
let mut uuid_data = locator.serialize();
|
||||
uuid_data.extend(&user_id.0.serialize());
|
||||
UUID(ripemd160::Hash::hash(&uuid_data).into_inner())
|
||||
}
|
||||
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
self.0.to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for UUID {
|
||||
|
|
@ -24,7 +26,7 @@ impl std::fmt::Display for UUID {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub struct ExtendedAppointment {
|
||||
pub inner: Appointment,
|
||||
pub user_id: UserId,
|
||||
|
|
@ -32,7 +34,6 @@ pub struct ExtendedAppointment {
|
|||
pub start_block: u32,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct AppointmentSummary {
|
||||
locator: Locator,
|
||||
user_id: UserId,
|
||||
|
|
@ -59,14 +60,10 @@ impl ExtendedAppointment {
|
|||
user_id: self.user_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_json(data: &str) -> Result<Self, JSONError> {
|
||||
serde_json::from_str::<ExtendedAppointment>(data)
|
||||
}
|
||||
|
||||
pub fn to_json(self) -> Value {
|
||||
serde_json::to_value(&self).unwrap()
|
||||
}
|
||||
pub fn compute_appointment_slots(blob_size: usize, blob_max_size: usize) -> u32 {
|
||||
(blob_size as f32 / blob_max_size as f32).ceil() as u32
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -74,7 +71,6 @@ mod tests {
|
|||
use super::*;
|
||||
use bitcoin::secp256k1::key::ONE_KEY;
|
||||
use bitcoin::secp256k1::{PublicKey, Secp256k1};
|
||||
use serde_json::json;
|
||||
use teos_common::appointment::Appointment;
|
||||
use teos_common::UserId;
|
||||
|
||||
|
|
@ -92,56 +88,4 @@ mod tests {
|
|||
assert_eq!(e.inner.locator, s.locator);
|
||||
assert_eq!(e.user_id, s.user_id);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_json() {
|
||||
let locator = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
|
||||
let encrypted_blob = [1, 2, 3, 4].to_vec();
|
||||
let to_self_delay = 21;
|
||||
let appointment = Appointment::new(locator, encrypted_blob, to_self_delay);
|
||||
|
||||
let user_id = UserId(PublicKey::from_secret_key(&Secp256k1::new(), &ONE_KEY));
|
||||
let user_signature = String::new();
|
||||
let start_block = 42;
|
||||
|
||||
let data = json!({
|
||||
"inner": appointment,
|
||||
"user_id": user_id,
|
||||
"user_signature": user_signature,
|
||||
"start_block": start_block,
|
||||
})
|
||||
.to_string();
|
||||
|
||||
let e = ExtendedAppointment::from_json(&data).unwrap();
|
||||
|
||||
assert_eq!(e.inner, appointment);
|
||||
assert_eq!(e.user_id, user_id);
|
||||
assert_eq!(e.user_signature, user_signature);
|
||||
assert_eq!(e.start_block, start_block);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_json() {
|
||||
let locator = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
|
||||
let encrypted_blob = [1, 2, 3, 4].to_vec();
|
||||
let to_self_delay = 21;
|
||||
let appointment = Appointment::new(locator, encrypted_blob, to_self_delay);
|
||||
|
||||
let user_id = UserId(PublicKey::from_secret_key(&Secp256k1::new(), &ONE_KEY));
|
||||
let user_signature = String::new();
|
||||
let start_block = 42;
|
||||
|
||||
let extended_appointment = ExtendedAppointment::new(
|
||||
appointment.clone(),
|
||||
user_id,
|
||||
user_signature.clone(),
|
||||
start_block,
|
||||
);
|
||||
let e_json = extended_appointment.to_json();
|
||||
|
||||
assert_eq!(e_json["inner"], json!(appointment));
|
||||
assert_eq!(e_json["user_id"], json!(user_id));
|
||||
assert_eq!(e_json["user_signature"], json!(user_signature));
|
||||
assert_eq!(e_json["start_block"], json!(start_block));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{Error as JSONError, Value};
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
|
|
@ -11,9 +9,9 @@ use teos_common::cryptography;
|
|||
use teos_common::receipts::RegistrationReceipt;
|
||||
use teos_common::UserId;
|
||||
|
||||
use crate::extended_appointment::{ExtendedAppointment, UUID};
|
||||
use crate::extended_appointment::{compute_appointment_slots, ExtendedAppointment, UUID};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct UserInfo {
|
||||
pub(crate) available_slots: u32,
|
||||
pub(crate) subscription_expiry: u32,
|
||||
|
|
@ -28,13 +26,6 @@ impl UserInfo {
|
|||
appointments: HashMap::new(),
|
||||
}
|
||||
}
|
||||
pub fn from_json(data: &str) -> Result<Self, JSONError> {
|
||||
serde_json::from_str::<UserInfo>(data)
|
||||
}
|
||||
|
||||
pub fn to_json(self) -> Value {
|
||||
serde_json::to_value(&self).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
|
|
@ -143,9 +134,10 @@ impl Gatekeeper {
|
|||
let user_info = borrowed.get_mut(user_id).unwrap();
|
||||
let used_slots = user_info.appointments.get(&uuid).map_or(0, |x| x.clone());
|
||||
|
||||
let required_slots = (appointment.inner.encrypted_blob.len() as f32
|
||||
/ ENCRYPTED_BLOB_MAX_SIZE as f32)
|
||||
.ceil() as u32;
|
||||
let required_slots = compute_appointment_slots(
|
||||
appointment.inner.encrypted_blob.len(),
|
||||
ENCRYPTED_BLOB_MAX_SIZE,
|
||||
);
|
||||
|
||||
let diff = required_slots as i64 - used_slots as i64;
|
||||
if diff <= user_info.available_slots as i64 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue