Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes to support the monero ringct hard fork #4

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/cryptonote_config.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#define CRYPTONOTE_PUBLIC_ADDRESS_TEXTBLOB_VER 0
#define CURRENT_TRANSACTION_VERSION 1
#define CURRENT_TRANSACTION_VERSION 2
#define CURRENT_BLOCK_MAJOR_VERSION 1
#define CURRENT_BLOCK_MINOR_VERSION 0

Expand Down
69 changes: 47 additions & 22 deletions src/cryptonote_core/cryptonote_basic.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "crypto/hash.h"
#include "misc_language.h"
#include "tx_extra.h"
#include "ringct/rctTypes.h"


namespace cryptonote
Expand Down Expand Up @@ -181,6 +182,7 @@ namespace cryptonote
{
public:
std::vector<std::vector<crypto::signature> > signatures; //count signatures always the same as inputs count
rct::rctSig rct_signatures;

transaction();
virtual ~transaction();
Expand All @@ -189,34 +191,57 @@ namespace cryptonote
BEGIN_SERIALIZE_OBJECT()
FIELDS(*static_cast<transaction_prefix *>(this))

ar.tag("signatures");
ar.begin_array();
PREPARE_CUSTOM_VECTOR_SERIALIZATION(vin.size(), signatures);
bool signatures_not_expected = signatures.empty();
if (!signatures_not_expected && vin.size() != signatures.size())
return false;

for (size_t i = 0; i < vin.size(); ++i)
if (version == 1)
{
size_t signature_size = get_signature_size(vin[i]);
if (signatures_not_expected)
ar.tag("signatures");
ar.begin_array();
PREPARE_CUSTOM_VECTOR_SERIALIZATION(vin.size(), signatures);
bool signatures_not_expected = signatures.empty();
if (!signatures_not_expected && vin.size() != signatures.size())
return false;

for (size_t i = 0; i < vin.size(); ++i)
{
if (0 == signature_size)
continue;
else
size_t signature_size = get_signature_size(vin[i]);
if (signatures_not_expected)
{
if (0 == signature_size)
continue;
else
return false;
}

PREPARE_CUSTOM_VECTOR_SERIALIZATION(signature_size, signatures[i]);
if (signature_size != signatures[i].size())
return false;
}

PREPARE_CUSTOM_VECTOR_SERIALIZATION(signature_size, signatures[i]);
if (signature_size != signatures[i].size())
return false;

FIELDS(signatures[i]);
FIELDS(signatures[i]);

if (vin.size() - i > 1)
ar.delimit_array();
if (vin.size() - i > 1)
ar.delimit_array();
}
ar.end_array();
}
else
{
ar.tag("rct_signatures");
if (!vin.empty())
{
ar.begin_object();
bool r = rct_signatures.serialize_rctsig_base(ar, vin.size(), vout.size());
if (!r || !ar.stream().good()) return false;
ar.end_object();
if (rct_signatures.type != rct::RCTTypeNull)
{
ar.tag("rctsig_prunable");
ar.begin_object();
r = rct_signatures.p.serialize_rctsig_prunable(ar, rct_signatures.type, vin.size(), vout.size(),
vin[0].type() == typeid(txin_to_key) ? boost::get<txin_to_key>(vin[0]).key_offsets.size() - 1 : 0);
if (!r || !ar.stream().good()) return false;
ar.end_object();
}
}
}
ar.end_array();
END_SERIALIZE()

private:
Expand Down
57 changes: 56 additions & 1 deletion src/cryptonote_core/cryptonote_format_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,10 +593,65 @@ namespace cryptonote
return get_object_hash(static_cast<const bb_transaction_prefix&>(t), res, blob_size);
}

//---------------------------------------------------------------
bool get_transaction_hash(const transaction& t, crypto::hash& res, size_t* blob_size)
{
// v1 transactions hash the entire blob
if (t.version == 1)
{
size_t ignored_blob_size, &blob_size_ref = blob_size ? *blob_size : ignored_blob_size;
return get_object_hash(t, res, blob_size_ref);
}

// v2 transactions hash different parts together, than hash the set of those hashes
crypto::hash hashes[3];

// prefix
get_transaction_prefix_hash(t, hashes[0]);

transaction &tt = const_cast<transaction&>(t);

// base rct
{
std::stringstream ss;
binary_archive<true> ba(ss);
const size_t inputs = t.vin.size();
const size_t outputs = t.vout.size();
bool r = tt.rct_signatures.serialize_rctsig_base(ba, inputs, outputs);
CHECK_AND_ASSERT_MES(r, false, "Failed to serialize rct signatures base");
cryptonote::get_blob_hash(ss.str(), hashes[1]);
}

// prunable rct
if (t.rct_signatures.type == rct::RCTTypeNull)
{
hashes[2] = cryptonote::null_hash;
}
else
{
std::stringstream ss;
binary_archive<true> ba(ss);
const size_t inputs = t.vin.size();
const size_t outputs = t.vout.size();
const size_t mixin = t.vin.empty() ? 0 : t.vin[0].type() == typeid(txin_to_key) ? boost::get<txin_to_key>(t.vin[0]).key_offsets.size() - 1 : 0;
bool r = tt.rct_signatures.p.serialize_rctsig_prunable(ba, t.rct_signatures.type, inputs, outputs, mixin);
CHECK_AND_ASSERT_MES(r, false, "Failed to serialize rct signatures prunable");
cryptonote::get_blob_hash(ss.str(), hashes[2]);
}

// the tx hash is the hash of the 3 hashes
res = cn_fast_hash(hashes, sizeof(hashes));

// we still need the size
if (blob_size)
*blob_size = get_object_blobsize(t);

return true;
}
//---------------------------------------------------------------
bool get_transaction_hash(const transaction& t, crypto::hash& res, size_t& blob_size)
{
return get_object_hash(t, res, blob_size);
return get_transaction_hash(t, res, &blob_size);
}
//---------------------------------------------------------------
blobdata get_block_hashing_blob(const block& b)
Expand Down
1 change: 1 addition & 0 deletions src/cryptonote_core/cryptonote_format_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ namespace cryptonote
crypto::hash get_transaction_hash(const transaction& t);
bool get_transaction_hash(const transaction& t, crypto::hash& res);
bool get_transaction_hash(const transaction& t, crypto::hash& res, size_t& blob_size);
bool get_transaction_hash(const transaction& t, crypto::hash& res, size_t* blob_size);
blobdata get_block_hashing_blob(const block& b);
blobdata get_block_hashing_blob(const bb_block& b);
bool get_block_hash(const block& b, crypto::hash& res);
Expand Down