Changeset View
Changeset View
Standalone View
Standalone View
src/script/descriptor.cpp
Show First 20 Lines • Show All 1,060 Lines • ▼ Show 20 Lines | if (ExtractDestination(script, dest)) { | ||||
} | } | ||||
} | } | ||||
return std::make_unique<RawDescriptor>(script); | return std::make_unique<RawDescriptor>(script); | ||||
} | } | ||||
} // namespace | } // namespace | ||||
std::unique_ptr<Descriptor> Parse(const std::string &descriptor, | /** | ||||
FlatSigningProvider &out, | * Check a descriptor checksum, and update desc to be the checksum-less part. | ||||
bool require_checksum) { | */ | ||||
Span<const char> sp(descriptor.data(), descriptor.size()); | bool CheckChecksum(Span<const char> &sp, bool require_checksum, | ||||
std::string *out_checksum = nullptr) { | |||||
// Checksum checks | |||||
auto check_split = Split(sp, '#'); | auto check_split = Split(sp, '#'); | ||||
if (check_split.size() > 2) { | if (check_split.size() > 2) { | ||||
// Multiple '#' symbols | // Multiple '#' symbols | ||||
return nullptr; | return false; | ||||
} | } | ||||
if (check_split.size() == 1 && require_checksum) { | if (check_split.size() == 1 && require_checksum) { | ||||
// Missing checksum | // Missing checksum | ||||
return nullptr; | return false; | ||||
} | } | ||||
if (check_split.size() == 2) { | if (check_split.size() == 2) { | ||||
if (check_split[1].size() != 8) { | if (check_split[1].size() != 8) { | ||||
// Unexpected length for checksum | // Unexpected length for checksum | ||||
return nullptr; | return false; | ||||
} | |||||
} | } | ||||
auto checksum = DescriptorChecksum(check_split[0]); | auto checksum = DescriptorChecksum(check_split[0]); | ||||
if (checksum.empty()) { | if (checksum.empty()) { | ||||
// Invalid characters in payload | // Invalid characters in payload | ||||
return nullptr; | return false; | ||||
} | } | ||||
if (check_split.size() == 2) { | |||||
if (!std::equal(checksum.begin(), checksum.end(), | if (!std::equal(checksum.begin(), checksum.end(), | ||||
check_split[1].begin())) { | check_split[1].begin())) { | ||||
// Checksum mismatch | // Checksum mismatch | ||||
return nullptr; | return false; | ||||
} | |||||
} | } | ||||
if (out_checksum) { | |||||
*out_checksum = std::move(checksum); | |||||
} | } | ||||
sp = check_split[0]; | sp = check_split[0]; | ||||
return true; | |||||
} | |||||
std::unique_ptr<Descriptor> Parse(const std::string &descriptor, | |||||
FlatSigningProvider &out, | |||||
bool require_checksum) { | |||||
Span<const char> sp(descriptor.data(), descriptor.size()); | |||||
if (!CheckChecksum(sp, require_checksum)) { | |||||
return nullptr; | |||||
} | |||||
auto ret = ParseScript(sp, ParseScriptContext::TOP, out); | auto ret = ParseScript(sp, ParseScriptContext::TOP, out); | ||||
if (sp.size() == 0 && ret) { | if (sp.size() == 0 && ret) { | ||||
return std::unique_ptr<Descriptor>(std::move(ret)); | return std::unique_ptr<Descriptor>(std::move(ret)); | ||||
} | } | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
std::unique_ptr<Descriptor> InferDescriptor(const CScript &script, | std::unique_ptr<Descriptor> InferDescriptor(const CScript &script, | ||||
const SigningProvider &provider) { | const SigningProvider &provider) { | ||||
return InferScript(script, ParseScriptContext::TOP, provider); | return InferScript(script, ParseScriptContext::TOP, provider); | ||||
} | } |