Skip to content

Commit

Permalink
added timestamp to wallet (#152)
Browse files Browse the repository at this point in the history

Signed-off-by: muraca <mmuraca247@gmail.com>
  • Loading branch information
muraca authored Dec 11, 2023
1 parent 803bb17 commit 94a8709
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 23 deletions.
1 change: 1 addition & 0 deletions tuxedo-template-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub use kitties;
pub use money;
pub use poe;
pub use runtime_upgrade;
pub use timestamp;

/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
/// the specifics of the runtime. They can then be made to be agnostic over specific formats
Expand Down
3 changes: 3 additions & 0 deletions wallet/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ pub enum Command {

/// Show the complete list of UTXOs known to the wallet.
ShowAllOutputs,

/// Show the latest on-chain timestamp.
ShowTimestamp,
}

#[derive(Debug, Args)]
Expand Down
13 changes: 9 additions & 4 deletions wallet/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod money;
mod output_filter;
mod rpc;
mod sync;
mod timestamp;

use cli::{Cli, Command};

Expand Down Expand Up @@ -71,10 +72,10 @@ async fn main() -> anyhow::Result<()> {
// The filter function that will determine whether the local database should track a given utxo
// is based on whether that utxo is privately owned by a key that is in our keystore.
let keystore_filter = |v: &OuterVerifier| -> bool {
matches![
v,
OuterVerifier::Sr25519Signature(Sr25519Signature { owner_pubkey }) if crate::keystore::has_key(&keystore, owner_pubkey)
]
matches![v,
OuterVerifier::Sr25519Signature(Sr25519Signature { owner_pubkey })
if crate::keystore::has_key(&keystore, owner_pubkey)
] || matches![v, OuterVerifier::UpForGrabs(UpForGrabs)] // used for timestamp
};

if !sled::Db::was_recovered(&db) {
Expand Down Expand Up @@ -166,6 +167,10 @@ async fn main() -> anyhow::Result<()> {

Ok(())
}
Some(Command::ShowTimestamp) => {
println!("Timestamp: {}", timestamp::get_timestamp(&db)?);
Ok(())
}
None => {
log::info!("No Wallet Command invoked. Exiting.");
Ok(())
Expand Down
18 changes: 18 additions & 0 deletions wallet/src/money.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,21 @@ pub async fn get_coin_from_storage(

Ok((coin_in_storage, utxo.verifier))
}

/// Apply a transaction to the local database, storing the new coins.
pub(crate) fn apply_transaction(
db: &Db,
tx_hash: <BlakeTwo256 as Hash>::Output,
index: u32,
output: &Output<OuterVerifier>,
) -> anyhow::Result<()> {
let amount = output.payload.extract::<Coin<0>>()?.0;
let output_ref = OutputRef { tx_hash, index };
match output.verifier {
OuterVerifier::Sr25519Signature(Sr25519Signature { owner_pubkey }) => {
// Add it to the global unspent_outputs table
crate::sync::add_unspent_output(db, &output_ref, &owner_pubkey, &amount)
}
_ => Err(anyhow!("{:?}", ())),
}
}
30 changes: 11 additions & 19 deletions wallet/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ use sled::Db;
use sp_core::H256;
use sp_runtime::traits::{BlakeTwo256, Hash};
use tuxedo_core::{
dynamic_typing::UtxoData,
types::{Input, OutputRef},
verifier::Sr25519Signature,
};

use jsonrpsee::http_client::HttpClient;
use runtime::{money::Coin, Block, OuterVerifier, Transaction};
use runtime::{money::Coin, timestamp::Timestamp, Block, OuterVerifier, Transaction};

/// The identifier for the blocks tree in the db.
const BLOCKS: &str = "blocks";
Expand Down Expand Up @@ -262,23 +262,15 @@ async fn apply_transaction<F: Fn(&OuterVerifier) -> bool>(
.filter(|o| filter(&o.verifier))
.enumerate()
{
// For now the wallet only supports simple coins, so skip anything else
let amount = match output.payload.extract::<Coin<0>>() {
Ok(Coin(amount)) => amount,
Err(_) => continue,
};

let output_ref = OutputRef {
tx_hash,
index: index as u32,
};

match output.verifier {
OuterVerifier::Sr25519Signature(Sr25519Signature { owner_pubkey }) => {
// Add it to the global unspent_outputs table
add_unspent_output(db, &output_ref, &owner_pubkey, &amount)?;
// For now the wallet only supports simple coins and timestamp
match output.payload.type_id {
Coin::<0>::TYPE_ID => {
crate::money::apply_transaction(db, tx_hash, index as u32, output)?;
}
Timestamp::TYPE_ID => {
crate::timestamp::apply_transaction(db, output)?;
}
_ => return Err(anyhow!("{:?}", ())),
_ => continue,
}
}

Expand All @@ -292,7 +284,7 @@ async fn apply_transaction<F: Fn(&OuterVerifier) -> bool>(
}

/// Add a new output to the database updating all tables.
fn add_unspent_output(
pub(crate) fn add_unspent_output(
db: &Db,
output_ref: &OutputRef,
owner_pubkey: &H256,
Expand Down
27 changes: 27 additions & 0 deletions wallet/src/timestamp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//! Wallet features related to on-chain timestamps.
use anyhow::anyhow;
use parity_scale_codec::{Decode, Encode};
use runtime::{timestamp::Timestamp, OuterVerifier};
use sled::Db;
use tuxedo_core::types::Output;

/// The identifier for the current timestamp in the db.
const TIMESTAMP: &str = "timestamp";

pub(crate) fn apply_transaction(db: &Db, output: &Output<OuterVerifier>) -> anyhow::Result<()> {
let timestamp = output.payload.extract::<Timestamp>()?.time;
let timestamp_tree = db.open_tree(TIMESTAMP)?;
timestamp_tree.insert([0], timestamp.encode())?;
Ok(())
}

/// Apply a transaction to the local database, storing the new timestamp.
pub(crate) fn get_timestamp(db: &Db) -> anyhow::Result<u64> {
let timestamp_tree = db.open_tree(TIMESTAMP)?;
let timestamp = timestamp_tree
.get([0])?
.ok_or_else(|| anyhow!("Could not find timestamp in database."))?;
u64::decode(&mut &timestamp[..])
.map_err(|_| anyhow!("Could not decode timestamp from database."))
}

0 comments on commit 94a8709

Please sign in to comment.