Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(p2pk): show P2PK balance #2053

Merged
merged 33 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
50b4aad
fix copyright format
mariocynicys Feb 8, 2024
ce267a9
account for p2pk balances
mariocynicys Feb 8, 2024
d605dd5
Move `prev_script` into UTXOs
mariocynicys Feb 12, 2024
b70393c
fix docker tests
mariocynicys Feb 19, 2024
9ccc118
fix lint issues (unused vars)
mariocynicys Feb 19, 2024
0086b41
allow spending p2pk balance
mariocynicys Feb 20, 2024
926bc46
Refactor with_key_pair.rs to not use indices and use `&UnsignedTransa…
mariocynicys Feb 20, 2024
0df81c4
Revert "Refactor with_key_pair.rs to not use indices and use `&Unsign…
mariocynicys Feb 20, 2024
f7bf4bc
onur's suggestions 1
mariocynicys Feb 20, 2024
8f9d8d8
Never use `script: None` for `UtxoInfo`
mariocynicys Feb 20, 2024
2fa56fe
Convert `Option<Script>` -> `Script` in `UtxoInfo`
mariocynicys Feb 20, 2024
f788b50
get rid of `CachedUnspentInfo::script`
mariocynicys Feb 20, 2024
1f61269
clean up + notes
mariocynicys Feb 21, 2024
f11e0ed
add some tests
mariocynicys Feb 21, 2024
f07e720
use `Public` instead of `&Public`
mariocynicys Feb 26, 2024
8ecc4c7
remove benign discuss comments
mariocynicys Apr 8, 2024
92e3b90
add a note about p2pk spending test for later
mariocynicys Apr 8, 2024
8584428
remove over cautios discuss/fixme comments
mariocynicys Apr 8, 2024
f688395
format
mariocynicys Apr 9, 2024
aaa5517
use a pkh only address for HD wallet withdraw
mariocynicys Apr 9, 2024
d9da6da
fix formatting issue
mariocynicys Apr 9, 2024
7152910
add test for filtering p2pk cached recently spent outputs
mariocynicys Apr 9, 2024
5bee32a
suggestions from dimxy: remove witness field in UnsignedTransactionIn…
mariocynicys Apr 9, 2024
eceaa5d
merge with origin/dev
mariocynicys Apr 16, 2024
2ec84c4
merge with origin/dev
mariocynicys May 7, 2024
a76d587
patch/set `prev_script` as well in `build_uncheck`
mariocynicys May 7, 2024
a86b8a9
fix sign raw p2wpkh - different error is now emitted
mariocynicys May 7, 2024
f019f82
merge with origin/dev
mariocynicys May 7, 2024
c7a2cee
check for fee completeness before adding any input
mariocynicys May 8, 2024
11406e1
suggestions from omar: don't write a lot of json, use test helpers
mariocynicys May 8, 2024
fb1df6a
fix missing import in tests
mariocynicys May 8, 2024
644b2ec
refactor mm2_tests_inner
mariocynicys May 10, 2024
8679526
merge with origin/dev + fix failing tests
mariocynicys May 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions mm2src/coins/lightning/ln_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use super::*;
use crate::lightning::ln_db::{DBChannelDetails, HTLCStatus, LightningDB, PaymentType};
use crate::lightning::ln_errors::{SaveChannelClosingError, SaveChannelClosingResult};
use crate::lightning::ln_sql::SqliteLightningDB;
use crate::utxo::UtxoCommonOps;
use bitcoin::blockdata::script::Script;
use bitcoin::blockdata::transaction::Transaction;
use bitcoin::consensus::encode::serialize_hex;
Expand Down Expand Up @@ -209,25 +208,15 @@ async fn sign_funding_transaction(
};
unsigned.outputs[0].script_pubkey = output_script_pubkey.to_bytes().into();

let my_address = coin
.as_ref()
.derivation_method
.single_addr_or_err()
.await
.map_err(|e| SignFundingTransactionError::Internal(e.to_string()))?;
let key_pair = coin
.as_ref()
.priv_key_policy
.activated_key_or_err()
.map_err(|e| SignFundingTransactionError::Internal(e.to_string()))?;

