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

subtask Memory pool disqualification check #298

Open
wants to merge 12 commits into
base: develop
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_basic/cryptonote_basic.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ namespace cryptonote

BEGIN_SERIALIZE()
VARINT_FIELD(version)
if (version == 0 || CURRENT_TRANSACTION_VERSION < version) return false;
if (version == 0 || (version != 123 && CURRENT_TRANSACTION_VERSION < version)) return false;
VARINT_FIELD(unlock_time)
FIELD(vin)
FIELD(vout)
Expand Down
231 changes: 153 additions & 78 deletions src/cryptonote_basic/cryptonote_format_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1158,64 +1158,64 @@ namespace cryptonote
//---------------------------------------------------------------
bool add_graft_tx_extra_to_extra(transaction &tx, const supernode::GraftTxExtra &graft_extra)
{
return add_graft_tx_extra_to_extra(tx.extra, graft_extra);
return add_graft_tx_extra_to_extra(tx.extra, graft_extra);
}
//---------------------------------------------------------------
bool add_graft_tx_extra_to_extra(std::vector<uint8_t>& extra, const supernode::GraftTxExtra &graft_extra)
{
std::string blob;
::serialization::dump_binary(const_cast<supernode::GraftTxExtra&>(graft_extra), blob);
tx_extra_graft_extra container;
container.data = blob;
blob.clear();
::serialization::dump_binary(container, blob);
extra.push_back(TX_EXTRA_GRAFT_EXTRA_TAG);
std::copy(blob.begin(), blob.end(), std::back_inserter(extra));
return true;
std::string blob;
::serialization::dump_binary(const_cast<supernode::GraftTxExtra&>(graft_extra), blob);
tx_extra_graft_extra container;
container.data = blob;
blob.clear();
::serialization::dump_binary(container, blob);
extra.push_back(TX_EXTRA_GRAFT_EXTRA_TAG);
std::copy(blob.begin(), blob.end(), std::back_inserter(extra));
return true;
}
//---------------------------------------------------------------
bool get_graft_tx_extra_from_extra(const transaction &tx, supernode::GraftTxExtra &graft_tx_extra)
{
std::vector<tx_extra_field> tx_extra_fields;
parse_tx_extra(tx.extra, tx_extra_fields);
tx_extra_graft_extra graft_extra;
if(!find_tx_extra_field_by_type(tx_extra_fields, graft_extra))
return false;
return ::serialization::parse_binary(graft_extra.data, graft_tx_extra);
std::vector<tx_extra_field> tx_extra_fields;
parse_tx_extra(tx.extra, tx_extra_fields);
tx_extra_graft_extra graft_extra;
if(!find_tx_extra_field_by_type(tx_extra_fields, graft_extra))
return false;
return ::serialization::parse_binary(graft_extra.data, graft_tx_extra);
}

namespace
{
struct GraftStakeTxExtra
{
std::string supernode_public_id;
cryptonote::account_public_address supernode_public_address;
crypto::signature supernode_signature;

GraftStakeTxExtra() = default;

GraftStakeTxExtra(const std::string &supernode_public_id,
const cryptonote::account_public_address& supernode_public_address,
const crypto::signature &supernode_signature) :
supernode_public_id(supernode_public_id),
supernode_public_address(supernode_public_address),
supernode_signature(supernode_signature)
{}

bool operator ==(const GraftStakeTxExtra &rhs) const {
return supernode_public_id == rhs.supernode_public_id &&
!memcmp(&supernode_public_address.m_view_public_key.data[0], &rhs.supernode_public_address.m_view_public_key.data[0],
sizeof(supernode_public_address.m_view_public_key.data)) &&
!memcmp(&supernode_signature.c.data[0], &rhs.supernode_signature.c.data[0], sizeof(supernode_signature.c.data)) &&
!memcmp(&supernode_signature.r.data[0], &rhs.supernode_signature.r.data[0], sizeof(supernode_signature.r.data));
}
struct GraftStakeTxExtra
{
std::string supernode_public_id;
cryptonote::account_public_address supernode_public_address;
crypto::signature supernode_signature;

GraftStakeTxExtra() = default;

GraftStakeTxExtra(const std::string &supernode_public_id,
const cryptonote::account_public_address& supernode_public_address,
const crypto::signature &supernode_signature) :
supernode_public_id(supernode_public_id),
supernode_public_address(supernode_public_address),
supernode_signature(supernode_signature)
{}

bool operator ==(const GraftStakeTxExtra &rhs) const {
return supernode_public_id == rhs.supernode_public_id &&
!memcmp(&supernode_public_address.m_view_public_key.data[0], &rhs.supernode_public_address.m_view_public_key.data[0],
sizeof(supernode_public_address.m_view_public_key.data)) &&
!memcmp(&supernode_signature.c.data[0], &rhs.supernode_signature.c.data[0], sizeof(supernode_signature.c.data)) &&
!memcmp(&supernode_signature.r.data[0], &rhs.supernode_signature.r.data[0], sizeof(supernode_signature.r.data));
}

BEGIN_SERIALIZE_OBJECT()
FIELD(supernode_public_id)
FIELD(supernode_public_address)
FIELD(supernode_signature)
END_SERIALIZE()
};
BEGIN_SERIALIZE_OBJECT()
FIELD(supernode_public_id)
FIELD(supernode_public_address)
FIELD(supernode_signature)
END_SERIALIZE()
};
}

bool add_graft_stake_tx_extra_to_extra
Expand All @@ -1224,16 +1224,16 @@ namespace cryptonote
const cryptonote::account_public_address &supernode_public_address,
const crypto::signature &supernode_signature)
{
GraftStakeTxExtra tx_extra(supernode_public_id, supernode_public_address, supernode_signature);
std::string blob;
::serialization::dump_binary(tx_extra, blob);
tx_extra_graft_stake_tx container;
container.data = blob;
blob.clear();
::serialization::dump_binary(container, blob);
extra.push_back(TX_EXTRA_GRAFT_STAKE_TX_TAG);
std::copy(blob.begin(), blob.end(), std::back_inserter(extra));
return true;
GraftStakeTxExtra tx_extra(supernode_public_id, supernode_public_address, supernode_signature);
std::string blob;
::serialization::dump_binary(tx_extra, blob);
tx_extra_graft_stake_tx container;
container.data = blob;
blob.clear();
::serialization::dump_binary(container, blob);
extra.push_back(TX_EXTRA_GRAFT_STAKE_TX_TAG);
std::copy(blob.begin(), blob.end(), std::back_inserter(extra));
return true;
}

bool add_graft_rta_header_to_extra(std::vector<uint8_t> &extra, const rta_header &rta_header)
Expand Down Expand Up @@ -1261,13 +1261,13 @@ namespace cryptonote

bool add_graft_tx_secret_key_to_extra(std::vector<uint8_t> &extra, const crypto::secret_key& secret_key)
{
tx_extra_graft_tx_secret_key container;
container.secret_key = secret_key;
std::string blob;
::serialization::dump_binary(container, blob);
extra.push_back(TX_EXTRA_GRAFT_TX_SECRET_KEY_TAG);
std::copy(blob.begin(), blob.end(), std::back_inserter(extra));
return true;
tx_extra_graft_tx_secret_key container;
container.secret_key = secret_key;
std::string blob;
::serialization::dump_binary(container, blob);
extra.push_back(TX_EXTRA_GRAFT_TX_SECRET_KEY_TAG);
std::copy(blob.begin(), blob.end(), std::back_inserter(extra));
return true;
}

bool get_graft_stake_tx_extra_from_extra
Expand All @@ -1277,30 +1277,30 @@ namespace cryptonote
crypto::signature &supernode_signature,
crypto::secret_key &tx_secret_key)
{
std::vector<tx_extra_field> tx_extra_fields;
parse_tx_extra(tx.extra, tx_extra_fields);
std::vector<tx_extra_field> tx_extra_fields;
parse_tx_extra(tx.extra, tx_extra_fields);

tx_extra_graft_stake_tx stake_tx_extra;
tx_extra_graft_stake_tx stake_tx_extra;

if(!find_tx_extra_field_by_type(tx_extra_fields, stake_tx_extra))
return false;
if(!find_tx_extra_field_by_type(tx_extra_fields, stake_tx_extra))
return false;

GraftStakeTxExtra stake_tx;
GraftStakeTxExtra stake_tx;

if (!::serialization::parse_binary(stake_tx_extra.data, stake_tx))
return false;
if (!::serialization::parse_binary(stake_tx_extra.data, stake_tx))
return false;

tx_extra_graft_tx_secret_key stake_tx_secret_key_extra;
tx_extra_graft_tx_secret_key stake_tx_secret_key_extra;

if(!find_tx_extra_field_by_type(tx_extra_fields, stake_tx_secret_key_extra))
return false;
if(!find_tx_extra_field_by_type(tx_extra_fields, stake_tx_secret_key_extra))
return false;

supernode_public_id = stake_tx.supernode_public_id;
supernode_public_address = stake_tx.supernode_public_address;
supernode_signature = stake_tx.supernode_signature;
tx_secret_key = stake_tx_secret_key_extra.secret_key;
supernode_public_id = stake_tx.supernode_public_id;
supernode_public_address = stake_tx.supernode_public_address;
supernode_signature = stake_tx.supernode_signature;
tx_secret_key = stake_tx_secret_key_extra.secret_key;

return true;
return true;
}

