aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/psbt.cpp4
-rw-r--r--src/psbt.h116
-rw-r--r--src/rpc/rawtransaction.cpp54
3 files changed, 173 insertions, 1 deletions
diff --git a/src/psbt.cpp b/src/psbt.cpp
index 4c9b439815..203e0a0bd3 100644
--- a/src/psbt.cpp
+++ b/src/psbt.cpp
@@ -153,6 +153,10 @@ void PSBTInput::Merge(const PSBTInput& input)
}
partial_sigs.insert(input.partial_sigs.begin(), input.partial_sigs.end());
+ ripemd160_preimages.insert(input.ripemd160_preimages.begin(), input.ripemd160_preimages.end());
+ sha256_preimages.insert(input.sha256_preimages.begin(), input.sha256_preimages.end());
+ hash160_preimages.insert(input.hash160_preimages.begin(), input.hash160_preimages.end());
+ hash256_preimages.insert(input.hash256_preimages.begin(), input.hash256_preimages.end());
hd_keypaths.insert(input.hd_keypaths.begin(), input.hd_keypaths.end());
unknown.insert(input.unknown.begin(), input.unknown.end());
diff --git a/src/psbt.h b/src/psbt.h
index 690d1b3bbd..43b1b249c5 100644
--- a/src/psbt.h
+++ b/src/psbt.h
@@ -37,6 +37,10 @@ static constexpr uint8_t PSBT_IN_WITNESSSCRIPT = 0x05;
static constexpr uint8_t PSBT_IN_BIP32_DERIVATION = 0x06;
static constexpr uint8_t PSBT_IN_SCRIPTSIG = 0x07;
static constexpr uint8_t PSBT_IN_SCRIPTWITNESS = 0x08;
+static constexpr uint8_t PSBT_IN_RIPEMD160 = 0x0A;
+static constexpr uint8_t PSBT_IN_SHA256 = 0x0B;
+static constexpr uint8_t PSBT_IN_HASH160 = 0x0C;
+static constexpr uint8_t PSBT_IN_HASH256 = 0x0D;
static constexpr uint8_t PSBT_IN_PROPRIETARY = 0xFC;
// Output types
@@ -171,6 +175,10 @@ struct PSBTInput
CScriptWitness final_script_witness;
std::map<CPubKey, KeyOriginInfo> hd_keypaths;
std::map<CKeyID, SigPair> partial_sigs;
+ std::map<uint160, std::vector<unsigned char>> ripemd160_preimages;
+ std::map<uint256, std::vector<unsigned char>> sha256_preimages;
+ std::map<uint160, std::vector<unsigned char>> hash160_preimages;
+ std::map<uint256, std::vector<unsigned char>> hash256_preimages;
std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown;
std::set<PSBTProprietary> m_proprietary;
std::optional<int> sighash_type;
@@ -221,6 +229,30 @@ struct PSBTInput
// Write any hd keypaths
SerializeHDKeypaths(s, hd_keypaths, CompactSizeWriter(PSBT_IN_BIP32_DERIVATION));
+
+ // Write any ripemd160 preimage
+ for (const auto& [hash, preimage] : ripemd160_preimages) {
+ SerializeToVector(s, CompactSizeWriter(PSBT_IN_RIPEMD160), Span{hash});
+ s << preimage;
+ }
+
+ // Write any sha256 preimage
+ for (const auto& [hash, preimage] : sha256_preimages) {
+ SerializeToVector(s, CompactSizeWriter(PSBT_IN_SHA256), Span{hash});
+ s << preimage;
+ }
+
+ // Write any hash160 preimage
+ for (const auto& [hash, preimage] : hash160_preimages) {
+ SerializeToVector(s, CompactSizeWriter(PSBT_IN_HASH160), Span{hash});
+ s << preimage;
+ }
+
+ // Write any hash256 preimage
+ for (const auto& [hash, preimage] : hash256_preimages) {
+ SerializeToVector(s, CompactSizeWriter(PSBT_IN_HASH256), Span{hash});
+ s << preimage;
+ }
}
// Write script sig
@@ -373,6 +405,90 @@ struct PSBTInput
UnserializeFromVector(s, final_script_witness.stack);
break;
}
+ case PSBT_IN_RIPEMD160:
+ {
+ // Make sure that the key is the size of a ripemd160 hash + 1
+ if (key.size() != CRIPEMD160::OUTPUT_SIZE + 1) {
+ throw std::ios_base::failure("Size of key was not the expected size for the type ripemd160 preimage");
+ }
+ // Read in the hash from key
+ std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
+ uint160 hash(hash_vec);
+ if (ripemd160_preimages.count(hash) > 0) {
+ throw std::ios_base::failure("Duplicate Key, input ripemd160 preimage already provided");
+ }
+
+ // Read in the preimage from value
+ std::vector<unsigned char> preimage;
+ s >> preimage;
+
+ // Add to preimages list
+ ripemd160_preimages.emplace(hash, std::move(preimage));
+ break;
+ }
+ case PSBT_IN_SHA256:
+ {
+ // Make sure that the key is the size of a sha256 hash + 1
+ if (key.size() != CSHA256::OUTPUT_SIZE + 1) {
+ throw std::ios_base::failure("Size of key was not the expected size for the type sha256 preimage");
+ }
+ // Read in the hash from key
+ std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
+ uint256 hash(hash_vec);
+ if (sha256_preimages.count(hash) > 0) {
+ throw std::ios_base::failure("Duplicate Key, input sha256 preimage already provided");
+ }
+
+ // Read in the preimage from value
+ std::vector<unsigned char> preimage;
+ s >> preimage;
+
+ // Add to preimages list
+ sha256_preimages.emplace(hash, std::move(preimage));
+ break;
+ }
+ case PSBT_IN_HASH160:
+ {
+ // Make sure that the key is the size of a hash160 hash + 1
+ if (key.size() != CHash160::OUTPUT_SIZE + 1) {
+ throw std::ios_base::failure("Size of key was not the expected size for the type hash160 preimage");
+ }
+ // Read in the hash from key
+ std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
+ uint160 hash(hash_vec);
+ if (hash160_preimages.count(hash) > 0) {
+ throw std::ios_base::failure("Duplicate Key, input hash160 preimage already provided");
+ }
+
+ // Read in the preimage from value
+ std::vector<unsigned char> preimage;
+ s >> preimage;
+
+ // Add to preimages list
+ hash160_preimages.emplace(hash, std::move(preimage));
+ break;
+ }
+ case PSBT_IN_HASH256:
+ {
+ // Make sure that the key is the size of a hash256 hash + 1
+ if (key.size() != CHash256::OUTPUT_SIZE + 1) {
+ throw std::ios_base::failure("Size of key was not the expected size for the type hash256 preimage");
+ }
+ // Read in the hash from key
+ std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
+ uint256 hash(hash_vec);
+ if (hash256_preimages.count(hash) > 0) {
+ throw std::ios_base::failure("Duplicate Key, input hash256 preimage already provided");
+ }
+
+ // Read in the preimage from value
+ std::vector<unsigned char> preimage;
+ s >> preimage;
+
+ // Add to preimages list
+ hash256_preimages.emplace(hash, std::move(preimage));
+ break;
+ }
case PSBT_IN_PROPRIETARY:
{
PSBTProprietary this_prop;
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index 12ade466da..f2e8104e14 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -1154,7 +1154,23 @@ static RPCHelpMan decodepsbt()
{
{RPCResult::Type::STR_HEX, "", "hex-encoded witness data (if any)"},
}},
- {RPCResult::Type::OBJ_DYN, "unknown", /*optional=*/true, "The unknown global fields",
+ {RPCResult::Type::OBJ_DYN, "ripemd160_preimages", /*optional=*/ true, "",
+ {
+ {RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
+ }},
+ {RPCResult::Type::OBJ_DYN, "sha256_preimages", /*optional=*/ true, "",
+ {
+ {RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
+ }},
+ {RPCResult::Type::OBJ_DYN, "hash160_preimages", /*optional=*/ true, "",
+ {
+ {RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
+ }},
+ {RPCResult::Type::OBJ_DYN, "hash256_preimages", /*optional=*/ true, "",
+ {
+ {RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
+ }},
+ {RPCResult::Type::OBJ_DYN, "unknown", /*optional=*/ true, "The unknown input fields",
{
{RPCResult::Type::STR_HEX, "key", "(key-value pair) An unknown key-value pair"},
}},
@@ -1373,6 +1389,42 @@ static RPCHelpMan decodepsbt()
in.pushKV("final_scriptwitness", txinwitness);
}
+ // Ripemd160 hash preimages
+ if (!input.ripemd160_preimages.empty()) {
+ UniValue ripemd160_preimages(UniValue::VOBJ);
+ for (const auto& [hash, preimage] : input.ripemd160_preimages) {
+ ripemd160_preimages.pushKV(HexStr(hash), HexStr(preimage));
+ }
+ in.pushKV("ripemd160_preimages", ripemd160_preimages);
+ }
+
+ // Sha256 hash preimages
+ if (!input.sha256_preimages.empty()) {
+ UniValue sha256_preimages(UniValue::VOBJ);
+ for (const auto& [hash, preimage] : input.sha256_preimages) {
+ sha256_preimages.pushKV(HexStr(hash), HexStr(preimage));
+ }
+ in.pushKV("sha256_preimages", sha256_preimages);
+ }
+
+ // Hash160 hash preimages
+ if (!input.hash160_preimages.empty()) {
+ UniValue hash160_preimages(UniValue::VOBJ);
+ for (const auto& [hash, preimage] : input.hash160_preimages) {
+ hash160_preimages.pushKV(HexStr(hash), HexStr(preimage));
+ }
+ in.pushKV("hash160_preimages", hash160_preimages);
+ }
+
+ // Hash256 hash preimages
+ if (!input.hash256_preimages.empty()) {
+ UniValue hash256_preimages(UniValue::VOBJ);
+ for (const auto& [hash, preimage] : input.hash256_preimages) {
+ hash256_preimages.pushKV(HexStr(hash), HexStr(preimage));
+ }
+ in.pushKV("hash256_preimages", hash256_preimages);
+ }
+
// Proprietary
if (!input.m_proprietary.empty()) {
UniValue proprietary(UniValue::VARR);