mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-09-11 21:20:39 +02:00
descriptor: Add ToCanonicalString
This commit is contained in:
@@ -203,6 +203,7 @@ public:
|
||||
|
||||
enum class StringType {
|
||||
PUBLIC,
|
||||
CANONICAL, // string calculation that always use h
|
||||
COMPAT // string calculation that mustn't change over time to stay compatible with previous software versions
|
||||
};
|
||||
|
||||
@@ -259,7 +260,7 @@ class OriginPubkeyProvider final : public PubkeyProvider
|
||||
std::string OriginString(StringType type, bool normalized=false) const
|
||||
{
|
||||
// If StringType==COMPAT, always use the apostrophe to stay compatible with previous versions
|
||||
bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
|
||||
bool use_apostrophe = (type != StringType::CANONICAL && !normalized && m_apostrophe) || type == StringType::COMPAT;
|
||||
return HexStr(m_origin.fingerprint) + FormatHDKeypath(m_origin.path, use_apostrophe);
|
||||
}
|
||||
|
||||
@@ -509,7 +510,7 @@ public:
|
||||
std::string ToString(StringType type, bool normalized) const
|
||||
{
|
||||
// If StringType==COMPAT, always use the apostrophe to stay compatible with previous versions
|
||||
const bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
|
||||
const bool use_apostrophe = (type != StringType::CANONICAL && !normalized && m_apostrophe) || type == StringType::COMPAT;
|
||||
std::string ret = EncodeExtPubKey(m_root_extkey) + FormatHDKeypath(m_path, /*apostrophe=*/use_apostrophe);
|
||||
if (IsRange()) {
|
||||
ret += "/*";
|
||||
@@ -874,6 +875,7 @@ public:
|
||||
PUBLIC,
|
||||
PRIVATE,
|
||||
NORMALIZED,
|
||||
CANONICAL,
|
||||
COMPAT, // string calculation that mustn't change over time to stay compatible with previous software versions
|
||||
};
|
||||
|
||||
@@ -960,6 +962,9 @@ public:
|
||||
case StringType::COMPAT:
|
||||
tmp = pubkey->ToString(PubkeyProvider::StringType::COMPAT);
|
||||
break;
|
||||
case StringType::CANONICAL:
|
||||
tmp = pubkey->ToString(PubkeyProvider::StringType::CANONICAL);
|
||||
break;
|
||||
}
|
||||
ret += tmp;
|
||||
}
|
||||
@@ -979,6 +984,13 @@ public:
|
||||
return AddChecksum(ret);
|
||||
}
|
||||
|
||||
std::string ToCanonicalString() const final
|
||||
{
|
||||
std::string ret;
|
||||
ToStringHelper(nullptr, ret, StringType::CANONICAL);
|
||||
return AddChecksum(ret);
|
||||
}
|
||||
|
||||
bool ToPrivateString(const SigningProvider& arg, std::string& out) const override
|
||||
{
|
||||
bool has_priv_key{ToStringHelper(&arg, out, StringType::PRIVATE)};
|
||||
@@ -1667,6 +1679,9 @@ public:
|
||||
// must be preserved for wallets with Miniscript descriptors to be loaded
|
||||
ret = m_pubkeys[key]->ToString(PubkeyProvider::StringType::PUBLIC);
|
||||
break;
|
||||
case DescriptorImpl::StringType::CANONICAL:
|
||||
ret = m_pubkeys[key]->ToString(PubkeyProvider::StringType::CANONICAL);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -118,6 +118,11 @@ struct Descriptor {
|
||||
/** Convert the descriptor back to a string, undoing parsing. */
|
||||
virtual std::string ToString(bool compat_format=false) const = 0;
|
||||
|
||||
/** Convert the descriptor to the canonical string.
|
||||
* The canonical string is the same as the public string but always uses h as the hardened indicator
|
||||
*/
|
||||
virtual std::string ToCanonicalString() const = 0;
|
||||
|
||||
/** Whether this descriptor will return at most one scriptPubKey or multiple (aka is or is not combo) */
|
||||
virtual bool IsSingleType() const = 0;
|
||||
|
||||
|
||||
@@ -226,14 +226,21 @@ void DoCheck(std::string prv, std::string pub, const std::string& norm_pub, int
|
||||
// Otherwise check that they serialize back to the public version.
|
||||
std::string pub1 = parse_priv->ToString();
|
||||
std::string pub2 = parse_pub->ToString();
|
||||
std::string canonical = UseHInsteadOfApostrophe(pub);
|
||||
if (expected_pub) {
|
||||
BOOST_CHECK_MESSAGE(EqualDescriptor(*expected_pub, pub1), "Private ser: " + pub1 + " Public desc: " + *expected_pub);
|
||||
BOOST_CHECK_MESSAGE(EqualDescriptor(*expected_pub, pub2), "Public ser: " + pub2 + " Public desc: " + *expected_pub);
|
||||
canonical = UseHInsteadOfApostrophe(*expected_pub);
|
||||
} else {
|
||||
BOOST_CHECK_MESSAGE(EqualDescriptor(pub, pub1), "Private ser: " + pub1 + " Public desc: " + pub);
|
||||
BOOST_CHECK_MESSAGE(EqualDescriptor(pub, pub2), "Public ser: " + pub2 + " Public desc: " + pub);
|
||||
}
|
||||
|
||||
std::string priv_canonical = parse_priv->ToCanonicalString();
|
||||
std::string pub_canonical = parse_pub->ToCanonicalString();
|
||||
BOOST_CHECK_MESSAGE(EqualDescriptor(priv_canonical, canonical), "Private ser: " + priv_canonical + " Expected desc: " + canonical);
|
||||
BOOST_CHECK_MESSAGE(EqualDescriptor(pub_canonical, canonical), "Public ser: " + pub_canonical + " Expected desc: " + canonical);
|
||||
|
||||
// Check that the COMPAT identifier did not change
|
||||
if (op_desc_id) {
|
||||
BOOST_CHECK_MESSAGE(DescriptorID(*parse_priv) == *op_desc_id, "DescriptorID() " + DescriptorID(*parse_priv).ToString() + " does not match for priv " + prv);
|
||||
|
||||
@@ -22,6 +22,7 @@ public:
|
||||
~DummyDescriptor() = default;
|
||||
|
||||
std::string ToString(bool compat_format) const override { return desc; }
|
||||
std::string ToCanonicalString() const override { return desc; }
|
||||
std::optional<OutputType> GetOutputType() const override { return OutputType::UNKNOWN; }
|
||||
|
||||
bool IsRange() const override { return false; }
|
||||
|
||||
Reference in New Issue
Block a user