fedimint_core/core/
backup.rs
1use std::fmt::Debug;
2
3use bitcoin::hashes::{Hash, sha256};
4use fedimint_core::encoding::{Decodable, Encodable};
5use secp256k1::{Keypair, Message, Secp256k1, Signing, Verification};
6use serde::{Deserialize, Serialize};
7
8pub const BACKUP_REQUEST_MAX_PAYLOAD_SIZE_BYTES: usize = 128 * 1024;
16
17#[derive(Debug, Serialize, Deserialize, Encodable, Decodable)]
18pub struct BackupRequest {
19 pub id: secp256k1::PublicKey,
20 #[serde(with = "fedimint_core::hex::serde")]
21 pub payload: Vec<u8>,
22 pub timestamp: std::time::SystemTime,
23}
24
25impl BackupRequest {
26 fn hash(&self) -> sha256::Hash {
27 self.consensus_hash()
28 }
29
30 pub fn sign(self, keypair: &Keypair) -> anyhow::Result<SignedBackupRequest> {
31 let signature = secp256k1::SECP256K1
32 .sign_schnorr(&Message::from_digest(*self.hash().as_ref()), keypair);
33
34 Ok(SignedBackupRequest {
35 request: self,
36 signature,
37 })
38 }
39}
40
41#[derive(Debug, Serialize, Deserialize)]
42pub struct SignedBackupRequest {
43 #[serde(flatten)]
44 request: BackupRequest,
45 pub signature: secp256k1::schnorr::Signature,
46}
47
48impl SignedBackupRequest {
49 pub fn verify_valid<C>(&self, ctx: &Secp256k1<C>) -> Result<&BackupRequest, secp256k1::Error>
50 where
51 C: Signing + Verification,
52 {
53 ctx.verify_schnorr(
54 &self.signature,
55 &secp256k1::Message::from_digest_slice(&self.request.hash().to_byte_array())
56 .expect("Can't fail"),
57 &self.request.id.x_only_public_key().0,
58 )?;
59
60 Ok(&self.request)
61 }
62}