mirror of
https://github.com/talaia-labs/rust-teos.git
synced 2026-08-18 13:09:03 +02:00
Improves overall memory management
Refactors severals parts of the code so: - Copy values are not passed as reference - Copy values are derefered when needed instead of cloned - Clones are avoided as much as possible - Strings are replaced by &str when possible More passes to the code may be necessary in the future, but this is a good start
This commit is contained in:
parent
fc5ac0e8dc
commit
8a8772df99
9 changed files with 315 additions and 340 deletions
|
|
@ -20,8 +20,8 @@ impl RegistrationReceipt {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn user_id(&self) -> &UserId {
|
||||
&self.user_id
|
||||
pub fn user_id(&self) -> UserId {
|
||||
self.user_id
|
||||
}
|
||||
|
||||
pub fn available_slots(&self) -> u32 {
|
||||
|
|
@ -66,8 +66,8 @@ impl AppointmentReceipt {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn user_signature(&self) -> String {
|
||||
self.user_signature.clone()
|
||||
pub fn user_signature(&self) -> &str {
|
||||
&self.user_signature
|
||||
}
|
||||
|
||||
pub fn start_block(&self) -> u32 {
|
||||
|
|
|
|||
|
|
@ -20,15 +20,15 @@ use lightning_block_sync::http::HttpEndpoint;
|
|||
use lightning_block_sync::rpc::RpcClient;
|
||||
use lightning_block_sync::{AsyncBlockSourceResult, BlockHeaderData, BlockSource};
|
||||
|
||||
pub struct BitcoindClient {
|
||||
pub struct BitcoindClient<'a> {
|
||||
bitcoind_rpc_client: Arc<Mutex<RpcClient>>,
|
||||
host: String,
|
||||
host: &'a str,
|
||||
port: u16,
|
||||
rpc_user: String,
|
||||
rpc_password: String,
|
||||
rpc_user: &'a str,
|
||||
rpc_password: &'a str,
|
||||
}
|
||||
|
||||
impl BlockSource for &BitcoindClient {
|
||||
impl BlockSource for &BitcoindClient<'_> {
|
||||
fn get_header<'a>(
|
||||
&'a mut self,
|
||||
header_hash: &'a BlockHash,
|
||||
|
|
@ -58,16 +58,15 @@ impl BlockSource for &BitcoindClient {
|
|||
}
|
||||
}
|
||||
|
||||
impl BitcoindClient {
|
||||
impl<'a> BitcoindClient<'a> {
|
||||
pub async fn new(
|
||||
host: String,
|
||||
host: &'a str,
|
||||
port: u16,
|
||||
rpc_user: String,
|
||||
rpc_password: String,
|
||||
) -> std::io::Result<Self> {
|
||||
let http_endpoint = HttpEndpoint::for_host(host.clone()).with_port(port);
|
||||
let rpc_credentials =
|
||||
base64::encode(format!("{}:{}", rpc_user.clone(), rpc_password.clone()));
|
||||
rpc_user: &'a str,
|
||||
rpc_password: &'a str,
|
||||
) -> std::io::Result<BitcoindClient<'a>> {
|
||||
let http_endpoint = HttpEndpoint::for_host(host.to_owned()).with_port(port);
|
||||
let rpc_credentials = base64::encode(format!("{}:{}", rpc_user, rpc_password));
|
||||
let bitcoind_rpc_client = RpcClient::new(&rpc_credentials, http_endpoint)?;
|
||||
|
||||
let client = Self {
|
||||
|
|
@ -86,12 +85,8 @@ impl BitcoindClient {
|
|||
}
|
||||
|
||||
pub fn get_new_rpc_client(&self) -> std::io::Result<RpcClient> {
|
||||
let http_endpoint = HttpEndpoint::for_host(self.host.clone()).with_port(self.port);
|
||||
let rpc_credentials = base64::encode(format!(
|
||||
"{}:{}",
|
||||
self.rpc_user.clone(),
|
||||
self.rpc_password.clone()
|
||||
));
|
||||
let http_endpoint = HttpEndpoint::for_host(self.host.to_owned()).with_port(self.port);
|
||||
let rpc_credentials = base64::encode(format!("{}:{}", self.rpc_user, self.rpc_password));
|
||||
RpcClient::new(&rpc_credentials, http_endpoint)
|
||||
}
|
||||
|
||||
|
|
|
|||
164
teos/src/dbm.rs
164
teos/src/dbm.rs
|
|
@ -133,7 +133,7 @@ impl DBM {
|
|||
self.remove_data(query, params)
|
||||
}
|
||||
|
||||
pub fn store_user(&self, user_id: &UserId, user_info: &UserInfo) -> Result<(), Error> {
|
||||
pub fn store_user(&self, user_id: UserId, user_info: &UserInfo) -> Result<(), Error> {
|
||||
let query =
|
||||
"INSERT INTO users (user_id, available_slots, subscription_expiry) VALUES (?1, ?2, ?3)";
|
||||
|
||||
|
|
@ -156,7 +156,7 @@ impl DBM {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn update_user(&self, user_id: &UserId, user_info: &UserInfo) {
|
||||
pub fn update_user(&self, user_id: UserId, user_info: &UserInfo) {
|
||||
let query =
|
||||
"UPDATE users SET available_slots=(?1), subscription_expiry=(?2) WHERE user_id=(?3)";
|
||||
match self.update_data(
|
||||
|
|
@ -178,7 +178,7 @@ impl DBM {
|
|||
|
||||
// DISCUSS: This could be implemented with an INNER JOIN query, but the logic will be more complex given each row
|
||||
// will have the user info replicated. Consider whether it makes sense to change it.
|
||||
pub fn load_user(&self, user_id: &UserId) -> Result<UserInfo, Error> {
|
||||
pub fn load_user(&self, user_id: UserId) -> Result<UserInfo, Error> {
|
||||
let key = user_id.serialize();
|
||||
let mut stmt = self
|
||||
.connection
|
||||
|
|
@ -235,7 +235,7 @@ impl DBM {
|
|||
users
|
||||
}
|
||||
|
||||
pub fn remove_user(&self, user_id: &UserId) {
|
||||
pub fn remove_user(&self, user_id: UserId) {
|
||||
let query = "DELETE FROM users WHERE user_id=(?)";
|
||||
match self.remove_data(query, params![user_id.serialize()]) {
|
||||
Ok(_) => {
|
||||
|
|
@ -249,7 +249,7 @@ impl DBM {
|
|||
|
||||
pub fn store_appointment(
|
||||
&self,
|
||||
uuid: &UUID,
|
||||
uuid: UUID,
|
||||
appointment: &ExtendedAppointment,
|
||||
) -> Result<(), Error> {
|
||||
let query = "INSERT INTO appointments (UUID, locator, encrypted_blob, to_self_delay, user_signature, start_block, user_id) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)";
|
||||
|
|
@ -276,7 +276,7 @@ impl DBM {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn update_appointment(&self, uuid: &UUID, appointment: &ExtendedAppointment) {
|
||||
pub fn update_appointment(&self, uuid: UUID, appointment: &ExtendedAppointment) {
|
||||
// DISCUSS: Check what fields we'd like to make updatable. e_blob and signature are the obvious, to_self_delay and start_block may not be necessary (or even risky)
|
||||
let query =
|
||||
"UPDATE appointments SET encrypted_blob=(?1), to_self_delay=(?2), user_signature=(?3), start_block=(?4) WHERE UUID=(?5)";
|
||||
|
|
@ -299,7 +299,7 @@ impl DBM {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn load_appointment(&self, uuid: &UUID) -> Result<ExtendedAppointment, Error> {
|
||||
pub fn load_appointment(&self, uuid: UUID) -> Result<ExtendedAppointment, Error> {
|
||||
let key = uuid.serialize();
|
||||
let mut stmt = self
|
||||
.connection
|
||||
|
|
@ -355,7 +355,7 @@ impl DBM {
|
|||
appointments
|
||||
}
|
||||
|
||||
pub fn remove_appointment(&self, uuid: &UUID) {
|
||||
pub fn remove_appointment(&self, uuid: UUID) {
|
||||
let query = "DELETE FROM appointments WHERE UUID=(?)";
|
||||
match self.remove_data(query, params![uuid.serialize()]) {
|
||||
Ok(_) => {
|
||||
|
|
@ -389,7 +389,7 @@ impl DBM {
|
|||
(appointments.len() as f64 / limit as f64).ceil() as usize
|
||||
}
|
||||
|
||||
pub fn store_tracker(&self, uuid: &UUID, tracker: &TransactionTracker) -> Result<(), Error> {
|
||||
pub fn store_tracker(&self, uuid: UUID, tracker: &TransactionTracker) -> Result<(), Error> {
|
||||
let query = "INSERT INTO trackers (UUID, dispute_tx, penalty_tx) VALUES (?1, ?2, ?3)";
|
||||
match self.store_data(
|
||||
query,
|
||||
|
|
@ -410,7 +410,7 @@ impl DBM {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn load_tracker(&self, uuid: &UUID) -> Result<TransactionTracker, Error> {
|
||||
pub fn load_tracker(&self, uuid: UUID) -> Result<TransactionTracker, Error> {
|
||||
let key = uuid.serialize();
|
||||
let mut stmt = self.connection.prepare(
|
||||
"SELECT t.*, a.locator, a.user_id FROM trackers as t INNER JOIN appointments as a ON t.UUID=a.UUID WHERE t.UUID=(?)").unwrap();
|
||||
|
|
@ -587,13 +587,13 @@ mod tests {
|
|||
let user_id = get_random_user_id();
|
||||
let mut user = UserInfo::new(21, 42);
|
||||
|
||||
assert!(matches!(dbm.store_user(&user_id, &user), Ok { .. }));
|
||||
assert_eq!(dbm.load_user(&user_id).unwrap(), user);
|
||||
assert!(matches!(dbm.store_user(user_id, &user), Ok { .. }));
|
||||
assert_eq!(dbm.load_user(user_id).unwrap(), user);
|
||||
|
||||
// User info should be updatable but only via the update_user method
|
||||
user = UserInfo::new(42, 21);
|
||||
assert!(matches!(
|
||||
dbm.store_user(&user_id, &user),
|
||||
dbm.store_user(user_id, &user),
|
||||
Err(Error::AlreadyExists)
|
||||
));
|
||||
}
|
||||
|
|
@ -605,16 +605,16 @@ mod tests {
|
|||
let user_id = get_random_user_id();
|
||||
let mut user = UserInfo::new(21, 42);
|
||||
|
||||
dbm.store_user(&user_id, &user).unwrap();
|
||||
dbm.store_user(user_id, &user).unwrap();
|
||||
|
||||
// Add some appointments to the user
|
||||
for _ in 0..10 {
|
||||
let (uuid, appointment) = generate_dummy_appointment_with_user(user_id, None);
|
||||
dbm.store_appointment(&uuid, &appointment).unwrap();
|
||||
dbm.store_appointment(uuid, &appointment).unwrap();
|
||||
user.appointments.insert(uuid, 1);
|
||||
}
|
||||
|
||||
assert_eq!(dbm.load_user(&user_id).unwrap(), user);
|
||||
assert_eq!(dbm.load_user(user_id).unwrap(), user);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -622,7 +622,7 @@ mod tests {
|
|||
let dbm = DBM::in_memory().unwrap();
|
||||
|
||||
let user_id = get_random_user_id();
|
||||
assert!(matches!(dbm.load_user(&user_id), Err(Error::NotFound)));
|
||||
assert!(matches!(dbm.load_user(user_id), Err(Error::NotFound)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -632,12 +632,12 @@ mod tests {
|
|||
let user_id = get_random_user_id();
|
||||
let mut user = UserInfo::new(21, 42);
|
||||
|
||||
dbm.store_user(&user_id, &user).unwrap();
|
||||
assert_eq!(dbm.load_user(&user_id).unwrap(), user);
|
||||
dbm.store_user(user_id, &user).unwrap();
|
||||
assert_eq!(dbm.load_user(user_id).unwrap(), user);
|
||||
|
||||
user.available_slots *= 2;
|
||||
dbm.update_user(&user_id, &user);
|
||||
assert_eq!(dbm.load_user(&user_id).unwrap(), user);
|
||||
dbm.update_user(user_id, &user);
|
||||
assert_eq!(dbm.load_user(user_id).unwrap(), user);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -649,7 +649,7 @@ mod tests {
|
|||
let user_id = get_random_user_id();
|
||||
let user = UserInfo::new(i, i * 2);
|
||||
users.insert(user_id, user.clone());
|
||||
dbm.store_user(&user_id, &user).unwrap();
|
||||
dbm.store_user(user_id, &user).unwrap();
|
||||
}
|
||||
|
||||
assert_eq!(dbm.load_all_users(), users);
|
||||
|
|
@ -661,10 +661,10 @@ mod tests {
|
|||
let user_id = get_random_user_id();
|
||||
|
||||
let user = UserInfo::new(21, 42);
|
||||
assert!(matches!(dbm.store_user(&user_id, &user), Ok { .. }));
|
||||
assert!(matches!(dbm.store_user(user_id, &user), Ok { .. }));
|
||||
|
||||
dbm.remove_user(&user_id);
|
||||
assert!(matches!(dbm.load_user(&user_id), Err(Error::NotFound)));
|
||||
dbm.remove_user(user_id);
|
||||
assert!(matches!(dbm.load_user(user_id), Err(Error::NotFound)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -673,7 +673,7 @@ mod tests {
|
|||
let user_id = get_random_user_id();
|
||||
|
||||
// Test it does not fail even if the user does not exist (it will log though)
|
||||
dbm.remove_user(&user_id);
|
||||
dbm.remove_user(user_id);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -683,19 +683,19 @@ mod tests {
|
|||
// In order to add an appointment we need the associated user to be present
|
||||
let user_id = get_random_user_id();
|
||||
let user = UserInfo::new(21, 42);
|
||||
dbm.store_user(&user_id, &user).unwrap();
|
||||
dbm.store_user(user_id, &user).unwrap();
|
||||
|
||||
let (uuid, appointment) = generate_dummy_appointment_with_user(user_id, None);
|
||||
|
||||
assert!(matches!(
|
||||
dbm.store_appointment(&uuid, &appointment),
|
||||
dbm.store_appointment(uuid, &appointment),
|
||||
Ok { .. }
|
||||
));
|
||||
assert_eq!(dbm.load_appointment(&uuid).unwrap(), appointment);
|
||||
assert_eq!(dbm.load_appointment(uuid).unwrap(), appointment);
|
||||
|
||||
// Appointment info should be updatable but only via the update_appointment method
|
||||
assert!(matches!(
|
||||
dbm.store_appointment(&uuid, &appointment),
|
||||
dbm.store_appointment(uuid, &appointment),
|
||||
Err(Error::AlreadyExists)
|
||||
));
|
||||
}
|
||||
|
|
@ -708,10 +708,10 @@ mod tests {
|
|||
let appointment = generate_dummy_appointment(None);
|
||||
|
||||
assert!(matches!(
|
||||
dbm.store_appointment(&uuid, &appointment),
|
||||
dbm.store_appointment(uuid, &appointment),
|
||||
Err(Error::MissingForeignKey)
|
||||
));
|
||||
assert!(matches!(dbm.load_tracker(&uuid), Err(Error::NotFound)));
|
||||
assert!(matches!(dbm.load_tracker(uuid), Err(Error::NotFound)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -719,7 +719,7 @@ mod tests {
|
|||
let dbm = DBM::in_memory().unwrap();
|
||||
|
||||
let uuid = generate_uuid();
|
||||
assert!(matches!(dbm.load_appointment(&uuid), Err(Error::NotFound)));
|
||||
assert!(matches!(dbm.load_appointment(uuid), Err(Error::NotFound)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -728,11 +728,11 @@ mod tests {
|
|||
|
||||
let user_id = get_random_user_id();
|
||||
let user = UserInfo::new(21, 42);
|
||||
dbm.store_user(&user_id, &user).unwrap();
|
||||
dbm.store_user(user_id, &user).unwrap();
|
||||
|
||||
let (uuid, appointment) = generate_dummy_appointment_with_user(user_id, None);
|
||||
assert!(matches!(
|
||||
dbm.store_appointment(&uuid, &appointment),
|
||||
dbm.store_appointment(uuid, &appointment),
|
||||
Ok { .. }
|
||||
));
|
||||
|
||||
|
|
@ -745,10 +745,10 @@ mod tests {
|
|||
another_modified_appointment.user_id = get_random_user_id();
|
||||
|
||||
// Check how only the modifiable fields have been updated
|
||||
dbm.update_appointment(&uuid, &another_modified_appointment);
|
||||
assert_eq!(dbm.load_appointment(&uuid).unwrap(), modified_appointment);
|
||||
dbm.update_appointment(uuid, &another_modified_appointment);
|
||||
assert_eq!(dbm.load_appointment(uuid).unwrap(), modified_appointment);
|
||||
assert_ne!(
|
||||
dbm.load_appointment(&uuid).unwrap(),
|
||||
dbm.load_appointment(uuid).unwrap(),
|
||||
another_modified_appointment
|
||||
);
|
||||
}
|
||||
|
|
@ -761,10 +761,10 @@ mod tests {
|
|||
for i in 1..11 {
|
||||
let user_id = get_random_user_id();
|
||||
let user = UserInfo::new(i, i * 2);
|
||||
dbm.store_user(&user_id, &user).unwrap();
|
||||
dbm.store_user(user_id, &user).unwrap();
|
||||
|
||||
let (uuid, appointment) = generate_dummy_appointment_with_user(user_id, None);
|
||||
dbm.store_appointment(&uuid, &appointment).unwrap();
|
||||
dbm.store_appointment(uuid, &appointment).unwrap();
|
||||
appointments.insert(uuid, appointment);
|
||||
}
|
||||
|
||||
|
|
@ -774,14 +774,14 @@ mod tests {
|
|||
// as a triggered appointment
|
||||
let user_id = get_random_user_id();
|
||||
let user = UserInfo::new(21, 42);
|
||||
dbm.store_user(&user_id, &user).unwrap();
|
||||
dbm.store_user(user_id, &user).unwrap();
|
||||
|
||||
let (uuid, appointment) = generate_dummy_appointment_with_user(user_id, None);
|
||||
dbm.store_appointment(&uuid, &appointment).unwrap();
|
||||
dbm.store_appointment(uuid, &appointment).unwrap();
|
||||
|
||||
let mut tracker = get_random_tracker(user_id);
|
||||
tracker.locator = appointment.locator();
|
||||
dbm.store_tracker(&uuid, &tracker).unwrap();
|
||||
dbm.store_tracker(uuid, &tracker).unwrap();
|
||||
|
||||
// We should get all the appointments back except from the triggered one
|
||||
assert_eq!(dbm.load_all_appointments(), appointments);
|
||||
|
|
@ -792,15 +792,15 @@ mod tests {
|
|||
let dbm = DBM::in_memory().unwrap();
|
||||
let user_id = get_random_user_id();
|
||||
let user = UserInfo::new(21, 42);
|
||||
dbm.store_user(&user_id, &user).unwrap();
|
||||
dbm.store_user(user_id, &user).unwrap();
|
||||
|
||||
// Store and delete appointment
|
||||
let (uuid, appointment) = generate_dummy_appointment_with_user(user_id, None);
|
||||
dbm.store_appointment(&uuid, &appointment).unwrap();
|
||||
assert_eq!(dbm.load_appointment(&uuid).unwrap(), appointment);
|
||||
dbm.remove_appointment(&uuid);
|
||||
dbm.store_appointment(uuid, &appointment).unwrap();
|
||||
assert_eq!(dbm.load_appointment(uuid).unwrap(), appointment);
|
||||
dbm.remove_appointment(uuid);
|
||||
|
||||
assert!(matches!(dbm.load_appointment(&uuid), Err(Error::NotFound)));
|
||||
assert!(matches!(dbm.load_appointment(uuid), Err(Error::NotFound)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -808,10 +808,10 @@ mod tests {
|
|||
let dbm = DBM::in_memory().unwrap();
|
||||
let user_id = get_random_user_id();
|
||||
let user = UserInfo::new(21, 42);
|
||||
dbm.store_user(&user_id, &user).unwrap();
|
||||
dbm.store_user(user_id, &user).unwrap();
|
||||
|
||||
// Test it does not fail even if the appointment does not exist (it will log though)
|
||||
dbm.remove_appointment(&generate_uuid());
|
||||
dbm.remove_appointment(generate_uuid());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -822,17 +822,17 @@ mod tests {
|
|||
// at the same time requires an associated user to be present)
|
||||
let user_id = get_random_user_id();
|
||||
let user = UserInfo::new(21, 42);
|
||||
dbm.store_user(&user_id, &user).unwrap();
|
||||
dbm.store_user(user_id, &user).unwrap();
|
||||
|
||||
let (uuid, appointment) = generate_dummy_appointment_with_user(user_id, None);
|
||||
dbm.store_appointment(&uuid, &appointment).unwrap();
|
||||
dbm.store_appointment(uuid, &appointment).unwrap();
|
||||
|
||||
let mut tracker = get_random_tracker(user_id);
|
||||
// Set the locator to match between appointment and tracker
|
||||
tracker.locator = appointment.locator();
|
||||
|
||||
assert!(matches!(dbm.store_tracker(&uuid, &tracker), Ok { .. }));
|
||||
assert_eq!(dbm.load_tracker(&uuid).unwrap(), tracker);
|
||||
assert!(matches!(dbm.store_tracker(uuid, &tracker), Ok { .. }));
|
||||
assert_eq!(dbm.load_tracker(uuid).unwrap(), tracker);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -841,18 +841,18 @@ mod tests {
|
|||
|
||||
let user_id = get_random_user_id();
|
||||
let user = UserInfo::new(21, 42);
|
||||
dbm.store_user(&user_id, &user).unwrap();
|
||||
dbm.store_user(user_id, &user).unwrap();
|
||||
|
||||
let (uuid, appointment) = generate_dummy_appointment_with_user(user_id, None);
|
||||
dbm.store_appointment(&uuid, &appointment).unwrap();
|
||||
dbm.store_appointment(uuid, &appointment).unwrap();
|
||||
|
||||
let mut tracker = get_random_tracker(user_id);
|
||||
tracker.locator = appointment.locator();
|
||||
assert!(matches!(dbm.store_tracker(&uuid, &tracker), Ok { .. }));
|
||||
assert!(matches!(dbm.store_tracker(uuid, &tracker), Ok { .. }));
|
||||
|
||||
// Try to store it again, but it shouldn't go trough
|
||||
assert!(matches!(
|
||||
dbm.store_tracker(&uuid, &tracker),
|
||||
dbm.store_tracker(uuid, &tracker),
|
||||
Err(Error::AlreadyExists)
|
||||
));
|
||||
}
|
||||
|
|
@ -866,7 +866,7 @@ mod tests {
|
|||
let tracker = get_random_tracker(user_id);
|
||||
|
||||
assert!(matches!(
|
||||
dbm.store_tracker(&uuid, &tracker),
|
||||
dbm.store_tracker(uuid, &tracker),
|
||||
Err(Error::MissingForeignKey)
|
||||
));
|
||||
}
|
||||
|
|
@ -876,7 +876,7 @@ mod tests {
|
|||
let dbm = DBM::in_memory().unwrap();
|
||||
|
||||
let uuid = generate_uuid();
|
||||
assert!(matches!(dbm.load_tracker(&uuid), Err(Error::NotFound)));
|
||||
assert!(matches!(dbm.load_tracker(uuid), Err(Error::NotFound)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -887,14 +887,14 @@ mod tests {
|
|||
for i in 1..11 {
|
||||
let user_id = get_random_user_id();
|
||||
let user = UserInfo::new(i, i * 2);
|
||||
dbm.store_user(&user_id, &user).unwrap();
|
||||
dbm.store_user(user_id, &user).unwrap();
|
||||
|
||||
let (uuid, appointment) = generate_dummy_appointment_with_user(user_id, None);
|
||||
dbm.store_appointment(&uuid, &appointment).unwrap();
|
||||
dbm.store_appointment(uuid, &appointment).unwrap();
|
||||
|
||||
let mut tracker = get_random_tracker(user_id);
|
||||
tracker.locator = appointment.locator();
|
||||
dbm.store_tracker(&uuid, &tracker).unwrap();
|
||||
dbm.store_tracker(uuid, &tracker).unwrap();
|
||||
trackers.insert(uuid, tracker);
|
||||
}
|
||||
|
||||
|
|
@ -986,14 +986,14 @@ mod tests {
|
|||
|
||||
let user_id = get_random_user_id();
|
||||
let user = UserInfo::new(21, 42);
|
||||
dbm.store_user(&user_id, &user).unwrap();
|
||||
dbm.store_user(user_id, &user).unwrap();
|
||||
|
||||
let mut rest = HashSet::new();
|
||||
for i in 1..6 {
|
||||
let mut to_be_deleted = HashSet::new();
|
||||
for j in 0..limit * 2 * i {
|
||||
let (uuid, appointment) = generate_dummy_appointment_with_user(user_id, None);
|
||||
dbm.store_appointment(&uuid, &appointment).unwrap();
|
||||
dbm.store_appointment(uuid, &appointment).unwrap();
|
||||
|
||||
if j % 2 == 0 {
|
||||
to_be_deleted.insert(uuid);
|
||||
|
|
@ -1021,31 +1021,31 @@ mod tests {
|
|||
let tracker = get_random_tracker(appointment.user_id);
|
||||
|
||||
// Add the user b/c of FK restrictions
|
||||
dbm.store_user(&appointment.user_id, &UserInfo::new(21, 42))
|
||||
dbm.store_user(appointment.user_id, &UserInfo::new(21, 42))
|
||||
.unwrap();
|
||||
|
||||
// Appointment only
|
||||
assert!(matches!(
|
||||
dbm.store_appointment(&uuid, &appointment.clone()),
|
||||
dbm.store_appointment(uuid, &appointment.clone()),
|
||||
Ok { .. }
|
||||
));
|
||||
|
||||
dbm.batch_remove_appointments(&HashSet::from_iter(vec![uuid]));
|
||||
assert!(matches!(dbm.load_appointment(&uuid), Err(Error::NotFound)));
|
||||
assert!(matches!(dbm.load_appointment(uuid), Err(Error::NotFound)));
|
||||
|
||||
// Appointment + Tracker
|
||||
assert!(matches!(
|
||||
dbm.store_appointment(&uuid, &appointment.clone()),
|
||||
dbm.store_appointment(uuid, &appointment.clone()),
|
||||
Ok { .. }
|
||||
));
|
||||
assert!(matches!(
|
||||
dbm.store_tracker(&uuid, &tracker.clone()),
|
||||
dbm.store_tracker(uuid, &tracker.clone()),
|
||||
Ok { .. }
|
||||
));
|
||||
|
||||
dbm.batch_remove_appointments(&HashSet::from_iter(vec![uuid]));
|
||||
assert!(matches!(dbm.load_appointment(&uuid), Err(Error::NotFound)));
|
||||
assert!(matches!(dbm.load_tracker(&uuid), Err(Error::NotFound)));
|
||||
assert!(matches!(dbm.load_appointment(uuid), Err(Error::NotFound)));
|
||||
assert!(matches!(dbm.load_tracker(uuid), Err(Error::NotFound)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -1073,19 +1073,19 @@ mod tests {
|
|||
user_id,
|
||||
);
|
||||
|
||||
dbm.store_user(&user_id, &user).unwrap();
|
||||
dbm.store_appointment(&uuid, &appointment).unwrap();
|
||||
dbm.store_tracker(&uuid, &tracker).unwrap();
|
||||
dbm.store_user(user_id, &user).unwrap();
|
||||
dbm.store_appointment(uuid, &appointment).unwrap();
|
||||
dbm.store_tracker(uuid, &tracker).unwrap();
|
||||
|
||||
// Check data is in the DB (this is implicitly checked by the unwraps, but anyway)
|
||||
assert_eq!(dbm.load_user(&user_id).unwrap(), user);
|
||||
assert_eq!(dbm.load_appointment(&uuid).unwrap(), appointment);
|
||||
assert_eq!(dbm.load_tracker(&uuid).unwrap(), tracker);
|
||||
assert_eq!(dbm.load_user(user_id).unwrap(), user);
|
||||
assert_eq!(dbm.load_appointment(uuid).unwrap(), appointment);
|
||||
assert_eq!(dbm.load_tracker(uuid).unwrap(), tracker);
|
||||
|
||||
// Remove the user and check again
|
||||
dbm.remove_user(&user_id);
|
||||
assert!(matches!(dbm.load_user(&user_id), Err(Error::NotFound)));
|
||||
assert!(matches!(dbm.load_appointment(&uuid), Err(Error::NotFound)));
|
||||
assert!(matches!(dbm.load_tracker(&uuid), Err(Error::NotFound)));
|
||||
dbm.remove_user(user_id);
|
||||
assert!(matches!(dbm.load_user(user_id), Err(Error::NotFound)));
|
||||
assert!(matches!(dbm.load_appointment(uuid), Err(Error::NotFound)));
|
||||
assert!(matches!(dbm.load_tracker(uuid), Err(Error::NotFound)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use teos_common::UserId;
|
|||
pub struct UUID(pub [u8; 20]);
|
||||
|
||||
impl UUID {
|
||||
pub fn new(locator: &Locator, user_id: &UserId) -> Self {
|
||||
pub fn new(locator: Locator, user_id: UserId) -> Self {
|
||||
let mut uuid_data = locator.serialize();
|
||||
uuid_data.extend(&user_id.0.serialize());
|
||||
UUID(ripemd160::Hash::hash(&uuid_data).into_inner())
|
||||
|
|
|
|||
|
|
@ -88,15 +88,12 @@ impl Gatekeeper {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn add_update_user(
|
||||
&self,
|
||||
user_id: &UserId,
|
||||
) -> Result<RegistrationReceipt, MaxSlotsReached> {
|
||||
pub fn add_update_user(&self, user_id: UserId) -> Result<RegistrationReceipt, MaxSlotsReached> {
|
||||
let block_count = self.last_known_block_header.height;
|
||||
|
||||
// TODO: For now, new calls to register add subscription_slots to the current count and reset the expiry time
|
||||
let mut borrowed = self.registered_users.borrow_mut();
|
||||
let user_info = match borrowed.get_mut(user_id) {
|
||||
let user_info = match borrowed.get_mut(&user_id) {
|
||||
// User already exists, updating the info
|
||||
Some(user_info) => {
|
||||
user_info.available_slots = user_info
|
||||
|
|
@ -106,7 +103,7 @@ impl Gatekeeper {
|
|||
user_info.subscription_expiry = block_count + self.subscription_duration;
|
||||
self.dbm.lock().unwrap().update_user(user_id, &user_info);
|
||||
|
||||
user_info.clone()
|
||||
user_info
|
||||
}
|
||||
// New user
|
||||
None => {
|
||||
|
|
@ -114,19 +111,19 @@ impl Gatekeeper {
|
|||
self.subscription_slots,
|
||||
block_count + self.subscription_duration,
|
||||
);
|
||||
borrowed.insert(user_id.clone(), user_info.clone());
|
||||
self.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.store_user(user_id, &user_info)
|
||||
.unwrap();
|
||||
|
||||
user_info
|
||||
borrowed.insert(user_id, user_info);
|
||||
borrowed.get_mut(&user_id).unwrap()
|
||||
}
|
||||
};
|
||||
|
||||
Ok(RegistrationReceipt::new(
|
||||
user_id.clone(),
|
||||
user_id,
|
||||
user_info.available_slots,
|
||||
user_info.subscription_expiry,
|
||||
))
|
||||
|
|
@ -134,14 +131,14 @@ impl Gatekeeper {
|
|||
|
||||
pub fn add_update_appointment(
|
||||
&self,
|
||||
user_id: &UserId,
|
||||
user_id: UserId,
|
||||
uuid: UUID,
|
||||
appointment: &ExtendedAppointment,
|
||||
) -> Result<u32, NotEnoughSlots> {
|
||||
// For updates, the difference between the existing appointment size and the update is computed.
|
||||
let mut borrowed = self.registered_users.borrow_mut();
|
||||
let user_info = borrowed.get_mut(user_id).unwrap();
|
||||
let used_slots = user_info.appointments.get(&uuid).map_or(0, |x| x.clone());
|
||||
let user_info = borrowed.get_mut(&user_id).unwrap();
|
||||
let used_slots = user_info.appointments.get(&uuid).map_or(0, |x| *x);
|
||||
|
||||
let required_slots =
|
||||
compute_appointment_slots(appointment.encrypted_blob().len(), ENCRYPTED_BLOB_MAX_SIZE);
|
||||
|
|
@ -163,7 +160,7 @@ impl Gatekeeper {
|
|||
|
||||
pub fn has_subscription_expired(
|
||||
&self,
|
||||
user_id: &UserId,
|
||||
user_id: UserId,
|
||||
) -> Result<(bool, u32), AuthenticationFailure<'_>> {
|
||||
self.registered_users.borrow().get(&user_id).map_or(
|
||||
Err(AuthenticationFailure("User not found.")),
|
||||
|
|
@ -176,17 +173,15 @@ impl Gatekeeper {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn get_outdated_users(&self, block_height: &u32) -> HashMap<UserId, Vec<UUID>> {
|
||||
match self.outdated_users_cache.borrow().get(&block_height) {
|
||||
pub fn get_outdated_users(&self, block_height: u32) -> HashMap<UserId, Vec<UUID>> {
|
||||
let borrowed = self.outdated_users_cache.borrow();
|
||||
match borrowed.get(&block_height) {
|
||||
Some(users) => users.clone(),
|
||||
None => {
|
||||
let mut users = HashMap::new();
|
||||
for (user_id, user_info) in self.registered_users.borrow().iter() {
|
||||
if *block_height == user_info.subscription_expiry + self.expiry_delta {
|
||||
users.insert(
|
||||
user_id.clone(),
|
||||
user_info.appointments.keys().cloned().collect(),
|
||||
);
|
||||
if block_height == user_info.subscription_expiry + self.expiry_delta {
|
||||
users.insert(*user_id, user_info.appointments.keys().cloned().collect());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -194,14 +189,14 @@ impl Gatekeeper {
|
|||
}
|
||||
}
|
||||
}
|
||||
pub fn get_outdated_user_ids(&self, block_height: &u32) -> Vec<UserId> {
|
||||
pub fn get_outdated_user_ids(&self, block_height: u32) -> Vec<UserId> {
|
||||
self.get_outdated_users(block_height)
|
||||
.keys()
|
||||
.cloned()
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn get_outdated_appointments(&self, block_height: &u32) -> HashSet<UUID> {
|
||||
pub fn get_outdated_appointments(&self, block_height: u32) -> HashSet<UUID> {
|
||||
HashSet::from_iter(
|
||||
self.get_outdated_users(block_height)
|
||||
.into_values()
|
||||
|
|
@ -209,7 +204,7 @@ impl Gatekeeper {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn update_outdated_users_cache(&self, block_height: &u32) -> HashMap<UserId, Vec<UUID>> {
|
||||
pub fn update_outdated_users_cache(&self, block_height: u32) -> HashMap<UserId, Vec<UUID>> {
|
||||
let mut outdated_users = HashMap::new();
|
||||
|
||||
if !self
|
||||
|
|
@ -232,7 +227,7 @@ impl Gatekeeper {
|
|||
// TODO: This can be implemented as a batch delete
|
||||
borrowed.remove(&first).map(|users| {
|
||||
for user_id in users.keys() {
|
||||
self.dbm.lock().unwrap().remove_user(user_id);
|
||||
self.dbm.lock().unwrap().remove_user(*user_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -261,7 +256,7 @@ impl Gatekeeper {
|
|||
// Update data in the database
|
||||
for user_id in updated_users {
|
||||
self.dbm.lock().unwrap().update_user(
|
||||
user_id,
|
||||
*user_id,
|
||||
self.registered_users.borrow().get(user_id).unwrap(),
|
||||
);
|
||||
}
|
||||
|
|
@ -272,7 +267,7 @@ impl chain::Listen for Gatekeeper {
|
|||
fn block_connected(&self, block: &bitcoin::Block, height: u32) {
|
||||
// Expired user deletion is delayed. Users are deleted when their subscription is outdated, not expired.
|
||||
log::info!("New block received: {}", block.block_hash());
|
||||
let outdated_users = self.update_outdated_users_cache(&height);
|
||||
let outdated_users = self.update_outdated_users_cache(height);
|
||||
|
||||
for user_id in outdated_users.keys() {
|
||||
self.registered_users.borrow_mut().remove(user_id);
|
||||
|
|
@ -330,7 +325,7 @@ mod tests {
|
|||
|
||||
// Last, let's add the user to the Gatekeeper and try again.
|
||||
let user_id = UserId(user_pk);
|
||||
gatekeeper.add_update_user(&user_id).unwrap();
|
||||
gatekeeper.add_update_user(user_id).unwrap();
|
||||
assert_eq!(
|
||||
gatekeeper.authenticate_user(message, &signature),
|
||||
Ok(user_id)
|
||||
|
|
@ -349,17 +344,17 @@ mod tests {
|
|||
|
||||
// Let's start by adding new user
|
||||
let user_id = get_random_user_id();
|
||||
let receipt = gatekeeper.add_update_user(&user_id).unwrap();
|
||||
let receipt = gatekeeper.add_update_user(user_id).unwrap();
|
||||
// The data should have been also added to the database
|
||||
assert_eq!(
|
||||
dbm.lock().unwrap().load_user(&user_id).unwrap(),
|
||||
dbm.lock().unwrap().load_user(user_id).unwrap(),
|
||||
UserInfo::new(receipt.available_slots(), receipt.subscription_expiry())
|
||||
);
|
||||
|
||||
// Let generate a new block and add the user again to check that both the slots and expiry are updated.
|
||||
chain.generate_with_txs(Vec::new());
|
||||
gatekeeper.last_known_block_header = chain.tip();
|
||||
let updated_receipt = gatekeeper.add_update_user(&user_id).unwrap();
|
||||
let updated_receipt = gatekeeper.add_update_user(user_id).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
updated_receipt.available_slots(),
|
||||
|
|
@ -372,7 +367,7 @@ mod tests {
|
|||
|
||||
// Data in the database should have been updated too
|
||||
assert_eq!(
|
||||
dbm.lock().unwrap().load_user(&user_id).unwrap(),
|
||||
dbm.lock().unwrap().load_user(user_id).unwrap(),
|
||||
UserInfo::new(
|
||||
updated_receipt.available_slots(),
|
||||
updated_receipt.subscription_expiry()
|
||||
|
|
@ -388,13 +383,13 @@ mod tests {
|
|||
.available_slots = u32::MAX;
|
||||
|
||||
assert!(matches!(
|
||||
gatekeeper.add_update_user(&user_id),
|
||||
gatekeeper.add_update_user(user_id),
|
||||
Err(MaxSlotsReached)
|
||||
));
|
||||
|
||||
// Data in the database remains untouched
|
||||
assert_eq!(
|
||||
dbm.lock().unwrap().load_user(&user_id).unwrap(),
|
||||
dbm.lock().unwrap().load_user(user_id).unwrap(),
|
||||
UserInfo::new(
|
||||
updated_receipt.available_slots(),
|
||||
updated_receipt.subscription_expiry()
|
||||
|
|
@ -414,7 +409,7 @@ mod tests {
|
|||
|
||||
// Let's first add the a user to the Gatekeeper (inputs are always sanitized here, so we don't need tests for non-registered users)
|
||||
let user_id = get_random_user_id();
|
||||
gatekeeper.add_update_user(&user_id).unwrap();
|
||||
gatekeeper.add_update_user(user_id).unwrap();
|
||||
|
||||
// Now let's add a new appointment
|
||||
let slots_before = gatekeeper
|
||||
|
|
@ -425,7 +420,7 @@ mod tests {
|
|||
.available_slots;
|
||||
let (uuid, appointment) = generate_dummy_appointment_with_user(user_id, None);
|
||||
let available_slots = gatekeeper
|
||||
.add_update_appointment(&user_id, uuid, &appointment)
|
||||
.add_update_appointment(user_id, uuid, &appointment)
|
||||
.unwrap();
|
||||
|
||||
assert!(gatekeeper.registered_users.borrow()[&user_id]
|
||||
|
|
@ -435,54 +430,54 @@ mod tests {
|
|||
|
||||
// Slots should have been updated in the database too. Notice the appointment won't be there yet
|
||||
// given the Watcher is responsible for adding it, and it will do so after calling this method
|
||||
let mut loaded_user = dbm.lock().unwrap().load_user(&user_id).unwrap();
|
||||
let mut loaded_user = dbm.lock().unwrap().load_user(user_id).unwrap();
|
||||
assert_eq!(loaded_user.available_slots, available_slots);
|
||||
|
||||
// Adding the exact same appointment should leave the slots count unchanged
|
||||
let mut updated_slot_count = gatekeeper
|
||||
.add_update_appointment(&user_id, uuid, &appointment)
|
||||
.add_update_appointment(user_id, uuid, &appointment)
|
||||
.unwrap();
|
||||
assert!(gatekeeper.registered_users.borrow()[&user_id]
|
||||
.appointments
|
||||
.contains_key(&uuid));
|
||||
assert_eq!(updated_slot_count, available_slots);
|
||||
loaded_user = dbm.lock().unwrap().load_user(&user_id).unwrap();
|
||||
loaded_user = dbm.lock().unwrap().load_user(user_id).unwrap();
|
||||
assert_eq!(loaded_user.available_slots, updated_slot_count);
|
||||
|
||||
// If we add an update to an existing appointment with a bigger data blob (modulo ENCRYPTED_BLOB_MAX_SIZE), additional slots should be taken
|
||||
let mut bigger_appointment = appointment.clone();
|
||||
bigger_appointment.inner.encrypted_blob = get_random_bytes(ENCRYPTED_BLOB_MAX_SIZE + 1);
|
||||
updated_slot_count = gatekeeper
|
||||
.add_update_appointment(&user_id, uuid, &bigger_appointment)
|
||||
.add_update_appointment(user_id, uuid, &bigger_appointment)
|
||||
.unwrap();
|
||||
assert!(gatekeeper.registered_users.borrow()[&user_id]
|
||||
.appointments
|
||||
.contains_key(&uuid));
|
||||
assert_eq!(updated_slot_count, available_slots - 1);
|
||||
loaded_user = dbm.lock().unwrap().load_user(&user_id).unwrap();
|
||||
loaded_user = dbm.lock().unwrap().load_user(user_id).unwrap();
|
||||
assert_eq!(loaded_user.available_slots, updated_slot_count);
|
||||
|
||||
// Adding back a smaller update (modulo ENCRYPTED_BLOB_MAX_SIZE) should reduce the count
|
||||
updated_slot_count = gatekeeper
|
||||
.add_update_appointment(&user_id, uuid, &appointment)
|
||||
.add_update_appointment(user_id, uuid, &appointment)
|
||||
.unwrap();
|
||||
assert!(gatekeeper.registered_users.borrow()[&user_id]
|
||||
.appointments
|
||||
.contains_key(&uuid));
|
||||
assert_eq!(updated_slot_count, available_slots);
|
||||
loaded_user = dbm.lock().unwrap().load_user(&user_id).unwrap();
|
||||
loaded_user = dbm.lock().unwrap().load_user(user_id).unwrap();
|
||||
assert_eq!(loaded_user.available_slots, updated_slot_count);
|
||||
|
||||
// Adding an appointment with a different uuid should not count as an update
|
||||
let new_uuid = generate_uuid();
|
||||
updated_slot_count = gatekeeper
|
||||
.add_update_appointment(&user_id, new_uuid, &appointment)
|
||||
.add_update_appointment(user_id, new_uuid, &appointment)
|
||||
.unwrap();
|
||||
assert!(gatekeeper.registered_users.borrow()[&user_id]
|
||||
.appointments
|
||||
.contains_key(&new_uuid));
|
||||
assert_eq!(updated_slot_count, available_slots - 1);
|
||||
loaded_user = dbm.lock().unwrap().load_user(&user_id).unwrap();
|
||||
loaded_user = dbm.lock().unwrap().load_user(user_id).unwrap();
|
||||
assert_eq!(loaded_user.available_slots, updated_slot_count);
|
||||
|
||||
// Finally, trying to add an appointment when the user has no enough slots should fail
|
||||
|
|
@ -493,11 +488,11 @@ mod tests {
|
|||
.unwrap()
|
||||
.available_slots = 0;
|
||||
assert!(matches!(
|
||||
gatekeeper.add_update_appointment(&user_id, generate_uuid(), &appointment),
|
||||
gatekeeper.add_update_appointment(user_id, generate_uuid(), &appointment),
|
||||
Err(NotEnoughSlots)
|
||||
));
|
||||
// The entry in the database should remain unchanged in this case
|
||||
loaded_user = dbm.lock().unwrap().load_user(&user_id).unwrap();
|
||||
loaded_user = dbm.lock().unwrap().load_user(user_id).unwrap();
|
||||
assert_eq!(loaded_user.available_slots, updated_slot_count);
|
||||
}
|
||||
|
||||
|
|
@ -512,14 +507,14 @@ mod tests {
|
|||
|
||||
// If the user is not registered, querying for a subscription expiry check should return an error
|
||||
assert!(matches!(
|
||||
gatekeeper.has_subscription_expired(&user_id),
|
||||
gatekeeper.has_subscription_expired(user_id),
|
||||
Err(AuthenticationFailure { .. })
|
||||
));
|
||||
|
||||
// If the user is registered and the subscription is active we should get (false, expiry)
|
||||
gatekeeper.add_update_user(&user_id).unwrap();
|
||||
gatekeeper.add_update_user(user_id).unwrap();
|
||||
assert_eq!(
|
||||
gatekeeper.has_subscription_expired(&user_id),
|
||||
gatekeeper.has_subscription_expired(user_id),
|
||||
Ok((false, DURATION + START_HEIGHT as u32))
|
||||
);
|
||||
|
||||
|
|
@ -532,7 +527,7 @@ mod tests {
|
|||
.unwrap()
|
||||
.subscription_expiry = expiry;
|
||||
assert_eq!(
|
||||
gatekeeper.has_subscription_expired(&user_id),
|
||||
gatekeeper.has_subscription_expired(user_id),
|
||||
Ok((true, expiry))
|
||||
);
|
||||
}
|
||||
|
|
@ -547,18 +542,18 @@ mod tests {
|
|||
|
||||
// Initially, the outdated_users_cache is empty, so querying any block height should return an empty map
|
||||
for i in 0..start_height {
|
||||
assert_eq!(gatekeeper.get_outdated_users(&i).len(), 0);
|
||||
assert_eq!(gatekeeper.get_outdated_users(i).len(), 0);
|
||||
}
|
||||
|
||||
// Adding a user whose subscription is outdated should return an entry
|
||||
let user_id = get_random_user_id();
|
||||
gatekeeper.add_update_user(&user_id).unwrap();
|
||||
gatekeeper.add_update_user(user_id).unwrap();
|
||||
|
||||
// Add also an appointment so we can check the returned data
|
||||
let appointment = generate_dummy_appointment(None);
|
||||
let uuid = generate_uuid();
|
||||
gatekeeper
|
||||
.add_update_appointment(&user_id, uuid, &appointment)
|
||||
.add_update_appointment(user_id, uuid, &appointment)
|
||||
.unwrap();
|
||||
|
||||
// Check that data is not in the cache before querying
|
||||
|
|
@ -571,7 +566,7 @@ mod tests {
|
|||
.unwrap()
|
||||
.subscription_expiry = START_HEIGHT as u32;
|
||||
|
||||
let outdated_users = gatekeeper.get_outdated_users(&start_height);
|
||||
let outdated_users = gatekeeper.get_outdated_users(start_height);
|
||||
assert_eq!(outdated_users.len(), 1);
|
||||
assert_eq!(outdated_users[&user_id], Vec::from([uuid]));
|
||||
|
||||
|
|
@ -582,10 +577,7 @@ mod tests {
|
|||
gatekeeper.outdated_users_cache.borrow().get(&target_height),
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
gatekeeper.get_outdated_users(&target_height),
|
||||
HashMap::new()
|
||||
);
|
||||
assert_eq!(gatekeeper.get_outdated_users(target_height), HashMap::new());
|
||||
|
||||
let mut hm = HashMap::new();
|
||||
hm.insert(user_id, Vec::from([uuid]));
|
||||
|
|
@ -593,7 +585,7 @@ mod tests {
|
|||
.outdated_users_cache
|
||||
.borrow_mut()
|
||||
.insert(target_height, hm.clone());
|
||||
assert_eq!(gatekeeper.get_outdated_users(&start_height), hm);
|
||||
assert_eq!(gatekeeper.get_outdated_users(start_height), hm);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -608,14 +600,14 @@ mod tests {
|
|||
|
||||
// If there are no outdated users, there cannot be outdated appointments
|
||||
for i in 0..start_height {
|
||||
assert_eq!(gatekeeper.get_outdated_appointments(&i).len(), 0);
|
||||
assert_eq!(gatekeeper.get_outdated_appointments(i).len(), 0);
|
||||
}
|
||||
|
||||
// Adding data about different users and appointments should return a flattened list of appointments
|
||||
let user1_id = get_random_user_id();
|
||||
let user2_id = get_random_user_id();
|
||||
gatekeeper.add_update_user(&user1_id).unwrap();
|
||||
gatekeeper.add_update_user(&user2_id).unwrap();
|
||||
gatekeeper.add_update_user(user1_id).unwrap();
|
||||
gatekeeper.add_update_user(user2_id).unwrap();
|
||||
|
||||
// Manually set the user expiry for the test
|
||||
gatekeeper
|
||||
|
|
@ -637,13 +629,13 @@ mod tests {
|
|||
let appointment = generate_dummy_appointment(None);
|
||||
|
||||
gatekeeper
|
||||
.add_update_appointment(&user1_id, uuid1, &appointment)
|
||||
.add_update_appointment(user1_id, uuid1, &appointment)
|
||||
.unwrap();
|
||||
gatekeeper
|
||||
.add_update_appointment(&user2_id, uuid2, &appointment)
|
||||
.add_update_appointment(user2_id, uuid2, &appointment)
|
||||
.unwrap();
|
||||
|
||||
let outdated_appointments = gatekeeper.get_outdated_appointments(&start_height);
|
||||
let outdated_appointments = gatekeeper.get_outdated_appointments(start_height);
|
||||
assert_eq!(outdated_appointments.len(), 2);
|
||||
assert!(outdated_appointments.contains(&uuid1));
|
||||
assert!(outdated_appointments.contains(&uuid2));
|
||||
|
|
@ -662,7 +654,7 @@ mod tests {
|
|||
|
||||
// If there's outdated data to be added and there's room in the cache, the data will be added
|
||||
let user_id = get_random_user_id();
|
||||
gatekeeper.add_update_user(&user_id).unwrap();
|
||||
gatekeeper.add_update_user(user_id).unwrap();
|
||||
gatekeeper
|
||||
.registered_users
|
||||
.borrow_mut()
|
||||
|
|
@ -671,11 +663,11 @@ mod tests {
|
|||
.subscription_expiry = start_height - EXPIRY_DELTA - 1;
|
||||
|
||||
assert_eq!(gatekeeper.outdated_users_cache.borrow().len(), 0);
|
||||
gatekeeper.update_outdated_users_cache(&(start_height - 1));
|
||||
gatekeeper.update_outdated_users_cache(start_height - 1);
|
||||
assert_eq!(gatekeeper.outdated_users_cache.borrow().len(), 1);
|
||||
|
||||
// If the cache has room and there's no data to add, an empty entry will be added
|
||||
gatekeeper.update_outdated_users_cache(&start_height);
|
||||
gatekeeper.update_outdated_users_cache(start_height);
|
||||
assert_eq!(gatekeeper.outdated_users_cache.borrow().len(), 2);
|
||||
assert_eq!(
|
||||
gatekeeper.outdated_users_cache.borrow()[&(start_height)],
|
||||
|
|
@ -684,7 +676,7 @@ mod tests {
|
|||
|
||||
// Adding data (even empty) to the cache up to it's limit should remove the first element
|
||||
for i in start_height + 1..start_height + OUTDATED_USERS_CACHE_SIZE_BLOCKS as u32 - 1 {
|
||||
gatekeeper.update_outdated_users_cache(&i);
|
||||
gatekeeper.update_outdated_users_cache(i);
|
||||
}
|
||||
|
||||
// Check the first key is still there and that the user can still be found in the database
|
||||
|
|
@ -697,13 +689,13 @@ mod tests {
|
|||
.borrow()
|
||||
.contains_key(&(start_height - 1)));
|
||||
assert!(matches!(
|
||||
dbm.lock().unwrap().load_user(&user_id),
|
||||
dbm.lock().unwrap().load_user(user_id),
|
||||
Ok(UserInfo { .. })
|
||||
));
|
||||
|
||||
// Add one more block and check again. Data should have been removed from the cache and the database
|
||||
gatekeeper.update_outdated_users_cache(
|
||||
&(start_height + OUTDATED_USERS_CACHE_SIZE_BLOCKS as u32 - 1),
|
||||
start_height + OUTDATED_USERS_CACHE_SIZE_BLOCKS as u32 - 1,
|
||||
);
|
||||
assert_eq!(
|
||||
gatekeeper.outdated_users_cache.borrow().len(),
|
||||
|
|
@ -713,7 +705,7 @@ mod tests {
|
|||
.outdated_users_cache
|
||||
.borrow()
|
||||
.contains_key(&(start_height - 1)));
|
||||
assert!(matches!(dbm.lock().unwrap().load_user(&user_id), Err(..)));
|
||||
assert!(matches!(dbm.lock().unwrap().load_user(user_id), Err(..)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -730,7 +722,7 @@ mod tests {
|
|||
for i in 1..11 {
|
||||
let user_id = get_random_user_id();
|
||||
let uuid = generate_uuid();
|
||||
all_appointments.insert(uuid, user_id.clone());
|
||||
all_appointments.insert(uuid, user_id);
|
||||
|
||||
if i % 2 == 0 {
|
||||
to_be_deleted.insert(uuid, user_id);
|
||||
|
|
@ -746,9 +738,9 @@ mod tests {
|
|||
|
||||
// If there's matching data in the gatekeeper it should be deleted
|
||||
for (uuid, user_id) in to_be_deleted.iter() {
|
||||
gatekeeper.add_update_user(&user_id).unwrap();
|
||||
gatekeeper.add_update_user(*user_id).unwrap();
|
||||
gatekeeper
|
||||
.add_update_appointment(&user_id, *uuid, &generate_dummy_appointment(None))
|
||||
.add_update_appointment(*user_id, *uuid, &generate_dummy_appointment(None))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
|
|
@ -769,7 +761,7 @@ mod tests {
|
|||
.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.load_user(user_id)
|
||||
.load_user(*user_id)
|
||||
.unwrap()
|
||||
.available_slots,
|
||||
gatekeeper.subscription_slots
|
||||
|
|
@ -782,13 +774,13 @@ mod tests {
|
|||
// And after
|
||||
gatekeeper.delete_appointments(&all_appointments);
|
||||
for (uuid, user_id) in to_be_deleted.iter() {
|
||||
assert!(!gatekeeper.registered_users.borrow()[user_id]
|
||||
assert!(!gatekeeper.registered_users.borrow()[&user_id]
|
||||
.appointments
|
||||
.contains_key(uuid));
|
||||
|
||||
// The slot count is back to default
|
||||
assert_eq!(
|
||||
gatekeeper.registered_users.borrow()[user_id].available_slots,
|
||||
gatekeeper.registered_users.borrow()[&user_id].available_slots,
|
||||
gatekeeper.subscription_slots
|
||||
);
|
||||
assert_eq!(
|
||||
|
|
@ -796,7 +788,7 @@ mod tests {
|
|||
.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.load_user(user_id)
|
||||
.load_user(*user_id)
|
||||
.unwrap()
|
||||
.available_slots,
|
||||
gatekeeper.subscription_slots
|
||||
|
|
@ -840,7 +832,7 @@ mod tests {
|
|||
|
||||
last_height += 1;
|
||||
for user in vec![user1_id, user2_id, user3_id] {
|
||||
gatekeeper.add_update_user(&user).unwrap();
|
||||
gatekeeper.add_update_user(user).unwrap();
|
||||
gatekeeper
|
||||
.registered_users
|
||||
.borrow_mut()
|
||||
|
|
@ -859,7 +851,7 @@ mod tests {
|
|||
|
||||
// Data is still in the database since the user is in the cache
|
||||
assert!(matches!(
|
||||
dbm.lock().unwrap().load_user(&user),
|
||||
dbm.lock().unwrap().load_user(user),
|
||||
Ok(UserInfo { .. })
|
||||
));
|
||||
}
|
||||
|
|
@ -872,7 +864,7 @@ mod tests {
|
|||
|
||||
for user in vec![user1_id, user2_id, user3_id] {
|
||||
assert!(matches!(
|
||||
dbm.lock().unwrap().load_user(&user),
|
||||
dbm.lock().unwrap().load_user(user),
|
||||
Err(DBError::NotFound)
|
||||
));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ use teos_common::cryptography::get_random_keypair;
|
|||
|
||||
async fn get_last_n_blocks<B, T>(
|
||||
poller: &mut ChainPoller<B, T>,
|
||||
tip: ValidatedBlockHeader,
|
||||
mut last_known_block: ValidatedBlockHeader,
|
||||
n: usize,
|
||||
) -> Vec<ValidatedBlock>
|
||||
where
|
||||
|
|
@ -31,7 +31,6 @@ where
|
|||
T: BlockSource,
|
||||
{
|
||||
let mut last_n_blocks = Vec::new();
|
||||
let mut last_known_block = tip;
|
||||
for _ in 0..n {
|
||||
let block = poller.fetch_block(&last_known_block).await.unwrap();
|
||||
last_known_block = poller
|
||||
|
|
@ -96,10 +95,10 @@ pub async fn main() {
|
|||
|
||||
// Initialize our bitcoind client
|
||||
let bitcoin_cli = match BitcoindClient::new(
|
||||
conf.btc_rpc_connect.clone(),
|
||||
&conf.btc_rpc_connect,
|
||||
conf.btc_rpc_port,
|
||||
conf.btc_rpc_user.clone(),
|
||||
conf.btc_rpc_password.clone(),
|
||||
&conf.btc_rpc_user,
|
||||
&conf.btc_rpc_password,
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
|
@ -120,7 +119,7 @@ pub async fn main() {
|
|||
let rpc = Arc::new(
|
||||
Client::new(
|
||||
format!("{}{}:{}", schema, conf.btc_rpc_connect, conf.btc_rpc_port).to_string(),
|
||||
Auth::UserPass(conf.btc_rpc_user, conf.btc_rpc_password),
|
||||
Auth::UserPass(conf.btc_rpc_user.clone(), conf.btc_rpc_password.clone()),
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ impl TransactionTracker {
|
|||
Self {
|
||||
locator: breach.locator,
|
||||
dispute_tx: breach.dispute_tx,
|
||||
penalty_tx: breach.penalty_tx.clone(),
|
||||
penalty_tx: breach.penalty_tx,
|
||||
user_id,
|
||||
}
|
||||
}
|
||||
|
|
@ -84,7 +84,7 @@ impl<'a> Responder<'a> {
|
|||
missed_confirmations,
|
||||
dbm,
|
||||
gatekeeper,
|
||||
last_known_block_header: RefCell::new(last_known_block_header.deref().clone()),
|
||||
last_known_block_header: RefCell::new(*last_known_block_header.deref()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ impl<'a> Responder<'a> {
|
|||
confirmations: u32,
|
||||
) {
|
||||
let penalty_txid = breach.penalty_tx.txid();
|
||||
let tracker = TransactionTracker::new(breach.clone(), user_id);
|
||||
let tracker = TransactionTracker::new(breach, user_id);
|
||||
|
||||
self.trackers
|
||||
.borrow_mut()
|
||||
|
|
@ -129,27 +129,27 @@ impl<'a> Responder<'a> {
|
|||
if !self
|
||||
.unconfirmed_txs
|
||||
.borrow()
|
||||
.contains(&breach.penalty_tx.txid())
|
||||
.contains(&tracker.penalty_tx.txid())
|
||||
&& confirmations == 0
|
||||
{
|
||||
self.unconfirmed_txs
|
||||
.borrow_mut()
|
||||
.insert(breach.penalty_tx.txid());
|
||||
.insert(tracker.penalty_tx.txid());
|
||||
}
|
||||
|
||||
self.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.store_tracker(&uuid, &tracker)
|
||||
.store_tracker(uuid, &tracker)
|
||||
.unwrap();
|
||||
log::info!("New tracker added (uuid={}).", uuid);
|
||||
}
|
||||
|
||||
pub fn has_tracker(&self, uuid: &UUID) -> bool {
|
||||
pub fn has_tracker(&self, uuid: UUID) -> bool {
|
||||
// Has tracker should return true as long as the given tracker is hold by the Responder.
|
||||
// If the tracker is partially kept, the function will log and the return will be false.
|
||||
// This may point out that some partial data deletion is happening, which must be fixed.
|
||||
self.trackers.borrow().get(uuid).map_or(false, |tracker| {
|
||||
self.trackers.borrow().get(&uuid).map_or(false, |tracker| {
|
||||
self.tx_tracker_map
|
||||
.borrow()
|
||||
.get(&tracker.penalty_txid)
|
||||
|
|
@ -165,9 +165,9 @@ impl<'a> Responder<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn get_tracker(&self, uuid: &UUID) -> Option<TransactionTracker> {
|
||||
pub fn get_tracker(&self, uuid: UUID) -> Option<TransactionTracker> {
|
||||
if self.trackers.borrow().contains_key(&uuid) {
|
||||
self.dbm.lock().unwrap().load_tracker(&uuid).ok()
|
||||
self.dbm.lock().unwrap().load_tracker(uuid).ok()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
@ -188,7 +188,7 @@ impl<'a> Responder<'a> {
|
|||
match missed_confirmations.get_mut(txid) {
|
||||
Some(x) => *x += 1,
|
||||
None => {
|
||||
missed_confirmations.insert(txid.clone(), 1);
|
||||
missed_confirmations.insert(*txid, 1);
|
||||
}
|
||||
}
|
||||
log::info!(
|
||||
|
|
@ -206,7 +206,7 @@ impl<'a> Responder<'a> {
|
|||
for (txid, missed_conf) in self.missed_confirmations.borrow().iter() {
|
||||
if missed_conf >= &CONFIRMATIONS_BEFORE_RETRY {
|
||||
for uuid in self.tx_tracker_map.borrow().get(txid).unwrap() {
|
||||
tracker = self.dbm.lock().unwrap().load_tracker(uuid).unwrap();
|
||||
tracker = self.dbm.lock().unwrap().load_tracker(*uuid).unwrap();
|
||||
tx_to_rebroadcast.push(tracker.penalty_tx)
|
||||
}
|
||||
}
|
||||
|
|
@ -228,7 +228,7 @@ impl<'a> Responder<'a> {
|
|||
.await
|
||||
.map(|confirmations| {
|
||||
if confirmations > constants::IRREVOCABLY_RESOLVED {
|
||||
completed_trackers.insert(uuid.clone());
|
||||
completed_trackers.insert(*uuid);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -237,13 +237,13 @@ impl<'a> Responder<'a> {
|
|||
completed_trackers
|
||||
}
|
||||
|
||||
fn get_outdated_trackers(&self, block_height: &u32) -> HashSet<UUID> {
|
||||
fn get_outdated_trackers(&self, block_height: u32) -> HashSet<UUID> {
|
||||
let mut outdated_trackers = HashSet::new();
|
||||
let trackers: HashSet<UUID> = self.trackers.borrow().keys().cloned().collect();
|
||||
|
||||
for uuid in self
|
||||
.gatekeeper
|
||||
.get_outdated_appointments(&block_height)
|
||||
.get_outdated_appointments(block_height)
|
||||
.intersection(&trackers)
|
||||
{
|
||||
if self
|
||||
|
|
@ -251,7 +251,7 @@ impl<'a> Responder<'a> {
|
|||
.borrow()
|
||||
.contains(&self.trackers.borrow()[&uuid].penalty_txid)
|
||||
{
|
||||
outdated_trackers.insert(uuid.clone());
|
||||
outdated_trackers.insert(*uuid);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -349,11 +349,11 @@ impl<'a> Listen for Responder<'a> {
|
|||
|
||||
if self.trackers.borrow().len() > 0 {
|
||||
let completed_trackers = block_on(self.get_completed_trackers());
|
||||
let outdated_trackers = self.get_outdated_trackers(&height);
|
||||
let outdated_trackers = self.get_outdated_trackers(height);
|
||||
|
||||
let trackers_to_delete_gk = completed_trackers
|
||||
.iter()
|
||||
.map(|uuid| (uuid.clone(), self.trackers.borrow()[uuid].user_id))
|
||||
.map(|uuid| (*uuid, self.trackers.borrow()[uuid].user_id))
|
||||
.collect();
|
||||
|
||||
self.check_confirmations(&block.txdata);
|
||||
|
|
@ -421,7 +421,7 @@ mod tests {
|
|||
|
||||
let user_id = get_random_user_id();
|
||||
let (uuid, appointment) = generate_dummy_appointment_with_user(user_id, None);
|
||||
store_appointment_and_fks_to_db(&dbm.lock().unwrap(), &uuid, &appointment);
|
||||
store_appointment_and_fks_to_db(&dbm.lock().unwrap(), uuid, &appointment);
|
||||
|
||||
let breach = get_random_breach_from_locator(appointment.locator());
|
||||
let penalty_txid = breach.penalty_tx.txid();
|
||||
|
|
@ -475,7 +475,7 @@ mod tests {
|
|||
// Add the necessary FKs in the database
|
||||
let user_id = get_random_user_id();
|
||||
let (uuid, appointment) = generate_dummy_appointment_with_user(user_id, None);
|
||||
store_appointment_and_fks_to_db(&dbm.lock().unwrap(), &uuid, &appointment);
|
||||
store_appointment_and_fks_to_db(&dbm.lock().unwrap(), uuid, &appointment);
|
||||
|
||||
let mut breach = get_random_breach_from_locator(appointment.locator());
|
||||
responder.add_tracker(uuid, breach.clone(), user_id, 0);
|
||||
|
|
@ -493,7 +493,7 @@ mod tests {
|
|||
.contains(&breach.penalty_tx.txid()));
|
||||
// Check that the data is also in the database
|
||||
assert_eq!(
|
||||
dbm.lock().unwrap().load_tracker(&uuid).unwrap(),
|
||||
dbm.lock().unwrap().load_tracker(uuid).unwrap(),
|
||||
TransactionTracker::new(breach, user_id)
|
||||
);
|
||||
|
||||
|
|
@ -506,7 +506,7 @@ mod tests {
|
|||
.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.store_appointment(&uuid, &appointment)
|
||||
.store_appointment(uuid, &appointment)
|
||||
.unwrap();
|
||||
|
||||
responder.add_tracker(uuid, breach.clone(), user_id, 1);
|
||||
|
|
@ -525,7 +525,7 @@ mod tests {
|
|||
.borrow()
|
||||
.contains(&breach.penalty_tx.txid()));
|
||||
assert_eq!(
|
||||
dbm.lock().unwrap().load_tracker(&uuid).unwrap(),
|
||||
dbm.lock().unwrap().load_tracker(uuid).unwrap(),
|
||||
TransactionTracker::new(breach.clone(), user_id)
|
||||
);
|
||||
|
||||
|
|
@ -535,7 +535,7 @@ mod tests {
|
|||
.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.store_appointment(&uuid, &appointment)
|
||||
.store_appointment(uuid, &appointment)
|
||||
.unwrap();
|
||||
|
||||
responder.add_tracker(uuid, breach.clone(), user_id, 1);
|
||||
|
|
@ -550,7 +550,7 @@ mod tests {
|
|||
2
|
||||
);
|
||||
assert_eq!(
|
||||
dbm.lock().unwrap().load_tracker(&uuid).unwrap(),
|
||||
dbm.lock().unwrap().load_tracker(uuid).unwrap(),
|
||||
TransactionTracker::new(breach, user_id)
|
||||
);
|
||||
}
|
||||
|
|
@ -569,16 +569,16 @@ mod tests {
|
|||
// Add a new tracker
|
||||
let user_id = get_random_user_id();
|
||||
let (uuid, appointment) = generate_dummy_appointment_with_user(user_id, None);
|
||||
store_appointment_and_fks_to_db(&dbm.lock().unwrap(), &uuid, &appointment);
|
||||
store_appointment_and_fks_to_db(&dbm.lock().unwrap(), uuid, &appointment);
|
||||
|
||||
let breach = get_random_breach_from_locator(appointment.locator());
|
||||
responder.add_tracker(uuid, breach.clone(), user_id, 0);
|
||||
|
||||
assert!(responder.has_tracker(&uuid));
|
||||
assert!(responder.has_tracker(uuid));
|
||||
|
||||
// Delete the tracker and check again
|
||||
responder.delete_trackers(HashSet::from_iter([uuid]), false);
|
||||
assert!(!responder.has_tracker(&uuid));
|
||||
assert!(!responder.has_tracker(uuid));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -592,20 +592,20 @@ mod tests {
|
|||
// Store the user and the appointment in the database so we can add the tracker later on (due to FK restrictions)
|
||||
let user_id = get_random_user_id();
|
||||
let (uuid, appointment) = generate_dummy_appointment_with_user(user_id, None);
|
||||
store_appointment_and_fks_to_db(&dbm.lock().unwrap(), &uuid, &appointment);
|
||||
store_appointment_and_fks_to_db(&dbm.lock().unwrap(), uuid, &appointment);
|
||||
|
||||
// Data should not be there before adding it
|
||||
assert_eq!(responder.get_tracker(&uuid), None);
|
||||
assert_eq!(responder.get_tracker(uuid), None);
|
||||
|
||||
// Data should be there now
|
||||
let breach = get_random_breach_from_locator(appointment.locator());
|
||||
let tracker = TransactionTracker::new(breach.clone(), user_id);
|
||||
responder.add_tracker(uuid, breach, user_id, 0);
|
||||
assert_eq!(responder.get_tracker(&uuid).unwrap(), tracker);
|
||||
assert_eq!(responder.get_tracker(uuid).unwrap(), tracker);
|
||||
|
||||
// After deleting the data it should be gone
|
||||
responder.delete_trackers(HashSet::from_iter([uuid]), false);
|
||||
assert_eq!(responder.get_tracker(&uuid), None);
|
||||
assert_eq!(responder.get_tracker(uuid), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -669,7 +669,7 @@ mod tests {
|
|||
.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.store_user(&user_id, &UserInfo::new(21, 42))
|
||||
.store_user(user_id, &UserInfo::new(21, 42))
|
||||
.unwrap();
|
||||
|
||||
// Transactions are flagged to be rebroadcast when they've missed CONFIRMATIONS_BEFORE_RETRY confirmations
|
||||
|
|
@ -682,7 +682,7 @@ mod tests {
|
|||
.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.store_appointment(&uuid, &appointment)
|
||||
.store_appointment(uuid, &appointment)
|
||||
.unwrap();
|
||||
|
||||
// Create a breach and add it, manually setting the missed confirmation count
|
||||
|
|
@ -718,7 +718,7 @@ mod tests {
|
|||
|
||||
let user_id = get_random_user_id();
|
||||
let (uuid, appointment) = generate_dummy_appointment_with_user(user_id, None);
|
||||
store_appointment_and_fks_to_db(&dbm.lock().unwrap(), &uuid, &appointment);
|
||||
store_appointment_and_fks_to_db(&dbm.lock().unwrap(), uuid, &appointment);
|
||||
|
||||
// Let's add a tracker first
|
||||
let breach = get_random_breach_from_locator(appointment.locator());
|
||||
|
|
@ -766,7 +766,7 @@ mod tests {
|
|||
|
||||
// If data is not in the unconfirmed_transaction it won't be returned
|
||||
assert_eq!(
|
||||
responder.get_outdated_trackers(&target_block_height),
|
||||
responder.get_outdated_trackers(target_block_height),
|
||||
HashSet::new(),
|
||||
);
|
||||
|
||||
|
|
@ -792,7 +792,7 @@ mod tests {
|
|||
|
||||
// Check the expected data is there
|
||||
assert_eq!(
|
||||
responder.get_outdated_trackers(&target_block_height),
|
||||
responder.get_outdated_trackers(target_block_height),
|
||||
target_uuids
|
||||
);
|
||||
}
|
||||
|
|
@ -810,7 +810,7 @@ mod tests {
|
|||
.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.store_user(&user_id, &UserInfo::new(21, 42))
|
||||
.store_user(user_id, &UserInfo::new(21, 42))
|
||||
.unwrap();
|
||||
|
||||
// Transactions are rebroadcast once they hit CONFIRMATIONS_BEFORE_RETRY
|
||||
|
|
@ -825,7 +825,7 @@ mod tests {
|
|||
.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.store_appointment(&uuid, &appointment)
|
||||
.store_appointment(uuid, &appointment)
|
||||
.unwrap();
|
||||
|
||||
let breach = get_random_breach_from_locator(appointment.locator());
|
||||
|
|
@ -886,7 +886,7 @@ mod tests {
|
|||
.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.store_user(&user_id, &UserInfo::new(21, 42))
|
||||
.store_user(user_id, &UserInfo::new(21, 42))
|
||||
.unwrap();
|
||||
|
||||
// Delete trackers removes data from the trackers, tx_tracker_map maps, the database (and unconfirmed_txs if the data is outdated)
|
||||
|
|
@ -904,7 +904,7 @@ mod tests {
|
|||
.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.store_appointment(&uuid, &appointment)
|
||||
.store_appointment(uuid, &appointment)
|
||||
.unwrap();
|
||||
|
||||
let breach = get_random_breach_from_locator(appointment.locator());
|
||||
|
|
@ -922,8 +922,8 @@ mod tests {
|
|||
txs_with_multiple_uuids.insert(breach.penalty_tx.txid());
|
||||
}
|
||||
|
||||
all_trackers.insert(uuid.clone());
|
||||
uuid_txid_map.insert(uuid.clone(), breach.penalty_tx.txid());
|
||||
all_trackers.insert(uuid);
|
||||
uuid_txid_map.insert(uuid, breach.penalty_tx.txid());
|
||||
|
||||
// Add some trackers to be deleted
|
||||
if i % 2 == 0 {
|
||||
|
|
@ -939,7 +939,7 @@ mod tests {
|
|||
if target_trackers.contains(&uuid) {
|
||||
assert!(!responder.trackers.borrow().contains_key(&uuid));
|
||||
assert!(matches!(
|
||||
dbm.lock().unwrap().load_tracker(&uuid),
|
||||
dbm.lock().unwrap().load_tracker(uuid),
|
||||
Err(DBError::NotFound)
|
||||
));
|
||||
let penalty_txid = &uuid_txid_map[&uuid];
|
||||
|
|
@ -966,7 +966,7 @@ mod tests {
|
|||
.borrow()
|
||||
.contains_key(&uuid_txid_map[&uuid]));
|
||||
assert!(matches!(
|
||||
dbm.lock().unwrap().load_tracker(&uuid),
|
||||
dbm.lock().unwrap().load_tracker(uuid),
|
||||
Ok(TransactionTracker { .. })
|
||||
));
|
||||
}
|
||||
|
|
@ -1025,7 +1025,7 @@ mod tests {
|
|||
for _ in 2..23 {
|
||||
let user_id = get_random_user_id();
|
||||
|
||||
gk.add_update_user(&user_id).unwrap();
|
||||
gk.add_update_user(user_id).unwrap();
|
||||
users.push(user_id);
|
||||
}
|
||||
|
||||
|
|
@ -1041,7 +1041,7 @@ mod tests {
|
|||
.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.store_appointment(&uuid, &appointment)
|
||||
.store_appointment(uuid, &appointment)
|
||||
.unwrap();
|
||||
|
||||
let breach = get_random_breach_from_locator(appointment.locator());
|
||||
|
|
@ -1076,12 +1076,12 @@ mod tests {
|
|||
.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.store_appointment(&uuid, &appointment)
|
||||
.store_appointment(*uuid, &appointment)
|
||||
.unwrap();
|
||||
|
||||
let breach = get_random_breach_from_locator(appointment.locator());
|
||||
penalties.push(breach.penalty_tx.txid());
|
||||
responder.add_tracker(uuid.clone(), breach, user_id, 0);
|
||||
responder.add_tracker(*uuid, breach, user_id, 0);
|
||||
}
|
||||
|
||||
outdated_users.insert(user_id, pair.clone());
|
||||
|
|
@ -1094,7 +1094,7 @@ mod tests {
|
|||
|
||||
// CONFIRMATIONS SETUP
|
||||
let standalone_user_id = get_random_user_id();
|
||||
gk.add_update_user(&standalone_user_id).unwrap();
|
||||
gk.add_update_user(standalone_user_id).unwrap();
|
||||
|
||||
let mut transactions = Vec::new();
|
||||
let mut confirmed_txs = Vec::new();
|
||||
|
|
@ -1106,7 +1106,7 @@ mod tests {
|
|||
.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.store_appointment(&uuid, &appointment)
|
||||
.store_appointment(uuid, &appointment)
|
||||
.unwrap();
|
||||
|
||||
let breach = get_random_breach_from_locator(appointment.locator());
|
||||
|
|
@ -1129,7 +1129,7 @@ mod tests {
|
|||
.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.store_appointment(&uuid, &appointment)
|
||||
.store_appointment(uuid, &appointment)
|
||||
.unwrap();
|
||||
|
||||
let breach_rebroadcast = get_random_breach_from_locator(appointment.locator());
|
||||
|
|
|
|||
|
|
@ -104,12 +104,7 @@ impl Blockchain {
|
|||
};
|
||||
|
||||
for _ in 1..=height {
|
||||
let mut txs = Vec::new();
|
||||
for _ in 0..tx_count {
|
||||
txs.push(get_random_tx());
|
||||
}
|
||||
|
||||
self.generate_with_txs(txs);
|
||||
self.generate_with_txs((0..tx_count).map(|_| get_random_tx()).collect());
|
||||
}
|
||||
|
||||
self
|
||||
|
|
@ -334,7 +329,7 @@ pub(crate) fn get_random_tx() -> Transaction {
|
|||
|
||||
pub(crate) fn generate_dummy_appointment(dispute_txid: Option<&Txid>) -> ExtendedAppointment {
|
||||
let dispute_txid = match dispute_txid {
|
||||
Some(l) => l.clone(),
|
||||
Some(l) => *l,
|
||||
None => {
|
||||
let prev_txid_bytes = get_random_bytes(32);
|
||||
Txid::from_slice(&prev_txid_bytes).unwrap()
|
||||
|
|
@ -363,7 +358,7 @@ pub(crate) fn generate_dummy_appointment_with_user(
|
|||
let mut app = generate_dummy_appointment(dispute_txid);
|
||||
app.user_id = user_id;
|
||||
|
||||
(UUID::new(&app.locator(), &user_id), app)
|
||||
(UUID::new(app.locator(), user_id), app)
|
||||
}
|
||||
|
||||
pub fn get_random_breach() -> Breach {
|
||||
|
|
@ -385,10 +380,10 @@ pub fn get_random_tracker(user_id: UserId) -> TransactionTracker {
|
|||
TransactionTracker::new(breach, user_id)
|
||||
}
|
||||
|
||||
pub fn store_appointment_and_fks_to_db(dbm: &DBM, uuid: &UUID, appointment: &ExtendedAppointment) {
|
||||
dbm.store_user(&appointment.user_id, &UserInfo::new(21, 42))
|
||||
pub fn store_appointment_and_fks_to_db(dbm: &DBM, uuid: UUID, appointment: &ExtendedAppointment) {
|
||||
dbm.store_user(appointment.user_id, &UserInfo::new(21, 42))
|
||||
.unwrap();
|
||||
dbm.store_appointment(&uuid, &appointment).unwrap();
|
||||
dbm.store_appointment(uuid, &appointment).unwrap();
|
||||
}
|
||||
|
||||
pub enum MockedServerQuery {
|
||||
|
|
|
|||
|
|
@ -57,9 +57,9 @@ impl LocatorCache {
|
|||
});
|
||||
|
||||
let mut locators = Vec::new();
|
||||
for tx in block.txdata.clone() {
|
||||
for tx in &block.txdata {
|
||||
let locator = Locator::new(tx.txid());
|
||||
cache.insert(locator, tx);
|
||||
cache.insert(locator, tx.clone());
|
||||
locators.push(locator);
|
||||
}
|
||||
|
||||
|
|
@ -75,8 +75,8 @@ impl LocatorCache {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_tx(&self, locator: &Locator) -> Option<&Transaction> {
|
||||
self.cache.get(locator)
|
||||
pub fn get_tx(&self, locator: Locator) -> Option<&Transaction> {
|
||||
self.cache.get(&locator)
|
||||
}
|
||||
|
||||
pub fn is_full(&self) -> bool {
|
||||
|
|
@ -92,8 +92,8 @@ impl LocatorCache {
|
|||
|
||||
let mut locators = Vec::new();
|
||||
for (locator, tx) in locator_tx_map {
|
||||
self.cache.insert(locator.clone(), tx.clone());
|
||||
locators.push(locator.clone());
|
||||
self.cache.insert(*locator, tx.clone());
|
||||
locators.push(*locator);
|
||||
}
|
||||
|
||||
self.tx_in_block.insert(block_header.block_hash(), locators);
|
||||
|
|
@ -205,13 +205,13 @@ impl<'a> Watcher<'a> {
|
|||
locator_cache,
|
||||
responder,
|
||||
gatekeeper,
|
||||
last_known_block_header: RefCell::new(last_known_block_header.deref().clone()),
|
||||
last_known_block_header: RefCell::new(*last_known_block_header.deref()),
|
||||
signing_key,
|
||||
dbm,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn register(&mut self, user_id: &UserId) -> Result<RegistrationReceipt, MaxSlotsReached> {
|
||||
pub fn register(&mut self, user_id: UserId) -> Result<RegistrationReceipt, MaxSlotsReached> {
|
||||
let mut receipt = self.gatekeeper.add_update_user(user_id)?;
|
||||
receipt.sign(&self.signing_key);
|
||||
|
||||
|
|
@ -229,7 +229,7 @@ impl<'a> Watcher<'a> {
|
|||
.map_err(|_| AddAppointmentFailure::AuthenticationFailure)?;
|
||||
|
||||
let (has_subscription_expired, expiry) =
|
||||
self.gatekeeper.has_subscription_expired(&user_id).unwrap();
|
||||
self.gatekeeper.has_subscription_expired(user_id).unwrap();
|
||||
|
||||
if has_subscription_expired {
|
||||
return Err(AddAppointmentFailure::SubscriptionExpired(expiry));
|
||||
|
|
@ -242,20 +242,20 @@ impl<'a> Watcher<'a> {
|
|||
self.last_known_block_header.borrow().height,
|
||||
);
|
||||
|
||||
let uuid = UUID::new(&extended_appointment.locator(), &user_id);
|
||||
let uuid = UUID::new(extended_appointment.locator(), user_id);
|
||||
|
||||
if self.responder.has_tracker(&uuid) {
|
||||
if self.responder.has_tracker(uuid) {
|
||||
log::info!("Tracker for {} already found in Responder", uuid);
|
||||
return Err(AddAppointmentFailure::AlreadyTriggered);
|
||||
}
|
||||
|
||||
let available_slots = self
|
||||
.gatekeeper
|
||||
.add_update_appointment(&user_id, uuid, &extended_appointment)
|
||||
.add_update_appointment(user_id, uuid, &extended_appointment)
|
||||
.map_err(|_| AddAppointmentFailure::NotEnoughSlots)?;
|
||||
|
||||
let locator = extended_appointment.locator();
|
||||
match self.locator_cache.borrow().get_tx(&locator) {
|
||||
match self.locator_cache.borrow().get_tx(locator) {
|
||||
// Appointments that were triggered in blocks held in the cache
|
||||
Some(dispute_tx) => {
|
||||
log::info!("Trigger for locator {} found in cache", locator);
|
||||
|
|
@ -269,7 +269,7 @@ impl<'a> Watcher<'a> {
|
|||
self.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.store_appointment(&uuid, &extended_appointment)
|
||||
.store_appointment(uuid, &extended_appointment)
|
||||
.unwrap();
|
||||
|
||||
let breach = Breach::new(locator, dispute_tx.clone(), penalty_tx);
|
||||
|
|
@ -285,7 +285,7 @@ impl<'a> Watcher<'a> {
|
|||
receipt.reason()
|
||||
);
|
||||
|
||||
self.dbm.lock().unwrap().remove_appointment(&uuid);
|
||||
self.dbm.lock().unwrap().remove_appointment(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -318,14 +318,14 @@ impl<'a> Watcher<'a> {
|
|||
self.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.store_appointment(&uuid, &extended_appointment)
|
||||
.store_appointment(uuid, &extended_appointment)
|
||||
.unwrap();
|
||||
} else {
|
||||
log::debug!("Update received for {}, locator map not modified", uuid);
|
||||
self.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.update_appointment(&uuid, &extended_appointment);
|
||||
.update_appointment(uuid, &extended_appointment);
|
||||
}
|
||||
} else {
|
||||
// New appointment
|
||||
|
|
@ -336,7 +336,7 @@ impl<'a> Watcher<'a> {
|
|||
self.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.store_appointment(&uuid, &extended_appointment)
|
||||
.store_appointment(uuid, &extended_appointment)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
|
@ -353,8 +353,8 @@ impl<'a> Watcher<'a> {
|
|||
|
||||
pub fn get_appointment(
|
||||
&self,
|
||||
locator: &Locator,
|
||||
user_signature: &String,
|
||||
locator: Locator,
|
||||
user_signature: &str,
|
||||
) -> Result<AppointmentInfo, GetAppointmentFailure> {
|
||||
let message = format!("get appointment {}", locator);
|
||||
|
||||
|
|
@ -364,26 +364,26 @@ impl<'a> Watcher<'a> {
|
|||
.map_err(|_| GetAppointmentFailure::AuthenticationFailure)?;
|
||||
|
||||
let (has_subscription_expired, expiry) =
|
||||
self.gatekeeper.has_subscription_expired(&user_id).unwrap();
|
||||
self.gatekeeper.has_subscription_expired(user_id).unwrap();
|
||||
|
||||
if has_subscription_expired {
|
||||
return Err(GetAppointmentFailure::SubscriptionExpired(expiry));
|
||||
}
|
||||
|
||||
let uuid = UUID::new(locator, &user_id);
|
||||
let uuid = UUID::new(locator, user_id);
|
||||
|
||||
if self.appointments.borrow().contains_key(&uuid) {
|
||||
Ok(AppointmentInfo::Appointment(
|
||||
self.dbm
|
||||
.lock()
|
||||
.unwrap()
|
||||
.load_appointment(&uuid)
|
||||
.load_appointment(uuid)
|
||||
.unwrap()
|
||||
.inner,
|
||||
))
|
||||
} else {
|
||||
self.responder
|
||||
.get_tracker(&uuid)
|
||||
.get_tracker(uuid)
|
||||
.map(|tracker| AppointmentInfo::Tracker(tracker))
|
||||
.ok_or({
|
||||
log::info!("Cannot find {}", locator);
|
||||
|
|
@ -402,7 +402,7 @@ impl<'a> Watcher<'a> {
|
|||
|
||||
for locator in local_set.intersection(&new_set) {
|
||||
let (k, v) = locator_tx_map.get_key_value(locator).unwrap();
|
||||
breaches.insert(k.clone(), v.clone());
|
||||
breaches.insert(*k, v.clone());
|
||||
}
|
||||
|
||||
if breaches.is_empty() {
|
||||
|
|
@ -428,18 +428,12 @@ impl<'a> Watcher<'a> {
|
|||
let mut decrypted_blobs: HashMap<Vec<u8>, Transaction> = HashMap::new();
|
||||
|
||||
for (locator, dispute_tx) in breaches.into_iter() {
|
||||
for uuid in self
|
||||
.locator_uuid_map
|
||||
.borrow()
|
||||
.get(&locator)
|
||||
.unwrap()
|
||||
.clone()
|
||||
{
|
||||
let appointment = self.dbm.lock().unwrap().load_appointment(&uuid).unwrap();
|
||||
for uuid in self.locator_uuid_map.borrow().get(&locator).unwrap() {
|
||||
let appointment = self.dbm.lock().unwrap().load_appointment(*uuid).unwrap();
|
||||
match decrypted_blobs.get(appointment.encrypted_blob()) {
|
||||
Some(penalty_tx) => {
|
||||
valid_breaches.insert(
|
||||
uuid,
|
||||
*uuid,
|
||||
Breach::new(locator, dispute_tx.clone(), penalty_tx.clone()),
|
||||
);
|
||||
}
|
||||
|
|
@ -454,12 +448,12 @@ impl<'a> Watcher<'a> {
|
|||
penalty_tx.clone(),
|
||||
);
|
||||
valid_breaches.insert(
|
||||
uuid,
|
||||
*uuid,
|
||||
Breach::new(locator, dispute_tx.clone(), penalty_tx),
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
invalid_breaches.insert(uuid, e);
|
||||
invalid_breaches.insert(*uuid, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -535,7 +529,7 @@ impl<'a> chain::Listen for Watcher<'a> {
|
|||
if !self.appointments.borrow().is_empty() {
|
||||
// Get a list of outdated appointments from the Gatekeeper. This appointments may be either in the Watcher
|
||||
// or in the Responder.
|
||||
let outdated_appointments = self.gatekeeper.get_outdated_appointments(&height);
|
||||
let outdated_appointments = self.gatekeeper.get_outdated_appointments(height);
|
||||
self.delete_appointments(outdated_appointments, true);
|
||||
|
||||
// Filter out those breaches that do not yield a valid transaction
|
||||
|
|
@ -674,16 +668,16 @@ mod tests {
|
|||
expected_slots: u32,
|
||||
expiry: u32,
|
||||
receipt: AppointmentReceipt,
|
||||
expected_user_signature: &String,
|
||||
tower_id: &UserId,
|
||||
expected_user_signature: &str,
|
||||
tower_id: UserId,
|
||||
) {
|
||||
assert_eq!(slots, expected_slots);
|
||||
assert_eq!(expiry, START_HEIGHT as u32 + DURATION);
|
||||
assert_eq!(receipt.start_block(), START_HEIGHT as u32);
|
||||
assert_eq!(&receipt.user_signature(), expected_user_signature);
|
||||
assert_eq!(receipt.user_signature(), expected_user_signature);
|
||||
let recovered_pk =
|
||||
cryptography::recover_pk(&receipt.serialize(), &receipt.signature().unwrap()).unwrap();
|
||||
assert_eq!(&UserId(recovered_pk), tower_id);
|
||||
assert_eq!(UserId(recovered_pk), tower_id);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
|
@ -712,9 +706,9 @@ mod tests {
|
|||
|
||||
let (_, user_pk) = get_random_keypair();
|
||||
let user_id = UserId(user_pk);
|
||||
let receipt = watcher.register(&user_id).unwrap();
|
||||
let receipt = watcher.register(user_id).unwrap();
|
||||
|
||||
assert_eq!(receipt.user_id(), &user_id);
|
||||
assert_eq!(receipt.user_id(), user_id);
|
||||
assert_eq!(receipt.available_slots(), SLOTS);
|
||||
assert_eq!(
|
||||
receipt.subscription_expiry(),
|
||||
|
|
@ -756,7 +750,7 @@ mod tests {
|
|||
));
|
||||
let (user_sk, user_pk) = get_random_keypair();
|
||||
let user_id = UserId(user_pk);
|
||||
watcher.register(&user_id).unwrap();
|
||||
watcher.register(user_id).unwrap();
|
||||
let appointment = generate_dummy_appointment(None).inner;
|
||||
|
||||
// Add the appointment for a new user (twice so we can check that updates work)
|
||||
|
|
@ -767,13 +761,13 @@ mod tests {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_appointment_added(slots, SLOTS - 1, expiry, receipt, &user_sig, &tower_id);
|
||||
assert_appointment_added(slots, SLOTS - 1, expiry, receipt, &user_sig, tower_id);
|
||||
}
|
||||
|
||||
// Add the same appointment but for another user
|
||||
let (user2_sk, user2_pk) = get_random_keypair();
|
||||
let user2_id = UserId(user2_pk);
|
||||
watcher.register(&user2_id).unwrap();
|
||||
watcher.register(user2_id).unwrap();
|
||||
|
||||
let user2_sig = cryptography::sign(&appointment.serialize(), &user2_sk).unwrap();
|
||||
let (receipt, slots, expiry) = watcher
|
||||
|
|
@ -781,7 +775,7 @@ mod tests {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_appointment_added(slots, SLOTS - 1, expiry, receipt, &user2_sig, &tower_id);
|
||||
assert_appointment_added(slots, SLOTS - 1, expiry, receipt, &user2_sig, tower_id);
|
||||
|
||||
// There should be now two appointments in the Watcher and the same locator should have two different uuids
|
||||
assert_eq!(watcher.appointments.borrow().len(), 2);
|
||||
|
|
@ -793,7 +787,7 @@ mod tests {
|
|||
// Check data was added to the database
|
||||
for uuid in watcher.appointments.borrow().keys() {
|
||||
assert!(matches!(
|
||||
dbm.lock().unwrap().load_appointment(&uuid),
|
||||
dbm.lock().unwrap().load_appointment(*uuid),
|
||||
Ok(ExtendedAppointment { .. })
|
||||
));
|
||||
}
|
||||
|
|
@ -830,21 +824,21 @@ mod tests {
|
|||
|
||||
// The appointment should have been accepted, slots should have been decreased, and data should have been deleted from
|
||||
// the Watcher's memory. Moreover, a new tracker should be found in the Responder
|
||||
assert_appointment_added(slots, SLOTS - 3, expiry, receipt, &user_sig, &tower_id);
|
||||
assert_appointment_added(slots, SLOTS - 3, expiry, receipt, &user_sig, tower_id);
|
||||
assert_eq!(watcher.appointments.borrow().len(), 3);
|
||||
assert!(!watcher
|
||||
.locator_uuid_map
|
||||
.borrow()
|
||||
.contains_key(&appointment_in_cache.locator()));
|
||||
assert!(watcher.responder.has_tracker(&uuid));
|
||||
assert!(watcher.responder.has_tracker(uuid));
|
||||
|
||||
// Check data was added to the database
|
||||
assert!(matches!(
|
||||
dbm.lock().unwrap().load_appointment(&uuid),
|
||||
dbm.lock().unwrap().load_appointment(uuid),
|
||||
Ok(ExtendedAppointment { .. })
|
||||
));
|
||||
assert!(matches!(
|
||||
dbm.lock().unwrap().load_tracker(&uuid),
|
||||
dbm.lock().unwrap().load_tracker(uuid),
|
||||
Ok(TransactionTracker { .. })
|
||||
));
|
||||
|
||||
|
|
@ -861,16 +855,16 @@ mod tests {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_appointment_added(slots, SLOTS - 4, expiry, receipt, &user_sig, &tower_id);
|
||||
assert_appointment_added(slots, SLOTS - 4, expiry, receipt, &user_sig, tower_id);
|
||||
assert_eq!(watcher.appointments.borrow().len(), 3);
|
||||
|
||||
// Data should not be in the database
|
||||
assert!(matches!(
|
||||
dbm.lock().unwrap().load_appointment(&uuid),
|
||||
dbm.lock().unwrap().load_appointment(uuid),
|
||||
Err(DBError::NotFound)
|
||||
));
|
||||
assert!(matches!(
|
||||
dbm.lock().unwrap().load_tracker(&uuid),
|
||||
dbm.lock().unwrap().load_tracker(uuid),
|
||||
Err(DBError::NotFound)
|
||||
));
|
||||
|
||||
|
|
@ -888,12 +882,12 @@ mod tests {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_appointment_added(slots, SLOTS - 4, expiry, receipt, &user_sig, &tower_id);
|
||||
assert_appointment_added(slots, SLOTS - 4, expiry, receipt, &user_sig, tower_id);
|
||||
assert_eq!(watcher.appointments.borrow().len(), 3);
|
||||
|
||||
// Data should not be in the database
|
||||
assert!(matches!(
|
||||
dbm.lock().unwrap().load_appointment(&uuid),
|
||||
dbm.lock().unwrap().load_appointment(uuid),
|
||||
Err(DBError::NotFound)
|
||||
));
|
||||
|
||||
|
|
@ -911,7 +905,7 @@ mod tests {
|
|||
));
|
||||
// Data should not be in the database
|
||||
assert!(matches!(
|
||||
dbm.lock().unwrap().load_appointment(&uuid),
|
||||
dbm.lock().unwrap().load_appointment(uuid),
|
||||
Err(DBError::NotFound)
|
||||
));
|
||||
|
||||
|
|
@ -935,7 +929,7 @@ mod tests {
|
|||
));
|
||||
// Data should not be in the database
|
||||
assert!(matches!(
|
||||
dbm.lock().unwrap().load_appointment(&uuid),
|
||||
dbm.lock().unwrap().load_appointment(uuid),
|
||||
Err(DBError::NotFound)
|
||||
));
|
||||
|
||||
|
|
@ -956,7 +950,7 @@ mod tests {
|
|||
));
|
||||
// Data should not be in the database
|
||||
assert!(matches!(
|
||||
dbm.lock().unwrap().load_appointment(&uuid),
|
||||
dbm.lock().unwrap().load_appointment(uuid),
|
||||
Err(DBError::NotFound)
|
||||
));
|
||||
}
|
||||
|
|
@ -977,14 +971,14 @@ mod tests {
|
|||
// If the user cannot be properly identified, the request will fail. This can be simulated by providing a wrong signature
|
||||
let wrong_sig = String::from_utf8((0..65).collect()).unwrap();
|
||||
assert!(matches!(
|
||||
watcher.get_appointment(&appointment.locator, &wrong_sig),
|
||||
watcher.get_appointment(appointment.locator, &wrong_sig),
|
||||
Err(GetAppointmentFailure::AuthenticationFailure)
|
||||
));
|
||||
|
||||
// If the user does exist and there's an appointment with the given locator belonging to him, it will be returned
|
||||
let (user_sk, user_pk) = get_random_keypair();
|
||||
let user_id = UserId(user_pk);
|
||||
watcher.register(&user_id).unwrap();
|
||||
watcher.register(user_id).unwrap();
|
||||
watcher
|
||||
.add_appointment(
|
||||
appointment.clone(),
|
||||
|
|
@ -996,7 +990,7 @@ mod tests {
|
|||
let message = format!("get appointment {}", appointment.locator);
|
||||
let signature = cryptography::sign(message.as_bytes(), &user_sk).unwrap();
|
||||
let info = watcher
|
||||
.get_appointment(&appointment.locator, &signature)
|
||||
.get_appointment(appointment.locator, &signature)
|
||||
.unwrap();
|
||||
|
||||
match info {
|
||||
|
|
@ -1007,7 +1001,7 @@ mod tests {
|
|||
// If the appointment is in the Responder (in the form of a Tracker), data should be also returned
|
||||
|
||||
// Remove the data from the Watcher memory first (data is kept in the db tho)
|
||||
let uuid = UUID::new(&appointment.locator, &user_id);
|
||||
let uuid = UUID::new(appointment.locator, user_id);
|
||||
watcher.appointments.borrow_mut().remove(&uuid);
|
||||
watcher
|
||||
.locator_uuid_map
|
||||
|
|
@ -1023,7 +1017,7 @@ mod tests {
|
|||
let tracker_message = format!("get appointment {}", tracker.locator);
|
||||
let tracker_signature = cryptography::sign(tracker_message.as_bytes(), &user_sk).unwrap();
|
||||
let info = watcher
|
||||
.get_appointment(&tracker.locator, &tracker_signature)
|
||||
.get_appointment(tracker.locator, &tracker_signature)
|
||||
.unwrap();
|
||||
|
||||
match info {
|
||||
|
|
@ -1035,11 +1029,11 @@ mod tests {
|
|||
// should be returned.
|
||||
let (user2_sk, user2_pk) = get_random_keypair();
|
||||
let user2_id = UserId(user2_pk);
|
||||
watcher.register(&user2_id).unwrap();
|
||||
watcher.register(user2_id).unwrap();
|
||||
|
||||
let signature2 = cryptography::sign(message.as_bytes(), &user2_sk).unwrap();
|
||||
assert!(matches!(
|
||||
watcher.get_appointment(&appointment.locator, &signature2),
|
||||
watcher.get_appointment(appointment.locator, &signature2),
|
||||
Err(GetAppointmentFailure::NotFound { .. })
|
||||
));
|
||||
|
||||
|
|
@ -1053,7 +1047,7 @@ mod tests {
|
|||
.subscription_expiry = START_HEIGHT as u32;
|
||||
|
||||
assert!(matches!(
|
||||
watcher.get_appointment(&appointment.locator, &signature),
|
||||
watcher.get_appointment(appointment.locator, &signature),
|
||||
Err(GetAppointmentFailure::SubscriptionExpired { .. })
|
||||
));
|
||||
}
|
||||
|
|
@ -1081,7 +1075,7 @@ mod tests {
|
|||
watcher
|
||||
.locator_uuid_map
|
||||
.borrow_mut()
|
||||
.insert(locator.clone(), HashSet::from_iter(vec![generate_uuid()]));
|
||||
.insert(*locator, HashSet::from_iter(vec![generate_uuid()]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1140,10 +1134,10 @@ mod tests {
|
|||
watcher
|
||||
.locator_uuid_map
|
||||
.borrow_mut()
|
||||
.insert(locator.clone(), HashSet::from_iter(vec![uuid]));
|
||||
.insert(*locator, HashSet::from_iter(vec![uuid]));
|
||||
|
||||
// Store data in the database (the user needs to be there as well since it is a FK for appointments)
|
||||
store_appointment_and_fks_to_db(&dbm.lock().unwrap(), &uuid, &appointment);
|
||||
store_appointment_and_fks_to_db(&dbm.lock().unwrap(), uuid, &appointment);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1200,7 +1194,7 @@ mod tests {
|
|||
.insert(appointment.locator(), HashSet::from_iter([uuid]));
|
||||
|
||||
// Add data to the database to check data deletion
|
||||
store_appointment_and_fks_to_db(&dbm.lock().unwrap(), &uuid, &appointment);
|
||||
store_appointment_and_fks_to_db(&dbm.lock().unwrap(), uuid, &appointment);
|
||||
|
||||
// Make it so some of the locators have multiple associated uuids
|
||||
if i % 3 == 0 {
|
||||
|
|
@ -1232,7 +1226,7 @@ mod tests {
|
|||
if target_appointments.contains(&uuid) {
|
||||
assert!(!watcher.appointments.borrow().contains_key(&uuid));
|
||||
assert!(matches!(
|
||||
dbm.lock().unwrap().load_appointment(&uuid),
|
||||
dbm.lock().unwrap().load_appointment(uuid),
|
||||
Err(DBError::NotFound)
|
||||
));
|
||||
|
||||
|
|
@ -1260,7 +1254,7 @@ mod tests {
|
|||
.borrow()
|
||||
.contains_key(&uuid_locator_map[&uuid]));
|
||||
assert!(matches!(
|
||||
dbm.lock().unwrap().load_appointment(&uuid),
|
||||
dbm.lock().unwrap().load_appointment(uuid),
|
||||
Ok(ExtendedAppointment { .. })
|
||||
));
|
||||
}
|
||||
|
|
@ -1315,12 +1309,12 @@ mod tests {
|
|||
let user_id = UserId(user_pk);
|
||||
let (user2_sk, user2_pk) = get_random_keypair();
|
||||
let user2_id = UserId(user2_pk);
|
||||
watcher.register(&user_id).unwrap();
|
||||
watcher.register(&user2_id).unwrap();
|
||||
watcher.register(user_id).unwrap();
|
||||
watcher.register(user2_id).unwrap();
|
||||
|
||||
let appointment = generate_dummy_appointment(None);
|
||||
let uuid1 = UUID::new(&appointment.locator(), &user_id);
|
||||
let uuid2 = UUID::new(&appointment.locator(), &user2_id);
|
||||
let uuid1 = UUID::new(appointment.locator(), user_id);
|
||||
let uuid2 = UUID::new(appointment.locator(), user2_id);
|
||||
|
||||
let user_sig = cryptography::sign(&appointment.inner.serialize(), &user_sk).unwrap();
|
||||
watcher
|
||||
|
|
@ -1361,7 +1355,7 @@ mod tests {
|
|||
.appointments
|
||||
.contains_key(&uuid1));
|
||||
assert!(matches!(
|
||||
dbm.lock().unwrap().load_appointment(&uuid1),
|
||||
dbm.lock().unwrap().load_appointment(uuid1),
|
||||
Err(DBError::NotFound)
|
||||
));
|
||||
|
||||
|
|
@ -1371,7 +1365,7 @@ mod tests {
|
|||
.appointments
|
||||
.contains_key(&uuid2));
|
||||
assert!(matches!(
|
||||
dbm.lock().unwrap().load_appointment(&uuid2),
|
||||
dbm.lock().unwrap().load_appointment(uuid2),
|
||||
Ok(ExtendedAppointment { .. })
|
||||
));
|
||||
|
||||
|
|
@ -1379,7 +1373,7 @@ mod tests {
|
|||
let dispute_tx = get_random_tx();
|
||||
let appointment = generate_dummy_appointment(Some(&dispute_tx.txid()));
|
||||
let sig = cryptography::sign(&appointment.inner.serialize(), &user2_sk).unwrap();
|
||||
let uuid = UUID::new(&appointment.locator(), &user2_id);
|
||||
let uuid = UUID::new(appointment.locator(), user2_id);
|
||||
watcher
|
||||
.add_appointment(appointment.inner.clone(), sig)
|
||||
.await
|
||||
|
|
@ -1406,7 +1400,7 @@ mod tests {
|
|||
//Both non-decryptable blobs and blobs with invalid transactions will yield an invalid trigger
|
||||
appointment.inner.encrypted_blob.reverse();
|
||||
let sig = cryptography::sign(&appointment.inner.serialize(), &user2_sk).unwrap();
|
||||
let uuid = UUID::new(&appointment.locator(), &user2_id);
|
||||
let uuid = UUID::new(appointment.locator(), user2_id);
|
||||
watcher
|
||||
.add_appointment(appointment.inner.clone(), sig)
|
||||
.await
|
||||
|
|
@ -1424,7 +1418,7 @@ mod tests {
|
|||
.appointments
|
||||
.contains_key(&uuid));
|
||||
assert!(matches!(
|
||||
dbm.lock().unwrap().load_appointment(&uuid),
|
||||
dbm.lock().unwrap().load_appointment(uuid),
|
||||
Err(DBError::NotFound)
|
||||
));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue