Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optional boundaries to getregistrationreceipt #2

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions watchtower-plugin/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ pub const TOWERS_DATA_DIR: &str = "TOWERS_DATA_DIR";
pub const DEFAULT_TOWERS_DATA_DIR: &str = ".watchtower";

/// Collections of plugin option names, default values and descriptions
pub const DEFAULT_SUBSCRIPTION_START: Option<i64> = None;
pub const SUBSCRIPTION_START: &str = "subscription-start";
pub const SUBSCRIPTION_START_DESC: &str = "subscription-start";
pub const DEFAULT_SUBSCRIPTION_EXPIRY: Option<i64> = None;
pub const SUBSCRIPTION_EXPIRY: &str = "subscription-expiry";
pub const SUBSCRIPTION_EXPIRY_DESC: &str = "subscription-expiry";

pub const WT_PORT: &str = "watchtower-port";
pub const DEFAULT_WT_PORT: i64 = 9814;
Expand Down
91 changes: 53 additions & 38 deletions watchtower-plugin/src/dbm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,18 +216,26 @@ impl DBM {
&self,
tower_id: TowerId,
user_id: UserId,
subscription_start: Option<u32>,
subscription_expiry: Option<u32>,
) -> Result<RegistrationReceipt, Error> {
let mut stmt = self
.connection
.prepare(
"SELECT available_slots, subscription_start, subscription_expiry, signature
FROM registration_receipts
WHERE tower_id = ?1 AND subscription_expiry = (SELECT MAX(subscription_expiry)
FROM registration_receipts
WHERE tower_id = ?1)",
)
.unwrap();
let mut query = "SELECT available_slots, subscription_start, subscription_expiry, signature FROM registration_receipts WHERE tower_id = ?1".to_string();

let mut params = vec![tower_id.to_vec()];

if let Some(start) = subscription_start {
query.push_str(" AND subscription_start >= ?2");
params.push(start.to_be_bytes().into());
}

if let Some(expiry) = subscription_expiry {
query.push_str(" AND subscription_expiry <= ?3");
params.push(expiry.to_be_bytes().into());
}

query.push_str(" ORDER BY subscription_expiry DESC LIMIT 1");

let mut stmt = self.connection.prepare(&query).unwrap();
let receipt = stmt
.query_row([tower_id.to_vec()], |row| {
let slots: u32 = row.get(0).unwrap();
Expand Down Expand Up @@ -259,13 +267,13 @@ impl DBM {
let mut stmt = self
.connection
.prepare("SELECT tw.tower_id, tw.net_addr, tw.available_slots, rr.subscription_start, rr.subscription_expiry
FROM towers AS tw
JOIN registration_receipts AS rr
JOIN (SELECT tower_id, MAX(subscription_expiry) AS max_se
FROM registration_receipts
GROUP BY tower_id) AS max_rrs ON (tw.tower_id = rr.tower_id)
AND (rr.tower_id = max_rrs.tower_id)
AND (rr.subscription_expiry = max_rrs.max_se)")
FROM towers AS tw
JOIN registration_receipts AS rr
JOIN (SELECT tower_id, MAX(subscription_expiry) AS max_se
FROM registration_receipts
GROUP BY tower_id) AS max_rrs ON (tw.tower_id = rr.tower_id)
AND (rr.tower_id = max_rrs.tower_id)
AND (rr.subscription_expiry = max_rrs.max_se)")
.unwrap();
let mut rows = stmt.query([]).unwrap();

Expand Down Expand Up @@ -312,15 +320,15 @@ impl DBM {
let tx = self.get_mut_connection().transaction().unwrap();
tx.execute(
"INSERT INTO appointment_receipts (locator, tower_id, start_block, user_signature, tower_signature)
VALUES (?1, ?2, ?3, ?4, ?5)",
VALUES (?1, ?2, ?3, ?4, ?5)",
params![
locator.to_vec(),
tower_id.to_vec(),
receipt.start_block(),
receipt.user_signature(),
receipt.signature()
locator.to_vec(),
tower_id.to_vec(),
receipt.start_block(),
receipt.user_signature(),
receipt.signature()
],
)?;
)?;
tx.execute(
"UPDATE towers SET available_slots=?1 WHERE tower_id=?2",
params![available_slots, tower_id.to_vec()],
Expand Down Expand Up @@ -579,15 +587,15 @@ impl DBM {
let tx = self.get_mut_connection().transaction().unwrap();
tx.execute(
"INSERT INTO appointment_receipts (tower_id, locator, start_block, user_signature, tower_signature)
VALUES (?1, ?2, ?3, ?4, ?5)",
VALUES (?1, ?2, ?3, ?4, ?5)",
params![
tower_id.to_vec(),
proof.locator.to_vec(),
proof.appointment_receipt.start_block(),
proof.appointment_receipt.user_signature(),
proof.appointment_receipt.signature()
tower_id.to_vec(),
proof.locator.to_vec(),
proof.appointment_receipt.start_block(),
proof.appointment_receipt.user_signature(),
proof.appointment_receipt.signature()
],
)?;
)?;
tx.execute(
"INSERT INTO misbehaving_proofs (tower_id, locator, recovered_id) VALUES (?1, ?2, ?3)",
params![
Expand Down Expand Up @@ -618,8 +626,8 @@ impl DBM {
.connection
.prepare(
"SELECT start_block, user_signature, tower_signature
FROM appointment_receipts
WHERE locator = ?1 AND tower_id = ?2",
FROM appointment_receipts
WHERE locator = ?1 AND tower_id = ?2",
)
.unwrap();
let receipt = receipt_stmt
Expand Down Expand Up @@ -736,7 +744,7 @@ mod tests {
dbm.store_tower_record(tower_id, net_addr, &receipt)
.unwrap();
assert_eq!(
dbm.load_registration_receipt(tower_id, receipt.user_id())
dbm.load_registration_receipt(tower_id, receipt.user_id(), None, None)
.unwrap(),
receipt
);
Expand All @@ -748,7 +756,7 @@ mod tests {
dbm.store_tower_record(tower_id, net_addr, &latest_receipt)
.unwrap();
assert_eq!(
dbm.load_registration_receipt(tower_id, latest_receipt.user_id())
dbm.load_registration_receipt(tower_id, latest_receipt.user_id(), None, None)
.unwrap(),
latest_receipt
);
Expand All @@ -757,7 +765,7 @@ mod tests {
dbm.store_tower_record(tower_id, net_addr, &middle_receipt)
.unwrap();
assert_eq!(
dbm.load_registration_receipt(tower_id, latest_receipt.user_id())
dbm.load_registration_receipt(tower_id, latest_receipt.user_id(), None, None)
.unwrap(),
latest_receipt
);
Expand All @@ -771,13 +779,20 @@ mod tests {
let tower_id = get_random_user_id();
let net_addr = "talaia.watch";
let receipt = get_random_registration_receipt();
let subscription_start = None;
let subscription_expiry = None;

// Store it once
dbm.store_tower_record(tower_id, net_addr, &receipt)
.unwrap();
assert_eq!(
dbm.load_registration_receipt(tower_id, receipt.user_id())
.unwrap(),
dbm.load_registration_receipt(
tower_id,
receipt.user_id(),
subscription_start,
subscription_expiry
)
.unwrap(),
receipt
);

Expand Down
31 changes: 23 additions & 8 deletions watchtower-plugin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,20 @@ async fn get_registration_receipt(
plugin: Plugin<Arc<Mutex<WTClient>>>,
v: serde_json::Value,
) -> Result<serde_json::Value, Error> {
let tower_id = TowerId::try_from(v).map_err(|x| anyhow!(x))?;
let subscription_start = v["subscription_start"].as_u64().map(|v| v as u32);
let tower_id = TowerId::try_from(v.clone()).map_err(|x| anyhow!(x))?;
let subscription_expiry = v["subscription_expiry"].as_u64().map(|v| v as u32);

let state = plugin.state().lock().unwrap();

let response = state.get_registration_receipt(tower_id).map_err(|_| {
anyhow!(
"Cannot find {} within the known towers. Have you registered?",
tower_id
)
})?;
let response = state
.get_registration_receipt(tower_id, subscription_start, subscription_expiry)
.map_err(|_| {
anyhow!(
"Cannot find {} within the known towers. Have you registered?",
tower_id
)
})?;

Ok(json!(response))
}
Expand Down Expand Up @@ -288,8 +293,8 @@ async fn get_tower_info(
plugin: Plugin<Arc<Mutex<WTClient>>>,
v: serde_json::Value,
) -> Result<serde_json::Value, Error> {
let state = plugin.state().lock().unwrap();
let tower_id = TowerId::try_from(v).map_err(|e| anyhow!(e))?;
let state = plugin.state().lock().unwrap();
let tower_info = state.load_tower_info(tower_id).map_err(|_| {
anyhow!(
"Cannot find {} within the known towers. Have you registered?",
Expand Down Expand Up @@ -519,6 +524,16 @@ async fn main() -> Result<(), Error> {
};

let builder = Builder::new(stdin(), stdout())
.option(ConfigOption::new(
constants::SUBSCRIPTION_START,
Value::OptInteger,
constants::SUBSCRIPTION_START_DESC,
))
.option(ConfigOption::new(
constants::SUBSCRIPTION_EXPIRY,
Value::OptInteger,
constants::SUBSCRIPTION_EXPIRY_DESC,
))
.option(ConfigOption::new(
constants::WT_PORT,
Value::Integer(constants::DEFAULT_WT_PORT),
Expand Down
9 changes: 8 additions & 1 deletion watchtower-plugin/src/wt_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,15 @@ impl WTClient {
pub fn get_registration_receipt(
&self,
tower_id: TowerId,
subscription_start: Option<u32>,
subscription_expiry: Option<u32>,
) -> Result<RegistrationReceipt, DBError> {
self.dbm.load_registration_receipt(tower_id, self.user_id)
self.dbm.load_registration_receipt(
tower_id,
self.user_id,
subscription_start,
subscription_expiry,
)
}

/// Loads a tower record from the database.
Expand Down