let prev_script = coin
.script_for_address(&my_address)
.map_err(|e| SignFundingTransactionError::Internal(e.to_string()))?;
let signed = sign_tx(
unsigned,
key_pair,
prev_script,
SignatureVersion::WitnessV0,
coin.as_ref().conf.fork_id,
)
Expand Down
2 changes: 1 addition & 1 deletion mm2src/coins/lp_coins.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2023 Pampex LTD and TillyHK LTD *
* Copyright © 2023 Pampex LTD and TillyHK LTD *
* *
* See the CONTRIBUTOR-LICENSE-AGREEMENT, COPYING, LICENSE-COPYRIGHT-NOTICE *
* and DEVELOPER-CERTIFICATE-OF-ORIGIN files in the LEGAL directory in *
Expand Down
5 changes: 0 additions & 5 deletions mm2src/coins/qrc20.rs
Original file line number Diff line number Diff line change
Expand Up @@ -539,16 +539,11 @@ impl Qrc20Coin {
.build()
.await?;

let my_address = self.utxo.derivation_method.single_addr_or_err().await?;
let key_pair = self.utxo.priv_key_policy.activated_key_or_err()?;

let prev_script = self
.script_for_address(&my_address)
.map_err(|e| Qrc20GenTxError::InvalidAddress(e.to_string()))?;
let signed = sign_tx(
unsigned,
key_pair,
prev_script,
self.utxo.conf.signature_version,
self.utxo.conf.fork_id,
)?;
Expand Down
26 changes: 15 additions & 11 deletions mm2src/coins/qrc20/qrc20_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,15 @@ fn test_withdraw_to_p2sh_address_should_fail() {

let p2sh_address = AddressBuilder::new(
UtxoAddressFormat::Standard,
block_on(coin.as_ref().derivation_method.unwrap_single_addr())
.hash()
.clone(),
*block_on(coin.as_ref().derivation_method.unwrap_single_addr()).checksum_type(),
coin.as_ref().conf.address_prefixes.clone(),
coin.as_ref().conf.bech32_hrp.clone(),
)
.as_sh()
.as_sh(
block_on(coin.as_ref().derivation_method.unwrap_single_addr())
.hash()
.clone(),
)
.build()
.expect("valid address props");

Expand All @@ -102,6 +103,13 @@ fn test_withdraw_to_p2sh_address_should_fail() {
#[cfg(not(target_arch = "wasm32"))]
#[test]
fn test_withdraw_impl_fee_details() {
// priv_key of qXxsj5RtciAby9T7m98AgAATL4zTi4UwDG
let priv_key = [
3, 98, 177, 3, 108, 39, 234, 144, 131, 178, 103, 103, 127, 80, 230, 166, 53, 68, 147, 215, 42, 216, 144, 72,
172, 110, 180, 13, 123, 179, 10, 49,
];
let (_ctx, coin) = qrc20_coin_for_test(priv_key, None);

Qrc20Coin::get_unspent_ordered_list.mock_safe(|coin, _| {
let cache = block_on(coin.as_ref().recently_spent_outpoints.lock());
let unspents = vec![UnspentInfo {
Expand All @@ -111,17 +119,13 @@ fn test_withdraw_impl_fee_details() {
},
value: 1000000000,
height: Default::default(),
script: coin
.script_for_address(&block_on(coin.as_ref().derivation_method.unwrap_single_addr()))
.unwrap(),
}];
MockResult::Return(Box::pin(futures::future::ok((unspents, cache))))
});

// priv_key of qXxsj5RtciAby9T7m98AgAATL4zTi4UwDG
let priv_key = [
3, 98, 177, 3, 108, 39, 234, 144, 131, 178, 103, 103, 127, 80, 230, 166, 53, 68, 147, 215, 42, 216, 144, 72,
172, 110, 180, 13, 123, 179, 10, 49,
];
let (_ctx, coin) = qrc20_coin_for_test(priv_key, None);

let withdraw_req = WithdrawRequest {
amount: 10.into(),
from: None,
Expand Down
67 changes: 33 additions & 34 deletions mm2src/coins/utxo.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2023 Pampex LTD and TillyHK LTD *
* Copyright © 2023 Pampex LTD and TillyHK LTD *
* *
* See the CONTRIBUTOR-LICENSE-AGREEMENT, COPYING, LICENSE-COPYRIGHT-NOTICE *
* and DEVELOPER-CERTIFICATE-OF-ORIGIN files in the LEGAL directory in *
Expand Down Expand Up @@ -309,21 +309,20 @@ pub struct CachedUnspentInfo {
pub value: u64,
}

impl From<UnspentInfo> for CachedUnspentInfo {
fn from(unspent: UnspentInfo) -> CachedUnspentInfo {
impl CachedUnspentInfo {
fn from_unspent_info(unspent: &UnspentInfo) -> CachedUnspentInfo {
CachedUnspentInfo {
outpoint: unspent.outpoint,
value: unspent.value,
}
}
}

impl From<CachedUnspentInfo> for UnspentInfo {
fn from(cached: CachedUnspentInfo) -> UnspentInfo {
fn to_unspent_info(&self, script: Script) -> UnspentInfo {
UnspentInfo {
outpoint: cached.outpoint,
value: cached.value,
outpoint: self.outpoint,
value: self.value,
height: None,
script,
}
}
}
Expand All @@ -350,22 +349,17 @@ impl RecentlySpentOutPoints {
}

pub fn add_spent(&mut self, inputs: Vec<UnspentInfo>, spend_tx_hash: H256, outputs: Vec<TransactionOutput>) {
let inputs: HashSet<_> = inputs.into_iter().map(From::from).collect();
let inputs: HashSet<_> = inputs.iter().map(CachedUnspentInfo::from_unspent_info).collect();
let to_replace: HashSet<_> = outputs
.iter()
.into_iter()
.enumerate()
.filter_map(|(index, output)| {
if output.script_pubkey == self.for_script_pubkey {
Some(CachedUnspentInfo {
outpoint: OutPoint {
hash: spend_tx_hash,
index: index as u32,
},
value: output.value,
})
} else {
None
}
.filter(|(_, output)| output.script_pubkey == self.for_script_pubkey)
.map(|(index, output)| CachedUnspentInfo {
outpoint: OutPoint {
hash: spend_tx_hash,
index: index as u32,
},
value: output.value,
})
.collect();

Expand Down Expand Up @@ -400,13 +394,14 @@ impl RecentlySpentOutPoints {
pub fn replace_spent_outputs_with_cache(&self, mut outputs: HashSet<UnspentInfo>) -> HashSet<UnspentInfo> {
let mut replacement_unspents = HashSet::new();
outputs.retain(|unspent| {
let outs = self.input_to_output_map.get(&unspent.clone().into());
let outs = self
.input_to_output_map
.get(&CachedUnspentInfo::from_unspent_info(unspent));

match outs {
Some(outs) => {
for out in outs.iter() {
if !replacement_unspents.contains(out) {
replacement_unspents.insert(out.clone());
}
for out in outs {
replacement_unspents.insert(out.clone());
}
false
},
Expand All @@ -416,7 +411,11 @@ impl RecentlySpentOutPoints {
if replacement_unspents.is_empty() {
return outputs;
}
outputs.extend(replacement_unspents.into_iter().map(From::from));
outputs.extend(
replacement_unspents
.iter()
.map(|cached| cached.to_unspent_info(self.for_script_pubkey.clone().into())),
);
self.replace_spent_outputs_with_cache(outputs)
}
}
Expand Down Expand Up @@ -1795,6 +1794,7 @@ where
outpoint: input.previous_output,
value: input.amount,
height: None,
script: input.prev_script.clone(),
})
.collect();

Expand All @@ -1803,12 +1803,9 @@ where
_ => coin.as_ref().conf.signature_version,
};

let prev_script = utxo_common::output_script_checked(coin.as_ref(), &my_address)
.map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))?;
let signed = try_tx_s!(sign_tx(
unsigned,
key_pair,
prev_script,
signature_version,
coin.as_ref().conf.fork_id
));
Expand All @@ -1830,6 +1827,9 @@ pub fn output_script(address: &Address) -> Result<Script, keys::Error> {
}
}

/// Builds transaction output script for a legacy P2PK address
pub fn output_script_p2pk(pubkey: &Public) -> Script { Builder::build_p2pk(pubkey) }

pub fn address_by_conf_and_pubkey_str(
coin: &str,
conf: &Json,
Expand All @@ -1854,16 +1854,15 @@ pub fn address_by_conf_and_pubkey_str(
let conf_builder = UtxoConfBuilder::new(conf, &params, coin);
let utxo_conf = try_s!(conf_builder.build());
let pubkey_bytes = try_s!(hex::decode(pubkey));
let hash = dhash160(&pubkey_bytes);
let pubkey = try_s!(Public::from_slice(&pubkey_bytes));

let address = AddressBuilder::new(
addr_format,
hash.into(),
utxo_conf.checksum_type,
utxo_conf.address_prefixes,
utxo_conf.bech32_hrp,
)
.as_pkh()
.as_pkh_from_pk(pubkey)
.build()?;
address.display_address()
}
Expand Down
9 changes: 9 additions & 0 deletions mm2src/coins/utxo/bchd_grpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ mod bchd_grpc_tests {
},
value: 0,
height: None,
script: Vec::new().into(),
},
slp_amount: 1000,
},
Expand All @@ -271,6 +272,7 @@ mod bchd_grpc_tests {
},
value: 0,
height: None,
script: Vec::new().into(),
},
slp_amount: 8999,
},
Expand All @@ -294,6 +296,7 @@ mod bchd_grpc_tests {
},
value: 0,
height: None,
script: Vec::new().into(),
},
slp_amount: 1000,
},
Expand All @@ -305,6 +308,7 @@ mod bchd_grpc_tests {
},
value: 0,
height: None,
script: Vec::new().into(),
},
slp_amount: 8999,
},
Expand All @@ -316,6 +320,7 @@ mod bchd_grpc_tests {
},
value: 0,
height: None,
script: Vec::new().into(),
},
slp_amount: 8999,
},
Expand All @@ -341,6 +346,7 @@ mod bchd_grpc_tests {
},
value: 0,
height: None,
script: Vec::new().into(),
},
slp_amount: 999,
};
Expand All @@ -353,6 +359,7 @@ mod bchd_grpc_tests {
},
value: 0,
height: None,
script: Vec::new().into(),
},
slp_amount: 8999,
}];
Expand Down Expand Up @@ -386,6 +393,7 @@ mod bchd_grpc_tests {
},
value: 0,
height: None,
script: Vec::new().into(),
},
slp_amount: 1000,
},
Expand All @@ -397,6 +405,7 @@ mod bchd_grpc_tests {
},
value: 0,
height: None,
script: Vec::new().into(),
},
slp_amount: 8999,
},
Expand Down
17 changes: 1 addition & 16 deletions mm2src/coins/utxo/qtum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,11 @@ pub trait QtumBasedCoin: UtxoCommonOps + MarketCoinOps {
let utxo = self.as_ref();
AddressBuilder::new(
self.addr_format().clone(),
AddressHashEnum::AddressHash(address.0.into()),
utxo.conf.checksum_type,
utxo.conf.address_prefixes.clone(),
utxo.conf.bech32_hrp.clone(),
)
.as_pkh()
.as_pkh(AddressHashEnum::AddressHash(address.0.into()))
.build()
.expect("valid address props")
}
Expand All @@ -161,20 +160,6 @@ pub trait QtumBasedCoin: UtxoCommonOps + MarketCoinOps {
contract_addr_from_utxo_addr(my_address).mm_err(Qrc20AddressError::from)
}

