Skip to content

Commit

Permalink
Add start_time to registration receipt
Browse files Browse the repository at this point in the history
  • Loading branch information
sr-gi committed Jul 19, 2022
1 parent 3175aca commit c14543d
Show file tree
Hide file tree
Showing 14 changed files with 597 additions and 148 deletions.
5 changes: 3 additions & 2 deletions teos-common/proto/common/teos/v2/user.proto
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ message RegisterRequest {

bytes user_id = 1;
uint32 available_slots = 2;
uint32 subscription_expiry = 3;
string subscription_signature = 4;
uint32 subscription_start = 3;
uint32 subscription_expiry = 4;
string subscription_signature = 5;
}

message GetSubscriptionInfoRequest {
Expand Down
34 changes: 32 additions & 2 deletions teos-common/src/receipts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,40 @@ use bitcoin::secp256k1::SecretKey;

use crate::{cryptography, UserId};

#[derive(Serialize, Debug)]
/// Proof that a user has registered with a tower. This serves two purposes:
///
/// - First, the user is able to prove that the tower agreed on providing a service. If a tower refuses to accept appointments
/// from a user (claiming the subscription has expired) but the expiry time has still not passed and the tower cannot
/// provide the relevant appointments signed by the user, it means it is cheating.
/// - Second, it serves as proof, alongside an appointment receipt, that an appointment was not fulfilled. A registration receipt
/// specifies a subscription period (`subscription_start` - `subscription_expiry`) and the appointment a `start_block` so inclusion
/// can be proved.
///
/// TODO: / DISCUSS: In order to minimize the amount of receipts the user has to store, the tower could batch subscription receipts
/// as long as the user info is still known. That is, if a user has a subscription with range (S, E) and the user renews the subscription
/// before the tower wipes their data, then the tower can create a new receipt with (S, E') for E' > E instead of a second receipt (E, E').
// Notice this only applies as long as there is no gap between the two subscriptions.
#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
pub struct RegistrationReceipt {
user_id: UserId,
available_slots: u32,
subscription_start: u32,
subscription_expiry: u32,
#[serde(skip)]
signature: Option<String>,
}

impl RegistrationReceipt {
pub fn new(user_id: UserId, available_slots: u32, subscription_expiry: u32) -> Self {
pub fn new(
user_id: UserId,
available_slots: u32,
subscription_start: u32,
subscription_expiry: u32,
) -> Self {
RegistrationReceipt {
user_id,
available_slots,
subscription_start,
subscription_expiry,
signature: None,
}
Expand All @@ -28,12 +48,14 @@ impl RegistrationReceipt {
pub fn with_signature(
user_id: UserId,
available_slots: u32,
subscription_start: u32,
subscription_expiry: u32,
signature: String,
) -> Self {
RegistrationReceipt {
user_id,
available_slots,
subscription_start,
subscription_expiry,
signature: Some(signature),
}
Expand All @@ -47,6 +69,10 @@ impl RegistrationReceipt {
self.available_slots
}

pub fn subscription_start(&self) -> u32 {
self.subscription_start
}

pub fn subscription_expiry(&self) -> u32 {
self.subscription_expiry
}
Expand All @@ -59,6 +85,7 @@ impl RegistrationReceipt {
let mut ser = Vec::new();
ser.extend_from_slice(&self.user_id.to_vec());
ser.extend_from_slice(&self.available_slots.to_be_bytes());
ser.extend_from_slice(&self.subscription_start.to_be_bytes());
ser.extend_from_slice(&self.subscription_expiry.to_be_bytes());

ser
Expand All @@ -78,6 +105,9 @@ impl RegistrationReceipt {
}
}

/// Proof that a certain state was backed up with the tower.
///
/// Appointment receipts can be used alongside a registration receipt that covers it, and on chain data (a breach not being reacted with a penalty), to prove a tower has not reacted to a channel breach.
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct AppointmentReceipt {
user_signature: String,
Expand Down
21 changes: 20 additions & 1 deletion teos-common/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,26 @@ pub fn generate_random_appointment(dispute_txid: Option<&Txid>) -> Appointment {
}

pub fn get_random_registration_receipt() -> RegistrationReceipt {
RegistrationReceipt::new(get_random_user_id(), get_random_int(), get_random_int())
let (sk, _) = cryptography::get_random_keypair();
let start = get_random_int();
let mut receipt =
RegistrationReceipt::new(get_random_user_id(), get_random_int(), start, start + 420);
receipt.sign(&sk);

receipt
}

pub fn get_registration_receipt_from_previous(r: &RegistrationReceipt) -> RegistrationReceipt {
let (sk, _) = cryptography::get_random_keypair();
let mut receipt = RegistrationReceipt::new(
r.user_id(),
r.available_slots() + 1 + get_random_int::<u8>() as u32,
r.subscription_start(),
r.subscription_expiry() + 1 + get_random_int::<u8>() as u32,
);
receipt.sign(&sk);

receipt
}

pub fn get_random_appointment_receipt(tower_sk: SecretKey) -> AppointmentReceipt {
Expand Down
1 change: 1 addition & 0 deletions teos/src/api/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ impl PublicTowerServices for Arc<InternalAPI> {
Ok(receipt) => Ok(Response::new(common_msgs::RegisterResponse {
user_id: req_data.user_id,
available_slots: receipt.available_slots(),
subscription_start: receipt.subscription_start(),
subscription_expiry: receipt.subscription_expiry(),
subscription_signature: receipt.signature().unwrap(),
})),
Expand Down
Loading

0 comments on commit c14543d

Please sign in to comment.