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 Common auth sample, BBQS, & QCL generating algorithms #300

Open
wants to merge 6 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
40 changes: 40 additions & 0 deletions src/cryptonote_basic/cryptonote_format_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1325,4 +1325,44 @@ 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);
if(!find_tx_extra_field_by_type(tx_extra_fields, disq))
return false;
return true;
}

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;
}

}
4 changes: 4 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,10 @@ 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 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
48 changes: 47 additions & 1 deletion src/cryptonote_basic/tx_extra.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#define TX_EXTRA_GRAFT_TX_SECRET_KEY_TAG 0x81
#define TX_EXTRA_GRAFT_RTA_HEADER_TAG 0x83
#define TX_EXTRA_GRAFT_RTA_SIGNATURES_TAG 0x84
#define TX_EXTRA_GRAFT_DISQUALIFICATION_TAG 0x85

#define TX_EXTRA_MYSTERIOUS_MINERGATE_TAG 0xDE
#define TX_EXTRA_NONCE_PAYMENT_ID 0x00
Expand Down Expand Up @@ -229,14 +230,58 @@ namespace cryptonote
END_SERIALIZE()
};

struct tx_extra_graft_signer_item
{
uint64_t block_height;
crypto::hash block_hash;
crypto::public_key id;
BEGIN_SERIALIZE()
FIELD(block_height)
FIELD(block_hash)
FIELD(id)
END_SERIALIZE()
};

struct tx_extra_graft_disqualification
{
struct disqualification_item
{
uint64_t block_height;
crypto::hash block_hash;
crypto::public_key id;
BEGIN_SERIALIZE()
FIELD(block_height)
FIELD(block_hash)
FIELD(id)
END_SERIALIZE()
};

struct signer_item
{
crypto::public_key signer_id;
crypto::signature sign;
BEGIN_SERIALIZE()
FIELD(signer_id)
FIELD(sign)
END_SERIALIZE()
};

disqualification_item item;
std::vector<signer_item> signers;
BEGIN_SERIALIZE()
FIELD(item)
FIELD(signers)
END_SERIALIZE()
};

// tx_extra_field format, except tx_extra_padding and tx_extra_pub_key:
// varint tag;
// varint size;
// varint data[];
typedef boost::variant<tx_extra_padding, tx_extra_pub_key, tx_extra_nonce, tx_extra_merge_mining_tag, tx_extra_additional_pub_keys,
tx_extra_mysterious_minergate, tx_extra_graft_extra, tx_extra_graft_stake_tx,
tx_extra_graft_tx_secret_key, tx_extra_graft_rta_header, tx_extra_graft_rta_signatures> tx_extra_field;
tx_extra_graft_tx_secret_key, tx_extra_graft_rta_header, tx_extra_graft_rta_signatures,
tx_extra_graft_disqualification> tx_extra_field;
}

VARIANT_TAG(binary_archive, cryptonote::tx_extra_padding, TX_EXTRA_TAG_PADDING);
Expand All @@ -250,3 +295,4 @@ VARIANT_TAG(binary_archive, cryptonote::tx_extra_graft_stake_tx, TX_EXTRA_GRAFT_
VARIANT_TAG(binary_archive, cryptonote::tx_extra_graft_tx_secret_key, TX_EXTRA_GRAFT_TX_SECRET_KEY_TAG);
VARIANT_TAG(binary_archive, cryptonote::tx_extra_graft_rta_header, TX_EXTRA_GRAFT_RTA_HEADER_TAG);
VARIANT_TAG(binary_archive, cryptonote::tx_extra_graft_rta_signatures, TX_EXTRA_GRAFT_RTA_SIGNATURES_TAG);
VARIANT_TAG(binary_archive, cryptonote::tx_extra_graft_disqualification, TX_EXTRA_GRAFT_DISQUALIFICATION_TAG);
8 changes: 6 additions & 2 deletions src/cryptonote_core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,13 @@ set(cryptonote_core_sources
cryptonote_tx_utils.cpp
stake_transaction_storage.cpp
stake_transaction_processor.cpp
blockchain_based_list.cpp)
blockchain_based_list.cpp
../utils/sample_generator.cpp
)

set(cryptonote_core_headers)
set(cryptonote_core_headers
../utils/sample_generator.h
)

