MCPcopy Create free account
hub / github.com/ElementsProject/elements / Unserialize

Method Unserialize

src/psbt.h:1686–1997  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1684
1685 template <typename Stream>
1686 inline void Unserialize(Stream& s) {
1687 // Read the magic bytes
1688 uint8_t magic[5];
1689 s >> magic;
1690 if (!std::equal(magic, magic + 5, PSBT_ELEMENTS_MAGIC_BYTES)) {
1691 throw std::ios_base::failure("Invalid PSBT magic bytes");
1692 }
1693
1694 // Used for duplicate key detection
1695 std::set<std::vector<unsigned char>> key_lookup;
1696
1697 // Track the global xpubs we have already seen. Just for sanity checking
1698 std::set<CExtPubKey> global_xpubs;
1699
1700 // Read global data
1701 bool found_sep = false;
1702 uint64_t input_count = 0;
1703 uint64_t output_count = 0;
1704 bool found_input_count = false;
1705 bool found_output_count = false;
1706 while(!s.empty()) {
1707 // Read
1708 std::vector<unsigned char> key;
1709 s >> key;
1710
1711 // the key is empty if that was actually a separator byte
1712 // This is a special case for key lengths 0 as those are not allowed (except for separator)
1713 if (key.empty()) {
1714 found_sep = true;
1715 break;
1716 }
1717
1718 // Type is compact size uint at beginning of key
1719 SpanReader skey(s.GetType(), s.GetVersion(), key);
1720 uint64_t type = ReadCompactSize(skey);
1721
1722 // Do stuff based on type
1723 switch(type) {
1724 case PSBT_GLOBAL_UNSIGNED_TX:
1725 {
1726 if (g_con_elementsmode) {
1727 throw std::ios_base::failure("Unsigned tx is not allowed in PSET");
1728 }
1729 if (!key_lookup.emplace(key).second) {
1730 throw std::ios_base::failure("Duplicate Key, unsigned tx already provided");
1731 } else if (key.size() != 1) {
1732 throw std::ios_base::failure("Global unsigned tx key is more than one byte type");
1733 }
1734 CMutableTransaction mtx;
1735 // Set the stream to serialize with non-witness since this should always be non-witness
1736 OverrideStream<Stream> os(&s, s.GetType(), s.GetVersion() | SERIALIZE_TRANSACTION_NO_WITNESS);
1737 UnserializeFromVector(os, mtx);
1738 tx = std::move(mtx);
1739 // Make sure that all scriptSigs and scriptWitnesses are empty
1740 for (unsigned int i = 0; i < tx->vin.size(); i++) {
1741 const CTxIn& txin = tx->vin[i];
1742 if (!txin.scriptSig.empty() || !tx->witness.vtxinwit[i].scriptWitness.IsNull()) {
1743 throw std::ios_base::failure("Unsigned tx does not have empty scriptSigs and scriptWitnesses.");

Callers

nothing calls this directly

Calls 15

ReadCompactSizeFunction · 0.85
UnserializeFromVectorFunction · 0.85
DeserializeHDKeypathFunction · 0.85
DecodeWithVersionMethod · 0.80
IsFullyValidMethod · 0.80
countMethod · 0.80
emptyMethod · 0.45
GetTypeMethod · 0.45
GetVersionMethod · 0.45
sizeMethod · 0.45
IsNullMethod · 0.45
dataMethod · 0.45

Tested by

no test coverage detected