Repository navigation
Conversation
| if !out.witness.rangeproof.is_empty() { | ||
| return Err(VerificationError::RangeProofError( | ||
| i, | ||
| secp256k1_zkp::Error::InvalidRangeProof, | ||
| )); | ||
| } |
There was a problem hiding this comment.
This check based on the mirrored one in elements:
https://github.com/ElementsProject/elements/blob/2ac51cac13876bf14d3d709b07535b1868eee896/src/confidential_validation.cpp#L374-L379
| if out.asset.is_explicit() && !out.witness.surjection_proof.is_empty() { | ||
| return Err(VerificationError::SurjectionProofError( | ||
| i, | ||
| secp256k1_zkp::Error::InvalidSurjectionProof, | ||
| )); | ||
| } |
There was a problem hiding this comment.
| if out.asset.is_null() { | ||
| return Err(VerificationError::TxOutError(i, TxOutError::UnExpectedNullAsset)); | ||
| } |
There was a problem hiding this comment.
This check is based on the explicit-or-commitment check in elements:
https://github.com/ElementsProject/elements/blob/2ac51cac13876bf14d3d709b07535b1868eee896/src/confidential_validation.cpp#L321-L331
delta1
left a comment
There was a problem hiding this comment.
Mostly looks good but 2 issues
| .get_value_commit(secp) | ||
| .map_err(|e| VerificationError::SpentTxOutError(i, e))?; | ||
| out_commits.push(out_commit); | ||
| if out.value == Value::Explicit(0) && out.script_pubkey.is_provably_unspendable() { |
There was a problem hiding this comment.
If an output has out.value == Value::Explicit(0) with a spendable script, it falls through to line 1175 where it maps to SpentTxOutError(i, e), which formats as "Input index {i} spent utxo error: ...".
A spendable zero-value output at index 0 is diagnosed as a corrupt prevout at input 0 which is incorrect
There was a problem hiding this comment.
cc https://github.com/ElementsProject/rust-elements/pull/300/changes#r4272012688 (will change to TxOutError)
|
|
||
| assert_eq!( | ||
| verify_with(0, explicit(0, spk.clone())), | ||
| Err(VerificationError::SpentTxOutError(0, TxOutError::NonUnspendableZeroValue)) |
There was a problem hiding this comment.
SpentTxOutError is not the correct error variant for this case it should be VerificationError::TxOutError
There was a problem hiding this comment.
This predates my changes
This error: VerificationError::SpentTxOutError(0, TxOutError::NonUnspendableZeroValue) in particular is thrown from get_value_commit function
I am not really sure whether it should be Spent or just TxOutError
The rustdoc of those errors does not help either:
/// Spent Txout error
SpentTxOutError(usize, TxOutError),
/// Current transaction txout error
TxOutError(usize, TxOutError),Will change anyway, following the suggestion
| return Err(VerificationError::TxOutError(i, TxOutError::UnExpectedNullAsset)); | ||
| } | ||
| // An explicit value or asset leaves its proof nothing to prove. | ||
| if !out.witness.rangeproof.is_empty() { |
There was a problem hiding this comment.
These checks for non-empty range/surjection proofs are only in the unspendable branch, but they are invalid for any explicit output not just unspendable outputs
There was a problem hiding this comment.
Make sense, moved those checks below
|
Also, can you split the unit test into a separate commit (after the fix) so it's easy to verify that it fails without the fix? |
Sure, will do |
And reject stray proofs
5266aac to
52f4674
Compare
52f4674 to
8cbfe53
Compare
Decided to keep it as one big regression test, let me know if I should split it |
This PR adds a condition check to
verify_tx_amt_proofsfunction to filter out outputs that are provably unspendable and with explicit 0 value.Current
Transaction::verify_tx_amt_proofsconverts every output into a Pedersen commitment:rust-elements/src/blind.rs
Lines 1150 to 1187 in 582ea61
Explicit zero values have no nonzero commitment, so valid zero-value data outputs cannot pass this path.
The commitment helper already distinguishes unspendable zero outputs from invalid spendable zero outputs:
rust-elements/src/blind.rs
Lines 735 to 742 in 582ea61
but the transaction verifier (
verify_tx_amt_proofs) propagates the former as an error.Because of this callers must clone a transaction and filter valid zero outputs before verification.