set(cryptonote_core_private_headers
blockchain_storage_boost_serialization.h
Expand Down
39 changes: 10 additions & 29 deletions src/cryptonote_core/blockchain_based_list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "graft_rta_config.h"
#include "blockchain_based_list.h"
#include "serialization/binary_utils.h"
#include "utils/sample_generator.h"

using namespace cryptonote;

Expand Down Expand Up @@ -42,22 +43,7 @@ const BlockchainBasedList::supernode_tier_array& BlockchainBasedList::tiers(size

void BlockchainBasedList::select_supernodes(size_t items_count, const supernode_array& src_list, supernode_array& dst_list)
{
size_t src_list_size = src_list.size();

if (items_count > src_list_size)
items_count = src_list_size;

for (size_t i=0; i<src_list_size; i++)
{
size_t random_value = m_rng() % (src_list_size - i);

if (random_value >= items_count)
continue;

dst_list.push_back(src_list[i]);

items_count--;
}
graft::generator::uniform_select(graft::generator::do_not_seed{}, items_count, src_list, dst_list);
}

void BlockchainBasedList::apply_block(uint64_t block_height, const crypto::hash& block_hash, StakeTransactionStorage& stake_txs_storage)
Expand All @@ -72,13 +58,11 @@ void BlockchainBasedList::apply_block(uint64_t block_height, const crypto::hash&

//build blockchain based list for each tier

supernode_array prev_supernodes, current_supernodes;
supernode_tier_array new_tier;

for (size_t i=0; i<config::graft::TIERS_COUNT; i++)
{
prev_supernodes.clear();
current_supernodes.clear();
supernode_array prev_supernodes;

//prepare lists of valid supernodes for this tier

Expand All @@ -98,10 +82,14 @@ void BlockchainBasedList::apply_block(uint64_t block_height, const crypto::hash&
if (stake->tier != i + 1)
continue;

if (stake_txs_storage.is_disqualified(block_height, sn.supernode_public_id))
continue;

prev_supernodes.push_back(sn);
}
}

supernode_array current_supernodes;
current_supernodes.reserve(stakes.size());

for (const supernode_stake& stake : stakes)
Expand All @@ -123,26 +111,19 @@ void BlockchainBasedList::apply_block(uint64_t block_height, const crypto::hash&
current_supernodes.emplace_back(std::move(sn));
}

//seed RNG

std::seed_seq seed(reinterpret_cast<const unsigned char*>(&block_hash.data[0]),
reinterpret_cast<const unsigned char*>(&block_hash.data[sizeof block_hash.data]));

m_rng.seed(seed);

//sort valid supernodes by the age of stake

std::stable_sort(current_supernodes.begin(), current_supernodes.end(), [](const supernode& s1, const supernode& s2) {
return s1.block_height < s2.block_height || (s1.block_height == s2.block_height && s1.supernode_public_id < s2.supernode_public_id);
});

//seed RNG
graft::generator::seed_uniform_select(block_hash);
//select supernodes from the previous list

supernode_array new_supernodes;

select_supernodes(PREVIOS_BLOCKCHAIN_BASED_LIST_MAX_SIZE, prev_supernodes, new_supernodes);

if (new_supernodes.size() < BLOCKCHAIN_BASED_LIST_SIZE)
if (new_supernodes.size() < BLOCKCHAIN_BASED_LIST_SIZE) //looks like it is always true
{
//remove supernodes of prev list from current list

Expand Down
1 change: 0 additions & 1 deletion src/cryptonote_core/blockchain_based_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ class BlockchainBasedList
list_history m_history;
uint64_t m_block_height;
size_t m_history_depth;
std::mt19937_64 m_rng;
uint64_t m_first_block_number;
mutable bool m_need_store;
};
Expand Down
10 changes: 9 additions & 1 deletion src/cryptonote_core/cryptonote_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ namespace cryptonote
uint8_t version = m_blockchain_storage.get_current_hard_fork_version();
// don't allow rta tx until hf 13
const size_t max_tx_version = version == 1 ? 1 : version < 13 ? 2 : CURRENT_TRANSACTION_VERSION;
if (tx.version == 0 || tx.version > max_tx_version)
if (tx.version == 0 || (tx.version != 123 && tx.version > max_tx_version))
{
// v3 is the latest one we know
tvc.m_verifivation_failed = true;
Expand Down Expand Up @@ -960,6 +960,14 @@ namespace cryptonote
//-----------------------------------------------------------------------------------------------
bool core::check_tx_semantic(const transaction& tx, bool keeped_by_block) const
{
if(tx.version == 123)
{
if(tx.vin.size() || tx.vout.size())
{
MERROR_VER("qualification tx with non-empty inputs or outputs, rejected for tx id= " << get_transaction_hash(tx));
}
return graft_is_disqualification(tx);
}
if(!tx.vin.size())
{
MERROR_VER("tx with empty inputs, rejected for tx id= " << get_transaction_hash(tx));
Expand Down
39 changes: 37 additions & 2 deletions src/cryptonote_core/stake_transaction_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "stake_transaction_processor.h"
#include "../graft_rta_config.h"
#include "serialization/binary_utils.h"

#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "staketransaction.processor"
Expand Down Expand Up @@ -171,12 +172,39 @@ void StakeTransactionProcessor::process_block_stake_transaction(uint64_t block_i
MWARNING(" " << tx_hash);
}

StakeTransactionStorage::disqualification_array disquals;

for (const transaction& tx : txs)
{
const crypto::hash tx_hash = get_transaction_prefix_hash(tx);

try
{
if(tx.version == 123)
{
continue;
tx_extra_graft_disqualification disq_extra;
if(graft_check_disqualification(tx, &disq_extra))
{
MWARNING("Ignore invalid disqualification transaction at block #" << block_index << ", tx_hash=" << tx_hash);
continue;
}

disqualification disq;
::serialization::dump_binary(disq_extra, disq.blob);
disq.block_index = block_index;
disq.id = disq_extra.item.id;
disq.id_str = epee::string_tools::pod_to_hex(disq.id);
//TODO: check unlock_time

MDEBUG("New disqualification transaction found at block #" << block_index << ", tx_hash=" << tx_hash << ", supernode_id '" << disq.id_str << "'");

disquals.push_back(std::move(disq));
continue;
} //if(tx.version == 123)

stake_transaction stake_tx;

if (!get_graft_stake_tx_extra_from_extra(tx, stake_tx.supernode_public_id, stake_tx.supernode_public_address, stake_tx.supernode_signature, stake_tx.tx_secret_key))
continue;

Expand Down Expand Up @@ -246,6 +274,8 @@ void StakeTransactionProcessor::process_block_stake_transaction(uint64_t block_i
}
}

m_storage->add_disquals(disquals);

m_stakes_need_update = true; //TODO: cache for stakes

//update supernode stakes
Expand Down Expand Up @@ -413,7 +443,7 @@ void StakeTransactionProcessor::invoke_update_stakes_handler_impl(uint64_t block
if (!m_storage)
return;

m_on_stakes_update(block_index, m_storage->get_supernode_stakes(block_index));
m_on_stakes_update(block_index, m_storage->get_supernode_stakes(block_index), m_storage->get_supernode_disqualiications(block_index));

m_stakes_need_update = false;
}
Expand Down Expand Up @@ -461,7 +491,12 @@ void StakeTransactionProcessor::invoke_update_blockchain_based_list_handler_impl
uint64_t height = m_blockchain_based_list->block_height();

for (size_t i=0; i<depth; i++)
m_on_blockchain_based_list_update(height - i, m_blockchain_based_list->tiers(i));
{
uint64_t block_height = height - i;
crypto::hash block_hash = m_blockchain.get_block_id_by_height(block_height);

m_on_blockchain_based_list_update(block_height, block_hash, m_blockchain_based_list->tiers(i));
}

m_blockchain_based_list_need_update = false;
}
Expand Down
5 changes: 3 additions & 2 deletions src/cryptonote_core/stake_transaction_processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class StakeTransactionProcessor
{
public:
typedef StakeTransactionStorage::supernode_stake_array supernode_stake_array;
typedef StakeTransactionStorage::supernode_disqualification_array supernode_disqualification_array;

StakeTransactionProcessor(Blockchain& blockchain);

Expand All @@ -26,7 +27,7 @@ class StakeTransactionProcessor
/// Synchronize with blockchain
void synchronize();

typedef std::function<void(uint64_t block_number, const supernode_stake_array&)> supernode_stakes_update_handler;
typedef std::function<void(uint64_t block_number, const supernode_stake_array&, const supernode_disqualification_array&)> supernode_stakes_update_handler;

/// Update handler for new stakes
void set_on_update_stakes_handler(const supernode_stakes_update_handler&);
Expand All @@ -35,7 +36,7 @@ class StakeTransactionProcessor
void invoke_update_stakes_handler(bool force = true);

typedef BlockchainBasedList::supernode_tier_array supernode_tier_array;
typedef std::function<void(uint64_t block_number, const supernode_tier_array&)> blockchain_based_list_update_handler;
typedef std::function<void(uint64_t block_number, const crypto::hash& block_hash, const supernode_tier_array&)> blockchain_based_list_update_handler;

/// Update handler for new blockchain based list
void set_on_update_blockchain_based_list_handler(const blockchain_based_list_update_handler&);
Expand Down
Loading