Skip to content
Open
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
59 changes: 58 additions & 1 deletion bank/src/bank_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ pub struct BankEngine {
pub withdrawal_request_rate_limiter_settings: RateLimiterSettings,
pub deposit_request_rate_limiter_settings: RateLimiterSettings,
pub withdrawal_request_rate_limiter: HashMap<UserId, (u64, Instant)>,
pub deposit_request_rate_limiter: HashMap<UserId, (u64, Instant)>
pub deposit_request_rate_limiter: HashMap<UserId, (u64, Instant)>,
pub suspended_users: HashMap<u64, bool>
}

impl BankEngine {
Expand Down Expand Up @@ -156,6 +157,7 @@ impl BankEngine {
)
})
.collect::<HashMap<Currency, Decimal>>(),
suspended_users: HashMap::new(),
logger,
tx_seq: 0,
lnurl_withdrawal_requests: HashMap::new(),
Expand Down Expand Up @@ -281,6 +283,32 @@ impl BankEngine {
self.ledger.insurance_fund_account.balance < Decimal::new(10, SATS_DECIMALS)
}

pub fn init_suspensions(&mut self) {
let conn = match &self.conn_pool {
Some(conn) => conn,
None => {
slog::error!(self.logger, "No database provided.");
return;
}
};

let c = match conn.get() {
Ok(psql_connection) => psql_connection,
Err(_) => {
slog::error!(self.logger, "Couldn't get psql connection.");
return;
}
};

let suspended_accounts = match User::get_all_suspended(&c) {
Ok(suspended_accs) => suspended_accs,
Err(_) => return,
};
for account in suspended_accounts {
self.suspended_users.insert(account.uid as u64, true);
}
}

pub fn init_accounts(&mut self) {
let conn = match &self.conn_pool {
Some(conn) => conn,
Expand Down Expand Up @@ -383,6 +411,11 @@ impl BankEngine {
}

pub fn update_account(&mut self, account: &Account, uid: UserId) {
if self.suspended_users.contains_key(uid) {
slog::error!(self.logger, "Attempted to update_account for suspended user");
return;
}

let conn = match &self.conn_pool {
Some(conn) => conn,
None => {
Expand Down Expand Up @@ -441,6 +474,10 @@ impl BankEngine {
amount: Decimal,
rate: Decimal,
) -> Result<(), BankError> {
if self.suspended_users.contains_key(&outbound_uid) {
slog::error!(self.logger, "Attempted to make_tx for suspended outbound user");
return Err(BankError::UserSuspended);
}

if amount <= dec!(0) {
return Err(BankError::FailedTransaction)
Expand Down Expand Up @@ -555,6 +592,10 @@ impl BankEngine {
.unwrap_or_else(|| panic!("Recipient's username not specified: {:?}", payment_request))
.clone();
let outbound_uid = payment_request.uid;
if self.suspended_users.contains_key(&outbound_uid) {
slog::error!(self.logger, "Attempted to make_internal_tx for suspended outbound user");
return;
}
let amount = *payment_request
.amount
.as_ref()
Expand Down Expand Up @@ -843,6 +884,10 @@ impl BankEngine {
}
Message::Api(msg) => match msg {
Api::InvoiceRequest(msg) => {
if self.suspended_users.contains_key(&msg.uid) {
slog::error!(self.logger, "Suspended user attempted an InvoiceRequest: {:?}", msg);
return;
}
slog::warn!(self.logger, "Received invoice request: {:?}", msg);

if !self.check_deposit_request_rate_limit(msg.uid) {
Expand Down Expand Up @@ -1142,6 +1187,10 @@ impl BankEngine {
}
}
Api::PaymentRequest(mut msg) => {
if self.suspended_users.contains_key(&msg.uid) {
slog::error!(self.logger, "Suspended user attempted a PaymentRequest: {:?}", msg);
return;
}
slog::warn!(self.logger, "Received withdrawal request: {:?}", msg);

let uid = msg.uid;
Expand Down Expand Up @@ -1606,6 +1655,10 @@ impl BankEngine {
slog::warn!(self.logger, "Insurance is depleted Deposit request Failed!");
return
}
if self.suspended_users.contains_key(&msg.uid) {
slog::error!(self.logger, "Suspended user attempted a SwapRequest: {:?}", msg);
return;
}
slog::warn!(self.logger, "Received swap request: {:?}", msg);
let msg = Message::Api(Api::SwapRequest(msg));
listener(msg, ServiceIdentity::Dealer);
Expand Down Expand Up @@ -1759,6 +1812,10 @@ impl BankEngine {
listener(msg, ServiceIdentity::Api);
}
Api::CreateLnurlWithdrawalRequest(msg) => {
if self.suspended_users.contains_key(&msg.uid) {
slog::error!(self.logger, "Suspended user attempted a CreateLnurlWithdrawalRequest: {:?}", msg);
return;
}
if self.is_insurance_fund_depleted() {
slog::warn!(self.logger, "Insurance fund is depleted. Rejecting Lnurl Withdrawal Request.");
}
Expand Down
1 change: 1 addition & 0 deletions bank/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ pub async fn start(
payment_thread_tx,
)
.await;
bank_engine.init_suspensions();
bank_engine.init_accounts();

let mut state_insertion_interval = Instant::now();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE users DROP COLUMN IF EXISTS is_suspended;
1 change: 1 addition & 0 deletions models/migrations/2022-10-26-235655_user_suspension/up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE users ADD COLUMN IF NOT EXISTS is_suspended BOOLEAN NOT NULL DEFAULT FALSE;
1 change: 1 addition & 0 deletions models/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ table! {
username -> Text,
password -> Text,
is_internal -> Bool,
is_suspended -> Bool,
}
}

Expand Down
9 changes: 9 additions & 0 deletions models/src/users.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ pub struct User {
pub password: String,
/// Internal user flag
pub is_internal: bool,
/// Suspension flag
pub is_suspended: bool,
}

#[derive(Insertable, Debug, Deserialize)]
Expand All @@ -58,6 +60,7 @@ pub struct InsertableUser {
pub username: String,
pub password: String,
pub is_internal: bool,
pub is_suspended: bool,
}

impl User {
Expand All @@ -70,6 +73,12 @@ impl User {
.filter(users::username.eq(username))
.first::<Self>(conn)
}

pub fn get_all_suspended(conn: &diesel::PgConnection) -> Result<Vec<Self>, DieselError> {
users::dsl::users
.filter(users::is_suspended.eq(true))
.load::<Self>(conn)
}
}

impl InsertableUser {
Expand Down
2 changes: 2 additions & 0 deletions xerror/src/bank_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub enum BankError {
AccountNotFound,
UserAccountAlreadyExists,
FailedTransaction,
UserSuspended,
SwapError,
}

Expand All @@ -14,6 +15,7 @@ impl std::fmt::Display for BankError {
BankError::AccountNotFound => "AccountNotFound",
BankError::UserAccountAlreadyExists => "UserAccountAlreadyExists",
BankError::FailedTransaction => "FailedTransaction",
BankError::UserSuspended => "UserSuspended",
BankError::SwapError => "SwapError",
};
write!(f, "{}", output)
Expand Down