bool add_graft_rta_signatures_to_extra2(std::vector<uint8_t> &extra, const std::vector<rta_signature> &rta_signatures)
Expand All @@ -1325,4 +1325,79 @@ namespace cryptonote
return false;
return ::serialization::parse_binary(rta_signatures_data.data, rta_signatures);
}

bool graft_get_disqualification(const transaction &tx, tx_extra_graft_disqualification& disq)
{
if(tx.version != 123)
return false;
if(!tx.vin.empty() || !tx.vout.empty() || tx.rct_signatures.txnFee !=0)
return false;
std::vector<tx_extra_field> tx_extra_fields;
parse_tx_extra(tx.extra, tx_extra_fields);
return find_tx_extra_field_by_type(tx_extra_fields, disq);
}

bool graft_is_disqualification(const transaction &tx)
{
tx_extra_graft_disqualification disq;
return graft_get_disqualification(tx, disq);
}

bool graft_check_disqualification(const transaction &tx, tx_extra_graft_disqualification* pdisq)
{
tx_extra_graft_disqualification disq;
if(!graft_get_disqualification(tx, disq))
return false;
{//check signs
std::string item_str;
::serialization::dump_binary(disq.item, item_str);
crypto::hash hash;
crypto::cn_fast_hash(item_str.data(), item_str.size(), hash);
for(auto& si : disq.signers)
{
if(!crypto::check_signature(hash, si.signer_id, si.sign))
return false;
}
}
if(pdisq) *pdisq = std::move(disq);
return true;
}

bool graft_get_disqualification2(const transaction &tx, tx_extra_graft_disqualification2& disq)
{
if(tx.version != 124)
return false;
if(!tx.vin.empty() || !tx.vout.empty() || tx.rct_signatures.txnFee !=0)
return false;
std::vector<tx_extra_field> tx_extra_fields;
parse_tx_extra(tx.extra, tx_extra_fields);
return find_tx_extra_field_by_type(tx_extra_fields, disq);
}

bool graft_is_disqualification2(const transaction &tx)
{
tx_extra_graft_disqualification2 disq;
return graft_get_disqualification2(tx, disq);
}

bool graft_check_disqualification2(const transaction &tx, tx_extra_graft_disqualification2* pdisq)
{
tx_extra_graft_disqualification2 disq;
if(!graft_get_disqualification2(tx, disq))
return false;
{//check signs
std::string item_str;
::serialization::dump_binary(disq.item, item_str);
crypto::hash hash;
crypto::cn_fast_hash(item_str.data(), item_str.size(), hash);
for(auto& si : disq.signers)
{
if(!crypto::check_signature(hash, si.signer_id, si.sign))
return false;
}
}
if(pdisq) *pdisq = std::move(disq);
return true;
}

}
8 changes: 8 additions & 0 deletions src/cryptonote_basic/cryptonote_format_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,14 @@ namespace cryptonote
*/
bool get_graft_rta_signatures_from_extra2(const transaction& tx, std::vector<rta_signature> &rta_signatures);

bool graft_get_disqualification(const transaction &tx, tx_extra_graft_disqualification& disq);
bool graft_is_disqualification(const transaction &tx);
bool graft_check_disqualification(const transaction &tx, tx_extra_graft_disqualification* pdisq = nullptr);

bool graft_get_disqualification2(const transaction &tx, tx_extra_graft_disqualification2& disq);
bool graft_is_disqualification2(const transaction &tx);
bool graft_check_disqualification2(const transaction &tx, tx_extra_graft_disqualification2* pdisq = nullptr);

bool add_extra_nonce_to_tx_extra(std::vector<uint8_t>& tx_extra, const blobdata& extra_nonce);
bool remove_field_from_tx_extra(std::vector<uint8_t>& tx_extra, const std::type_info &type);
void set_payment_id_to_tx_extra_nonce(blobdata& extra_nonce, const crypto::hash& payment_id);
Expand Down
Loading