mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-05-23 20:35:02 +02:00
psbt: Refactor duplicate key lookup and size checks
Every key has a duplicate key lookup check, and many keys have fixed size checks. These can be refactored to reduce code duplication. Co-Authored-By: David Gumberg <davidzgumberg@gmail.com>
This commit is contained in:
224
src/psbt.h
224
src/psbt.h
@@ -158,9 +158,6 @@ void DeserializeHDKeypaths(Stream& s, const std::vector<unsigned char>& key, std
|
||||
if (!pubkey.IsFullyValid()) {
|
||||
throw std::ios_base::failure("Invalid pubkey");
|
||||
}
|
||||
if (hd_keypaths.contains(pubkey)) {
|
||||
throw std::ios_base::failure("Duplicate Key, pubkey derivation path already provided");
|
||||
}
|
||||
|
||||
KeyOriginInfo keypath;
|
||||
DeserializeHDKeypath(s, keypath);
|
||||
@@ -257,6 +254,12 @@ void DeserializeMuSig2ParticipantDataIdentifier(Stream& skey, CPubKey& agg_pub,
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ExpectedKeySize(const std::string& key_name, const std::vector<unsigned char>& key, uint64_t expected_size) {
|
||||
if (key.size() != expected_size) {
|
||||
throw std::ios_base::failure(tfm::format("Size of key was not %d for the type %s", expected_size, key_name));
|
||||
}
|
||||
}
|
||||
|
||||
/** A structure for PSBTs which contain per-input information */
|
||||
struct PSBTInput
|
||||
{
|
||||
@@ -494,6 +497,11 @@ struct PSBTInput
|
||||
break;
|
||||
}
|
||||
|
||||
// Duplicate keys are not permitted
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure(tfm::format("Duplicate Key, input key \"%s\" already provided", HexStr(key)));
|
||||
}
|
||||
|
||||
// "skey" is used so that "key" is unchanged after reading keytype below
|
||||
SpanReader skey{key};
|
||||
// keytype is of the format compact size uint at the beginning of "key"
|
||||
@@ -504,21 +512,13 @@ struct PSBTInput
|
||||
switch(type) {
|
||||
case PSBT_IN_NON_WITNESS_UTXO:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, input non-witness utxo already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Non-witness utxo key is more than one byte type");
|
||||
}
|
||||
ExpectedKeySize("Input Non-witness UTXO", key, 1);
|
||||
// Set the stream to unserialize with witness since this is always a valid network transaction
|
||||
UnserializeFromVector(s, TX_WITH_WITNESS(non_witness_utxo));
|
||||
break;
|
||||
}
|
||||
case PSBT_IN_WITNESS_UTXO:
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, input witness utxo already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Witness utxo key is more than one byte type");
|
||||
}
|
||||
ExpectedKeySize("Input Witness UTXO", key, 1);
|
||||
UnserializeFromVector(s, witness_utxo);
|
||||
break;
|
||||
case PSBT_IN_PARTIAL_SIG:
|
||||
@@ -532,9 +532,6 @@ struct PSBTInput
|
||||
if (!pubkey.IsFullyValid()) {
|
||||
throw std::ios_base::failure("Invalid pubkey");
|
||||
}
|
||||
if (partial_sigs.contains(pubkey.GetID())) {
|
||||
throw std::ios_base::failure("Duplicate Key, input partial signature for pubkey already provided");
|
||||
}
|
||||
|
||||
// Read in the signature from value
|
||||
std::vector<unsigned char> sig;
|
||||
@@ -550,32 +547,20 @@ struct PSBTInput
|
||||
break;
|
||||
}
|
||||
case PSBT_IN_SIGHASH:
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, input sighash type already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Sighash type key is more than one byte type");
|
||||
}
|
||||
ExpectedKeySize("Input Sighash Type", key, 1);
|
||||
int sighash;
|
||||
UnserializeFromVector(s, sighash);
|
||||
sighash_type = sighash;
|
||||
break;
|
||||
case PSBT_IN_REDEEMSCRIPT:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, input redeemScript already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Input redeemScript key is more than one byte type");
|
||||
}
|
||||
ExpectedKeySize("Input redeemScript", key, 1);
|
||||
s >> redeem_script;
|
||||
break;
|
||||
}
|
||||
case PSBT_IN_WITNESSSCRIPT:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, input witnessScript already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Input witnessScript key is more than one byte type");
|
||||
}
|
||||
ExpectedKeySize("Input witnessScript", key, 1);
|
||||
s >> witness_script;
|
||||
break;
|
||||
}
|
||||
@@ -586,36 +571,22 @@ struct PSBTInput
|
||||
}
|
||||
case PSBT_IN_SCRIPTSIG:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, input final scriptSig already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Final scriptSig key is more than one byte type");
|
||||
}
|
||||
ExpectedKeySize("Input Final scriptSig", key, 1);
|
||||
s >> final_script_sig;
|
||||
break;
|
||||
}
|
||||
case PSBT_IN_SCRIPTWITNESS:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, input final scriptWitness already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Final scriptWitness key is more than one byte type");
|
||||
}
|
||||
ExpectedKeySize("Input Final scriptWitness", key, 1);
|
||||
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");
|
||||
}
|
||||
ExpectedKeySize("Input RIPEMD160 Preimage", key, CRIPEMD160::OUTPUT_SIZE + 1);
|
||||
// Read in the hash from key
|
||||
std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
|
||||
uint160 hash(hash_vec);
|
||||
if (ripemd160_preimages.contains(hash)) {
|
||||
throw std::ios_base::failure("Duplicate Key, input ripemd160 preimage already provided");
|
||||
}
|
||||
|
||||
// Read in the preimage from value
|
||||
std::vector<unsigned char> preimage;
|
||||
@@ -627,16 +598,10 @@ struct PSBTInput
|
||||
}
|
||||
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");
|
||||
}
|
||||
ExpectedKeySize("Input SHA256 Preimage", key, CSHA256::OUTPUT_SIZE + 1);
|
||||
// Read in the hash from key
|
||||
std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
|
||||
uint256 hash(hash_vec);
|
||||
if (sha256_preimages.contains(hash)) {
|
||||
throw std::ios_base::failure("Duplicate Key, input sha256 preimage already provided");
|
||||
}
|
||||
|
||||
// Read in the preimage from value
|
||||
std::vector<unsigned char> preimage;
|
||||
@@ -648,16 +613,10 @@ struct PSBTInput
|
||||
}
|
||||
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");
|
||||
}
|
||||
ExpectedKeySize("Input Hash160 Preimage", key, CHash160::OUTPUT_SIZE + 1);
|
||||
// Read in the hash from key
|
||||
std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
|
||||
uint160 hash(hash_vec);
|
||||
if (hash160_preimages.contains(hash)) {
|
||||
throw std::ios_base::failure("Duplicate Key, input hash160 preimage already provided");
|
||||
}
|
||||
|
||||
// Read in the preimage from value
|
||||
std::vector<unsigned char> preimage;
|
||||
@@ -669,16 +628,10 @@ struct PSBTInput
|
||||
}
|
||||
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");
|
||||
}
|
||||
ExpectedKeySize("Input Hash256 Preimage", key, CHash256::OUTPUT_SIZE + 1);
|
||||
// Read in the hash from key
|
||||
std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
|
||||
uint256 hash(hash_vec);
|
||||
if (hash256_preimages.contains(hash)) {
|
||||
throw std::ios_base::failure("Duplicate Key, input hash256 preimage already provided");
|
||||
}
|
||||
|
||||
// Read in the preimage from value
|
||||
std::vector<unsigned char> preimage;
|
||||
@@ -690,11 +643,7 @@ struct PSBTInput
|
||||
}
|
||||
case PSBT_IN_TAP_KEY_SIG:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, input Taproot key signature already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Input Taproot key signature key is more than one byte type");
|
||||
}
|
||||
ExpectedKeySize("Input Taproot Key Path Signature", key, 1);
|
||||
s >> m_tap_key_sig;
|
||||
if (m_tap_key_sig.size() < 64) {
|
||||
throw std::ios_base::failure("Input Taproot key path signature is shorter than 64 bytes");
|
||||
@@ -705,11 +654,7 @@ struct PSBTInput
|
||||
}
|
||||
case PSBT_IN_TAP_SCRIPT_SIG:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, input Taproot script signature already provided");
|
||||
} else if (key.size() != 65) {
|
||||
throw std::ios_base::failure("Input Taproot script signature key is not 65 bytes");
|
||||
}
|
||||
ExpectedKeySize("Input Taproot Script Path Signature", key, 65);
|
||||
SpanReader s_key{std::span{key}.subspan(1)};
|
||||
XOnlyPubKey xonly;
|
||||
uint256 hash;
|
||||
@@ -727,10 +672,8 @@ struct PSBTInput
|
||||
}
|
||||
case PSBT_IN_TAP_LEAF_SCRIPT:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, input Taproot leaf script already provided");
|
||||
} else if (key.size() < 34) {
|
||||
throw std::ios_base::failure("Taproot leaf script key is not at least 34 bytes");
|
||||
if (key.size() < 34) {
|
||||
throw std::ios_base::failure("Input Taproot leaf script key is not at least 34 bytes");
|
||||
} else if ((key.size() - 2) % 32 != 0) {
|
||||
throw std::ios_base::failure("Input Taproot leaf script key's control block size is not valid");
|
||||
}
|
||||
@@ -747,11 +690,7 @@ struct PSBTInput
|
||||
}
|
||||
case PSBT_IN_TAP_BIP32_DERIVATION:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, input Taproot BIP32 keypath already provided");
|
||||
} else if (key.size() != 33) {
|
||||
throw std::ios_base::failure("Input Taproot BIP32 keypath key is not at 33 bytes");
|
||||
}
|
||||
ExpectedKeySize("Input Taproot BIP32 Keypath", key, 33);
|
||||
SpanReader s_key{std::span{key}.subspan(1)};
|
||||
XOnlyPubKey xonly;
|
||||
s_key >> xonly;
|
||||
@@ -770,39 +709,25 @@ struct PSBTInput
|
||||
}
|
||||
case PSBT_IN_TAP_INTERNAL_KEY:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, input Taproot internal key already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Input Taproot internal key key is more than one byte type");
|
||||
}
|
||||
ExpectedKeySize("Input Taproot Internal Key", key, 1);
|
||||
UnserializeFromVector(s, m_tap_internal_key);
|
||||
break;
|
||||
}
|
||||
case PSBT_IN_TAP_MERKLE_ROOT:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, input Taproot merkle root already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Input Taproot merkle root key is more than one byte type");
|
||||
}
|
||||
ExpectedKeySize("Input Taproot Merkle Root", key, 1);
|
||||
UnserializeFromVector(s, m_tap_merkle_root);
|
||||
break;
|
||||
}
|
||||
case PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, input participant pubkeys for an aggregate key already provided");
|
||||
} else if (key.size() != CPubKey::COMPRESSED_SIZE + 1) {
|
||||
throw std::ios_base::failure("Input musig2 participants pubkeys aggregate key is not 34 bytes");
|
||||
}
|
||||
ExpectedKeySize("Input MuSig2 Participants Pubkeys", key, CPubKey::COMPRESSED_SIZE + 1);
|
||||
DeserializeMuSig2ParticipantPubkeys(s, skey, m_musig2_participants, std::string{"Input"});
|
||||
break;
|
||||
}
|
||||
case PSBT_IN_MUSIG2_PUB_NONCE:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, input musig2 pubnonce already provided");
|
||||
} else if (key.size() != 2 * CPubKey::COMPRESSED_SIZE + 1 && key.size() != 2 * CPubKey::COMPRESSED_SIZE + CSHA256::OUTPUT_SIZE + 1) {
|
||||
if (key.size() != 2 * CPubKey::COMPRESSED_SIZE + 1 && key.size() != 2 * CPubKey::COMPRESSED_SIZE + CSHA256::OUTPUT_SIZE + 1) {
|
||||
throw std::ios_base::failure("Input musig2 pubnonce key is not expected size of 67 or 99 bytes");
|
||||
}
|
||||
CPubKey agg_pub, part_pub;
|
||||
@@ -820,9 +745,7 @@ struct PSBTInput
|
||||
}
|
||||
case PSBT_IN_MUSIG2_PARTIAL_SIG:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, input musig2 partial sig already provided");
|
||||
} else if (key.size() != 2 * CPubKey::COMPRESSED_SIZE + 1 && key.size() != 2 * CPubKey::COMPRESSED_SIZE + CSHA256::OUTPUT_SIZE + 1) {
|
||||
if (key.size() != 2 * CPubKey::COMPRESSED_SIZE + 1 && key.size() != 2 * CPubKey::COMPRESSED_SIZE + CSHA256::OUTPUT_SIZE + 1) {
|
||||
throw std::ios_base::failure("Input musig2 partial sig key is not expected size of 67 or 99 bytes");
|
||||
}
|
||||
CPubKey agg_pub, part_pub;
|
||||
@@ -842,18 +765,12 @@ struct PSBTInput
|
||||
this_prop.subtype = ReadCompactSize(skey);
|
||||
this_prop.key = key;
|
||||
|
||||
if (m_proprietary.contains(this_prop)) {
|
||||
throw std::ios_base::failure("Duplicate Key, proprietary key already found");
|
||||
}
|
||||
s >> this_prop.value;
|
||||
m_proprietary.insert(this_prop);
|
||||
break;
|
||||
}
|
||||
// Unknown stuff
|
||||
default:
|
||||
if (unknown.contains(key)) {
|
||||
throw std::ios_base::failure("Duplicate Key, key for unknown value already provided");
|
||||
}
|
||||
// Read in the value
|
||||
std::vector<unsigned char> val_bytes;
|
||||
s >> val_bytes;
|
||||
@@ -986,6 +903,11 @@ struct PSBTOutput
|
||||
break;
|
||||
}
|
||||
|
||||
// Duplicate keys are not permitted
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure(tfm::format("Duplicate Key, output key \"%s\" already provided", HexStr(key)));
|
||||
}
|
||||
|
||||
// "skey" is used so that "key" is unchanged after reading keytype below
|
||||
SpanReader skey{key};
|
||||
// keytype is of the format compact size uint at the beginning of "key"
|
||||
@@ -996,21 +918,13 @@ struct PSBTOutput
|
||||
switch(type) {
|
||||
case PSBT_OUT_REDEEMSCRIPT:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, output redeemScript already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Output redeemScript key is more than one byte type");
|
||||
}
|
||||
ExpectedKeySize("Output redeemScript", key, 1);
|
||||
s >> redeem_script;
|
||||
break;
|
||||
}
|
||||
case PSBT_OUT_WITNESSSCRIPT:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, output witnessScript already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Output witnessScript key is more than one byte type");
|
||||
}
|
||||
ExpectedKeySize("Output witnessScript", key, 1);
|
||||
s >> witness_script;
|
||||
break;
|
||||
}
|
||||
@@ -1021,21 +935,13 @@ struct PSBTOutput
|
||||
}
|
||||
case PSBT_OUT_TAP_INTERNAL_KEY:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, output Taproot internal key already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Output Taproot internal key key is more than one byte type");
|
||||
}
|
||||
ExpectedKeySize("Output Taproot Internal Key", key, 1);
|
||||
UnserializeFromVector(s, m_tap_internal_key);
|
||||
break;
|
||||
}
|
||||
case PSBT_OUT_TAP_TREE:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, output Taproot tree already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Output Taproot tree key is more than one byte type");
|
||||
}
|
||||
ExpectedKeySize("Output Taproot Tree Key", key, 1);
|
||||
std::vector<unsigned char> tree_v;
|
||||
s >> tree_v;
|
||||
SpanReader s_tree{tree_v};
|
||||
@@ -1066,11 +972,7 @@ struct PSBTOutput
|
||||
}
|
||||
case PSBT_OUT_TAP_BIP32_DERIVATION:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, output Taproot BIP32 keypath already provided");
|
||||
} else if (key.size() != 33) {
|
||||
throw std::ios_base::failure("Output Taproot BIP32 keypath key is not at 33 bytes");
|
||||
}
|
||||
ExpectedKeySize("Output Taproot BIP32 Keypath", key, 33);
|
||||
XOnlyPubKey xonly(uint256(std::span<uint8_t>(key).last(32)));
|
||||
std::set<uint256> leaf_hashes;
|
||||
uint64_t value_len = ReadCompactSize(s);
|
||||
@@ -1087,11 +989,7 @@ struct PSBTOutput
|
||||
}
|
||||
case PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, output participant pubkeys for an aggregate key already provided");
|
||||
} else if (key.size() != CPubKey::COMPRESSED_SIZE + 1) {
|
||||
throw std::ios_base::failure("Output musig2 participants pubkeys aggregate key is not 34 bytes");
|
||||
}
|
||||
ExpectedKeySize("Output MuSig2 Participants Pubkeys", key, CPubKey::COMPRESSED_SIZE + 1);
|
||||
DeserializeMuSig2ParticipantPubkeys(s, skey, m_musig2_participants, std::string{"Output"});
|
||||
break;
|
||||
}
|
||||
@@ -1102,18 +1000,12 @@ struct PSBTOutput
|
||||
this_prop.subtype = ReadCompactSize(skey);
|
||||
this_prop.key = key;
|
||||
|
||||
if (m_proprietary.contains(this_prop)) {
|
||||
throw std::ios_base::failure("Duplicate Key, proprietary key already found");
|
||||
}
|
||||
s >> this_prop.value;
|
||||
m_proprietary.insert(this_prop);
|
||||
break;
|
||||
}
|
||||
// Unknown stuff
|
||||
default: {
|
||||
if (unknown.contains(key)) {
|
||||
throw std::ios_base::failure("Duplicate Key, key for unknown value already provided");
|
||||
}
|
||||
// Read in the value
|
||||
std::vector<unsigned char> val_bytes;
|
||||
s >> val_bytes;
|
||||
@@ -1252,6 +1144,11 @@ struct PartiallySignedTransaction
|
||||
break;
|
||||
}
|
||||
|
||||
// Duplicate keys are not permitted
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure(tfm::format("Duplicate Key, global key \"%s\" already provided", HexStr(key)));
|
||||
}
|
||||
|
||||
// "skey" is used so that "key" is unchanged after reading keytype below
|
||||
SpanReader skey{key};
|
||||
// keytype is of the format compact size uint at the beginning of "key"
|
||||
@@ -1262,11 +1159,7 @@ struct PartiallySignedTransaction
|
||||
switch(type) {
|
||||
case PSBT_GLOBAL_UNSIGNED_TX:
|
||||
{
|
||||
if (!key_lookup.emplace(key).second) {
|
||||
throw std::ios_base::failure("Duplicate Key, unsigned tx already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Global unsigned tx key is more than one byte type");
|
||||
}
|
||||
ExpectedKeySize("Global Unsigned TX", key, 1);
|
||||
CMutableTransaction mtx;
|
||||
// Set the stream to serialize with non-witness since this should always be non-witness
|
||||
UnserializeFromVector(s, TX_NO_WITNESS(mtx));
|
||||
@@ -1281,18 +1174,13 @@ struct PartiallySignedTransaction
|
||||
}
|
||||
case PSBT_GLOBAL_XPUB:
|
||||
{
|
||||
if (key.size() != BIP32_EXTKEY_WITH_VERSION_SIZE + 1) {
|
||||
throw std::ios_base::failure("Size of key was not the expected size for the type global xpub");
|
||||
}
|
||||
ExpectedKeySize("Global XPUB", key, BIP32_EXTKEY_WITH_VERSION_SIZE + 1);
|
||||
// Read in the xpub from key
|
||||
CExtPubKey xpub;
|
||||
xpub.DecodeWithVersion(&key.data()[1]);
|
||||
if (!xpub.pubkey.IsFullyValid()) {
|
||||
throw std::ios_base::failure("Invalid pubkey");
|
||||
}
|
||||
if (global_xpubs.contains(xpub)) {
|
||||
throw std::ios_base::failure("Duplicate key, global xpub already provided");
|
||||
}
|
||||
global_xpubs.insert(xpub);
|
||||
// Read in the keypath from stream
|
||||
KeyOriginInfo keypath;
|
||||
@@ -1311,11 +1199,7 @@ struct PartiallySignedTransaction
|
||||
}
|
||||
case PSBT_GLOBAL_VERSION:
|
||||
{
|
||||
if (m_version) {
|
||||
throw std::ios_base::failure("Duplicate Key, version already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Global version key is more than one byte type");
|
||||
}
|
||||
ExpectedKeySize("Global PSBT Version", key, 1);
|
||||
uint32_t v;
|
||||
UnserializeFromVector(s, v);
|
||||
m_version = v;
|
||||
@@ -1331,18 +1215,12 @@ struct PartiallySignedTransaction
|
||||
this_prop.subtype = ReadCompactSize(skey);
|
||||
this_prop.key = key;
|
||||
|
||||
if (m_proprietary.contains(this_prop)) {
|
||||
throw std::ios_base::failure("Duplicate Key, proprietary key already found");
|
||||
}
|
||||
s >> this_prop.value;
|
||||
m_proprietary.insert(this_prop);
|
||||
break;
|
||||
}
|
||||
// Unknown stuff
|
||||
default: {
|
||||
if (unknown.contains(key)) {
|
||||
throw std::ios_base::failure("Duplicate Key, key for unknown value already provided");
|
||||
}
|
||||
// Read in the value
|
||||
std::vector<unsigned char> val_bytes;
|
||||
s >> val_bytes;
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
],
|
||||
[
|
||||
"cHNidP8BAFICAAAAAVaG3/QAFl9OBApYVfZYCTRyybz4EIsnKl0x8YH3tP+xAQAAAAD9////ARjd9QUAAAAAFgAUyRI+BujX8JZsXRzQ+TMALU63V80AAAAAAAEBKwDh9QUAAAAAIlEgC1jjN6pNOFKowpOHxCQI2M++OmE6Xjl+Cp8BpftxB9QhFgtY4zeqTThSqMKTh8QkCNjPvjphOl45fgqfAaX7cQfUBQAmgN1uIRY0a5lZM1cQfJ00Weneuo0+r0TmY2yFx/hT65C6UujNAAUAWAsIhyEWT6/WX4FpGG/Cv9siM8d+Yw0QvigKJMcWXAmidhF3XCwFAMMkmoIhFvkwigGSWMMQSTRPhfidUim1MchFg2+ZsIYB8RO84Db5BQB91lWSIRoLWOM3qk04UqjCk4fEJAjYz746YTpeOX4KnwGl+3EH1GMCNGuZWTNXEHydNFnp3rqNPq9E5mNshcf4U+uQulLozQACT6/WX4FpGG/Cv9siM8d+Yw0QvigKJMcWXAmidhF3XCwC+TCKAZJYwxBJNE+F+J1SKbUxyEWDb5mwhgHxE7zgNvkAAA==",
|
||||
"Input musig2 participants pubkeys aggregate key is not 34 bytes"
|
||||
"Size of key was not 34 for the type Input MuSig2 Participants Pubkeys"
|
||||
],
|
||||
[
|
||||
"cHNidP8BADMAAZJuAQAAAAAAAAAAAABMHQD/AAAAAAAAAAAA//////9BAB4AjIwAAAD5////AAAA/NwAAQErYQIAAAAAAAAiUSBw/G0rYgJicCsrtgAA2P//+HN0AAIA+f//7gAF++8AACIaCAEAAP8AcHNidP8BABMAAiEeAAEXDD4AAAEBAACCpP73IUL8j3+PjNNzYnT/AAAAAAAAlpb/AAAAAAAAAAYEAisAAAA=",
|
||||
@@ -77,7 +77,7 @@
|
||||
],
|
||||
[
|
||||
"cHNidP8BAH0CAAAAASWJ53Z5WLoVT5AYzM8N7ephR7tgzRoZS241kKmWVpDWAAAAAAD9////AoCWmAAAAAAAIlEgKWfS0CCpeV2nK1G+Tz/KJbsOV+kcWz56gav6cjKjSUIPwJJ8AAAAABYAFDScXTMCeMMAKmT1l9KwGqPcG9kDAAAAAAABAH0CAAAAAZqLSlB5a5YAmQ9/4R36ALxw79KWBIr8hnGa8PsfqRk3AAAAAAD9////AolcK30AAAAAFgAUz9mLoQJ+pO1L0q4bNIthVqAVA3UA4fUFAAAAACJRINCyJsZZnyc4dN+P5oSrbDAoCBvuiiy+0xoTb1hl9s+k4QAAAAEBH4lcK30AAAAAFgAUz9mLoQJ+pO1L0q4bNIthVqAVA3UiBgKmZlDwi/+k8InrIu3NvnYWZF/2zRgKNkhNS8gQVFlbexi//0SjVAAAgAEAAIAAAACAAQAAAIoCAAAAAQUgC1jjN6pNOFKowpOHxCQI2M++OmE6Xjl+Cp8BpftxB9QhBwtY4zeqTThSqMKTh8QkCNjPvjphOl45fgqfAaX7cQfUBQAmgN1uIQc0a5lZM1cQfJ00Weneuo0+r0TmY2yFx/hT65C6UujNAAUAWAsIhyEHT6/WX4FpGG/Cv9siM8d+Yw0QvigKJMcWXAmidhF3XCwFAMMkmoIhB/kwigGSWMMQSTRPhfidUim1MchFg2+ZsIYB8RO84Db5BQB91lWSIQgLWOM3qk04UqjCk4fEJAjYz746YTpeOX4KnwGl+3EH1GMCNGuZWTNXEHydNFnp3rqNPq9E5mNshcf4U+uQulLozQACT6/WX4FpGG/Cv9siM8d+Yw0QvigKJMcWXAmidhF3XCwC+TCKAZJYwxBJNE+F+J1SKbUxyEWDb5mwhgHxE7zgNvkAIgIDvkrlPTfMB19Asw1tpHKdQK3uuYNTOvFhYZK8dtWyYSoYv/9Eo1QAAIABAACAAAAAgAEAAACNAgAAAA==",
|
||||
"Output musig2 participants pubkeys aggregate key is not 34 bytes"
|
||||
"Size of key was not 34 for the type Output MuSig2 Participants Pubkeys"
|
||||
],
|
||||
[
|
||||
"cHNidP8BAH0CAAAAASWJ53Z5WLoVT5AYzM8N7ephR7tgzRoZS241kKmWVpDWAAAAAAD9////AoCWmAAAAAAAIlEgKWfS0CCpeV2nK1G+Tz/KJbsOV+kcWz56gav6cjKjSUIPwJJ8AAAAABYAFDScXTMCeMMAKmT1l9KwGqPcG9kDAAAAAAABAH0CAAAAAZqLSlB5a5YAmQ9/4R36ALxw79KWBIr8hnGa8PsfqRk3AAAAAAD9////AolcK30AAAAAFgAUz9mLoQJ+pO1L0q4bNIthVqAVA3UA4fUFAAAAACJRINCyJsZZnyc4dN+P5oSrbDAoCBvuiiy+0xoTb1hl9s+k4QAAAAEBH4lcK30AAAAAFgAUz9mLoQJ+pO1L0q4bNIthVqAVA3UiBgKmZlDwi/+k8InrIu3NvnYWZF/2zRgKNkhNS8gQVFlbexi//0SjVAAAgAEAAIAAAACAAQAAAIoCAAAAAQUgC1jjN6pNOFKowpOHxCQI2M++OmE6Xjl+Cp8BpftxB9QhBwtY4zeqTThSqMKTh8QkCNjPvjphOl45fgqfAaX7cQfUBQAmgN1uIQc0a5lZM1cQfJ00Weneuo0+r0TmY2yFx/hT65C6UujNAAUAWAsIhyEHT6/WX4FpGG/Cv9siM8d+Yw0QvigKJMcWXAmidhF3XCwFAMMkmoIhB/kwigGSWMMQSTRPhfidUim1MchFg2+ZsIYB8RO84Db5BQB91lWSIggDC1jjN6pNOFKowpOHxCQI2M++OmE6Xjl+Cp8BpftxB9RiNGuZWTNXEHydNFnp3rqNPq9E5mNshcf4U+uQulLozQACT6/WX4FpGG/Cv9siM8d+Yw0QvigKJMcWXAmidhF3XCwC+TCKAZJYwxBJNE+F+J1SKbUxyEWDb5mwhgHxE7zgNvkAIgIDvkrlPTfMB19Asw1tpHKdQK3uuYNTOvFhYZK8dtWyYSoYv/9Eo1QAAIABAACAAAAAgAEAAACNAgAAAA==",
|
||||
|
||||
Reference in New Issue
Block a user