Skip to content
This repository has been archived by the owner on Sep 6, 2024. It is now read-only.

Commit

Permalink
[+] add account database
Browse files Browse the repository at this point in the history
  • Loading branch information
heng30 committed Dec 22, 2023
1 parent 24c313c commit 999d479
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 13 deletions.
157 changes: 155 additions & 2 deletions bitbox/src/db/account.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,158 @@
use super::pool;
use anyhow::Result;

pub fn save(uuid: &str, text: String) -> Result<()> {
todo!();
#[derive(Serialize, Deserialize, Debug, Clone, sqlx::FromRow)]
pub struct Account {
pub uuid: String,
pub data: String,
}

pub async fn new() -> Result<()> {
sqlx::query(
"CREATE TABLE IF NOT EXISTS account (
id INTEGER PRIMARY KEY,
uuid TEXT NOT NULL UNIQUE,
data TEXT NOT NULL)",
)
.execute(&pool())
.await?;

Ok(())
}

pub async fn delete(uuid: &str) -> Result<()> {
sqlx::query("DELETE FROM account WHERE uuid=?")
.bind(uuid)
.execute(&pool())
.await?;
Ok(())
}

pub async fn delete_all() -> Result<()> {
sqlx::query("DELETE FROM account").execute(&pool()).await?;
Ok(())
}

pub async fn insert(uuid: &str, data: &str) -> Result<()> {
sqlx::query("INSERT INTO account (uuid, data) VALUES (?, ?)")
.bind(uuid)
.bind(data)
.execute(&pool())
.await?;
Ok(())
}
pub async fn update(uuid: &str, data: &str) -> Result<()> {
sqlx::query("UPDATE account SET data=? WHERE uuid=?")
.bind(data)
.bind(uuid)
.execute(&pool())
.await?;

Ok(())
}

pub async fn select(uuid: &str) -> Result<Account> {
let pool = pool();
let stream = sqlx::query_as::<_, Account>("SELECT * FROM account WHERE uuid=?")
.bind(uuid)
.fetch_one(&pool);

Ok(stream.await?)
}

pub async fn select_all() -> Result<Vec<Account>> {
Ok(sqlx::query_as::<_, Account>("SELECT * FROM account")
.fetch_all(&pool())
.await?)
}

#[allow(dead_code)]
pub async fn is_exist(uuid: &str) -> Result<()> {
select(uuid).await?;
Ok(())
}

