feat(mint): restore function

This commit is contained in:
thesimplekid
2024-03-11 18:12:40 +00:00
parent 27677f881a
commit 65b0f66729
7 changed files with 86 additions and 7 deletions

View File

@@ -20,7 +20,7 @@ pub struct MemoryLocalStore {
melt_quotes: Arc<Mutex<HashMap<String, MeltQuote>>>,
pending_proofs: Arc<Mutex<HashMap<Vec<u8>, Proof>>>,
spent_proofs: Arc<Mutex<HashMap<Vec<u8>, Proof>>>,
blinded_signatures: Arc<Mutex<HashMap<String, BlindedSignature>>>,
blinded_signatures: Arc<Mutex<HashMap<Box<[u8]>, BlindedSignature>>>,
}
impl MemoryLocalStore {
@@ -33,7 +33,7 @@ impl MemoryLocalStore {
melt_quotes: Vec<MeltQuote>,
pending_proofs: Proofs,
spent_proofs: Proofs,
blinded_signatures: HashMap<String, BlindedSignature>,
blinded_signatures: HashMap<Box<[u8]>, BlindedSignature>,
) -> Result<Self, Error> {
Ok(Self {
mint_info: Arc::new(Mutex::new(mint_info)),
@@ -231,9 +231,10 @@ impl LocalStore for MemoryLocalStore {
self.blinded_signatures
.lock()
.await
.insert(blinded_message.to_string(), blinded_signature);
.insert(blinded_message.to_bytes(), blinded_signature);
Ok(())
}
async fn get_blinded_signature(
&self,
blinded_message: &PublicKey,
@@ -242,7 +243,24 @@ impl LocalStore for MemoryLocalStore {
.blinded_signatures
.lock()
.await
.get(&blinded_message.to_string())
.get(&blinded_message.to_bytes())
.cloned())
}
async fn get_blinded_signatures(
&self,
blinded_messages: Vec<PublicKey>,
) -> Result<Vec<Option<BlindedSignature>>, Error> {
let mut signatures = Vec::with_capacity(blinded_messages.len());
let blinded_signatures = self.blinded_signatures.lock().await;
for blinded_message in blinded_messages {
let signature = blinded_signatures.get(&blinded_message.to_bytes()).cloned();
signatures.push(signature)
}
Ok(signatures)
}
}

View File

@@ -88,4 +88,8 @@ pub trait LocalStore {
&self,
blinded_message: &PublicKey,
) -> Result<Option<BlindedSignature>, Error>;
async fn get_blinded_signatures(
&self,
blinded_messages: Vec<PublicKey>,
) -> Result<Vec<Option<BlindedSignature>>, Error>;
}

View File

@@ -23,7 +23,7 @@ const PENDING_PROOFS_TABLE: TableDefinition<&[u8], &str> = TableDefinition::new(
const SPENT_PROOFS_TABLE: TableDefinition<&[u8], &str> = TableDefinition::new("spent_proofs");
const CONFIG_TABLE: TableDefinition<&str, &str> = TableDefinition::new("config");
// Key is hex blinded_message B_ value is blinded_signature
const BLINDED_SIGNATURES: TableDefinition<&str, &str> = TableDefinition::new("blinded_signatures");
const BLINDED_SIGNATURES: TableDefinition<&[u8], &str> = TableDefinition::new("blinded_signatures");
#[derive(Debug, Clone)]
pub struct RedbLocalStore {
@@ -408,7 +408,7 @@ impl LocalStore for RedbLocalStore {
{
let mut table = write_txn.open_table(BLINDED_SIGNATURES)?;
table.insert(
blinded_message.to_string().as_str(),
blinded_message.to_bytes().as_ref(),
serde_json::to_string(&blinded_signature)?.as_str(),
)?;
}
@@ -426,10 +426,29 @@ impl LocalStore for RedbLocalStore {
let read_txn = db.begin_read()?;
let table = read_txn.open_table(BLINDED_SIGNATURES)?;
if let Some(blinded_signature) = table.get(blinded_message.to_string().as_str())? {
if let Some(blinded_signature) = table.get(blinded_message.to_bytes().as_ref())? {
return Ok(serde_json::from_str(blinded_signature.value())?);
}
Ok(None)
}
async fn get_blinded_signatures(
&self,
blinded_messages: Vec<PublicKey>,
) -> Result<Vec<Option<BlindedSignature>>, Error> {
let db = self.db.lock().await;
let read_txn = db.begin_read()?;
let table = read_txn.open_table(BLINDED_SIGNATURES)?;
let mut signatures = Vec::with_capacity(blinded_messages.len());
for blinded_message in blinded_messages {
if let Some(blinded_signature) = table.get(blinded_message.to_bytes().as_ref())? {
signatures.push(Some(serde_json::from_str(blinded_signature.value())?))
}
}
Ok(signatures)
}
}

View File

@@ -732,6 +732,35 @@ impl Mint {
pub async fn mint_info(&self) -> Result<MintInfo, Error> {
Ok(self.localstore.get_mint_info().await?)
}
#[cfg(feature = "nut09")]
pub async fn restore(&self, request: RestoreRequest) -> Result<RestoreResponse, Error> {
let output_len = request.outputs.len();
let mut outputs = Vec::with_capacity(output_len);
let mut signatures = Vec::with_capacity(output_len);
let blinded_message = request.outputs.iter().map(|b| b.b.clone()).collect();
let blinded_signatures = self
.localstore
.get_blinded_signatures(blinded_message)
.await?;
for (blinded_message, blinded_signature) in
request.outputs.into_iter().zip(blinded_signatures)
{
if let Some(blinded_signature) = blinded_signature {
outputs.push(blinded_message);
signatures.push(blinded_signature);
}
}
Ok(RestoreResponse {
outputs,
signatures,
})
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]

View File

@@ -39,6 +39,8 @@ pub use nut06::{MintInfo, MintVersion, Nuts};
pub use nut07::{CheckStateRequest, CheckStateResponse};
#[cfg(feature = "nut08")]
pub use nut08::{MeltBolt11Request, MeltBolt11Response};
#[cfg(feature = "nut09")]
pub use nut09::{RestoreRequest, RestoreResponse};
#[cfg(feature = "nut10")]
pub use nut10::{Kind, Secret as Nut10Secret, SecretData};
#[cfg(feature = "nut11")]

View File

@@ -79,6 +79,12 @@ impl PublicKey {
}
}
impl From<PublicKey> for Box<[u8]> {
fn from(pubkey: PublicKey) -> Box<[u8]> {
pubkey.to_bytes()
}
}
impl FromStr for PublicKey {
type Err = Error;

View File

@@ -17,6 +17,7 @@ pub struct RestoreResponse {
/// Outputs
pub outputs: Vec<BlindedMessage>,
/// Signatures
// TODO: remove rename just for temp compatanlite with nutshell
#[serde(rename = "promises")]
pub signatures: Vec<BlindedSignature>,
}