Skip to content

Commit

Permalink
Next
Browse files Browse the repository at this point in the history
  • Loading branch information
Rigidity committed Mar 16, 2024
1 parent 6beb7fb commit 7c8d034
Show file tree
Hide file tree
Showing 14 changed files with 137 additions and 35 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
/target
test.sqlite
test.sqlite-wal
test.sqlite-shm
16 changes: 16 additions & 0 deletions migrations/20240314021456_init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,20 @@ CREATE TABLE `unhardened_keys` (
`index` INT UNSIGNED NOT NULL PRIMARY KEY,
`public_key` BLOB NOT NULL,
`p2_puzzle_hash` BLOB NOT NULL
);

CREATE TABLE `hardened_cats` (
`puzzle_hash` BLOB NOT NULL PRIMARY KEY,
`asset_id` BLOB NOT NULL,
`public_key` BLOB NOT NULL,
`puzzle_hash` BLOB NOT NULL
);

CREATE TABLE `coin_states` (
`coin_id` BLOB NOT NULL PRIMARY KEY,
`parent_coin_info` BLOB NOT NULL,
`puzzle_hash` BLOB NOT NULL,
`amount` BIGINT UNSIGNED NOT NULL,
`created_height` INT UNSIGNED,
`spent_height` INT UNSIGNED
);
8 changes: 4 additions & 4 deletions src/spends/cat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use clvm_utils::{tree_hash, CurriedProgram};
use clvmr::{allocator::NodePtr, serde::node_from_bytes, Allocator};
use thiserror::Error;

use crate::{CatCondition, DerivationStore};
use crate::{CatCondition, PuzzleStore};

