diff --git a/src/psbt.h b/src/psbt.h --- a/src/psbt.h +++ b/src/psbt.h @@ -100,6 +100,9 @@ } template inline void Unserialize(Stream &s) { + // Used for duplicate key detection + std::set> key_lookup; + // Read loop bool found_sep = false; while (!s.empty()) { @@ -121,7 +124,7 @@ // Do stuff based on type switch (type) { case PSBT_IN_UTXO: - if (!utxo.IsNull()) { + if (!key_lookup.emplace(key).second) { throw std::ios_base::failure( "Duplicate Key, input utxo already provided"); } else if (key.size() != 1) { @@ -159,7 +162,7 @@ break; } case PSBT_IN_SIGHASH: - if (sighash_type.getRawSigHashType() != 0) { + if (!key_lookup.emplace(key).second) { throw std::ios_base::failure( "Duplicate Key, input sighash type already " "provided"); @@ -170,7 +173,7 @@ UnserializeFromVector(s, sighash_type); break; case PSBT_IN_REDEEMSCRIPT: { - if (!redeem_script.empty()) { + if (!key_lookup.emplace(key).second) { throw std::ios_base::failure( "Duplicate Key, input redeemScript already " "provided"); @@ -187,7 +190,7 @@ break; } case PSBT_IN_SCRIPTSIG: { - if (!final_script_sig.empty()) { + if (!key_lookup.emplace(key).second) { throw std::ios_base::failure( "Duplicate Key, input final scriptSig already " "provided"); @@ -256,6 +259,9 @@ } template inline void Unserialize(Stream &s) { + // Used for duplicate key detection + std::set> key_lookup; + // Read loop bool found_sep = false; while (!s.empty()) { @@ -277,7 +283,7 @@ // Do stuff based on type switch (type) { case PSBT_OUT_REDEEMSCRIPT: { - if (!redeem_script.empty()) { + if (!key_lookup.emplace(key).second) { throw std::ios_base::failure( "Duplicate Key, output redeemScript already " "provided"); @@ -392,6 +398,9 @@ throw std::ios_base::failure("Invalid PSBT magic bytes"); } + // Used for duplicate key detection + std::set> key_lookup; + // Read global data bool found_sep = false; while (!s.empty()) { @@ -413,7 +422,7 @@ // Do stuff based on type switch (type) { case PSBT_GLOBAL_UNSIGNED_TX: { - if (tx) { + if (!key_lookup.emplace(key).second) { throw std::ios_base::failure( "Duplicate Key, unsigned tx already provided"); } else if (key.size() != 1) { diff --git a/test/functional/data/rpc_psbt.json b/test/functional/data/rpc_psbt.json --- a/test/functional/data/rpc_psbt.json +++ b/test/functional/data/rpc_psbt.json @@ -15,7 +15,15 @@ "cHNidP8BAHMCAAAAATAa6YblFqHsisW0vGVz0y+DtGXiOtdhZ9aLOOcwtNvbAAAAAAD/////AnR7AQAAAAAAF6kUA6oXrogrXQ1Usl1jEE5P/s57nqKHYEOZOwAAAAAXqRS5IbG6b3IuS/qDtlV6MTmYakLsg4cAAAAAAAEAHwDKmjsAAAAAFgAU0tlLZK4IWH7vyO6xh8YB6Tn5A3wCAwAEQQAAAAABABYAFGLp6YL/803YI5YQMWsJDNKjt0fLAAEAIgAgh2utgy8dFoAV7UEjKp6mWhgV2e8TwO+HWfZLWysnimUBASVRIQO3ziOgHFtL8ApkJTfN+rsxW2aDMoZ0eO9RMJ0r1X+Kh1GuAA==", "cHNidP8BAHMCAAAAATAa6YblFqHsisW0vGVz0y+DtGXiOtdhZ9aLOOcwtNvbAAAAAAD/////AnR7AQAAAAAAF6kUA6oXrogrXQ1Usl1jEE5P/s57nqKHYEOZOwAAAAAXqRS5IbG6b3IuS/qDtlV6MTmYakLsg4cAAAAAAAACAAAWABRi6emC//NN2COWEDFrCQzSo7dHywACAAAiACCHa62DLx0WgBXtQSMqnqZaGBXZ7xPA74dZ9ktbKyeKZQEBJVEhA7fOI6AcW0vwCmQlN836uzFbZoMyhnR471EwnSvVf4qHUa4A", "cHNidP8BAHMCAAAAATAa6YblFqHsisW0vGVz0y+DtGXiOtdhZ9aLOOcwtNvbAAAAAAD/////AnR7AQAAAAAAF6kUA6oXrogrXQ1Usl1jEE5P/s57nqKHYEOZOwAAAAAXqRS5IbG6b3IuS/qDtlV6MTmYakLsg4cAAAAAAAEBHwDKmjsAAAAAFgAU0tlLZK4IWH7vyO6xh8YB6Tn5A3wAAQAWABRi6emC//NN2COWEDFrCQzSo7dHywABACIAIIdrrYMvHRaAFe1BIyqeploYFdnvE8Dvh1n2S1srJ4plIQEAJVEhA7fOI6AcW0vwCmQlN836uzFbZoMyhnR471EwnSvVf4qHUa4A", - "cHNidP8BAHMCAAAAAbiWoY6pOQepFsEGhUPXaulX9rvye2NH+NrdlAHg+WgpAQAAAAD/////AkBLTAAAAAAAF6kUqWwXCcLM5BN2zoNqMNT5qMlIi7+HQEtMAAAAAAAXqRSVF/in2XNxAlN1OSxkyp0z+Wtg2YcAAAAAAAEBIBNssgAAAAAAF6kUamsvautR8hRlMRY6OKNTx03DK96HAQcXFgAUo8u1LWpHprjt/uENAwBpGZD0UH0BCGsCRzBEAiAONfH3DYiw67ZbylrsxCF/XXpVwyWBRgofyRbPslzvwgIgIKCsWw5sHSIPh1icNvcVLZLHWj6NA7Dk+4Os2pOnMbQBIQPGStfYHPtyhpV7zIWtn0Q4GXv5gK1zy/tnJ+cBXu4iiwABABYAFMwmJQEz+HDpBEEabxJ5PogPsqZRAAEAFgAUyCrGc3h3FYCmiIspbv2pSTKZ5jU" + "cHNidP8BAHMCAAAAAbiWoY6pOQepFsEGhUPXaulX9rvye2NH+NrdlAHg+WgpAQAAAAD/////AkBLTAAAAAAAF6kUqWwXCcLM5BN2zoNqMNT5qMlIi7+HQEtMAAAAAAAXqRSVF/in2XNxAlN1OSxkyp0z+Wtg2YcAAAAAAAEBIBNssgAAAAAAF6kUamsvautR8hRlMRY6OKNTx03DK96HAQcXFgAUo8u1LWpHprjt/uENAwBpGZD0UH0BCGsCRzBEAiAONfH3DYiw67ZbylrsxCF/XXpVwyWBRgofyRbPslzvwgIgIKCsWw5sHSIPh1icNvcVLZLHWj6NA7Dk+4Os2pOnMbQBIQPGStfYHPtyhpV7zIWtn0Q4GXv5gK1zy/tnJ+cBXu4iiwABABYAFMwmJQEz+HDpBEEabxJ5PogPsqZRAAEAFgAUyCrGc3h3FYCmiIspbv2pSTKZ5jU", + "cHNidP8BACoCAAAAAAFAQg8AAAAAABepFG6Rty1Vk+fUOR4v9E6R6YXDFkHwhwAAAAAAAQEAAQEBagA=", + "cHNidP8BACoCAAAAAAFAQg8AAAAAABepFG6Rty1Vk+fUOR4v9E6R6YXDFkHwhwAAAAAAAQAAAQABagA=", + "cHNidP8BADMBAAAAAREREREREREREREREREREREREfrK3hERERERERERERERfwAAAAD/////AAAAAAAAAQEJ//////////8AAQEJAADK/gAAAAAAAA==", + "cHNidP8BADMBAAAAAREREREREREREREREREREREREfrK3hERERERERERERERfwAAAAD/////AAAAAAAAAQMErd7f7gEDBAEAAAAA", + "cHNidP8BADMBAAAAAREREREREREREREREREREREREfrK3hERERERERERERERfwAAAAD/////AAAAAAAAAQQAAQQBagA=", + "cHNidP8BADMBAAAAAREREREREREREREREREREREREfrK3hERERERERERERERfwAAAAD/////AAAAAAAAAQEJAOH1BQAAAAAAAQUAAQUBUQA=", + "cHNidP8BADMBAAAAAREREREREREREREREREREREREfrK3hERERERERERERERfwAAAAD/////AAAAAAAAAQcAAQcBUQA=", + "cHNidP8BADMBAAAAAREREREREREREREREREREREREfrK3hERERERERERERERfwAAAAD/////AAAAAAAAAQEJAOH1BQAAAAAAAQgBAAEIAwEBUQA=" ], "valid" : [ "cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQAiAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrAAAAA==",