To directly return a CRIPEMD160 hash from data.
Simplifies the call sites.
To directly return a CRIPEMD160 hash from data.
Simplifies the call sites.
97+ CRIPEMD160().Write(data, size).Finalize((unsigned char*)&result);
98+ return result;
99+}
100+
101+/** Compute the 160-bit RIPEMD-160 hash of a vector. */
102+inline uint160 RipeMd160(const std::vector<unsigned char>& vch)
.data()
and .size()
so that it works for Span
s too. In which case you could also remove the other signature for RipeMd160(ptr, size)
and just call RipeMd160(Span<unsigned char>(ptr, size))
.
RipeMd160
just a template and makes base_blob
and descendants compatible by adding base_blob::data()
. I figure it’s best to put that up separately as it’s mostly to do with base_blob
.
Concept ACK. I noticed you’re not touching the CRIPEMD160
code in script/interpreter.cpp
. I assume that’s intentional?
This should have wallet tag I think, since it touches IsMine and signing code.
Why hash.h
rather than ripemd160.h
? I’m a bit confused by the division of labor between hash.h and the various specific hash function files anyway.
7@@ -8,6 +8,8 @@
8 #include <stdint.h>
9 #include <stdlib.h>
10
11+#include <uint256.h> // For uint160
crypto/
is pretty conservative wrt inclusion, but seems this is okay because crypto/siphash.h
includes uint256.h
.
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
See the guideline for information on the review process.
Type | Reviewers |
---|---|
ACK | achow101, theStack, MarcoFalke |
Concept ACK | jimpo |
Stale ACK | Sjors, kiminuo, kristapsk, jonatack, stratospher |
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.
Reviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.
23@@ -24,6 +24,7 @@ class CScriptID : public uint160
24 CScriptID() : uint160() {}
25 explicit CScriptID(const CScript& in);
26 CScriptID(const uint160& in) : uint160(in) {}
27+ CScriptID(const uint160&& in) : uint160(std::move(in)) {}
Afaik this is the only const rvalue constructor in the codebase. They seem a bit controversial: https://stackoverflow.com/questions/10770181/should-a-move-constructor-take-a-const-or-non-const-rvalue-reference https://codesynthesis.com/~boris/blog/2012/07/24/const-rvalue-references/
It gets called 215 times during the unit test suite, e.g. for descriptor parsing: CScriptID scriptid{RipeMd160(data[0])};")
. When I drop the const
it also gets called 215 times.
Thanks, removed this ineffective attempt at optimization.
0$ git diff b29e95c cc91980
1diff --git a/src/script/standard.h b/src/script/standard.h
2index 717892f1d..49a45f3eb 100644
3--- a/src/script/standard.h
4+++ b/src/script/standard.h
5@@ -24,7 +24,6 @@ public:
6 CScriptID() : uint160() {}
7 explicit CScriptID(const CScript& in);
8 CScriptID(const uint160& in) : uint160(in) {}
9- CScriptID(const uint160&& in) : uint160(std::move(in)) {}
10 };
11
12 /**
26@@ -25,4 +27,19 @@ class CRIPEMD160
27 CRIPEMD160& Reset();
28 };
29
30+/** Compute the 160-bit RIPEMD-160 hash of an array. */
31+inline uint160 RipeMd160(const unsigned char* data, size_t size)
Nit: I think it would be nicer to have RipeMd160
-> RIPEMD160
given that
RIPEMD
represents RIPE Message Digest
andRIPE
represents RACE Integrity Primitives Evaluation
.TIL: RIPEMD -> Research and Development in Advanced Communications Technologies in Europe Integrity Primitives Evaluation Message Digest
I could go either way on this one - while all-caps is semantically correct for initialisms, capitalization has distinct meaning in code.
Span<>
instead. I thint that might even make the second variant below unnecessary, as many containers automatically coerce to a span.
re-ACK cd7fe489df0c84d21c80b9df473e883e8a267f0a
Checked via git range-diff that changes since my last ACK are only rebase-related.
Happy to also re-review if you decide to follow laanwj’s suggestion of changing the RipeMd160
interface to take a Span<>
instead (https://github.com/bitcoin/bitcoin/pull/15294#discussion_r705283491).
38 return result;
39 }
40
41-/** Compute the 160-bit RIPEMD-160 hash of an object. */
42-template <typename T>
43-inline uint160 RipeMd160(const T& container)
910@@ -910,8 +911,7 @@ static std::string RecurseImportData(const CScript& script, ImportData& import_d
911 case TxoutType::WITNESS_V0_SCRIPTHASH: {
912 if (script_ctx == ScriptContext::WITNESS_V0) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Trying to nest P2WSH inside another P2WSH");
913 uint256 fullid(solverdata[0]);
914- CScriptID id;
915- CRIPEMD160().Write(fullid.begin(), fullid.size()).Finalize(id.begin());
916+ CScriptID id{RipeMd160(fullid)};
suggestion s/fullid/full_id/
, or better yet remove it
0- uint256 fullid(solverdata[0]);
1- CScriptID id{RipeMd160(fullid)};
2+ CScriptID id{RipeMd160(solverdata[0])};
3814@@ -3816,10 +3815,8 @@ class DescribeWalletAddressVisitor
3815 {
3816 UniValue obj(UniValue::VOBJ);
3817 CScript subscript;
3818- CRIPEMD160 hasher;
3819- uint160 hash;
3820- hasher.Write(id.begin(), 32).Finalize(hash.begin());
3821- if (provider && provider->GetCScript(CScriptID(hash), subscript)) {
3822+ CScriptID scriptid{RipeMd160(id)};
3823+ if (provider && provider->GetCScript(scriptid, subscript)) {
suggestion s/scriptid/script_id/
0@@ -3814,9 +3814,9 @@ public:
1 UniValue operator()(const WitnessV0ScriptHash& id) const
2 {
3 UniValue obj(UniValue::VOBJ);
4+ CScriptID script_id{RipeMd160(id)};
5 CScript subscript;
6- CScriptID scriptid{RipeMd160(id)};
7- if (provider && provider->GetCScript(scriptid, subscript)) {
8+ if (provider && provider->GetCScript(script_id, subscript)) {
9 ProcessSubScript(subscript, obj);
10 }
11 return obj;
7@@ -8,6 +8,9 @@
8 #include <stdint.h>
9 #include <stdlib.h>
10
11+#include <uint256.h> // For uint160
12+#include <span.h> // For Span
suggestion, sort
0+#include <span.h>
1 #include <uint256.h> // For uint160
2-#include <span.h> // For Span
Nice refactoring/cleanup.
Code review ACK cd7fe489df0c84d21c80b9df473e883e8a267f0a and debug build is clean
Some minor suggestions for your consideration if you retouch.
s/moveonly/refactoring/
in the PR title.
crypto/
code depend on Bitcoin Core specific code like uint256.h
(for purely aesthetic reasons), and actually going the other direction (also removing it from siphash). I think with the suggestion here that may actually not even be needed (Span seems much “cleaner” to depend on, as it’s an almost identical copy of a c++20 stdlib feature).
211@@ -211,4 +212,12 @@ void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char he
212 */
213 CHashWriter TaggedHash(const std::string& tag);
214
215+/** Compute the 160-bit RIPEMD-160 hash of an array. */
216+inline uint160 RipeMd160(Span<const unsigned char> data)
3@@ -4,10 +4,12 @@
4
5 #include <script/descriptor.h>
6
7+#include <hash.h> // For RIPEMD160
For ...
comments
Two more places in src/wallet/rpc/coins.cpp
could be updated:
0diff --git a/src/wallet/rpc/coins.cpp b/src/wallet/rpc/coins.cpp
1index 82642194c20..250b580c37c 100644
2--- a/src/wallet/rpc/coins.cpp
3+++ b/src/wallet/rpc/coins.cpp
4@@ -679,8 +679,7 @@ RPCHelpMan listunspent()
5 CHECK_NONFATAL(extracted);
6 // Also return the witness script
7 const WitnessV0ScriptHash& whash = std::get<WitnessV0ScriptHash>(witness_destination);
8- CScriptID id;
9- CRIPEMD160().Write(whash.begin(), whash.size()).Finalize(id.begin());
10+ CScriptID id{RIPEMD160(whash)};
11 CScript witnessScript;
12 if (provider->GetCScript(id, witnessScript)) {
13 entry.pushKV("witnessScript", HexStr(witnessScript));
14@@ -689,8 +688,7 @@ RPCHelpMan listunspent()
15 }
16 } else if (scriptPubKey.IsPayToWitnessScriptHash()) {
17 const WitnessV0ScriptHash& whash = std::get<WitnessV0ScriptHash>(address);
18- CScriptID id;
19- CRIPEMD160().Write(whash.begin(), whash.size()).Finalize(id.begin());
20+ CScriptID id{RIPEMD160(whash)};
21 CScript witnessScript;
22 if (provider->GetCScript(id, witnessScript)) {
23 entry.pushKV("witnessScript", HexStr(witnessScript));
To directly return a CRIPEMD160 hash from data.
Incidentally, decoding this acronym:
* RIPEMD -> RIPE Message Digest
* RIPE -> RACE Integrity Primitives Evaluation
* RACE -> Research and Development in Advanced Communications Technologies in Europe
review ACK 6879be691bf636a53208ef058f2ebe18bfa8017c 🏔
Signature:
0-----BEGIN PGP SIGNED MESSAGE-----
1Hash: SHA512
2
3review ACK 6879be691bf636a53208ef058f2ebe18bfa8017c 🏔
4-----BEGIN PGP SIGNATURE-----
5
6iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
7pUiT1wv+JeOoQOIiy2NUd4vV1htnx+kXGz/gFFoDnqCY0M9sj6LdXfmwLf3EYpQA
8fKhnS86I49ms/985+Z9jviAiwZ6iA9ViVZjmoLhcfPqUi8l/cDInfml8UVwLI2dj
90aXCAqXRex56hieA3q8zHCQ3L12UPyD/pJvdVGIDim18llMB5lxld7gT7eC3fhyO
10i+jo6x86YDdxo7+OgwMXjSb/59IPK4bR/B10lBS64AGLKD1tSCpU2X/hQkUnNsut
11Q/RCJipWDBL5cepJwCR/h1XO4C2KFzYEw998cYm0ZnLLivKTKimrHeDgQfJ3akfZ
12m3YRylDN8OeJ/Fnwr7JuPisTBvisVm7wfFIF30RW8AgPF/5WFR2iddF7Awlf83Qr
13AMnEcCnM6mMCO1xxrxR92NjnEqXsqlTqf6f0ygNuCiFIA5xyADUvT3B+dMiT0eg5
140M6xp/ppnrP5AA8Nc9m+FZ9tEDOwiCh/9cYeZAZyyruEhw1JgjZyUAgU7qMD2cr4
15Ev+BKUFf
16=XLKt
17-----END PGP SIGNATURE-----