#[cfg(test)]
mod tests {
use super::*;
use crate::db;

#[tokio::test]
async fn test_account_table_new() -> Result<()> {
db::init("/tmp/bitbox-test.db").await;
new().await
}

#[tokio::test]
async fn test_account_table_delete_one() -> Result<()> {
db::init("/tmp/bitbox-test.db").await;
new().await?;
delete_all().await?;
insert("uuid-1", "data-1").await?;
delete("uuid-1").await
}

#[tokio::test]
async fn test_account_table_delete_all() -> Result<()> {
db::init("/tmp/bitbox-test.db").await;
new().await?;
delete_all().await
}

#[tokio::test]
async fn test_account_table_insert() -> Result<()> {
db::init("/tmp/bitbox-test.db").await;
new().await?;
delete_all().await?;
insert("uuid-1", "data-1").await?;
insert("uuid-2", "data-2").await
}

#[tokio::test]
async fn test_account_table_update() -> Result<()> {
db::init("/tmp/bitbox-test.db").await;
new().await?;
delete_all().await?;
insert("uuid-1", "data-1").await?;
update("uuid-1", "data-1.1").await
}

#[tokio::test]
async fn test_account_table_select_one() -> Result<()> {
db::init("/tmp/bitbox-test.db").await;
new().await?;
delete_all().await?;
assert!(select("uuid-1").await.is_err());

insert("uuid-1", "data-1").await?;
assert_eq!(select("uuid-1").await?.data, "data-1");
Ok(())
}

#[tokio::test]
async fn test_account_table_select_all() -> Result<()> {
db::init("/tmp/bitbox-test.db").await;
new().await?;
delete_all().await?;
insert("uuid-1", "data-1").await?;
insert("uuid-2", "data-2").await?;
let accounts = select_all().await?;

assert_eq!(accounts.len(), 2);
assert_eq!(accounts[0].uuid, "uuid-1");
assert_eq!(accounts[1].uuid, "uuid-2");
Ok(())
}

#[tokio::test]
async fn test_account_table_is_exist() -> Result<()> {
db::init("/tmp/bitbox-test.db").await;
new().await?;
delete_all().await?;
insert("uuid-1", "data-1").await?;

assert!(is_exist("uuid-0").await.is_err());
assert!(is_exist("uuid-1").await.is_ok());
Ok(())
}
}
56 changes: 50 additions & 6 deletions bitbox/src/db/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::config;
use anyhow::Result;
use sqlx::migrate::MigrateDatabase;
use sqlx::{
sqlite::{Sqlite, SqlitePoolOptions},
Expand All @@ -11,13 +12,15 @@ pub mod account;
const MAX_CONNECTIONS: u32 = 3;

lazy_static! {
pub static ref POOL: Mutex<Option<Pool<Sqlite>>> = Mutex::new(None);
static ref POOL: Mutex<Option<Pool<Sqlite>>> = Mutex::new(None);
}

async fn create_db() -> Result<(), sqlx::Error> {
let db_path = config::db_path();
fn pool() -> Pool<Sqlite> {
POOL.lock().unwrap().clone().unwrap()
}

Sqlite::create_database(&db_path).await?;
async fn create_db(db_path: &str) -> Result<(), sqlx::Error> {
Sqlite::create_database(db_path).await?;

let pool = SqlitePoolOptions::new()
.max_connections(MAX_CONNECTIONS)
Expand All @@ -29,8 +32,49 @@ async fn create_db() -> Result<(), sqlx::Error> {
Ok(())
}

pub async fn init() {
if let Err(e) = create_db().await {
pub async fn init(db_path: &str) {
if let Err(e) = create_db(db_path).await {
panic!("create db: {}, Error: {e:?}", config::db_path());
}
}

#[allow(dead_code)]
pub async fn is_table_exist(table_name: &str) -> Result<()> {
sqlx::query("SELECT name FROM sqlite_master WHERE type='table' AND name=?")
.bind(table_name)
.fetch_one(&pool())
.await?;

Ok(())
}

pub async fn drop_table(table_name: &str) -> Result<()> {

Check warning on line 51 in bitbox/src/db/mod.rs

View workflow job for this annotation

GitHub Actions / action-run

function `drop_table` is never used
sqlx::query(&format!("DROP TABLE {}", table_name))
.execute(&pool())
.await?;

Ok(())
}

#[cfg(test)]
mod tests {
use super::*;

#[tokio::test]
async fn test_db_is_table_exist() -> Result<()> {
init("/tmp/bitbox-test.db").await;
account::new().await?;
assert!(is_table_exist("hello").await.is_err());
assert!(is_table_exist("account").await.is_ok());
Ok(())
}

#[tokio::test]
async fn test_db_drop_table() -> Result<()> {
init("/tmp/bitbox-test.db").await;
account::new().await?;
assert!(drop_table("hello").await.is_err());
assert!(drop_table("account").await.is_ok());
Ok(())
}
}
2 changes: 1 addition & 1 deletion bitbox/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ async fn main() -> Result<()> {
debug!("start...");

config::init();
db::init();
db::init(&config::db_path()).await;

debug!("exit...");
Ok(())
Expand Down
4 changes: 2 additions & 2 deletions bitbox/src/wallet/account/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ impl Info {
Ok(())
}

pub fn save(&self) -> Result<()> {
pub async fn save(&self) -> Result<()> {
let text = serde_json::to_string(self)?;
db::account::save(&self.uuid, text)
db::account::insert(&self.uuid, &text).await
}
}

Expand Down
31 changes: 30 additions & 1 deletion bitbox/src/wallet/account/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use std::collections::BTreeMap;
use std::str::FromStr;

#[derive(Debug, Clone)]
struct TxDetail {
pub struct TxDetail {
pub tx_hex: String,
pub fee_amount: u64,
}
Expand Down Expand Up @@ -407,6 +407,21 @@ mod tests {
build(PASSWORD, acnt_2, tx_info).await
}

async fn build_transaction_to_pkh() -> Result<TxDetail> {
let acnt_1: address::Info = serde_json::from_str(TEST_ACCOUNT_1)?;

let tx_info = sendinfo::Info {
recipient_address: "msFbCzXbGxdeFRp6zm4WJZozm7akFSGRXg".to_string(),
send_amount: 1,
max_send_amount: 100_000,
fee_rate: 3,
max_fee_rate: 10,
max_fee_amount: 1_000_000,
};

build(PASSWORD, acnt_1, tx_info).await
}

#[tokio::test]
async fn test_build_transaction() -> Result<()> {
let tx_detail = build_transaction_1to2().await?;
Expand Down Expand Up @@ -447,6 +462,20 @@ mod tests {
Ok(())
}

#[tokio::test]
async fn test_broadcast_transaction_to_pkh() -> Result<()> {
let tx_detail = build_transaction_to_pkh().await?;
println!(
"tx hex: \n{}\nfee:{}",
tx_detail.tx_hex, tx_detail.fee_amount
);

let res = broadcast_transaction("test", tx_detail.tx_hex).await?;
println!("txid: {res}");

Ok(())
}

#[test]
fn test_parse_tx() -> Result<()> {
let hex_tx = "0200000000010298375ac8abe48596820881bb3680f3b0c188b951aba9bef71da9132aa72f51e40000000000ffffffffbffba2c7217503b46cf36816e04d717f523945d8ed634b8ddbf17fc6de1306a50000000000ffffffff02102700000000000016001401e4960aa9160f190c9020d723c613a860f1666e4225000000000000160014ffdfa7be127eb533fc2b34e17e7155602374321e0247304402201f3e52861f0f8b00f6c7e765d08f4b35e1389036a3ab3b6f48bebba8135ad5bb02204226566461e1a308f8df5b9e27aaea3e263fad3ccbaecbc271255c9b434fa3040121031a88cf3b115c06567ed3c3c4e997c52bd37f012f220c238e2e957871ab16989602483045022100a4bf46848bf833c4b72550f326d26e92b4b9ad203ef3af05e06282a7c1f5d22d02205751131ea0aebb7fd5bad56cd83c4d193fa4af64be4dadee42767374388d3fda0121031a88cf3b115c06567ed3c3c4e997c52bd37f012f220c238e2e957871ab16989600000000";
Expand Down
1 change: 0 additions & 1 deletion bitbox/src/wallet/transaction/blockstream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ pub async fn is_tx_confirmed(network: &str, txid: &str) -> Result<bool> {
mod tests {
use super::*;

const PASSWORD: &str = "12345678";
const MAIN_ADDRESS: &str = "36LjFk7tAn6j93nKBHcvtXd88wFGSPDtZG";
const TEST_ADDRESS: &str = "tb1q5sulqc5lq048s25jtcdv34fhxq7s68uk6m2nl0";

Expand Down

0 comments on commit 999d479

Please sign in to comment.