Types are compact size uints

This commit is contained in:
Andrew Chow
2019-10-02 15:49:33 -04:00
parent 65b49f60a4
commit 3235847473
4 changed files with 38 additions and 22 deletions

View File

@@ -69,52 +69,52 @@ struct PSBTInput
inline void Serialize(Stream& s) const { inline void Serialize(Stream& s) const {
// Write the utxo // Write the utxo
if (non_witness_utxo) { if (non_witness_utxo) {
SerializeToVector(s, PSBT_IN_NON_WITNESS_UTXO); SerializeToVector(s, CompactSizeWriter(PSBT_IN_NON_WITNESS_UTXO));
OverrideStream<Stream> os(&s, s.GetType(), s.GetVersion() | SERIALIZE_TRANSACTION_NO_WITNESS); OverrideStream<Stream> os(&s, s.GetType(), s.GetVersion() | SERIALIZE_TRANSACTION_NO_WITNESS);
SerializeToVector(os, non_witness_utxo); SerializeToVector(os, non_witness_utxo);
} }
if (!witness_utxo.IsNull()) { if (!witness_utxo.IsNull()) {
SerializeToVector(s, PSBT_IN_WITNESS_UTXO); SerializeToVector(s, CompactSizeWriter(PSBT_IN_WITNESS_UTXO));
SerializeToVector(s, witness_utxo); SerializeToVector(s, witness_utxo);
} }
if (final_script_sig.empty() && final_script_witness.IsNull()) { if (final_script_sig.empty() && final_script_witness.IsNull()) {
// Write any partial signatures // Write any partial signatures
for (auto sig_pair : partial_sigs) { for (auto sig_pair : partial_sigs) {
SerializeToVector(s, PSBT_IN_PARTIAL_SIG, Span{sig_pair.second.first}); SerializeToVector(s, CompactSizeWriter(PSBT_IN_PARTIAL_SIG), Span{sig_pair.second.first});
s << sig_pair.second.second; s << sig_pair.second.second;
} }
// Write the sighash type // Write the sighash type
if (sighash_type != std::nullopt) { if (sighash_type != std::nullopt) {
SerializeToVector(s, PSBT_IN_SIGHASH); SerializeToVector(s, CompactSizeWriter(PSBT_IN_SIGHASH));
SerializeToVector(s, *sighash_type); SerializeToVector(s, *sighash_type);
} }
// Write the redeem script // Write the redeem script
if (!redeem_script.empty()) { if (!redeem_script.empty()) {
SerializeToVector(s, PSBT_IN_REDEEMSCRIPT); SerializeToVector(s, CompactSizeWriter(PSBT_IN_REDEEMSCRIPT));
s << redeem_script; s << redeem_script;
} }
// Write the witness script // Write the witness script
if (!witness_script.empty()) { if (!witness_script.empty()) {
SerializeToVector(s, PSBT_IN_WITNESSSCRIPT); SerializeToVector(s, CompactSizeWriter(PSBT_IN_WITNESSSCRIPT));
s << witness_script; s << witness_script;
} }
// Write any hd keypaths // Write any hd keypaths
SerializeHDKeypaths(s, hd_keypaths, PSBT_IN_BIP32_DERIVATION); SerializeHDKeypaths(s, hd_keypaths, CompactSizeWriter(PSBT_IN_BIP32_DERIVATION));
} }
// Write script sig // Write script sig
if (!final_script_sig.empty()) { if (!final_script_sig.empty()) {
SerializeToVector(s, PSBT_IN_SCRIPTSIG); SerializeToVector(s, CompactSizeWriter(PSBT_IN_SCRIPTSIG));
s << final_script_sig; s << final_script_sig;
} }
// write script witness // write script witness
if (!final_script_witness.IsNull()) { if (!final_script_witness.IsNull()) {
SerializeToVector(s, PSBT_IN_SCRIPTWITNESS); SerializeToVector(s, CompactSizeWriter(PSBT_IN_SCRIPTWITNESS));
SerializeToVector(s, final_script_witness.stack); SerializeToVector(s, final_script_witness.stack);
} }
@@ -147,8 +147,9 @@ struct PSBTInput
break; break;
} }
// First byte of key is the type // Type is compact size uint at beginning of key
unsigned char type = key[0]; SpanReader skey(s.GetType(), s.GetVersion(), key);
uint64_t type = ReadCompactSize(skey);
// Do stuff based on type // Do stuff based on type
switch(type) { switch(type) {
@@ -292,18 +293,18 @@ struct PSBTOutput
inline void Serialize(Stream& s) const { inline void Serialize(Stream& s) const {
// Write the redeem script // Write the redeem script
if (!redeem_script.empty()) { if (!redeem_script.empty()) {
SerializeToVector(s, PSBT_OUT_REDEEMSCRIPT); SerializeToVector(s, CompactSizeWriter(PSBT_OUT_REDEEMSCRIPT));
s << redeem_script; s << redeem_script;
} }
// Write the witness script // Write the witness script
if (!witness_script.empty()) { if (!witness_script.empty()) {
SerializeToVector(s, PSBT_OUT_WITNESSSCRIPT); SerializeToVector(s, CompactSizeWriter(PSBT_OUT_WITNESSSCRIPT));
s << witness_script; s << witness_script;
} }
// Write any hd keypaths // Write any hd keypaths
SerializeHDKeypaths(s, hd_keypaths, PSBT_OUT_BIP32_DERIVATION); SerializeHDKeypaths(s, hd_keypaths, CompactSizeWriter(PSBT_OUT_BIP32_DERIVATION));
// Write unknown things // Write unknown things
for (auto& entry : unknown) { for (auto& entry : unknown) {
@@ -334,8 +335,9 @@ struct PSBTOutput
break; break;
} }
// First byte of key is the type // Type is compact size uint at beginning of key
unsigned char type = key[0]; SpanReader skey(s.GetType(), s.GetVersion(), key);
uint64_t type = ReadCompactSize(skey);
// Do stuff based on type // Do stuff based on type
switch(type) { switch(type) {
@@ -422,7 +424,7 @@ struct PartiallySignedTransaction
s << PSBT_MAGIC_BYTES; s << PSBT_MAGIC_BYTES;
// unsigned tx flag // unsigned tx flag
SerializeToVector(s, PSBT_GLOBAL_UNSIGNED_TX); SerializeToVector(s, CompactSizeWriter(PSBT_GLOBAL_UNSIGNED_TX));
// Write serialized tx to a stream // Write serialized tx to a stream
OverrideStream<Stream> os(&s, s.GetType(), s.GetVersion() | SERIALIZE_TRANSACTION_NO_WITNESS); OverrideStream<Stream> os(&s, s.GetType(), s.GetVersion() | SERIALIZE_TRANSACTION_NO_WITNESS);
@@ -474,8 +476,9 @@ struct PartiallySignedTransaction
break; break;
} }
// First byte of key is the type // Type is compact size uint at beginning of key
unsigned char type = key[0]; SpanReader skey(s.GetType(), s.GetVersion(), key);
uint64_t type = ReadCompactSize(skey);
// Do stuff based on type // Do stuff based on type
switch(type) { switch(type) {

View File

@@ -143,7 +143,7 @@ void DeserializeHDKeypaths(Stream& s, const std::vector<unsigned char>& key, std
// Serialize HD keypaths to a stream from a map // Serialize HD keypaths to a stream from a map
template<typename Stream> template<typename Stream>
void SerializeHDKeypaths(Stream& s, const std::map<CPubKey, KeyOriginInfo>& hd_keypaths, uint8_t type) void SerializeHDKeypaths(Stream& s, const std::map<CPubKey, KeyOriginInfo>& hd_keypaths, CompactSizeWriter type)
{ {
for (auto keypath_pair : hd_keypaths) { for (auto keypath_pair : hd_keypaths) {
if (!keypath_pair.first.IsValid()) { if (!keypath_pair.first.IsValid()) {

View File

@@ -527,6 +527,19 @@ struct CompactSizeFormatter
} }
}; };
class CompactSizeWriter
{
protected:
uint64_t n;
public:
explicit CompactSizeWriter(uint64_t n_in) : n(n_in) { }
template<typename Stream>
void Serialize(Stream &s) const {
WriteCompactSize<Stream>(s, n);
}
};
template<size_t Limit> template<size_t Limit>
struct LimitedStringFormatter struct LimitedStringFormatter
{ {

View File

@@ -43,7 +43,7 @@ FUZZ_TARGET_INIT(script_sign, initialize_script_sign)
} catch (const std::ios_base::failure&) { } catch (const std::ios_base::failure&) {
} }
CDataStream serialized{SER_NETWORK, PROTOCOL_VERSION}; CDataStream serialized{SER_NETWORK, PROTOCOL_VERSION};
SerializeHDKeypaths(serialized, hd_keypaths, fuzzed_data_provider.ConsumeIntegral<uint8_t>()); SerializeHDKeypaths(serialized, hd_keypaths, CompactSizeWriter(fuzzed_data_provider.ConsumeIntegral<uint8_t>()));
} }
{ {
@@ -61,7 +61,7 @@ FUZZ_TARGET_INIT(script_sign, initialize_script_sign)
} }
CDataStream serialized{SER_NETWORK, PROTOCOL_VERSION}; CDataStream serialized{SER_NETWORK, PROTOCOL_VERSION};
try { try {
SerializeHDKeypaths(serialized, hd_keypaths, fuzzed_data_provider.ConsumeIntegral<uint8_t>()); SerializeHDKeypaths(serialized, hd_keypaths, CompactSizeWriter(fuzzed_data_provider.ConsumeIntegral<uint8_t>()));
} catch (const std::ios_base::failure&) { } catch (const std::ios_base::failure&) {
} }
std::map<CPubKey, KeyOriginInfo> deserialized_hd_keypaths; std::map<CPubKey, KeyOriginInfo> deserialized_hd_keypaths;