Skip to content

Commit

Permalink
Merge bitcoin/bitcoin#30377: refactor: Replace ParseHex with consteva…
Browse files Browse the repository at this point in the history
…l ""_hex literals

8756ccd scripted-diff: Replace ParseHex[<std::byte>]("str") -> "str"_hex[_u8] (Hodlinator)
9cb6873 refactor: Prepare for ParseHex -> ""_hex scripted-diff (Hodlinator)
50bc017 refactor: Hand-replace some ParseHex -> ""_hex (Hodlinator)
5b74a84 util: Add consteval ""_hex[_v][_u8] literals (l0rinc)
dc5f6f6 test refactor: util_tests - parse_hex clean up (Hodlinator)
2b5e6ef refactor: Make XOnlyPubKey tolerate constexpr std::arrays (Hodlinator)
403d86f refactor: vector -> span in CCrypter (Hodlinator)
bd0830b refactor: de-Hungarianize CCrypter (Hodlinator)
d99c816 refactor: Improve CCrypter related lines (Hodlinator)
7e1d9a8 refactor: Enforce lowercase hex digits for consteval uint256 (Hodlinator)

Pull request description:

  Motivation:
  * Validates and converts the hex string into bytes at compile time instead of at runtime like `ParseHex()`.
  * Eliminates runtime dependencies: bitcoin/bitcoin#30377 (comment), bitcoin/bitcoin#30048 (comment)
  * Has stricter requirements than `ParseHex()` (disallows whitespace and uppercase hex digits) and replaces it in a bunch of places.
  * Makes it possible to derive other compile time constants.
  * Minor: should shave off a few runtime CPU cycles.

  `""_hex` produces `std::array<std::byte>` as the momentum in the codebase is to use `std::byte` over `uint8_t`.

  Also makes `uint256` hex string constructor disallow uppercase hex digits. Discussed: bitcoin/bitcoin#30560 (comment)

  Surprisingly does not change the size of the Guix **bitcoind** binary (on x86_64-linux-gnu) by 1 single byte.

  Spawned already merged PRs: #30436, #30482, #30532, #30560.

ACKs for top commit:
  l0rinc:
    ACK 8756ccd
  stickies-v:
    Rebase re-ACK 8756ccd, no changes since a096215c9c71a2ec03e76f1fd0bcdda0727996e0
  ryanofsky:
    Code review ACK 8756ccd, just rebasing since last review and taking advantage of CScript constructors in #29369, also tweaking a code comment

Tree-SHA512: 9b2011b7c37e0ef004c669f8601270a214b388916316458370f5902c79c2856790b1b2c7c123efa65decad04886ab5eff95644301e0d84358bb265cf1f8ec195
  • Loading branch information
ryanofsky committed Aug 31, 2024
2 parents e96f657 + 8756ccd commit b52d547
Show file tree
Hide file tree
Showing 31 changed files with 482 additions and 361 deletions.
5 changes: 3 additions & 2 deletions src/bench/bech32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@

#include <vector>

using namespace util::hex_literals;

