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)
Could make this a template function over things with .data() and .size() so that it works for Spans too. In which case you could also remove the other signature for RipeMd160(ptr, size) and just call RipeMd160(Span<unsigned char>(ptr, size)).
I have a follow-up here: https://github.com/Empact/bitcoin/tree/base-blob-data that makes 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
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
note: crypto/ is pretty conservative wrt inclusion, but seems this is okay because crypto/siphash.h includes uint256.h.
<!--e57a25ab6845829454e8d69fc972939a-->
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
<!--021abf342d371248e50ceaed478a90ca-->
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.
<!--174a7506f384e20aa4161008e828411d-->
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.
Rebased
ACK b29e95c02b5a75681ee3b59d7dd8cceb85d8b27b
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.
It doesn't do anything here, as it's equivalent to the const lvalue copy constructor.
Thanks, removed this ineffective attempt at optimization.
$ git diff b29e95c cc91980
diff --git a/src/script/standard.h b/src/script/standard.h
index 717892f1d..49a45f3eb 100644
--- a/src/script/standard.h
+++ b/src/script/standard.h
@@ -24,7 +24,6 @@ public:
CScriptID() : uint160() {}
explicit CScriptID(const CScript& in);
CScriptID(const uint160& in) : uint160(in) {}
- CScriptID(const uint160&& in) : uint160(std::move(in)) {}
};
/**
Code review ACK b29e95c02b5a75681ee3b59d7dd8cceb85d8b27b
re-ACK cc91980afd05796230e8ce95c622729accee1785
re-ACK https://github.com/bitcoin/bitcoin/commit/cc91980afd05796230e8ce95c622729accee1785 (checked that only the const rvalue constructor has been removed since my previous ACK)
re-ACK ce38f54e66e8584cdd01b7d0dac76bbf010f0e2b
Rebased
re-ACK d7432d398846a4fb6a1ebf0a4d45b195c11acada
re-ACK d7432d398846a4fb6a1ebf0a4d45b195c11acada
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.
Maybe make this take a Span<> instead. I thint that might even make the second variant below unnecessary, as many containers automatically coerce to a span.
crACK d7432d398846a4fb6a1ebf0a4d45b195c11acada
re-ACK cd7fe489df0c84d21c80b9df473e883e8a267f0a
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)
Instead of adding code and removing it in the next commit, it might be better to squash the commits. This will reduce review burden for reviewers starting from scratch as well as reduce the git history, blame depth and clone size.
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
- uint256 fullid(solverdata[0]);
- CScriptID id{RipeMd160(fullid)};
+ 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/
@@ -3814,9 +3814,9 @@ public:
UniValue operator()(const WitnessV0ScriptHash& id) const
{
UniValue obj(UniValue::VOBJ);
+ CScriptID script_id{RipeMd160(id)};
CScript subscript;
- CScriptID scriptid{RipeMd160(id)};
- if (provider && provider->GetCScript(scriptid, subscript)) {
+ if (provider && provider->GetCScript(script_id, subscript)) {
ProcessSubScript(subscript, obj);
}
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
+#include <span.h>
#include <uint256.h> // For uint160
-#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.
Perhaps s/moveonly/refactoring/ in the PR title.
I have a slight preference for not having the 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)
Nit (also mentioned earlier): this should be RIPEMD160 I think, as it's an acronym.
3 | @@ -4,10 +4,12 @@ 4 | 5 | #include <script/descriptor.h> 6 | 7 | +#include <hash.h> // For RIPEMD160
Please don't add these For ... comments
ACK ca55641. This PR defines RIPEMD160() as an inline function in src/hash.h and makes the function calls more intuitive.
Are you still working on this?
Two more places in src/wallet/rpc/coins.cpp could be updated:
diff --git a/src/wallet/rpc/coins.cpp b/src/wallet/rpc/coins.cpp
index 82642194c20..250b580c37c 100644
--- a/src/wallet/rpc/coins.cpp
+++ b/src/wallet/rpc/coins.cpp
@@ -679,8 +679,7 @@ RPCHelpMan listunspent()
CHECK_NONFATAL(extracted);
// Also return the witness script
const WitnessV0ScriptHash& whash = std::get<WitnessV0ScriptHash>(witness_destination);
- CScriptID id;
- CRIPEMD160().Write(whash.begin(), whash.size()).Finalize(id.begin());
+ CScriptID id{RIPEMD160(whash)};
CScript witnessScript;
if (provider->GetCScript(id, witnessScript)) {
entry.pushKV("witnessScript", HexStr(witnessScript));
@@ -689,8 +688,7 @@ RPCHelpMan listunspent()
}
} else if (scriptPubKey.IsPayToWitnessScriptHash()) {
const WitnessV0ScriptHash& whash = std::get<WitnessV0ScriptHash>(address);
- CScriptID id;
- CRIPEMD160().Write(whash.begin(), whash.size()).Finalize(id.begin());
+ CScriptID id{RIPEMD160(whash)};
CScript witnessScript;
if (provider->GetCScript(id, witnessScript)) {
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
ACK 6879be691bf636a53208ef058f2ebe18bfa8017c
re-ACK 6879be691bf636a53208ef058f2ebe18bfa8017c
review ACK 6879be691bf636a53208ef058f2ebe18bfa8017c 🏔
<details><summary>Show signature</summary>
Signature:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
review ACK 6879be691bf636a53208ef058f2ebe18bfa8017c 🏔
-----BEGIN PGP SIGNATURE-----
iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUiT1wv+JeOoQOIiy2NUd4vV1htnx+kXGz/gFFoDnqCY0M9sj6LdXfmwLf3EYpQA
fKhnS86I49ms/985+Z9jviAiwZ6iA9ViVZjmoLhcfPqUi8l/cDInfml8UVwLI2dj
0aXCAqXRex56hieA3q8zHCQ3L12UPyD/pJvdVGIDim18llMB5lxld7gT7eC3fhyO
i+jo6x86YDdxo7+OgwMXjSb/59IPK4bR/B10lBS64AGLKD1tSCpU2X/hQkUnNsut
Q/RCJipWDBL5cepJwCR/h1XO4C2KFzYEw998cYm0ZnLLivKTKimrHeDgQfJ3akfZ
m3YRylDN8OeJ/Fnwr7JuPisTBvisVm7wfFIF30RW8AgPF/5WFR2iddF7Awlf83Qr
AMnEcCnM6mMCO1xxrxR92NjnEqXsqlTqf6f0ygNuCiFIA5xyADUvT3B+dMiT0eg5
0M6xp/ppnrP5AA8Nc9m+FZ9tEDOwiCh/9cYeZAZyyruEhw1JgjZyUAgU7qMD2cr4
Ev+BKUFf
=XLKt
-----END PGP SIGNATURE-----
</details>