Page MenuHomePhabricator

D4486.diff
No OneTemporary

D4486.diff

diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -1529,12 +1529,10 @@
UniValue keypath(UniValue::VOBJ);
keypath.pushKV("pubkey", HexStr(entry.first));
- uint32_t fingerprint = entry.second.at(0);
- keypath.pushKV("master_fingerprint",
- strprintf("%08x", bswap_32(fingerprint)));
-
- entry.second.erase(entry.second.begin());
- keypath.pushKV("path", WriteHDKeypath(entry.second));
+ keypath.pushKV(
+ "master_fingerprint",
+ strprintf("%08x", ReadBE32(entry.second.fingerprint)));
+ keypath.pushKV("path", WriteHDKeypath(entry.second.path));
keypaths.push_back(keypath);
}
in.pushKV("bip32_derivs", keypaths);
@@ -1581,13 +1579,10 @@
for (auto entry : output.hd_keypaths) {
UniValue keypath(UniValue::VOBJ);
keypath.pushKV("pubkey", HexStr(entry.first));
-
- uint32_t fingerprint = entry.second.at(0);
- keypath.pushKV("master_fingerprint",
- strprintf("%08x", bswap_32(fingerprint)));
-
- entry.second.erase(entry.second.begin());
- keypath.pushKV("path", WriteHDKeypath(entry.second));
+ keypath.pushKV(
+ "master_fingerprint",
+ strprintf("%08x", ReadBE32(entry.second.fingerprint)));
+ keypath.pushKV("path", WriteHDKeypath(entry.second.path));
keypaths.push_back(keypath);
}
out.pushKV("bip32_derivs", keypaths);
diff --git a/src/script/sign.h b/src/script/sign.h
--- a/src/script/sign.h
+++ b/src/script/sign.h
@@ -21,6 +21,11 @@
class CScriptID;
class CTransaction;
+struct KeyOriginInfo {
+ uint8_t fingerprint[4];
+ std::vector<uint32_t> path;
+};
+
/** An interface to be implemented by keystores that support signing. */
class SigningProvider {
public:
@@ -171,9 +176,8 @@
// Deserialize HD keypaths into a map
template <typename Stream>
-void DeserializeHDKeypaths(
- Stream &s, const std::vector<uint8_t> &key,
- std::map<CPubKey, std::vector<uint32_t>> &hd_keypaths) {
+void DeserializeHDKeypaths(Stream &s, const std::vector<uint8_t> &key,
+ std::map<CPubKey, KeyOriginInfo> &hd_keypaths) {
// Make sure that the key is the size of pubkey + 1
if (key.size() != CPubKey::PUBLIC_KEY_SIZE + 1 &&
key.size() != CPubKey::COMPRESSED_PUBLIC_KEY_SIZE + 1) {
@@ -192,26 +196,33 @@
// Read in key path
uint64_t value_len = ReadCompactSize(s);
- std::vector<uint32_t> keypath;
- for (uint64_t i = 0; i < value_len; i += sizeof(uint32_t)) {
+ if (value_len % 4 || value_len == 0) {
+ throw std::ios_base::failure("Invalid length for HD key path");
+ }
+
+ KeyOriginInfo keypath;
+ s >> keypath.fingerprint;
+ for (unsigned int i = 4; i < value_len; i += sizeof(uint32_t)) {
uint32_t index;
s >> index;
- keypath.push_back(index);
+ keypath.path.push_back(index);
}
// Add to map
- hd_keypaths.emplace(pubkey, keypath);
+ hd_keypaths.emplace(pubkey, std::move(keypath));
}
// Serialize HD keypaths to a stream from a map
template <typename Stream>
-void SerializeHDKeypaths(
- Stream &s, const std::map<CPubKey, std::vector<uint32_t>> &hd_keypaths,
- uint8_t type) {
+void SerializeHDKeypaths(Stream &s,
+ const std::map<CPubKey, KeyOriginInfo> &hd_keypaths,
+ uint8_t type) {
for (auto keypath_pair : hd_keypaths) {
SerializeToVector(s, type, MakeSpan(keypath_pair.first));
- WriteCompactSize(s, keypath_pair.second.size() * sizeof(uint32_t));
- for (auto &path : keypath_pair.second) {
+ WriteCompactSize(s, (keypath_pair.second.path.size() + 1) *
+ sizeof(uint32_t));
+ s << keypath_pair.second.fingerprint;
+ for (const auto &path : keypath_pair.second.path) {
s << path;
}
}
@@ -222,7 +233,7 @@
CTxOut utxo;
CScript redeem_script;
CScript final_script_sig;
- std::map<CPubKey, std::vector<uint32_t>> hd_keypaths;
+ std::map<CPubKey, KeyOriginInfo> hd_keypaths;
std::map<CKeyID, SigPair> partial_sigs;
std::map<std::vector<uint8_t>, std::vector<uint8_t>> unknown;
SigHashType sighash_type = SigHashType(0);
@@ -401,7 +412,7 @@
/** A structure for PSBTs which contains per output information */
struct PSBTOutput {
CScript redeem_script;
- std::map<CPubKey, std::vector<uint32_t>> hd_keypaths;
+ std::map<CPubKey, KeyOriginInfo> hd_keypaths;
std::map<std::vector<uint8_t>, std::vector<uint8_t>> unknown;
bool IsNull() const;
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -5124,9 +5124,8 @@
return true;
}
-static void
-AddKeypathToMap(const CWallet *pwallet, const CKeyID &keyID,
- std::map<CPubKey, std::vector<uint32_t>> &hd_keypaths) {
+static void AddKeypathToMap(const CWallet *pwallet, const CKeyID &keyID,
+ std::map<CPubKey, KeyOriginInfo> &hd_keypaths) {
CPubKey vchPubKey;
if (!pwallet->GetPubKey(keyID, vchPubKey)) {
return;
@@ -5136,9 +5135,9 @@
if (it != pwallet->mapKeyMetadata.end()) {
meta = it->second;
}
- std::vector<uint32_t> keypath;
+ KeyOriginInfo info;
if (!meta.hdKeypath.empty()) {
- if (!ParseHDKeypath(meta.hdKeypath, keypath)) {
+ if (!ParseHDKeypath(meta.hdKeypath, info.path)) {
throw JSONRPCError(RPC_INTERNAL_ERROR,
"Internal keypath is broken");
}
@@ -5147,14 +5146,14 @@
pwallet->GetKey(meta.hd_seed_id, key);
CExtKey masterKey;
masterKey.SetSeed(key.begin(), key.size());
- // Add to map
- keypath.insert(keypath.begin(),
- ReadLE32(masterKey.key.GetPubKey().GetID().begin()));
+ // Compute identifier
+ CKeyID masterid = masterKey.key.GetPubKey().GetID();
+ std::copy(masterid.begin(), masterid.begin() + 4, info.fingerprint);
} else {
// Single pubkeys get the master fingerprint of themselves
- keypath.insert(keypath.begin(), ReadLE32(vchPubKey.GetID().begin()));
+ std::copy(keyID.begin(), keyID.begin() + 4, info.fingerprint);
}
- hd_keypaths.emplace(vchPubKey, keypath);
+ hd_keypaths.emplace(vchPubKey, std::move(info));
}
bool FillPSBT(const CWallet *pwallet, PartiallySignedTransaction &psbtx,

File Metadata

Mime Type
text/plain
Expires
Sat, Mar 1, 11:01 (12 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5187451
Default Alt Text
D4486.diff (6 KB)

Event Timeline