static void Bech32Encode(benchmark::Bench& bench)
{
std::vector<uint8_t> v = ParseHex("c97f5a67ec381b760aeaf67573bc164845ff39a3bb26a1cee401ac67243b48db");
constexpr std::array<uint8_t, 32> v{"c97f5a67ec381b760aeaf67573bc164845ff39a3bb26a1cee401ac67243b48db"_hex_u8};
std::vector<unsigned char> tmp = {0};
tmp.reserve(1 + 32 * 8 / 5);
tmp.reserve(1 + v.size() * 8 / 5);
ConvertBits<8, 5, true>([&](unsigned char c) { tmp.push_back(c); }, v.begin(), v.end());
bench.batch(v.size()).unit("byte").run([&] {
bech32::Encode(bech32::Encoding::BECH32, "bc", tmp);
Expand Down
4 changes: 3 additions & 1 deletion src/bench/index_blockfilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,16 @@
#include <memory>
#include <vector>

using namespace util::hex_literals;

// Very simple block filter index sync benchmark, only using coinbase outputs.
static void BlockFilterIndexSync(benchmark::Bench& bench)
{
const auto test_setup = MakeNoLogFileContext<TestChain100Setup>();

// Create more blocks
int CHAIN_SIZE = 600;
CPubKey pubkey{ParseHex("02ed26169896db86ced4cbb7b3ecef9859b5952825adbeab998fb5b307e54949c9")};
CPubKey pubkey{"02ed26169896db86ced4cbb7b3ecef9859b5952825adbeab998fb5b307e54949c9"_hex_u8};
CScript script = GetScriptForDestination(WitnessV0KeyHash(pubkey));
std::vector<CMutableTransaction> noTxns;
for (int i = 0; i < CHAIN_SIZE - 100; i++) {
Expand Down
8 changes: 5 additions & 3 deletions src/kernel/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include <cstring>
#include <type_traits>

using namespace util::hex_literals;

// Workaround MSVC bug triggering C7595 when calling consteval constructors in
// initializer lists.
// A fix may be on the way:
Expand Down Expand Up @@ -71,7 +73,7 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesi
static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
const CScript genesisOutputScript = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
const CScript genesisOutputScript = CScript() << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"_hex_v_u8 << OP_CHECKSIG;
return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
}

Expand Down Expand Up @@ -351,7 +353,7 @@ class CTestNet4Params : public CChainParams {
m_assumed_chain_state_size = 0;

const char* testnet4_genesis_msg = "03/May/2024 000000000000000000001ebd58c244970b3aa9d783bb001011fbe8ea8e98e00e";
const CScript testnet4_genesis_script = CScript() << ParseHex("000000000000000000000000000000000000000000000000000000000000000000") << OP_CHECKSIG;
const CScript testnet4_genesis_script = CScript() << "000000000000000000000000000000000000000000000000000000000000000000"_hex_v_u8 << OP_CHECKSIG;
genesis = CreateGenesisBlock(testnet4_genesis_msg,
testnet4_genesis_script,
1714777860,
Expand Down Expand Up @@ -412,7 +414,7 @@ class SigNetParams : public CChainParams {
vSeeds.clear();

if (!options.challenge) {
bin = ParseHex("512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae");
bin = "512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae"_hex_v_u8;
vSeeds.emplace_back("seed.signet.bitcoin.sprovoost.nl.");
vSeeds.emplace_back("seed.signet.achownodes.xyz."); // Ava Chow, only supports x1, x5, x9, x49, x809, x849, xd, x400, x404, x408, x448, xc08, xc48, x40c

Expand Down
6 changes: 4 additions & 2 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
#include <typeinfo>
#include <utility>

using namespace util::hex_literals;

/** Headers download timeout.
* Timeout = base + per_header * (expected number of headers) */
static constexpr auto HEADERS_DOWNLOAD_TIMEOUT_BASE = 15min;
Expand Down Expand Up @@ -3931,8 +3933,8 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,

// If the peer is old enough to have the old alert system, send it the final alert.
if (greatest_common_version <= 70012) {
const auto finalAlert{ParseHex("60010000000000000000000000ffffff7f00000000ffffff7ffeffff7f01ffffff7f00000000ffffff7f00ffffff7f002f555247454e543a20416c657274206b657920636f6d70726f6d697365642c2075706772616465207265717569726564004630440220653febd6410f470f6bae11cad19c48413becb1ac2c17f908fd0fd53bdc3abd5202206d0e9c96fe88d4a0f01ed9dedae2b6f9e00da94cad0fecaae66ecf689bf71b50")};
MakeAndPushMessage(pfrom, "alert", Span{finalAlert});
constexpr auto finalAlert{"60010000000000000000000000ffffff7f00000000ffffff7ffeffff7f01ffffff7f00000000ffffff7f00ffffff7f002f555247454e543a20416c657274206b657920636f6d70726f6d697365642c2075706772616465207265717569726564004630440220653febd6410f470f6bae11cad19c48413becb1ac2c17f908fd0fd53bdc3abd5202206d0e9c96fe88d4a0f01ed9dedae2b6f9e00da94cad0fecaae66ecf689bf71b50"_hex};
MakeAndPushMessage(pfrom, "alert", finalAlert);
}

// Feeler connections exist only to verify if address is online.
Expand Down
11 changes: 3 additions & 8 deletions src/pubkey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include <algorithm>
#include <cassert>

using namespace util::hex_literals;

namespace {

struct Secp256k1SelfTester
Expand Down Expand Up @@ -190,14 +192,7 @@ int ecdsa_signature_parse_der_lax(secp256k1_ecdsa_signature* sig, const unsigned
* For an example script for calculating H, refer to the unit tests in
* ./test/functional/test_framework/crypto/secp256k1.py
*/
static const std::vector<unsigned char> NUMS_H_DATA{ParseHex("50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0")};
const XOnlyPubKey XOnlyPubKey::NUMS_H{NUMS_H_DATA};

XOnlyPubKey::XOnlyPubKey(Span<const unsigned char> bytes)
{
assert(bytes.size() == 32);
std::copy(bytes.begin(), bytes.end(), m_keydata.begin());
}
constexpr XOnlyPubKey XOnlyPubKey::NUMS_H{"50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0"_hex_u8};

std::vector<CKeyID> XOnlyPubKey::GetKeyIDs() const
{
Expand Down
2 changes: 1 addition & 1 deletion src/pubkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ class XOnlyPubKey
bool IsNull() const { return m_keydata.IsNull(); }

/** Construct an x-only pubkey from exactly 32 bytes. */
explicit XOnlyPubKey(Span<const unsigned char> bytes);
constexpr explicit XOnlyPubKey(std::span<const unsigned char> bytes) : m_keydata{bytes} {}

/** Construct an x-only pubkey from a normal pubkey. */
explicit XOnlyPubKey(const CPubKey& pubkey) : XOnlyPubKey(Span{pubkey}.subspan(1, 32)) {}
Expand Down
3 changes: 2 additions & 1 deletion src/test/base58_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <string>

using namespace std::literals;
using namespace util::hex_literals;

BOOST_FIXTURE_TEST_SUITE(base58_tests, BasicTestingSetup)

Expand Down Expand Up @@ -72,7 +73,7 @@ BOOST_AUTO_TEST_CASE(base58_DecodeBase58)
// check that DecodeBase58 skips whitespace, but still fails with unexpected non-whitespace at the end.
BOOST_CHECK(!DecodeBase58(" \t\n\v\f\r skip \r\f\v\n\t a", result, 3));
BOOST_CHECK( DecodeBase58(" \t\n\v\f\r skip \r\f\v\n\t ", result, 3));
std::vector<unsigned char> expected = ParseHex("971a55");
constexpr auto expected{"971a55"_hex_u8};
BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());

BOOST_CHECK(DecodeBase58Check("3vQB7B6MrGQZaxCuFg4oh"s, result, 100));
Expand Down
Loading

0 comments on commit b52d547

Please sign in to comment.