mirror of
https://github.com/serai-dex/serai.git
synced 2024-12-22 19:49:22 +00:00
3.10 Remove use of Network::Bitcoin
All uses were safe due to addresses being converted to script_pubkeys which don't embed their network. The only risk of there being an issue is if a future address spec did embed the net ID into the script_pubkey and that was moved to. This resolves the audit note and does offer that tightening.
This commit is contained in:
parent
6f9d02fdf8
commit
f66fe3c1cb
4 changed files with 28 additions and 22 deletions
|
@ -15,7 +15,8 @@ use frost::{
|
|||
use bitcoin::{
|
||||
consensus::encode::{Decodable, serialize},
|
||||
key::TweakedPublicKey,
|
||||
OutPoint, ScriptBuf, TxOut, Transaction, Block, Network, Address,
|
||||
address::Payload,
|
||||
OutPoint, ScriptBuf, TxOut, Transaction, Block,
|
||||
};
|
||||
|
||||
use crate::crypto::{x_only, make_even};
|
||||
|
@ -32,15 +33,15 @@ pub fn tweak_keys(keys: &ThresholdKeys<Secp256k1>) -> ThresholdKeys<Secp256k1> {
|
|||
keys.offset(Scalar::from(offset))
|
||||
}
|
||||
|
||||
/// Return the Taproot address for a public key.
|
||||
/// Return the Taproot address payload for a public key.
|
||||
///
|
||||
/// If the key is odd, this will return None.
|
||||
pub fn address(network: Network, key: ProjectivePoint) -> Option<Address> {
|
||||
pub fn address_payload(key: ProjectivePoint) -> Option<Payload> {
|
||||
if key.to_encoded_point(true).tag() != Tag::CompressedEvenY {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(Address::p2tr_tweaked(TweakedPublicKey::dangerous_assume_tweaked(x_only(&key)), network))
|
||||
Some(Payload::p2tr_tweaked(TweakedPublicKey::dangerous_assume_tweaked(x_only(&key))))
|
||||
}
|
||||
|
||||
/// A spendable output.
|
||||
|
@ -109,8 +110,7 @@ impl Scanner {
|
|||
/// Returns None if this key can't be scanned for.
|
||||
pub fn new(key: ProjectivePoint) -> Option<Scanner> {
|
||||
let mut scripts = HashMap::new();
|
||||
// Uses Network::Bitcoin since network is irrelevant here
|
||||
scripts.insert(address(Network::Bitcoin, key)?.script_pubkey(), Scalar::ZERO);
|
||||
scripts.insert(address_payload(key)?.script_pubkey(), Scalar::ZERO);
|
||||
Some(Scanner { key, scripts })
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ impl Scanner {
|
|||
// chance of being even
|
||||
// That means this should terminate within a very small amount of iterations
|
||||
loop {
|
||||
match address(Network::Bitcoin, self.key + (ProjectivePoint::GENERATOR * offset)) {
|
||||
match address_payload(self.key + (ProjectivePoint::GENERATOR * offset)) {
|
||||
Some(address) => {
|
||||
let script = address.script_pubkey();
|
||||
if self.scripts.contains_key(&script) {
|
||||
|
|
|
@ -16,12 +16,12 @@ use bitcoin::{
|
|||
sighash::{TapSighashType, SighashCache, Prevouts},
|
||||
absolute::LockTime,
|
||||
script::{PushBytesBuf, ScriptBuf},
|
||||
OutPoint, Sequence, Witness, TxIn, TxOut, Transaction, Network, Address,
|
||||
OutPoint, Sequence, Witness, TxIn, TxOut, Transaction, Address,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
crypto::Schnorr,
|
||||
wallet::{address, ReceivedOutput},
|
||||
wallet::{ReceivedOutput, address_payload},
|
||||
};
|
||||
|
||||
#[rustfmt::skip]
|
||||
|
@ -226,9 +226,7 @@ impl SignableTransaction {
|
|||
transcript.append_message(b"signing_input", u32::try_from(i).unwrap().to_le_bytes());
|
||||
|
||||
let offset = keys.clone().offset(self.offsets[i]);
|
||||
if address(Network::Bitcoin, offset.group_key())?.script_pubkey() !=
|
||||
self.prevouts[i].script_pubkey
|
||||
{
|
||||
if address_payload(offset.group_key())?.script_pubkey() != self.prevouts[i].script_pubkey {
|
||||
None?;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,9 +22,12 @@ use bitcoin_serai::{
|
|||
hashes::Hash as HashTrait,
|
||||
blockdata::opcodes::all::OP_RETURN,
|
||||
script::{PushBytesBuf, Instruction, Instructions, Script},
|
||||
address::NetworkChecked,
|
||||
OutPoint, TxOut, Transaction, Network, Address,
|
||||
},
|
||||
wallet::{tweak_keys, address, ReceivedOutput, Scanner, TransactionError, SignableTransaction},
|
||||
wallet::{
|
||||
tweak_keys, address_payload, ReceivedOutput, Scanner, TransactionError, SignableTransaction,
|
||||
},
|
||||
rpc::Rpc,
|
||||
};
|
||||
|
||||
|
@ -43,7 +46,10 @@ async fn send_and_get_output(rpc: &Rpc, scanner: &Scanner, key: ProjectivePoint)
|
|||
rpc
|
||||
.rpc_call::<Vec<String>>(
|
||||
"generatetoaddress",
|
||||
serde_json::json!([1, address(Network::Regtest, key).unwrap()]),
|
||||
serde_json::json!([
|
||||
1,
|
||||
Address::<NetworkChecked>::new(Network::Regtest, address_payload(key).unwrap())
|
||||
]),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -187,7 +193,7 @@ async_sequential! {
|
|||
assert_eq!(output.offset(), Scalar::ZERO);
|
||||
|
||||
let inputs = vec![output];
|
||||
let addr = || address(Network::Regtest, key).unwrap();
|
||||
let addr = || Address::<NetworkChecked>::new(Network::Regtest, address_payload(key).unwrap());
|
||||
let payments = vec![(addr(), 1000)];
|
||||
|
||||
assert!(SignableTransaction::new(inputs.clone(), &payments, None, None, FEE).is_ok());
|
||||
|
@ -250,13 +256,14 @@ async_sequential! {
|
|||
|
||||
// Declare payments, change, fee
|
||||
let payments = [
|
||||
(address(Network::Regtest, key).unwrap(), 1005),
|
||||
(address(Network::Regtest, offset_key).unwrap(), 1007)
|
||||
(Address::<NetworkChecked>::new(Network::Regtest, address_payload(key).unwrap()), 1005),
|
||||
(Address::<NetworkChecked>::new(Network::Regtest, address_payload(offset_key).unwrap()), 1007)
|
||||
];
|
||||
|
||||
let change_offset = scanner.register_offset(Scalar::random(&mut OsRng)).unwrap();
|
||||
let change_key = key + (ProjectivePoint::GENERATOR * change_offset);
|
||||
let change_addr = address(Network::Regtest, change_key).unwrap();
|
||||
let change_addr =
|
||||
Address::<NetworkChecked>::new(Network::Regtest, address_payload(change_key).unwrap());
|
||||
|
||||
// Create and sign the TX
|
||||
let tx = SignableTransaction::new(
|
||||
|
@ -327,7 +334,7 @@ async_sequential! {
|
|||
SignableTransaction::new(
|
||||
vec![output],
|
||||
&[],
|
||||
address(Network::Regtest, key),
|
||||
Some(Address::<NetworkChecked>::new(Network::Regtest, address_payload(key).unwrap())),
|
||||
Some(data.clone()),
|
||||
FEE
|
||||
).unwrap()
|
||||
|
|
|
@ -17,10 +17,11 @@ use bitcoin_serai::{
|
|||
hashes::Hash as HashTrait,
|
||||
consensus::{Encodable, Decodable},
|
||||
script::Instruction,
|
||||
address::{NetworkChecked, Address as BAddress},
|
||||
OutPoint, Transaction, Block, Network,
|
||||
},
|
||||
wallet::{
|
||||
tweak_keys, address, ReceivedOutput, Scanner, TransactionError,
|
||||
tweak_keys, address_payload, ReceivedOutput, Scanner, TransactionError,
|
||||
SignableTransaction as BSignableTransaction, TransactionMachine,
|
||||
},
|
||||
rpc::{RpcError, Rpc},
|
||||
|
@ -33,7 +34,7 @@ use bitcoin_serai::bitcoin::{
|
|||
sighash::{EcdsaSighashType, SighashCache},
|
||||
script::{PushBytesBuf, Builder},
|
||||
absolute::LockTime,
|
||||
Sequence, Script, Witness, TxIn, TxOut, Address as BAddress,
|
||||
Sequence, Script, Witness, TxIn, TxOut,
|
||||
};
|
||||
|
||||
use serai_client::{
|
||||
|
@ -326,7 +327,7 @@ impl Coin for Bitcoin {
|
|||
}
|
||||
|
||||
fn address(key: ProjectivePoint) -> Address {
|
||||
Address(address(Network::Bitcoin, key).unwrap())
|
||||
Address(BAddress::<NetworkChecked>::new(Network::Bitcoin, address_payload(key).unwrap()))
|
||||
}
|
||||
|
||||
fn branch_address(key: ProjectivePoint) -> Self::Address {
|
||||
|
|
Loading…
Reference in a new issue