mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-09 11:27:28 -03:00
Merge 352391c2cf
into 433412fd84
This commit is contained in:
commit
d6d6ae91fa
3 changed files with 77 additions and 5 deletions
|
@ -1360,7 +1360,7 @@ public:
|
||||||
for (const auto& arg : m_pubkey_args) {
|
for (const auto& arg : m_pubkey_args) {
|
||||||
providers.push_back(arg->Clone());
|
providers.push_back(arg->Clone());
|
||||||
}
|
}
|
||||||
return std::make_unique<MiniscriptDescriptor>(std::move(providers), miniscript::MakeNodeRef<uint32_t>(*m_node));
|
return std::make_unique<MiniscriptDescriptor>(std::move(providers), m_node->Clone());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2150,7 +2150,7 @@ std::vector<std::unique_ptr<DescriptorImpl>> ParseScript(uint32_t& key_exp_index
|
||||||
for (auto& pub : parser.m_keys) {
|
for (auto& pub : parser.m_keys) {
|
||||||
pubs.emplace_back(std::move(pub.at(i)));
|
pubs.emplace_back(std::move(pub.at(i)));
|
||||||
}
|
}
|
||||||
ret.emplace_back(std::make_unique<MiniscriptDescriptor>(std::move(pubs), node));
|
ret.emplace_back(std::make_unique<MiniscriptDescriptor>(std::move(pubs), node->Clone()));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,11 +189,11 @@ inline consteval Type operator""_mst(const char* c, size_t l)
|
||||||
using Opcode = std::pair<opcodetype, std::vector<unsigned char>>;
|
using Opcode = std::pair<opcodetype, std::vector<unsigned char>>;
|
||||||
|
|
||||||
template<typename Key> struct Node;
|
template<typename Key> struct Node;
|
||||||
template<typename Key> using NodeRef = std::shared_ptr<const Node<Key>>;
|
template<typename Key> using NodeRef = std::unique_ptr<const Node<Key>>;
|
||||||
|
|
||||||
//! Construct a miniscript node as a shared_ptr.
|
//! Construct a miniscript node as a unique_ptr.
|
||||||
template<typename Key, typename... Args>
|
template<typename Key, typename... Args>
|
||||||
NodeRef<Key> MakeNodeRef(Args&&... args) { return std::make_shared<const Node<Key>>(std::forward<Args>(args)...); }
|
NodeRef<Key> MakeNodeRef(Args&&... args) { return std::make_unique<const Node<Key>>(std::forward<Args>(args)...); }
|
||||||
|
|
||||||
//! The different node types in miniscript.
|
//! The different node types in miniscript.
|
||||||
enum class Fragment {
|
enum class Fragment {
|
||||||
|
@ -528,6 +528,35 @@ struct Node {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeRef<Key> Clone() const
|
||||||
|
{
|
||||||
|
// Use TreeEval() to avoid a stack-overflow due to recursion
|
||||||
|
auto upfn = [](const Node& node, Span<NodeRef<Key>> children) {
|
||||||
|
NodeRef<Key> ret;
|
||||||
|
// As all members of Node are const, except for subs, we need to construct the cloned node with all of these members.
|
||||||
|
// However, there is no constructor that takes all three of data, keys, and subs.
|
||||||
|
// But, they are mutually exclusive, so we can use the appropriate constructor depending on what is available.
|
||||||
|
if (!node.keys.empty()) {
|
||||||
|
Assert(node.data.empty() && node.subs.empty());
|
||||||
|
ret = MakeNodeRef<Key>(internal::NoDupCheck{}, node.m_script_ctx, node.fragment, node.keys, node.k);
|
||||||
|
} else if (!node.data.empty()) {
|
||||||
|
Assert(node.keys.empty() && node.subs.empty());
|
||||||
|
ret = MakeNodeRef<Key>(internal::NoDupCheck{}, node.m_script_ctx, node.fragment, node.data, node.k);
|
||||||
|
} else if (!node.subs.empty()) {
|
||||||
|
Assert(node.data.empty() && node.keys.empty());
|
||||||
|
std::vector<NodeRef<Key>> new_subs;
|
||||||
|
for (auto child = children.begin(); child != children.end(); ++child) {
|
||||||
|
new_subs.emplace_back(std::move(*child));
|
||||||
|
}
|
||||||
|
ret = MakeNodeRef<Key>(internal::NoDupCheck{}, node.m_script_ctx, node.fragment, std::move(new_subs), node.k);
|
||||||
|
} else {
|
||||||
|
ret = MakeNodeRef<Key>(internal::NoDupCheck{}, node.m_script_ctx, node.fragment, node.k);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
return TreeEval<NodeRef<Key>>(upfn);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! Cached ops counts.
|
//! Cached ops counts.
|
||||||
const internal::Ops ops;
|
const internal::Ops ops;
|
||||||
|
@ -1663,6 +1692,10 @@ public:
|
||||||
: Node(internal::NoDupCheck{}, ctx.MsContext(), nt, std::move(sub), val) { DuplicateKeyCheck(ctx); }
|
: Node(internal::NoDupCheck{}, ctx.MsContext(), nt, std::move(sub), val) { DuplicateKeyCheck(ctx); }
|
||||||
template <typename Ctx> Node(const Ctx& ctx, Fragment nt, uint32_t val = 0)
|
template <typename Ctx> Node(const Ctx& ctx, Fragment nt, uint32_t val = 0)
|
||||||
: Node(internal::NoDupCheck{}, ctx.MsContext(), nt, val) { DuplicateKeyCheck(ctx); }
|
: Node(internal::NoDupCheck{}, ctx.MsContext(), nt, val) { DuplicateKeyCheck(ctx); }
|
||||||
|
|
||||||
|
// Delete copy constructor and assignment operator, use Clone() instead
|
||||||
|
Node(const Node&) = delete;
|
||||||
|
Node& operator=(const Node&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
|
@ -430,6 +430,20 @@ void CheckMultipath(const std::string& prv,
|
||||||
/*spender_nlocktime=*/0, /*spender_nsequence=*/CTxIn::SEQUENCE_FINAL, /*preimages=*/{},
|
/*spender_nlocktime=*/0, /*spender_nsequence=*/CTxIn::SEQUENCE_FINAL, /*preimages=*/{},
|
||||||
expanded_prvs.at(i), expanded_pubs.at(i), i);
|
expanded_prvs.at(i), expanded_pubs.at(i), i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The descriptor for each path must be standalone. They should not share common references. Test this
|
||||||
|
// by parsing a multipath descriptor expression, deallocating all but one of the descriptors and making
|
||||||
|
// sure we can perform operations on it.
|
||||||
|
FlatSigningProvider prov, out;
|
||||||
|
std::string error;
|
||||||
|
const auto desc{[&](){
|
||||||
|
auto parsed{Parse(pub, prov, error)};
|
||||||
|
assert(parsed.size() > 1);
|
||||||
|
return std::move(parsed.at(0));
|
||||||
|
}()};
|
||||||
|
desc->ToString();
|
||||||
|
std::vector<CScript> out_scripts;
|
||||||
|
desc->Expand(0, prov, out_scripts, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckInferDescriptor(const std::string& script_hex, const std::string& expected_desc, const std::vector<std::string>& hex_scripts, const std::vector<std::pair<std::string, std::string>>& origin_pubkeys)
|
void CheckInferDescriptor(const std::string& script_hex, const std::string& expected_desc, const std::vector<std::string>& hex_scripts, const std::vector<std::pair<std::string, std::string>>& origin_pubkeys)
|
||||||
|
@ -808,6 +822,31 @@ BOOST_AUTO_TEST_CASE(descriptor_test)
|
||||||
{{0x80000000UL + 48, 0x80000000UL + 1, 0x80000000UL, 0x80000000UL + 2, 1, 0}, {0x80000000UL + 48, 0x80000000UL + 1, 0x80000000UL, 0x80000000UL + 2, 1, 1}, {0x80000000UL + 48, 0x80000000UL + 1, 0x80000000UL, 0x80000000UL + 2, 1, 2}},
|
{{0x80000000UL + 48, 0x80000000UL + 1, 0x80000000UL, 0x80000000UL + 2, 1, 0}, {0x80000000UL + 48, 0x80000000UL + 1, 0x80000000UL, 0x80000000UL + 2, 1, 1}, {0x80000000UL + 48, 0x80000000UL + 1, 0x80000000UL, 0x80000000UL + 2, 1, 2}},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
CheckMultipath("tr(xprv9yYge4PS54XkYT9KiLfCRwc8Jeuz8DucxQGtuEecJZYhKNiqbPxYHTPzXtskmzWBqdqkRAGsghNmZzNsfU2wstaB3XjDQFPv567aQSSuPyo/<2;3>,l:pk(xprvA1ADjaN8H3HGnZSmt4VF7YdWoV9oNq8jhqhurxsrYycBAFK555cECoaY22KWt6BTRNLuvobW5VQTF89PN3iA485LAg7epazevPyjCa4xTzd))",
|
||||||
|
"tr(xpub6CY33ZvKuS63kwDnpNCCo5YrrgkUXgdUKdCVhd4Dru5gCB3z8wGnqFiUP98Za5pYSYF5KmvBHTY3Ra8FAJGggzBjuHS69WzN8gscPupuZwK/<2;3>,l:pk(xpub6E9a95u27Qqa13XEz62FUgaFMWzHnHrb54dWfMHU7K9A33eDccvUkbu1sHYoByHAgJdR326rWqn9pGZgZHz1afDprW5gGwS4gUX8Ri6aGPZ))",
|
||||||
|
{
|
||||||
|
"tr(xprv9yYge4PS54XkYT9KiLfCRwc8Jeuz8DucxQGtuEecJZYhKNiqbPxYHTPzXtskmzWBqdqkRAGsghNmZzNsfU2wstaB3XjDQFPv567aQSSuPyo/2,l:pk(xprvA1ADjaN8H3HGnZSmt4VF7YdWoV9oNq8jhqhurxsrYycBAFK555cECoaY22KWt6BTRNLuvobW5VQTF89PN3iA485LAg7epazevPyjCa4xTzd))",
|
||||||
|
"tr(xprv9yYge4PS54XkYT9KiLfCRwc8Jeuz8DucxQGtuEecJZYhKNiqbPxYHTPzXtskmzWBqdqkRAGsghNmZzNsfU2wstaB3XjDQFPv567aQSSuPyo/3,l:pk(xprvA1ADjaN8H3HGnZSmt4VF7YdWoV9oNq8jhqhurxsrYycBAFK555cECoaY22KWt6BTRNLuvobW5VQTF89PN3iA485LAg7epazevPyjCa4xTzd))",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tr(xpub6CY33ZvKuS63kwDnpNCCo5YrrgkUXgdUKdCVhd4Dru5gCB3z8wGnqFiUP98Za5pYSYF5KmvBHTY3Ra8FAJGggzBjuHS69WzN8gscPupuZwK/2,l:pk(xpub6E9a95u27Qqa13XEz62FUgaFMWzHnHrb54dWfMHU7K9A33eDccvUkbu1sHYoByHAgJdR326rWqn9pGZgZHz1afDprW5gGwS4gUX8Ri6aGPZ))",
|
||||||
|
"tr(xpub6CY33ZvKuS63kwDnpNCCo5YrrgkUXgdUKdCVhd4Dru5gCB3z8wGnqFiUP98Za5pYSYF5KmvBHTY3Ra8FAJGggzBjuHS69WzN8gscPupuZwK/3,l:pk(xpub6E9a95u27Qqa13XEz62FUgaFMWzHnHrb54dWfMHU7K9A33eDccvUkbu1sHYoByHAgJdR326rWqn9pGZgZHz1afDprW5gGwS4gUX8Ri6aGPZ))",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tr(xpub6CY33ZvKuS63kwDnpNCCo5YrrgkUXgdUKdCVhd4Dru5gCB3z8wGnqFiUP98Za5pYSYF5KmvBHTY3Ra8FAJGggzBjuHS69WzN8gscPupuZwK/2,l:pk(xpub6E9a95u27Qqa13XEz62FUgaFMWzHnHrb54dWfMHU7K9A33eDccvUkbu1sHYoByHAgJdR326rWqn9pGZgZHz1afDprW5gGwS4gUX8Ri6aGPZ))",
|
||||||
|
"tr(xpub6CY33ZvKuS63kwDnpNCCo5YrrgkUXgdUKdCVhd4Dru5gCB3z8wGnqFiUP98Za5pYSYF5KmvBHTY3Ra8FAJGggzBjuHS69WzN8gscPupuZwK/3,l:pk(xpub6E9a95u27Qqa13XEz62FUgaFMWzHnHrb54dWfMHU7K9A33eDccvUkbu1sHYoByHAgJdR326rWqn9pGZgZHz1afDprW5gGwS4gUX8Ri6aGPZ))",
|
||||||
|
},
|
||||||
|
XONLY_KEYS,
|
||||||
|
{
|
||||||
|
{{"51200e3c14456bfa30f9f0bed6e55f35e1e9ca17c835e9f71b25bac0dfaab38ff2cd"}},
|
||||||
|
{{"51202bdda29337ecaf8fcd5aa395febac6f99b8a866a0e8fb3f7bde2e24b1a7df2ba"}},
|
||||||
|
},
|
||||||
|
OutputType::BECH32M,
|
||||||
|
{
|
||||||
|
{{2}, {}},
|
||||||
|
{{3}, {}},
|
||||||
|
}
|
||||||
|
);
|
||||||
CheckUnparsable("pkh(xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/<0;1>/<2;3>)", "pkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/<0;1>/<2;3>)", "pkh(): Multiple multipath key path specifiers found");
|
CheckUnparsable("pkh(xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/<0;1>/<2;3>)", "pkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/<0;1>/<2;3>)", "pkh(): Multiple multipath key path specifiers found");
|
||||||
CheckUnparsable("pkh([deadbeef/<0;1>]xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/0)", "pkh([deadbeef/<0;1>]xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/0)", "pkh(): Key path value \'<0;1>\' specifies multipath in a section where multipath is not allowed");
|
CheckUnparsable("pkh([deadbeef/<0;1>]xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/0)", "pkh([deadbeef/<0;1>]xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/0)", "pkh(): Key path value \'<0;1>\' specifies multipath in a section where multipath is not allowed");
|
||||||
CheckUnparsable("tr(xprv9s21ZrQH143K2Zu2kTVKcQi9nKhfgJUkYqG73wXsHuhATm1wkt6kcSZeTYEw2PL7krZtJopEYDvBdYWdAai3n3TWUTCVfHvPHqTYJv7smYe/6/*,{pk(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/<1;2;3>/0/*),pk(xprv9s21ZrQH143K3jUwNHoqQNrtzJnJmx4Yup8NkNLdVQCymYbPbJXnPhwkfTfxZfptcs3rLAPUXS39oDLgrNKQGwbGsEmJJ8BU3RzQuvShEG4/0/0/<3;4>/*)})", "tr(xpub6B4sSbNr8XFYXqqKB7PeUemqgEaVtCLjgd5Lf2VYtezSHozC7ffCvVNCyu9TCgHntRQdimjV3tHbxmNfocxtuh6saNtZEw91gjXLRhQ3Yar/6/*,{pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/<1;2;3>/0/*),pk(xpub6AhFhZJJGt9YB8i85RfrJ8jT3T2FF5EejDCXqXfm1DAczFEXkk8HD3CXTg2TmKM8wTbSnSw3wPg5JuyLitUrpRmkjn2BQXyZnqJx16AGy94/0/0/<3;4>/*)})", "tr(): Multipath subscripts have mismatched lengths");
|
CheckUnparsable("tr(xprv9s21ZrQH143K2Zu2kTVKcQi9nKhfgJUkYqG73wXsHuhATm1wkt6kcSZeTYEw2PL7krZtJopEYDvBdYWdAai3n3TWUTCVfHvPHqTYJv7smYe/6/*,{pk(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/<1;2;3>/0/*),pk(xprv9s21ZrQH143K3jUwNHoqQNrtzJnJmx4Yup8NkNLdVQCymYbPbJXnPhwkfTfxZfptcs3rLAPUXS39oDLgrNKQGwbGsEmJJ8BU3RzQuvShEG4/0/0/<3;4>/*)})", "tr(xpub6B4sSbNr8XFYXqqKB7PeUemqgEaVtCLjgd5Lf2VYtezSHozC7ffCvVNCyu9TCgHntRQdimjV3tHbxmNfocxtuh6saNtZEw91gjXLRhQ3Yar/6/*,{pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/<1;2;3>/0/*),pk(xpub6AhFhZJJGt9YB8i85RfrJ8jT3T2FF5EejDCXqXfm1DAczFEXkk8HD3CXTg2TmKM8wTbSnSw3wPg5JuyLitUrpRmkjn2BQXyZnqJx16AGy94/0/0/<3;4>/*)})", "tr(): Multipath subscripts have mismatched lengths");
|
||||||
|
|
Loading…
Reference in a new issue