diff options
author | Wladimir J. van der Laan <laanwj@protonmail.com> | 2020-08-19 13:39:33 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@protonmail.com> | 2020-08-19 14:20:15 +0200 |
commit | 44ddcd887ddf3f62bcfb9c0b59ba2124335dbe94 (patch) | |
tree | 6857630f21e38b5cb47052099c5e5b894a8d2f37 | |
parent | c6532fa6c14d3cea5941cff9411937db9a8d5f1a (diff) | |
parent | 356988e200b1debaa80d210d502d2d085c72dc64 (diff) |
Merge #19706: refactor: make EncodeBase58{Check} consume Spans
356988e200b1debaa80d210d502d2d085c72dc64 util: make EncodeBase58Check consume Spans (Sebastian Falbesoner)
f0fce0675d56b2226a993253731690ca864066c8 util: make EncodeBase58 consume Spans (Sebastian Falbesoner)
Pull request description:
This PR improves the interfaces for the functions `EncodeBase58{Check}` by using Spans, in a similar fashion to e.g. PRs #19660, #19687. Note that on the master branch there are currently two versions of `EncodeBase58`: one that takes two pointers (marking begin and end) and another one that takes a `std::vector<unsigned char>` const-ref. The PR branch only leaves one generic Span-interface, both simplifying the interface and allowing more generic containers to be passed. The same is done for `EncodeBase58Check`, where only one interface existed but it's more generic now (e.g. a std::array can be directly passed, as done in the benchmarks).
ACKs for top commit:
laanwj:
Code review ACK 356988e200b1debaa80d210d502d2d085c72dc64
Tree-SHA512: 47cfccdd7f3a2d4694bb8785e6e5fd756daee04ce1652ee59a7822e7e833b4a441ae9362b9bd67ea020d2b5b7d927629c9addb6abaa9881d8564fd3b1257f512
-rw-r--r-- | src/base58.cpp | 23 | ||||
-rw-r--r-- | src/base58.h | 15 | ||||
-rw-r--r-- | src/bench/base58.cpp | 6 | ||||
-rw-r--r-- | src/qt/guiutil.cpp | 2 | ||||
-rw-r--r-- | src/test/base58_tests.cpp | 2 |
5 files changed, 18 insertions, 30 deletions
diff --git a/src/base58.cpp b/src/base58.cpp index 9b2946e7a9..18cd2090e0 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -84,21 +84,21 @@ bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch, int max_ret_ return true; } -std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) +std::string EncodeBase58(Span<const unsigned char> input) { // Skip & count leading zeroes. int zeroes = 0; int length = 0; - while (pbegin != pend && *pbegin == 0) { - pbegin++; + while (input.size() > 0 && input[0] == 0) { + input = input.subspan(1); zeroes++; } // Allocate enough space in big-endian base58 representation. - int size = (pend - pbegin) * 138 / 100 + 1; // log(256) / log(58), rounded up. + int size = input.size() * 138 / 100 + 1; // log(256) / log(58), rounded up. std::vector<unsigned char> b58(size); // Process the bytes. - while (pbegin != pend) { - int carry = *pbegin; + while (input.size() > 0) { + int carry = input[0]; int i = 0; // Apply "b58 = b58 * 256 + ch". for (std::vector<unsigned char>::reverse_iterator it = b58.rbegin(); (carry != 0 || i < length) && (it != b58.rend()); it++, i++) { @@ -109,7 +109,7 @@ std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) assert(carry == 0); length = i; - pbegin++; + input = input.subspan(1); } // Skip leading zeroes in base58 result. std::vector<unsigned char>::iterator it = b58.begin() + (size - length); @@ -124,11 +124,6 @@ std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) return str; } -std::string EncodeBase58(const std::vector<unsigned char>& vch) -{ - return EncodeBase58(vch.data(), vch.data() + vch.size()); -} - bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet, int max_ret_len) { if (!ValidAsCString(str)) { @@ -137,10 +132,10 @@ bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet, in return DecodeBase58(str.c_str(), vchRet, max_ret_len); } -std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn) +std::string EncodeBase58Check(Span<const unsigned char> input) { // add 4-byte hash check to the end - std::vector<unsigned char> vch(vchIn); + std::vector<unsigned char> vch(input.begin(), input.end()); uint256 hash = Hash(vch); vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4); return EncodeBase58(vch); diff --git a/src/base58.h b/src/base58.h index 042ad671d3..b87664b78b 100644 --- a/src/base58.h +++ b/src/base58.h @@ -15,20 +15,15 @@ #define BITCOIN_BASE58_H #include <attributes.h> +#include <span.h> #include <string> #include <vector> /** - * Encode a byte sequence as a base58-encoded string. - * pbegin and pend cannot be nullptr, unless both are. + * Encode a byte span as a base58-encoded string */ -std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend); - -/** - * Encode a byte vector as a base58-encoded string - */ -std::string EncodeBase58(const std::vector<unsigned char>& vch); +std::string EncodeBase58(Span<const unsigned char> input); /** * Decode a base58-encoded string (psz) into a byte vector (vchRet). @@ -44,9 +39,9 @@ NODISCARD bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet, NODISCARD bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet, int max_ret_len); /** - * Encode a byte vector into a base58-encoded string, including checksum + * Encode a byte span into a base58-encoded string, including checksum */ -std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn); +std::string EncodeBase58Check(Span<const unsigned char> input); /** * Decode a base58-encoded string (psz) that includes a checksum into a byte diff --git a/src/bench/base58.cpp b/src/bench/base58.cpp index 00544cba31..18cb5de196 100644 --- a/src/bench/base58.cpp +++ b/src/bench/base58.cpp @@ -20,7 +20,7 @@ static void Base58Encode(benchmark::Bench& bench) } }; bench.batch(buff.size()).unit("byte").run([&] { - EncodeBase58(buff.data(), buff.data() + buff.size()); + EncodeBase58(buff); }); } @@ -34,10 +34,8 @@ static void Base58CheckEncode(benchmark::Bench& bench) 200, 24 } }; - std::vector<unsigned char> vch; - vch.assign(buff.begin(), buff.end()); bench.batch(buff.size()).unit("byte").run([&] { - EncodeBase58Check(vch); + EncodeBase58Check(buff); }); } diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 7f439fa45e..6e34aca0eb 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -94,7 +94,7 @@ static std::string DummyAddress(const CChainParams ¶ms) std::vector<unsigned char> sourcedata = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS); sourcedata.insert(sourcedata.end(), dummydata, dummydata + sizeof(dummydata)); for(int i=0; i<256; ++i) { // Try every trailing byte - std::string s = EncodeBase58(sourcedata.data(), sourcedata.data() + sourcedata.size()); + std::string s = EncodeBase58(sourcedata); if (!IsValidDestinationString(s)) { return s; } diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index 57559fa687..6a636f2574 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -33,7 +33,7 @@ BOOST_AUTO_TEST_CASE(base58_EncodeBase58) std::vector<unsigned char> sourcedata = ParseHex(test[0].get_str()); std::string base58string = test[1].get_str(); BOOST_CHECK_MESSAGE( - EncodeBase58(sourcedata.data(), sourcedata.data() + sourcedata.size()) == base58string, + EncodeBase58(sourcedata) == base58string, strTest); } } |