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

Disqualification transactions unit test #335

Open
wants to merge 26 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
aa4122c
Add block hash to blockchain_based_list request from cryptonode to su…
LenyKholodov Apr 19, 2019
4b618b6
Disqualification transaction support added.
AlexanderSuprunenko May 5, 2019
f4c1758
Initial disqualification lookup added.
AlexanderSuprunenko May 8, 2019
3cf1fe8
Common uniform selection algorithm added.
AlexanderSuprunenko May 10, 2019
f62ecee
selectSample is made common
AlexanderSuprunenko May 10, 2019
1681b76
select_BBQS_QCL common function added
AlexanderSuprunenko May 10, 2019
70214e5
Disqualification transaction validation added.
AlexanderSuprunenko May 11, 2019
9e62ba7
select_AuthSample added
AlexanderSuprunenko May 17, 2019
3416dae
A bug in the selectSample fixed
AlexanderSuprunenko May 21, 2019
12f6f79
style fix
AlexanderSuprunenko May 22, 2019
9b9ac3c
Auth sample disqualification transactions added.
AlexanderSuprunenko May 23, 2019
c3aed21
Disqualification transaction check is performed on tx_memory_pool::ad…
AlexanderSuprunenko May 27, 2019
de9e42d
Disqualifications rollback
AlexanderSuprunenko May 27, 2019
ea4bda5
Build fix
AlexanderSuprunenko May 28, 2019
00b9adb
core_tests: introducing rta tests for stake transactions
mbg033 Jun 14, 2019
2ae1541
get_block_reward: pre-mine works for every hf version (for core_tests)
mbg033 Jun 17, 2019
b07d8ef
cryptonote::core: return StakeTransactionProcessor for tests
mbg033 Jun 17, 2019
c80d5d6
StakeTransactionProcessor: set_active_from_height method added
mbg033 Jun 17, 2019
4c337db
add: construct_stake_tx_* functions
mbg033 Jun 17, 2019
b21e36f
simple supernode stake tests
mbg033 Jun 17, 2019
34f38a4
renamed unlock_height to be consistent with the existing terminology
mbg033 Jun 20, 2019
a96a6a7
[WIP] generating many stake txes
mbg033 Jun 21, 2019
3df6e56
disqualification bugs fixed
AlexanderSuprunenko Jul 19, 2019
ac27d2c
Disqualification unit test support
AlexanderSuprunenko Jul 22, 2019
38c9f3d
gen_rta_disqualification_test added
AlexanderSuprunenko Jul 22, 2019
613e4f4
gen_rta_tests renamed to gen_rta_test
AlexanderSuprunenko Jul 22, 2019
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 && version != 124 && CURRENT_TRANSACTION_VERSION < version)) return false;
VARINT_FIELD(unlock_time)
FIELD(vin)
FIELD(vout)
Expand Down
4 changes: 2 additions & 2 deletions src/cryptonote_basic/cryptonote_basic_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ namespace cryptonote {
const int emission_speed_factor = EMISSION_SPEED_FACTOR_PER_MINUTE - (target_minutes-1);

const uint64_t first_reward = 8301030000000000000U;

if (version >= 6 && median_weight > 0 && already_generated_coins < first_reward) {
if ((version >= 6 || already_generated_coins > 0) && median_weight > 0 && already_generated_coins < first_reward) {
reward = first_reward;
MDEBUG("premine triggered");
return true;
}

Expand Down
235 changes: 156 additions & 79 deletions src/cryptonote_basic/cryptonote_format_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ namespace cryptonote
//---------------------------------------------------------------
bool get_tx_fee(const transaction& tx, uint64_t & fee)
{
if (tx.version > 1)
if (tx.version > 1 && tx.version != 123 && tx.version != 124)
{
fee = tx.rct_signatures.txnFee;
return true;
Expand Down 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,81 @@ 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;
//get_tx_fee(tx) should return 0 when tx.vin tx.vout are empty
if(!tx.vin.empty() || !tx.vout.empty())
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;
//get_tx_fee(tx) should return 0 when tx.vin tx.vout are empty
if(!tx.vin.empty() || !tx.vout.empty())
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