fn utxo_address_from_contract_addr(&self, address: H160) -> Address {
let utxo = self.as_ref();
AddressBuilder::new(
self.addr_format().clone(),
AddressHashEnum::AddressHash(address.0.into()),
utxo.conf.checksum_type,
utxo.conf.address_prefixes.clone(),
utxo.conf.bech32_hrp.clone(),
)
.as_pkh()
.build()
.expect("valid address props")
}

fn contract_address_from_raw_pubkey(&self, pubkey: &[u8]) -> Result<H160, String> {
let utxo = self.as_ref();
let qtum_address = try_s!(utxo_common::address_from_raw_pubkey(
Expand Down
13 changes: 2 additions & 11 deletions mm2src/coins/utxo/qtum_delegation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ impl QtumCoin {
.map(|padded_staker_address_hex| padded_staker_address_hex.trim_start_matches('0'))
}) {
let hash = H160::from_str(raw).map_to_mm(|e| StakingInfosError::Internal(e.to_string()))?;
let address = self.utxo_address_from_contract_addr(hash);
let address = self.utxo_addr_from_contract_addr(hash);
Ok(Some(address.to_string()))
} else {
Ok(None)
Expand Down Expand Up @@ -290,16 +290,7 @@ impl QtumCoin {
DelegationError::from_generate_tx_error(gen_tx_error, self.ticker().to_string(), utxo.decimals)
})?;

let prev_script = self
.script_for_address(&my_address)
.map_err(|e| DelegationError::InternalError(e.to_string()))?;
let signed = sign_tx(
unsigned,
key_pair,
prev_script,
utxo.conf.signature_version,
utxo.conf.fork_id,
)?;
let signed = sign_tx(unsigned, key_pair, utxo.conf.signature_version, utxo.conf.fork_id)?;

let miner_fee = data.fee_amount + data.unused_change;
let generated_tx = GenerateQrc20TxResult {
Expand Down
Loading
Loading