mod issuance;
mod raw_spend;
Expand Down Expand Up @@ -49,7 +49,7 @@ pub async fn construct_cat_spends(
standard_puzzle_ptr: NodePtr,
cat_puzzle_ptr: NodePtr,
peer: &Peer,
derivation_store: &impl DerivationStore,
puzzle_store: &impl PuzzleStore,
coins: Vec<Coin>,
conditions: Vec<CatCondition<NodePtr>>,
asset_id: [u8; 32],
Expand All @@ -65,12 +65,12 @@ pub async fn construct_cat_spends(
for (i, coin) in coins.into_iter().enumerate() {
// Coin info.
let puzzle_hash = &coin.puzzle_hash;
let index = derivation_store
let index = puzzle_store
.puzzle_hash_index(puzzle_hash.into())
.await
.expect("cannot spend coin with unknown puzzle hash");

let synthetic_key = derivation_store
let synthetic_key = puzzle_store
.public_key(index)
.await
.expect("cannot spend coin with unknown public key");
Expand Down
8 changes: 4 additions & 4 deletions src/spends/standard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use clvm_traits::{clvm_quote, FromNodePtr, ToClvmError, ToNodePtr};
use clvm_utils::CurriedProgram;
use clvmr::{allocator::NodePtr, Allocator};

use crate::{Condition, DerivationStore};
use crate::{Condition, PuzzleStore};

/// Creates a new coin spend for a given standard transaction coin.
pub fn spend_standard_coin(
Expand Down Expand Up @@ -38,19 +38,19 @@ pub fn spend_standard_coin(
pub async fn spend_standard_coins(
a: &mut Allocator,
standard_puzzle_ptr: NodePtr,
derivation_store: &impl DerivationStore,
puzzle_store: &impl PuzzleStore,
coins: Vec<Coin>,
conditions: &[Condition<NodePtr>],
) -> Vec<CoinSpend> {
let mut coin_spends = Vec::new();
for (i, coin) in coins.into_iter().enumerate() {
let puzzle_hash = &coin.puzzle_hash;
let index = derivation_store
let index = puzzle_store
.puzzle_hash_index(puzzle_hash.into())
.await
.expect("cannot spend coin with unknown puzzle hash");

let synthetic_key = derivation_store
let synthetic_key = puzzle_store
.public_key(index)
.await
.expect("cannot spend coin with unknown public key");
Expand Down
2 changes: 2 additions & 0 deletions src/sqlite.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
mod coin_store;
mod hardened_key_store;
mod unhardened_key_store;

pub use coin_store::*;
pub use hardened_key_store::*;
pub use unhardened_key_store::*;
101 changes: 101 additions & 0 deletions src/sqlite/coin_store.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
use chia_protocol::{Coin, CoinState};
use sqlx::SqlitePool;

pub struct CoinStore {
pool: SqlitePool,
}

impl CoinStore {
pub fn new(pool: SqlitePool) -> Self {
Self { pool }
}

pub async fn unspent_coins(&self) -> Vec<Coin> {
let rows = sqlx::query!(
"
SELECT `parent_coin_info`, `puzzle_hash`, `amount`
FROM `coin_states`
WHERE `spent_height` IS NULL
"
)
.fetch_all(&self.pool)
.await
.unwrap();

rows.into_iter()
.map(|row| {
let parent_coin_info = row.parent_coin_info;
let puzzle_hash = row.puzzle_hash;
let amount = row.amount as u64;

Coin {
parent_coin_info: parent_coin_info.try_into().unwrap(),
puzzle_hash: puzzle_hash.try_into().unwrap(),
amount,
}
})
.collect()
}

pub async fn coin_state(&self, coin_id: [u8; 32]) -> CoinState {
let coin_id = coin_id.to_vec();

let row = sqlx::query!(
"
SELECT `parent_coin_info`, `puzzle_hash`, `amount`, `created_height`, `spent_height`
FROM `coin_states`
WHERE `coin_id` = ?
",
coin_id
)
.fetch_one(&self.pool)
.await
.unwrap();

CoinState {
coin: Coin {
parent_coin_info: row.parent_coin_info.try_into().unwrap(),
puzzle_hash: row.puzzle_hash.try_into().unwrap(),
amount: row.amount as u64,
},
created_height: row.created_height.map(|height| height as u32),
spent_height: row.spent_height.map(|height| height as u32),
}
}

pub async fn apply_updates(&self, coin_states: Vec<CoinState>) {
let mut tx = self.pool.begin().await.unwrap();

for coin_state in coin_states {
let coin_id = coin_state.coin.coin_id().to_vec();
let parent_coin_info = coin_state.coin.parent_coin_info.to_bytes().to_vec();
let puzzle_hash = coin_state.coin.puzzle_hash.to_bytes().to_vec();
let amount = coin_state.coin.amount as i64;

sqlx::query!(
"
REPLACE INTO `coin_states` (
`coin_id`,
`parent_coin_info`,
`puzzle_hash`,
`amount`,
`created_height`,
`spent_height`
)
VALUES (?, ?, ?, ?, ?, ?)
",
coin_id,
parent_coin_info,
puzzle_hash,
amount,
coin_state.created_height,
coin_state.spent_height
)
.execute(&mut *tx)
.await
.unwrap();
}

tx.commit().await.unwrap();
}
}
Empty file.
4 changes: 2 additions & 2 deletions src/sqlite/hardened_key_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use chia_bls::{PublicKey, SecretKey};
use chia_wallet::{standard::standard_puzzle_hash, DeriveSynthetic};
use sqlx::SqlitePool;

use crate::{DerivationStore, KeyStore};
use crate::{KeyStore, PuzzleStore};

pub struct HardenedKeyStore {
pool: SqlitePool,
Expand Down Expand Up @@ -97,7 +97,7 @@ impl KeyStore for HardenedKeyStore {
}
}

impl DerivationStore for HardenedKeyStore {
impl PuzzleStore for HardenedKeyStore {
async fn puzzle_hash(&self, index: u32) -> Option<[u8; 32]> {
sqlx::query!(
"SELECT `p2_puzzle_hash` FROM `hardened_keys` WHERE `index` = ?",
Expand Down
Empty file.
4 changes: 2 additions & 2 deletions src/sqlite/unhardened_key_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use chia_bls::{DerivableKey, PublicKey};
use chia_wallet::{standard::standard_puzzle_hash, DeriveSynthetic};
use sqlx::SqlitePool;

use crate::{DerivationStore, KeyStore};
use crate::{KeyStore, PuzzleStore};

pub struct UnhardenedKeyStore {
pool: SqlitePool,
Expand Down Expand Up @@ -109,7 +109,7 @@ impl KeyStore for UnhardenedKeyStore {
}
}

impl DerivationStore for UnhardenedKeyStore {
impl PuzzleStore for UnhardenedKeyStore {
async fn puzzle_hash(&self, index: u32) -> Option<[u8; 32]> {
sqlx::query!(
"SELECT `p2_puzzle_hash` FROM `unhardened_keys` WHERE `index` = ?",
Expand Down
6 changes: 2 additions & 4 deletions src/stores.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
mod coin_store;
mod derivation_store;
mod key_store;
mod puzzle_store;
mod transaction_store;

pub use coin_store::*;
pub use derivation_store::*;
pub use key_store::*;
pub use puzzle_store::*;
pub use transaction_store::*;
18 changes: 0 additions & 18 deletions src/stores/coin_store.rs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::future::Future;
use crate::KeyStore;

/// Keeps track of derived puzzle hashes in a wallet, based on its public keys.
pub trait DerivationStore: KeyStore {
pub trait PuzzleStore: KeyStore {
/// Gets the derivation index of a puzzle hash.
fn puzzle_hash_index(&self, puzzle_hash: [u8; 32]) -> impl Future<Output = Option<u32>> + Send;

Expand Down
Binary file removed test.sqlite
Binary file not shown.

0 comments on commit 7c8d034

Please sign in to comment.