Skip to content

Commit 9244975

Browse files
committed
also feeding the TxOut to verify_proof
1 parent 7a2b1bc commit 9244975

File tree

1 file changed

+38
-23
lines changed

1 file changed

+38
-23
lines changed

src/wallet/reserves.rs

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ pub enum ProofError {
7373
InvalidOutput,
7474
/// Input and output values are not equal, implying a miner fee
7575
InAndOutValueNotEqual,
76+
/// No matching outpoing found
77+
OutpointNotFound(usize),
7678
}
7779

7880
impl<B, D> ProofOfReserves for Wallet<B, D>
@@ -115,7 +117,7 @@ where
115117
let outpoints = self
116118
.list_unspent()?
117119
.iter()
118-
.map(|utxo| utxo.outpoint)
120+
.map(|utxo| (utxo.outpoint, utxo.txout.clone()))
119121
.collect();
120122

121123
verify_proof(psbt, message, outpoints, self.network)
@@ -131,7 +133,7 @@ where
131133
pub fn verify_proof(
132134
psbt: &PSBT,
133135
message: &str,
134-
outpoints: Vec<OutPoint>,
136+
outpoints: Vec<(OutPoint, TxOut)>,
135137
network: Network,
136138
) -> Result<u64, Error> {
137139
let tx = psbt.clone().extract_tx();
@@ -155,7 +157,7 @@ pub fn verify_proof(
155157
.iter()
156158
.enumerate()
157159
.skip(1)
158-
.find(|(_i, inp)| outpoints.iter().find(|op| **op == inp.previous_output) == None)
160+
.find(|(_i, inp)| outpoints.iter().find(|op| op.0 == inp.previous_output) == None)
159161
{
160162
return Err(Error::Proof(ProofError::NonSpendableInput(i)));
161163
}
@@ -178,29 +180,45 @@ pub fn verify_proof(
178180
return Err(Error::Proof(ProofError::UnsupportedSighashType(i)));
179181
}
180182

181-
// Verify other inputs against prevouts and calculate the amount.
182183
let serialized_tx = serialize(&tx);
183-
if let Some((i, res)) = psbt
184-
.inputs
184+
// Verify the challenge input
185+
if let Some(utxo) = &psbt.inputs[0].witness_utxo {
186+
if let Err(err) = bitcoinconsensus::verify(
187+
utxo.script_pubkey.to_bytes().as_slice(),
188+
utxo.value,
189+
&serialized_tx,
190+
0,
191+
) {
192+
return Err(Error::Proof(ProofError::SignatureValidation(
193+
0,
194+
format!("{:?}", err),
195+
)));
196+
}
197+
} else {
198+
return Err(Error::Proof(ProofError::SignatureValidation(
199+
0,
200+
"witness_utxo not found for challenge input".to_string(),
201+
)));
202+
}
203+
// Verify other inputs against prevouts.
204+
if let Some((i, res)) = tx
205+
.input
185206
.iter()
186-
.zip(tx.input.iter())
187207
.enumerate()
188-
.map(|(i, (psbt_in, tx_in))| {
189-
if let Some(utxo) = &psbt_in.witness_utxo {
190-
(i, Ok((&utxo.script_pubkey, utxo.value)))
191-
} else if let Some(nwtx) = &psbt_in.non_witness_utxo {
192-
let outp = &nwtx.output[tx_in.previous_output.vout as usize];
193-
(i, Ok((&outp.script_pubkey, outp.value)))
208+
.skip(1)
209+
.map(|(i, tx_in)| {
210+
if let Some(op) = outpoints.iter().find(|op| op.0 == tx_in.previous_output) {
211+
(i, Ok(op.1.clone()))
194212
} else {
195-
(i, Err(Error::Proof(ProofError::NeitherWitnessNorLegacy(i))))
213+
(i, Err(Error::Proof(ProofError::OutpointNotFound(i))))
196214
}
197215
})
198216
.map(|(i, res)| match res {
199-
Ok((script, value)) => (
217+
Ok(txout) => (
200218
i,
201219
Ok(bitcoinconsensus::verify(
202-
script.to_bytes().as_slice(),
203-
value,
220+
txout.script_pubkey.to_bytes().as_slice(),
221+
txout.value,
204222
&serialized_tx,
205223
i,
206224
)),
@@ -219,12 +237,9 @@ pub fn verify_proof(
219237
let sum = tx
220238
.input
221239
.iter()
222-
.zip(psbt.inputs.iter())
223-
.map(|(tx_in, psbt_in)| {
224-
if let Some(utxo) = &psbt_in.witness_utxo {
225-
utxo.value
226-
} else if let Some(nwtx) = &psbt_in.non_witness_utxo {
227-
nwtx.output[tx_in.previous_output.vout as usize].value
240+
.map(|tx_in| {
241+
if let Some(op) = outpoints.iter().find(|op| op.0 == tx_in.previous_output) {
242+
op.1.value
228243
} else {
229244
0
230245
}

0 commit comments

Comments
 (0)