-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
A simple mock of L2 logic without proofs or signatures
Deposit is a big unanswered question
- Loading branch information
1 parent
33f63eb
commit b78dc74
Showing
10 changed files
with
258 additions
and
54 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,41 @@ | ||
use std::sync::Arc; | ||
use std::ops::Deref; | ||
|
||
use axum::{extract::State, Json}; | ||
use anyhow::anyhow; | ||
use axum::{extract::State, http::StatusCode, Json}; | ||
use serde::{Deserialize, Serialize}; | ||
use tokio::sync::RwLock; | ||
|
||
use crate::{AppErr, BatchState, PublicKey}; | ||
use crate::{state::LockedBatchState, AppErr, PublicKey}; | ||
|
||
#[derive(Serialize, Deserialize)] | ||
pub struct DepositRequest { | ||
pub struct Deposit { | ||
pub public_key: PublicKey, | ||
pub amount: u64, | ||
} | ||
|
||
pub async fn deposit( | ||
State(pool): State<Arc<RwLock<BatchState>>>, | ||
Json(proof_request): Json<DepositRequest>, | ||
state: State<LockedBatchState>, | ||
Json(Deposit { public_key, amount }): Json<Deposit>, | ||
) -> Result<(), AppErr> { | ||
todo!("deposit") | ||
tracing::info!("TODO: verifying deposit"); | ||
|
||
tracing::info!("TODO: adding deposit to batch"); | ||
|
||
let mut state = state.deref().write().await; | ||
let account = state.balances.entry(public_key.clone()); | ||
|
||
let prior_balance = account.or_insert(0); | ||
let updated_balance = prior_balance.checked_add(amount).ok_or_else(|| { | ||
AppErr::set_status( | ||
anyhow!("deposit would overflow account"), | ||
StatusCode::CONFLICT, | ||
) | ||
})?; | ||
|
||
tracing::info!( | ||
"Updated account public_key={} balance={}", | ||
public_key, | ||
updated_balance | ||
); | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
pub mod deposit; | ||
pub mod withdraw; | ||
pub mod transfer; | ||
pub mod withdraw; | ||
|
||
pub use deposit::deposit; | ||
pub use withdraw::withdraw; | ||
pub use transfer::transfer; | ||
pub use withdraw::withdraw; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,87 @@ | ||
use std::sync::Arc; | ||
|
||
use axum::{extract::State, Json}; | ||
use anyhow::anyhow; | ||
use axum::{extract::State, http::StatusCode, Json}; | ||
use serde::{Deserialize, Serialize}; | ||
use tokio::sync::RwLock; | ||
|
||
use crate::{AppErr, BatchState, PublicKey}; | ||
use crate::{state::LockedBatchState, AppErr, PublicKey}; | ||
|
||
#[derive(Serialize, Deserialize)] | ||
pub struct WithdrawRequest { | ||
pub struct Withdrawal { | ||
pub public_key: PublicKey, | ||
pub signature: String, | ||
pub amount: u64, | ||
} | ||
|
||
pub async fn withdraw( | ||
State(pool): State<Arc<RwLock<BatchState>>>, | ||
Json(proof_request): Json<WithdrawRequest>, | ||
State(state): State<LockedBatchState>, | ||
Json(withdrawal): Json<Withdrawal>, | ||
) -> Result<(), AppErr> { | ||
tracing::info!("TODO: verifying withdrawal signature"); | ||
|
||
tracing::info!("verifying withdrawal sender has sufficient funds"); | ||
check_sender_funds(&state, &withdrawal).await?; | ||
|
||
tracing::info!("TODO: adding withdrawal to batch"); | ||
|
||
let mut state = state.write().await; | ||
let from_balance = state | ||
.balances | ||
.get_mut(&withdrawal.public_key) | ||
.ok_or_else(|| { | ||
AppErr::set_status( | ||
anyhow!( | ||
"Sender no longer has an account. | ||
The sender just removed all their funds." | ||
), | ||
StatusCode::CONFLICT, | ||
) | ||
})?; | ||
|
||
let updated_balance = from_balance.checked_sub(withdrawal.amount).ok_or_else(|| { | ||
AppErr::set_status( | ||
anyhow!( | ||
"Sender no longer has sufficient funds, balance={}, withdrawal_amount={}. | ||
The sender just moved their funds in a concurrent request", | ||
from_balance, | ||
withdrawal.amount | ||
), | ||
StatusCode::CONFLICT, | ||
) | ||
})?; | ||
|
||
*from_balance = updated_balance; | ||
|
||
if updated_balance == 0 { | ||
state.balances.remove(&withdrawal.public_key); | ||
} | ||
|
||
tracing::info!( | ||
"Updated account public_key={} balance={}", | ||
withdrawal.public_key, | ||
updated_balance | ||
); | ||
|
||
Ok(()) | ||
} | ||
|
||
async fn check_sender_funds( | ||
state: &LockedBatchState, | ||
withdrawal: &Withdrawal, | ||
) -> Result<(), AppErr> { | ||
todo!() | ||
let state = state.read().await; | ||
let from_balance = state.balances.get(&withdrawal.public_key).ok_or_else(|| { | ||
AppErr::set_status(anyhow!("Withdrawer has no account."), StatusCode::CONFLICT) | ||
})?; | ||
|
||
if *from_balance < withdrawal.amount { | ||
return Err(AppErr::set_status( | ||
anyhow!( | ||
"Withdrawer has insufficient funds, balance={}, withdrawal_amount={}.", | ||
from_balance, | ||
withdrawal.amount | ||
), | ||
StatusCode::FORBIDDEN, | ||
)); | ||
} | ||
|
||
Ok(()) | ||
} |
Oops, something went wrong.