Upgrade to latest sp_client

This commit is contained in:
NicolasCantu 2025-04-03 14:51:16 +02:00 committed by Nicolas Cantu
parent a3de9e4666
commit 8eb3baaf9f
7 changed files with 201 additions and 307 deletions

View File

@ -17,7 +17,7 @@ serde = { version = "1.0.193", features = ["derive"] }
serde_json = { version = "1.0.108" }
serde-wasm-bindgen = "0.6.5"
# sp_client = { path = "../sp-client" }
sp_client = { git = "https://github.com/Sosthene00/sp-client.git", branch = "4nk" }
sp_client = { git = "https://github.com/Sosthene00/sp-client.git", branch = "dev" }
tsify = { git = "https://github.com/Sosthene00/tsify", branch = "next" }
wasm-bindgen = "0.2.91"
rs_merkle = "1.4.2"

View File

@ -3,7 +3,9 @@ use tsify::Tsify;
use wasm_bindgen::prelude::*;
use sp_client::{
bitcoin::OutPoint, silentpayments::utils::SilentPaymentAddress, spclient::SpWallet
SpClient,
bitcoin::OutPoint,
silentpayments::SilentPaymentAddress,
};
use crate::pcd::Member;
@ -11,28 +13,28 @@ use crate::pcd::Member;
#[derive(Debug, Serialize, Deserialize, Clone, Default, Tsify)]
#[tsify(into_wasm_abi, from_wasm_abi)]
pub struct Device {
sp_wallet: SpWallet,
sp_client: SpClient,
pairing_process_commitment: Option<OutPoint>,
paired_member: Member,
}
impl Device {
pub fn new(sp_wallet: SpWallet) -> Self {
let local_address = sp_wallet.get_client().get_receiving_address();
pub fn new(sp_client: SpClient) -> Self {
let local_address = sp_client.get_receiving_address();
let member = Member::new(vec![SilentPaymentAddress::try_from(local_address).unwrap()]);
Self {
sp_wallet,
sp_client,
pairing_process_commitment: None,
paired_member: member,
}
}
pub fn get_wallet(&self) -> &SpWallet {
&self.sp_wallet
pub fn get_sp_client(&self) -> &SpClient {
&self.sp_client
}
pub fn get_mut_wallet(&mut self) -> &mut SpWallet {
&mut self.sp_wallet
pub fn get_mut_sp_client(&mut self) -> &mut SpClient {
&mut self.sp_client
}
pub fn get_pairing_commitment(&self) -> Option<OutPoint> {
@ -45,7 +47,7 @@ impl Device {
}
pub fn unpair(&mut self) {
let local_address = self.get_wallet().get_client().get_receiving_address();
let local_address = self.get_sp_client().get_receiving_address();
let member = Member::new(vec![SilentPaymentAddress::try_from(local_address).unwrap()]);
self.paired_member = member;
self.pairing_process_commitment = None;
@ -55,8 +57,12 @@ impl Device {
self.paired_member.clone()
}
pub fn get_address(&self) -> SilentPaymentAddress {
self.get_sp_client().get_receiving_address()
}
pub fn get_other_addresses(&self) -> Vec<String> {
let our_address = self.get_wallet().get_client().get_receiving_address();
let our_address: String = self.get_sp_client().get_receiving_address().into();
self.to_member()
.get_addresses()
.into_iter()

View File

@ -14,7 +14,7 @@ use sp_client::{
bitcoin::{
consensus::serialize, hashes::{sha256t_hash_newtype, Hash, HashEngine}, secp256k1::PublicKey, OutPoint
},
silentpayments::utils::SilentPaymentAddress,
silentpayments::SilentPaymentAddress,
};
use tsify::Tsify;
@ -481,7 +481,7 @@ mod tests {
use serde_json::json;
use sp_client::{
bitcoin::{secp256k1::SecretKey, Network},
spclient::{SpClient, SpWallet, SpendKey},
SpClient, SpendKey,
};
use super::*;
@ -490,10 +490,8 @@ mod tests {
signature::{AnkHash, Proof},
};
fn create_alice_wallet() -> SpWallet {
SpWallet::new(
fn create_alice_wallet() -> SpClient {
SpClient::new(
"default".to_owned(),
SecretKey::from_str(
"a67fb6bf5639efd0aeb19c1c584dd658bceda87660ef1088d4a29d2e77846973",
)
@ -504,20 +502,13 @@ mod tests {
)
.unwrap(),
),
None,
Network::Signet,
)
.unwrap(),
None,
vec![],
)
.unwrap()
}
fn create_bob_wallet() -> SpWallet {
SpWallet::new(
fn create_bob_wallet() -> SpClient {
SpClient::new(
"default".to_owned(),
SecretKey::from_str(
"4d9f62b2340de3f0bafd671b78b19edcfded918c4106baefd34512f12f520e9b",
)
@ -528,13 +519,8 @@ mod tests {
)
.unwrap(),
),
None,
Network::Signet,
)
.unwrap(),
None,
vec![],
)
.unwrap()
}
@ -605,18 +591,17 @@ mod tests {
let validation_hash2 = AnkValidationNoHash::from_merkle_root(new_state_merkle_root);
let alice_spend_key: SecretKey = alice_wallet
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let bob_spend_key: SecretKey = bob_wallet.get_client().get_spend_key().try_into().unwrap();
let bob_spend_key: SecretKey = bob_wallet.get_spend_key().try_into().unwrap();
let alice_proof = Proof::new(AnkHash::ValidationNo(validation_hash2), alice_spend_key);
let bob_proof = Proof::new(AnkHash::ValidationYes(validation_hash1), bob_spend_key);
let members_list = get_members_map([
alice_wallet.get_client().get_receiving_address(),
bob_wallet.get_client().get_receiving_address()
alice_wallet.get_receiving_address().to_string(),
bob_wallet.get_receiving_address().to_string()
]);
let members: Vec<&Member> = members_list.values().collect();
@ -667,11 +652,10 @@ mod tests {
let validation_hash_no = AnkValidationNoHash::from_merkle_root(new_state_merkle_root);
let alice_spend_key: SecretKey = alice_wallet
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let bob_spend_key: SecretKey = bob_wallet.get_client().get_spend_key().try_into().unwrap();
let bob_spend_key: SecretKey = bob_wallet.get_spend_key().try_into().unwrap();
let alice_proof = Proof::new(AnkHash::ValidationNo(validation_hash_no), alice_spend_key);
let bob_proof = Proof::new(AnkHash::ValidationYes(validation_hash_yes), bob_spend_key);
@ -679,8 +663,8 @@ mod tests {
let proofs = vec![alice_proof, bob_proof];
let members_list = get_members_map([
alice_wallet.get_client().get_receiving_address(),
bob_wallet.get_client().get_receiving_address()
alice_wallet.get_receiving_address().to_string(),
bob_wallet.get_receiving_address().to_string()
]);
let members: Vec<&Member> = members_list.values().collect();
@ -715,7 +699,6 @@ mod tests {
let validation_hash = AnkValidationYesHash::from_merkle_root(new_state_merkle_root);
let alice_spend_key: SecretKey = alice_wallet
.get_client()
.get_spend_key()
.try_into()
.unwrap();
@ -727,8 +710,8 @@ mod tests {
let proofs = vec![alice_proof_1, alice_proof_2];
let members_list = get_members_map([
alice_wallet.get_client().get_receiving_address(),
bob_wallet.get_client().get_receiving_address()
alice_wallet.get_receiving_address().to_string(),
bob_wallet.get_receiving_address().to_string()
]);
let members: Vec<&Member> = members_list.values().collect();
@ -758,7 +741,6 @@ mod tests {
let validation_hash = AnkValidationYesHash::from_merkle_root(new_state_merkle_root);
let alice_spend_key: SecretKey = alice_wallet
.get_client()
.get_spend_key()
.try_into()
.unwrap();
@ -770,8 +752,8 @@ mod tests {
let proofs = vec![alice_proof_1, alice_proof_2];
let members_list = get_members_map([
alice_wallet.get_client().get_receiving_address(),
bob_wallet.get_client().get_receiving_address()
alice_wallet.get_receiving_address().to_string(),
bob_wallet.get_receiving_address().to_string()
]);
let members: Vec<&Member> = members_list.values().collect();
@ -790,7 +772,7 @@ mod tests {
let alice_wallet = create_alice_wallet();
let member = Member::new(vec![SilentPaymentAddress::try_from(
alice_wallet.get_client().get_receiving_address(),
alice_wallet.get_receiving_address(),
)
.unwrap()]);
let clear_state_value = json!({"field1": "value1", "field2": "value2"});
@ -802,7 +784,6 @@ mod tests {
let new_state_merkle_root = commitments.create_merkle_tree().unwrap().root().unwrap();
let alice_spend_key: SecretKey = alice_wallet
.get_client()
.get_spend_key()
.try_into()
.unwrap();
@ -823,8 +804,8 @@ mod tests {
let bob_wallet = create_bob_wallet();
let members = get_members_map([
alice_wallet.get_client().get_receiving_address(),
bob_wallet.get_client().get_receiving_address(),
alice_wallet.get_receiving_address().to_string(),
bob_wallet.get_receiving_address().to_string(),
]);
let fields = vec!["field1".to_string(), "field2".to_string()];
let validation_rule1 = ValidationRule::new(1.0, vec![fields[0].clone()], 0.5).unwrap();
@ -853,11 +834,10 @@ mod tests {
let validation_hash = AnkValidationYesHash::from_merkle_root(new_state_merkle_root);
let alice_spend_key: SecretKey = alice_wallet
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let bob_spend_key: SecretKey = bob_wallet.get_client().get_spend_key().try_into().unwrap();
let bob_spend_key: SecretKey = bob_wallet.get_spend_key().try_into().unwrap();
let alice_proof = Proof::new(AnkHash::ValidationYes(validation_hash), alice_spend_key);
let bob_proof = Proof::new(AnkHash::ValidationYes(validation_hash), bob_spend_key);
@ -875,8 +855,8 @@ mod tests {
let bob_wallet = create_bob_wallet();
let members_list = get_members_map([
alice_wallet.get_client().get_receiving_address(),
bob_wallet.get_client().get_receiving_address()
alice_wallet.get_receiving_address().to_string(),
bob_wallet.get_receiving_address().to_string()
]);
let fields = vec!["field1".to_string(), "field2".to_string()];
@ -907,11 +887,10 @@ mod tests {
let validation_hash = AnkValidationNoHash::from_merkle_root(new_state_merkle_root);
let alice_spend_key: SecretKey = alice_wallet
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let bob_spend_key: SecretKey = bob_wallet.get_client().get_spend_key().try_into().unwrap();
let bob_spend_key: SecretKey = bob_wallet.get_spend_key().try_into().unwrap();
let alice_proof = Proof::new(AnkHash::ValidationNo(validation_hash), alice_spend_key);
let bob_proof = Proof::new(AnkHash::ValidationNo(validation_hash), bob_spend_key);
@ -929,8 +908,8 @@ mod tests {
let bob_wallet = create_bob_wallet();
let members = get_members_map([
alice_wallet.get_client().get_receiving_address(),
bob_wallet.get_client().get_receiving_address(),
alice_wallet.get_receiving_address().to_string(),
bob_wallet.get_receiving_address().to_string(),
]);
let fields = vec!["field1".to_string(), "field2".to_string()];
@ -961,11 +940,10 @@ mod tests {
// let validation_hash = AnkValidationNoHash::from_merkle_root(new_state_merkle_root);
let alice_spend_key: SecretKey = alice_wallet
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let bob_spend_key: SecretKey = bob_wallet.get_client().get_spend_key().try_into().unwrap();
let bob_spend_key: SecretKey = bob_wallet.get_spend_key().try_into().unwrap();
let alice_proof = Proof::new(AnkHash::ValidationYes(validation_hash), alice_spend_key);
let bob_proof = Proof::new(AnkHash::ValidationYes(validation_hash), bob_spend_key);
@ -983,8 +961,8 @@ mod tests {
let bob_wallet = create_bob_wallet();
let members = get_members_map([
alice_wallet.get_client().get_receiving_address(),
bob_wallet.get_client().get_receiving_address(),
alice_wallet.get_receiving_address().to_string(),
bob_wallet.get_receiving_address().to_string(),
]);
let fields = vec!["field1".to_string(), "field2".to_string()];
@ -1015,7 +993,6 @@ mod tests {
// let validation_hash = AnkValidationNoHash::from_merkle_root(new_state_merkle_root);
let alice_spend_key: SecretKey = alice_wallet
.get_client()
.get_spend_key()
.try_into()
.unwrap();

View File

@ -7,8 +7,8 @@ use serde_json::{Map, Value};
use sp_client::bitcoin::hashes::{sha256t_hash_newtype, Hash, HashEngine};
use sp_client::bitcoin::secp256k1::{PublicKey, SecretKey};
use sp_client::bitcoin::OutPoint;
use sp_client::silentpayments::utils::SilentPaymentAddress;
use sp_client::spclient::SpWallet;
use sp_client::silentpayments::SilentPaymentAddress;
use sp_client::SpClient;
use tsify::Tsify;
use crate::pcd::{Member, Pcd, PcdCommitments, Roles};
@ -198,8 +198,8 @@ impl Prd {
}
/// Generate the signed proof and serialize to send over the network
pub fn to_network_msg(&self, sp_wallet: &SpWallet) -> Result<String> {
let spend_sk: SecretKey = sp_wallet.get_client().get_spend_key().try_into()?;
pub fn to_network_msg(&self, sp_wallet: &SpClient) -> Result<String> {
let spend_sk: SecretKey = sp_wallet.get_spend_key().try_into()?;
let mut to_sign = self.clone(); // we sign the whole prd, incl the keys, for each recipient
let message_hash =

View File

@ -4,7 +4,7 @@ use std::{
use serde::{Deserialize, Serialize};
use serde_json::Value;
use sp_client::{bitcoin::{OutPoint, Transaction}, silentpayments::utils::SilentPaymentAddress};
use sp_client::{bitcoin::{OutPoint, Transaction}, silentpayments::SilentPaymentAddress};
use tsify::Tsify;
use crate::{
@ -561,7 +561,9 @@ mod tests {
use serde_json::json;
use sp_client::{
bitcoin::{secp256k1::SecretKey, Network, Txid}, silentpayments::utils::SilentPaymentAddress, spclient::{SpClient, SpWallet, SpendKey}
bitcoin::{secp256k1::SecretKey, Network, Txid},
silentpayments::SilentPaymentAddress,
SpClient, SpendKey
};
use crate::pcd::{Member, ValidationRule};
@ -572,10 +574,8 @@ mod tests {
const CAROL_PAIRING: &str = "a4f3d2d5ca7af258e6a2c1cfe85b85d4e3f3d1387417fd64012d3c7bfb95a9e9:0";
const DAVE_PAIRING: &str = "bd21f6acdd0e026e8c02298a51ec40dfaced34d95aec685f407ab5ac91b5f775:0";
fn create_alice_wallet() -> SpWallet {
SpWallet::new(
fn create_alice_wallet() -> SpClient {
SpClient::new(
"default".to_owned(),
SecretKey::from_str(
"a67fb6bf5639efd0aeb19c1c584dd658bceda87660ef1088d4a29d2e77846973",
)
@ -586,20 +586,13 @@ mod tests {
)
.unwrap(),
),
None,
Network::Signet,
)
.unwrap(),
None,
vec![],
)
.unwrap()
}
fn create_bob_wallet() -> SpWallet {
SpWallet::new(
fn create_bob_wallet() -> SpClient {
SpClient::new(
"default".to_owned(),
SecretKey::from_str(
"4d9f62b2340de3f0bafd671b78b19edcfded918c4106baefd34512f12f520e9b",
)
@ -610,20 +603,13 @@ mod tests {
)
.unwrap(),
),
None,
Network::Signet,
)
.unwrap(),
None,
vec![],
)
.unwrap()
}
fn create_carol_wallet() -> SpWallet {
SpWallet::new(
fn create_carol_wallet() -> SpClient {
SpClient::new(
"default".to_owned(),
SecretKey::from_str(
"e4a5906eaa1a7ab24d5fc8d9b600d47f79caa6511c056c111677b7a33e62c5e9",
)
@ -634,20 +620,13 @@ mod tests {
)
.unwrap(),
),
None,
Network::Signet,
)
.unwrap(),
None,
vec![],
)
.unwrap()
}
fn create_dave_wallet() -> SpWallet {
SpWallet::new(
fn create_dave_wallet() -> SpClient {
SpClient::new(
"default".to_owned(),
SecretKey::from_str(
"261d5f9ae4d2b0d8b17ed0c52bd2be7dbce14d9ac1f0f1d4904d3ca7df03766d",
)
@ -658,13 +637,8 @@ mod tests {
)
.unwrap(),
),
None,
Network::Signet,
)
.unwrap(),
None,
vec![],
)
.unwrap()
}
@ -675,16 +649,16 @@ mod tests {
let dave_wallet = create_dave_wallet();
let alice_address =
SilentPaymentAddress::try_from(alice_wallet.get_client().get_receiving_address())
SilentPaymentAddress::try_from(alice_wallet.get_receiving_address())
.unwrap();
let bob_address =
SilentPaymentAddress::try_from(bob_wallet.get_client().get_receiving_address())
SilentPaymentAddress::try_from(bob_wallet.get_receiving_address())
.unwrap();
let carol_address =
SilentPaymentAddress::try_from(carol_wallet.get_client().get_receiving_address())
SilentPaymentAddress::try_from(carol_wallet.get_receiving_address())
.unwrap();
let dave_address =
SilentPaymentAddress::try_from(dave_wallet.get_client().get_receiving_address())
SilentPaymentAddress::try_from(dave_wallet.get_receiving_address())
.unwrap();
let members_map: HashMap<OutPoint, Member> = HashMap::from([
@ -758,7 +732,7 @@ mod tests {
fn create_pairing_process_one() -> ProcessState {
let carol_wallet = create_carol_wallet();
let carol_address = carol_wallet.get_client().get_receiving_address();
let carol_address = carol_wallet.get_receiving_address();
let pairing_rule =
ValidationRule::new(1.0, vec![PAIREDADDRESSES.to_owned()], 1.0).unwrap();
let pairing_role_def = RoleDefinition {
@ -771,16 +745,16 @@ mod tests {
let private_data = BTreeMap::from([("description".to_owned(), Value::String("pairing".to_owned()))]);
let paired_addresses = Value::Array(vec![carol_address.try_into().unwrap()]);
let paired_addresses = Value::Array(vec![Value::String(carol_address.to_string())]);
ProcessState::new(outpoint, Pcd::new(private_data), Pcd::new(BTreeMap::from([(PAIREDADDRESSES.to_owned(), paired_addresses)])), Roles::new(BTreeMap::from([(PAIRING.to_owned(), pairing_role_def)]))).unwrap()
}
fn create_pairing_process_two() -> ProcessState {
let carol_wallet = create_carol_wallet();
let carol_address = carol_wallet.get_client().get_receiving_address();
let carol_address = carol_wallet.get_receiving_address();
let dave_wallet = create_dave_wallet();
let dave_address = dave_wallet.get_client().get_receiving_address();
let dave_address = dave_wallet.get_receiving_address();
let pairing_rule =
ValidationRule::new(1.0, vec![PAIREDADDRESSES.to_owned()], 1.0).unwrap();
let pairing_role_def = RoleDefinition {
@ -794,8 +768,8 @@ mod tests {
let private_data = BTreeMap::from([("description".to_owned(), Value::String("pairing".to_owned()))]);
let paired_addresses = Value::Array(vec![
carol_address.try_into().unwrap(),
dave_address.try_into().unwrap()
Value::String(carol_address.to_string()),
Value::String(dave_address.to_string())
]);
ProcessState::new(outpoint, Pcd::new(private_data), Pcd::new(BTreeMap::from([(PAIREDADDRESSES.to_owned(), paired_addresses)])), Roles::new(BTreeMap::from([(PAIRING.to_owned(), pairing_role_def)]))).unwrap()
@ -834,7 +808,6 @@ mod tests {
let mut state = dummy_process_state();
// We sign with Carol key
let carol_key: SecretKey = create_carol_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
@ -851,12 +824,10 @@ mod tests {
let mut state = dummy_process_state();
// We sign with Alice and Carol keys
let alice_key: SecretKey = create_alice_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let carol_key: SecretKey = create_carol_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
@ -871,7 +842,6 @@ mod tests {
fn test_valid_pairing() {
let mut pairing_first_state = create_pairing_process_one();
let carol_key: SecretKey = create_carol_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
@ -885,7 +855,6 @@ mod tests {
fn test_error_pairing_wrong_proof() {
let mut pairing_first_state = create_pairing_process_one();
let alice_key: SecretKey = create_alice_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
@ -915,14 +884,13 @@ mod tests {
);
// Add Dave address
let dave_address = create_dave_wallet().get_client().get_receiving_address();
paired_addresses.as_array_mut().unwrap().push(Value::String(dave_address));
let dave_address = create_dave_wallet().get_receiving_address();
paired_addresses.as_array_mut().unwrap().push(Value::String(dave_address.to_string()));
let roles = &pairing_process.get_latest_commited_state().unwrap().roles;
let mut add_device_state = ProcessState::new(new_commitment, Pcd::new(BTreeMap::new()), Pcd::new(BTreeMap::from([(PAIREDADDRESSES.to_owned(), paired_addresses)])), roles.clone()).unwrap();
let carol_key: SecretKey = create_carol_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
@ -953,10 +921,10 @@ mod tests {
);
// Remove Dave address
let dave_address = create_dave_wallet().get_client().get_receiving_address();
let dave_address = create_dave_wallet().get_receiving_address();
let paired_addresses = extract_paired_addresses(&paired_addresses).unwrap();
let filtered_paired_addresses = Value::from_iter(paired_addresses.into_iter().filter_map(|a| {
if a.to_string() != dave_address {
if a != dave_address {
Some(a.to_string())
} else {
None
@ -976,12 +944,10 @@ mod tests {
// We need both devices to agree to remove one
let carol_key: SecretKey = create_carol_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let dave_key: SecretKey = create_dave_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
@ -1014,14 +980,13 @@ mod tests {
);
// Add Dave address
let dave_address = create_dave_wallet().get_client().get_receiving_address();
paired_addresses.as_array_mut().unwrap().push(Value::String(dave_address));
let dave_address = create_dave_wallet().get_receiving_address();
paired_addresses.as_array_mut().unwrap().push(Value::String(dave_address.to_string()));
let roles = &pairing_process.get_latest_commited_state().unwrap().roles;
let mut add_device_state = ProcessState::new(new_commitment, Pcd::new(BTreeMap::new()), Pcd::new(BTreeMap::from([(PAIREDADDRESSES.to_owned(), paired_addresses)])), roles.clone()).unwrap();
let dave_key: SecretKey = create_dave_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
@ -1037,17 +1002,14 @@ mod tests {
fn test_valid_all_signatures() {
let mut state = dummy_process_state();
let alice_key: SecretKey = create_alice_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let bob_key: SecretKey = create_bob_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let carol_key: SecretKey = create_carol_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
@ -1077,7 +1039,6 @@ mod tests {
// Now we take the last empty state and try to invalidate it
let empty_state = process.get_state_for_id(&[0u8; 32]).unwrap();
let carol_key: SecretKey = create_carol_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
@ -1105,7 +1066,6 @@ mod tests {
// Now we take the last empty state and try to commit it to invalidate the whole process
let empty_state = process.get_state_for_id_mut(&[0u8; 32]).unwrap();
let dave_key: SecretKey = create_dave_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
@ -1120,17 +1080,14 @@ mod tests {
fn test_error_carol_votes_no() {
let mut state = dummy_process_state();
let alice_key: SecretKey = create_alice_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let bob_key: SecretKey = create_bob_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let carol_key: SecretKey = create_carol_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
@ -1149,17 +1106,14 @@ mod tests {
fn test_valid_bob_votes_no() {
let mut state = dummy_process_state();
let alice_key: SecretKey = create_alice_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let bob_key: SecretKey = create_bob_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let carol_key: SecretKey = create_carol_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
@ -1180,17 +1134,14 @@ mod tests {
let key_to_modify = state.pcd_commitment.keys().into_iter().next().unwrap();
new_state.update_value(key_to_modify.as_str(), &Value::String("new_value1".to_string())).unwrap();
let alice_key: SecretKey = create_alice_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let bob_key: SecretKey = create_bob_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
let carol_key: SecretKey = create_carol_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
@ -1210,7 +1161,6 @@ mod tests {
let key_to_modify = state.pcd_commitment.keys().into_iter().next().unwrap();
new_state.update_value(key_to_modify.as_str(), &Value::String("new_value1".to_string())).unwrap();
let carol_key: SecretKey = create_carol_wallet()
.get_client()
.get_spend_key()
.try_into()
.unwrap();
@ -1219,4 +1169,46 @@ mod tests {
let result = new_state.is_valid(Some(&state), &OutPointMemberMap(get_members_map()));
assert!(result.is_err());
}
#[test]
fn test_valid_add_someone_role() {
let mut state = dummy_process_state();
if let Some(role) = state.roles.get_mut(APOPHIS) {
role.members = vec![];
}
let mut process = Process::new(state.commited_in);
process.insert_concurrent_state(state).unwrap();
process.update_states_tip(
OutPoint::new(
Txid::from_str(
"cbeb4455f8d11848809bacd59bfd570243dbe7c4e9a340fa949aae3020fdb127"
).unwrap()
, 0
)
).unwrap();
// We now try to add dave into apophis role
let mut new_roles = process.get_latest_commited_state().unwrap().roles.clone();
if let Some(role) = new_roles.get_mut(APOPHIS) {
role.members = vec![OutPoint::from_str(DAVE_PAIRING).unwrap()];
}
let mut new_state = ProcessState::new(process.get_process_tip().unwrap(), Pcd::new(BTreeMap::new()), Pcd::new(BTreeMap::new()), new_roles).unwrap();
// Alice and Bob validate
let alice_key: SecretKey = create_alice_wallet()
.get_spend_key()
.try_into()
.unwrap();
let bob_key: SecretKey = create_bob_wallet()
.get_spend_key()
.try_into()
.unwrap();
let message_hash = new_state.get_message_hash(true).unwrap();
new_state.validation_tokens.push(Proof::new(message_hash, alice_key));
new_state.validation_tokens.push(Proof::new(message_hash, bob_key));
let result = new_state.is_valid(process.get_parent_state(&new_state.commited_in), &OutPointMemberMap(get_members_map()));
assert!(result.is_ok());
}
}

View File

@ -3,9 +3,8 @@ use tsify::Tsify;
use crate::aes_gcm::aead::{Aead, Payload};
use crate::aes_gcm::Nonce;
use crate::sp_client::bitcoin::hashes::Hash;
use crate::sp_client::silentpayments::utils::SilentPaymentAddress;
use crate::sp_client::silentpayments::SilentPaymentAddress;
use crate::crypto::{Aes256Gcm, AnkSharedSecretHash, KeyInit, AAD};
use crate::log;
use serde::ser::SerializeStruct;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::collections::HashMap;

View File

@ -1,31 +1,20 @@
use std::collections::{HashMap, HashSet};
use std::str::FromStr;
use anyhow::{Error, Result};
use rand::{thread_rng, Rng};
use sp_client::bitcoin::consensus::deserialize;
use sp_client::bitcoin::psbt::raw;
use sp_client::bitcoin::{Amount, OutPoint, Psbt};
use sp_client::constants::{
self, DUST_THRESHOLD, PSBT_SP_ADDRESS_KEY, PSBT_SP_PREFIX, PSBT_SP_SUBTYPE,
};
use sp_client::silentpayments::utils::SilentPaymentAddress;
use sp_client::spclient::{OwnedOutput, Recipient, SpClient, SpWallet};
use sp_client::bitcoin::{Amount, OutPoint, Transaction};
use sp_client::{OwnedOutput, Recipient, SilentPaymentUnsignedTransaction, SpClient};
pub fn create_transaction(
mandatory_inputs: Vec<OutPoint>,
mut available_outpoints: HashMap<OutPoint, OwnedOutput>,
freezed_utxos: &HashSet<OutPoint>,
sp_wallet: &SpWallet,
sp_client: &SpClient,
mut recipients: Vec<Recipient>,
payload: Option<Vec<u8>>,
fee_rate: Amount,
fee_payer: Option<String>, // None means sender pays everything
) -> Result<Psbt> {
let mut available_outpoints: HashMap<OutPoint, OwnedOutput> = sp_wallet
.get_outputs()
.to_spendable_list();
) -> Result<SilentPaymentUnsignedTransaction> {
let sum_outputs = recipients
.iter()
.fold(Amount::from_sat(0), |acc, x| acc + x.amount);
@ -46,13 +35,13 @@ pub fn create_transaction(
let fee_provision = Amount::from_sat(1000);
for (outpoint, output) in available_outpoints {
if freezed_utxos.contains(&outpoint) { continue }
for (outpoint, output) in &available_outpoints {
if freezed_utxos.contains(outpoint) { continue }
if total_available > sum_outputs.checked_add(fee_provision).unwrap() {
break;
}
total_available += output.amount;
inputs.insert(outpoint, output);
inputs.insert(*outpoint, output.clone());
}
if total_available <= sum_outputs.checked_add(fee_provision).unwrap() {
@ -71,91 +60,22 @@ pub fn create_transaction(
thread_rng().fill(&mut commitment);
}
let mut new_psbt =
sp_wallet
.get_client()
.create_new_psbt(inputs, recipients, Some(&commitment))?;
let new_transaction = sp_client.create_new_transaction(
available_outpoints.into_iter().collect(),
recipients,
fee_rate.to_btc() as f32,
sp_client.get_network()
)?;
let sender_address = sp_wallet.get_client().get_receiving_address();
let change_address = sp_wallet.get_client().sp_receiver.get_change_address();
if let Some(address) = fee_payer {
SpClient::set_fees(&mut new_psbt, fee_rate, address)?;
} else {
let candidates: Vec<Option<String>> = new_psbt
.outputs
.iter()
.map(|o| {
if let Some(value) = o.proprietary.get(&raw::ProprietaryKey {
prefix: PSBT_SP_PREFIX.as_bytes().to_vec(),
subtype: PSBT_SP_SUBTYPE,
key: PSBT_SP_ADDRESS_KEY.as_bytes().to_vec(),
}) {
let candidate: String =
SilentPaymentAddress::try_from(deserialize::<String>(value).unwrap())
.unwrap()
.into();
return Some(candidate);
} else {
return None;
let finalized_transaction = SpClient::finalize_transaction(new_transaction)?;
Ok(finalized_transaction)
}
})
.collect();
let fee_set = candidates.iter().filter_map(|candidate_opt| {
candidate_opt.as_ref().and_then(|c| {
if *c == change_address {
Some(SpClient::set_fees(&mut new_psbt, fee_rate, change_address.clone()))
} else if *c == sender_address {
Some(SpClient::set_fees(&mut new_psbt, fee_rate, sender_address.clone()))
} else {
None
}
})
}).find_map(|result| result.ok());
if fee_set.is_none() {
return Err(Error::msg("Must specify payer for fee"));
}
};
let partial_secret = sp_wallet
.get_client()
.get_partial_secret_from_psbt(&new_psbt)?;
sp_wallet
.get_client()
.fill_sp_outputs(&mut new_psbt, partial_secret)?;
pub fn sign_transaction(sp_client: &SpClient, unsigned_transaction: SilentPaymentUnsignedTransaction) -> Result<Transaction> {
let mut aux_rand = [0u8; 32];
thread_rng().fill(&mut aux_rand);
let mut signed = sp_wallet.get_client().sign_psbt(new_psbt, &aux_rand)?;
SpClient::finalize_psbt(&mut signed)?;
Ok(signed)
}
pub fn map_outputs_to_sp_address(psbt_str: &str) -> Result<HashMap<String, Vec<usize>>> {
let psbt = Psbt::from_str(&psbt_str)?;
let mut res: HashMap<String, Vec<usize>> = HashMap::new();
for (i, output) in psbt.outputs.iter().enumerate() {
if let Some(value) = output.proprietary.get(&raw::ProprietaryKey {
prefix: constants::PSBT_SP_PREFIX.as_bytes().to_vec(),
subtype: constants::PSBT_SP_SUBTYPE,
key: constants::PSBT_SP_ADDRESS_KEY.as_bytes().to_vec(),
}) {
let sp_address = SilentPaymentAddress::try_from(deserialize::<String>(value)?)?;
if let Some(vouts) = res.get_mut::<String>(&sp_address.into()) {
vouts.push(i);
} else {
res.insert(sp_address.into(), vec![i]);
}
} else {
// Not a sp output
continue;
}
}
Ok(res)
sp_client.sign_transaction(unsigned_transaction, &aux_rand)
}
// #[cfg(test)]
@ -215,8 +135,8 @@ pub fn map_outputs_to_sp_address(psbt_str: &str) -> Result<HashMap<String, Vec<u
// amount: Amount::from_sat(1200),
// nb_outputs: 1,
// };
// let mut alice_wallet: SpWallet = serde_json::from_str(ALICE_WALLET).unwrap();
// let mut bob_wallet: SpWallet = serde_json::from_str(BOB_WALLET).unwrap();
// let mut alice_wallet: SpClient = serde_json::from_str(ALICE_WALLET).unwrap();
// let mut bob_wallet: SpClient = serde_json::from_str(BOB_WALLET).unwrap();
// let pcd = Pcd::new(Value::String("TEST".to_owned()));
// let pcd_hash = helper_create_commitment(pcd.to_string());
// let mut key = [0u8; 32];
@ -297,8 +217,8 @@ pub fn map_outputs_to_sp_address(psbt_str: &str) -> Result<HashMap<String, Vec<u
// #[test]
// fn it_creates_confirmation_transaction() {
// let mut alice_wallet: SpWallet = serde_json::from_str(ALICE_WALLET_CONFIRMATION).unwrap();
// let mut bob_wallet: SpWallet = serde_json::from_str(BOB_WALLET_CONFIRMATION).unwrap();
// let mut alice_wallet: SpClient = serde_json::from_str(ALICE_WALLET_CONFIRMATION).unwrap();
// let mut bob_wallet: SpClient = serde_json::from_str(BOB_WALLET_CONFIRMATION).unwrap();
// // Bob must spend notification output
// let (confirmation_outpoint, _) = bob_wallet
@ -352,8 +272,8 @@ pub fn map_outputs_to_sp_address(psbt_str: &str) -> Result<HashMap<String, Vec<u
// #[test]
// fn it_creates_answer_transaction() {
// let mut alice_wallet: SpWallet = serde_json::from_str(ALICE_WALLET_ANSWER).unwrap();
// let mut bob_wallet: SpWallet = serde_json::from_str(BOB_WALLET_ANSWER).unwrap();
// let mut alice_wallet: SpClient = serde_json::from_str(ALICE_WALLET_ANSWER).unwrap();
// let mut bob_wallet: SpClient = serde_json::from_str(BOB_WALLET_ANSWER).unwrap();
// // Bob must spend notification output
// let (confirmation_outpoint, _) = alice_wallet