Skip to content

Conversation

@theStack
Copy link
Contributor

The fingerprint matching logic in ExternalSigner::SignTransaction currently always iterates all inputs of a PSBT, even after a match has already been found. I guess the reason for that is not that it was not thought of, but rather the fact that breaking out of a nested loop is simply not possible (at least not without adding ugly constructs like gotos or extra state variables).
This PR fixes this by using std::any_of from C++'s standard library, see http://www.cplusplus.com/reference/algorithm/any_of/

@fanquake fanquake requested a review from Sjors August 24, 2021 10:48
@meshcollider
Copy link
Contributor

Concept ACK

breaking out of a nested loop is simply not possible (at least not without adding ugly constructs like gotos or extra state variables)

You could do this though:

-for (unsigned int i = 0; i < psbtx.inputs.size(); ++i) {
+for (unsigned int i = 0; !match && i < psbtx.inputs.size(); ++i) {
    const PSBTInput& input = psbtx.inputs[i];
    for (const auto& entry : input.hd_keypaths) {
-        if (m_fingerprint == strprintf("%08x", ReadBE32(entry.second.fingerprint))) match = true;
+        if (m_fingerprint == strprintf("%08x", ReadBE32(entry.second.fingerprint))) { 
+            match = true;
+            break;
+        }
    }
}

Copy link
Contributor

@lsilva01 lsilva01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review ACK d047ed7

Copy link
Member

@Sjors Sjors left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK d047ed7

I don't think there was a deep reason I didn't do this.

Copy link
Contributor

@Zero-1729 Zero-1729 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

crACK d047ed7

Copy link
Contributor

@mjdietzx mjdietzx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review ACK d047ed7

Comment on lines 80 to +84
for (const auto& entry : input.hd_keypaths) {
if (m_fingerprint == strprintf("%08x", ReadBE32(entry.second.fingerprint))) match = true;
if (m_fingerprint == strprintf("%08x", ReadBE32(entry.second.fingerprint))) return true;
}
}
return false;
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious, could you get rid of the other for loop as well with the same approach? Would that be cleaner? Something like:

return std::any_of(input.hd_keypaths.begin(), input.hd_keypaths.end(), [](auto& entry){ return m_fingerprint == strprintf("%08x", ReadBE32(entry.second.fingerprint)); });

@hebasto
Copy link
Member

hebasto commented Oct 8, 2021

Concept ACK.

Copy link
Member

@hebasto hebasto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK d047ed7, I have reviewed the code and it looks OK, I agree it can be merged.

};

if (!match) {
if (!std::any_of(psbtx.inputs.begin(), psbtx.inputs.end(), matches_signer_fingerprint)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
if (!std::any_of(psbtx.inputs.begin(), psbtx.inputs.end(), matches_signer_fingerprint)) {
if (!std::any_of(psbtx.inputs.cbegin(), psbtx.inputs.cend(), matches_signer_fingerprint)) {

luke-jr added a commit to bitcoinknots/bitcoin that referenced this pull request Oct 10, 2021
…tch)

Simplified rewritten version

Equivalent to d047ed7 by Sebastian Falbesoner <sebastian.falbesoner@gmail.com>
Github-Pull: bitcoin#22789
@laanwj laanwj merged commit 91c7d66 into bitcoin:master Oct 22, 2021
@theStack theStack deleted the 202108-external_signer-improve_fingerprint_matching branch October 22, 2021 14:15
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Oct 22, 2021
…gic (stop on first match)

d047ed7 external_signer: improve fingerprint matching logic (stop on first match) (Sebastian Falbesoner)

Pull request description:

  The fingerprint matching logic in `ExternalSigner::SignTransaction` currently always iterates all inputs of a PSBT, even after a match has already been found. I guess the reason for that is not that it was not thought of, but rather the fact that breaking out of a nested loop is simply not possible (at least not without adding ugly constructs like gotos or extra state variables).
  This PR fixes this by using `std::any_of` from C++'s standard library, see http://www.cplusplus.com/reference/algorithm/any_of/

ACKs for top commit:
  lsilva01:
    Code Review ACK bitcoin@d047ed7
  Sjors:
    utACK d047ed7
  Zero-1729:
    crACK d047ed7
  mjdietzx:
    Code review ACK d047ed7
  hebasto:
    ACK d047ed7, I have reviewed the code and it looks OK, I agree it can be merged.

Tree-SHA512: 447e7c0c6a5b5549a2c09d52e55ba4146302c1a06e4d96de11f6945d09f98c89129cba221202dff7e0718e01a83dd173b9f19b1f02b6be228978f3f6e35d8096
@bitcoin bitcoin locked and limited conversation to collaborators Oct 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants