Skip to content

Commit e7652d3

Browse files
committed
Add WriteHDKeypath function and move *HDKeypath to util/bip32.{h,cpp}
Creates new files util/bip32.h and util/bip32.cpp for containing BIP 32 stuff. Moves FormatKeyPath from descriptor.cpp to util/bip32. Adds a wrapper around it to prepent the 'm' for when just the BIP 32 style keypath is needed.
1 parent c45415f commit e7652d3

File tree

10 files changed

+95
-57
lines changed

10 files changed

+95
-57
lines changed

src/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ BITCOIN_CORE_H = \
196196
txmempool.h \
197197
ui_interface.h \
198198
undo.h \
199+
util/bip32.h \
199200
util/bytevectorhash.h \
200201
util/system.h \
201202
util/memory.h \
@@ -456,6 +457,7 @@ libbitcoin_util_a_SOURCES = \
456457
support/cleanse.cpp \
457458
sync.cpp \
458459
threadinterrupt.cpp \
460+
util/bip32.cpp \
459461
util/bytevectorhash.cpp \
460462
util/system.cpp \
461463
util/moneystr.cpp \

src/rpc/rawtransaction.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <script/sign.h>
2727
#include <script/standard.h>
2828
#include <uint256.h>
29+
#include <util/bip32.h>
2930
#include <util/strencodings.h>
3031
#include <validation.h>
3132
#include <validationinterface.h>

src/script/descriptor.cpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <script/standard.h>
1111

1212
#include <span.h>
13+
#include <util/bip32.h>
1314
#include <util/system.h>
1415
#include <util/strencodings.h>
1516

@@ -25,16 +26,6 @@ namespace {
2526

2627
typedef std::vector<uint32_t> KeyPath;
2728

28-
std::string FormatKeyPath(const KeyPath& path)
29-
{
30-
std::string ret;
31-
for (auto i : path) {
32-
ret += strprintf("/%i", (i << 1) >> 1);
33-
if (i >> 31) ret += '\'';
34-
}
35-
return ret;
36-
}
37-
3829
/** Interface for public key objects in descriptors. */
3930
struct PubkeyProvider
4031
{
@@ -63,7 +54,7 @@ class OriginPubkeyProvider final : public PubkeyProvider
6354

6455
std::string OriginString() const
6556
{
66-
return HexStr(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint)) + FormatKeyPath(m_origin.path);
57+
return HexStr(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint)) + FormatHDKeypath(m_origin.path);
6758
}
6859

6960
public:
@@ -184,7 +175,7 @@ class BIP32PubkeyProvider final : public PubkeyProvider
184175
}
185176
std::string ToString() const override
186177
{
187-
std::string ret = EncodeExtPubKey(m_extkey) + FormatKeyPath(m_path);
178+
std::string ret = EncodeExtPubKey(m_extkey) + FormatHDKeypath(m_path);
188179
if (IsRange()) {
189180
ret += "/*";
190181
if (m_derive == DeriveType::HARDENED) ret += '\'';
@@ -195,7 +186,7 @@ class BIP32PubkeyProvider final : public PubkeyProvider
195186
{
196187
CExtKey key;
197188
if (!GetExtKey(arg, key)) return false;
198-
out = EncodeExtKey(key) + FormatKeyPath(m_path);
189+
out = EncodeExtKey(key) + FormatHDKeypath(m_path);
199190
if (IsRange()) {
200191
out += "/*";
201192
if (m_derive == DeriveType::HARDENED) out += '\'';

src/util/bip32.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright (c) 2019 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <sstream>
6+
#include <stdio.h>
7+
#include <tinyformat.h>
8+
#include <util/bip32.h>
9+
#include <util/strencodings.h>
10+
11+
12+
bool ParseHDKeypath(const std::string& keypath_str, std::vector<uint32_t>& keypath)
13+
{
14+
std::stringstream ss(keypath_str);
15+
std::string item;
16+
bool first = true;
17+
while (std::getline(ss, item, '/')) {
18+
if (item.compare("m") == 0) {
19+
if (first) {
20+
first = false;
21+
continue;
22+
}
23+
return false;
24+
}
25+
// Finds whether it is hardened
26+
uint32_t path = 0;
27+
size_t pos = item.find("'");
28+
if (pos != std::string::npos) {
29+
// The hardened tick can only be in the last index of the string
30+
if (pos != item.size() - 1) {
31+
return false;
32+
}
33+
path |= 0x80000000;
34+
item = item.substr(0, item.size() - 1); // Drop the last character which is the hardened tick
35+
}
36+
37+
// Ensure this is only numbers
38+
if (item.find_first_not_of( "0123456789" ) != std::string::npos) {
39+
return false;
40+
}
41+
uint32_t number;
42+
if (!ParseUInt32(item, &number)) {
43+
return false;
44+
}
45+
path |= number;
46+
47+
keypath.push_back(path);
48+
first = false;
49+
}
50+
return true;
51+
}
52+
53+
std::string FormatHDKeypath(const std::vector<uint32_t>& path)
54+
{
55+
std::string ret;
56+
for (auto i : path) {
57+
ret += strprintf("/%i", (i << 1) >> 1);
58+
if (i >> 31) ret += '\'';
59+
}
60+
return ret;
61+
}
62+
63+
std::string WriteHDKeypath(const std::vector<uint32_t>& keypath)
64+
{
65+
return "m" + FormatHDKeypath(keypath);
66+
}

src/util/bip32.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) 2019 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_UTIL_BIP32_H
6+
#define BITCOIN_UTIL_BIP32_H
7+
8+
#include <attributes.h>
9+
#include <string>
10+
#include <vector>
11+
12+
/** Parse an HD keypaths like "m/7/0'/2000". */
13+
NODISCARD bool ParseHDKeypath(const std::string& keypath_str, std::vector<uint32_t>& keypath);
14+
15+
/** Write HD keypaths as strings */
16+
std::string WriteHDKeypath(const std::vector<uint32_t>& keypath);
17+
std::string FormatHDKeypath(const std::vector<uint32_t>& path);
18+
19+
#endif // BITCOIN_UTIL_BIP32_H

src/util/strencodings.cpp

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -546,47 +546,6 @@ bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out)
546546
return true;
547547
}
548548

549-
bool ParseHDKeypath(const std::string& keypath_str, std::vector<uint32_t>& keypath)
550-
{
551-
std::stringstream ss(keypath_str);
552-
std::string item;
553-
bool first = true;
554-
while (std::getline(ss, item, '/')) {
555-
if (item.compare("m") == 0) {
556-
if (first) {
557-
first = false;
558-
continue;
559-
}
560-
return false;
561-
}
562-
// Finds whether it is hardened
563-
uint32_t path = 0;
564-
size_t pos = item.find("'");
565-
if (pos != std::string::npos) {
566-
// The hardened tick can only be in the last index of the string
567-
if (pos != item.size() - 1) {
568-
return false;
569-
}
570-
path |= 0x80000000;
571-
item = item.substr(0, item.size() - 1); // Drop the last character which is the hardened tick
572-
}
573-
574-
// Ensure this is only numbers
575-
if (item.find_first_not_of( "0123456789" ) != std::string::npos) {
576-
return false;
577-
}
578-
uint32_t number;
579-
if (!ParseUInt32(item, &number)) {
580-
return false;
581-
}
582-
path |= number;
583-
584-
keypath.push_back(path);
585-
first = false;
586-
}
587-
return true;
588-
}
589-
590549
void Downcase(std::string& str)
591550
{
592551
std::transform(str.begin(), str.end(), str.begin(), [](char c){return ToLower(c);});

src/util/strencodings.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,6 @@ bool ConvertBits(const O& outfn, I it, I end) {
197197
return true;
198198
}
199199

200-
/** Parse an HD keypaths like "m/7/0'/2000". */
201-
NODISCARD bool ParseHDKeypath(const std::string& keypath_str, std::vector<uint32_t>& keypath);
202-
203200
/**
204201
* Converts the given character to its lowercase equivalent.
205202
* This function is locale independent. It only converts uppercase

src/wallet/rpcwallet.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <script/sign.h>
2828
#include <shutdown.h>
2929
#include <timedata.h>
30+
#include <util/bip32.h>
3031
#include <util/system.h>
3132
#include <util/moneystr.h>
3233
#include <wallet/coincontrol.h>

src/wallet/test/psbt_wallet_tests.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include <key_io.h>
66
#include <script/sign.h>
7+
#include <util/bip32.h>
78
#include <util/strencodings.h>
89
#include <wallet/psbtwallet.h>
910
#include <wallet/rpcwallet.h>

src/wallet/wallet.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <shutdown.h>
2828
#include <timedata.h>
2929
#include <txmempool.h>
30+
#include <util/bip32.h>
3031
#include <util/moneystr.h>
3132
#include <wallet/fees.h>
3233

0 commit comments

Comments
 (0)