Permalink
Browse files

Add invite processing operations and evaluators, remove temp account

  • Loading branch information...
On1x committed Sep 19, 2018
1 parent 0552aed commit 1604894377b38ca24892cd3e0bcd1d8c49983adc
@@ -21,6 +21,7 @@ if(BUILD_SHARED_LIBRARIES)
fork_database.cpp

chain_evaluator.cpp
invite_evaluator.cpp

chain_objects.cpp
shared_authority.cpp
@@ -31,6 +32,7 @@ if(BUILD_SHARED_LIBRARIES)
database_proposal_object.cpp
chain_properties_evaluators.cpp
committee_evaluator.cpp
invite_evaluator.cpp

include/graphene/chain/account_object.hpp
include/graphene/chain/block_log.hpp
@@ -59,6 +61,7 @@ if(BUILD_SHARED_LIBRARIES)
include/graphene/chain/transaction_object.hpp
include/graphene/chain/witness_objects.hpp
include/graphene/chain/committee_objects.hpp
include/graphene/chain/invite_objects.hpp

${hardfork_hpp_file}
"${CMAKE_CURRENT_BINARY_DIR}/include/graphene/chain/hardfork.hpp"
@@ -81,6 +84,7 @@ else()
database_proposal_object.cpp
chain_properties_evaluators.cpp
committee_evaluator.cpp
invite_evaluator.cpp

include/graphene/chain/account_object.hpp
include/graphene/chain/block_log.hpp
@@ -109,14 +113,15 @@ else()
include/graphene/chain/transaction_object.hpp
include/graphene/chain/witness_objects.hpp
include/graphene/chain/committee_objects.hpp
include/graphene/chain/invite_objects.hpp

${hardfork_hpp_file}
"${CMAKE_CURRENT_BINARY_DIR}/include/graphene/chain/hardfork.hpp"
)
endif()

add_dependencies(graphene_chain graphene_protocol build_hardfork_hpp)
target_link_libraries(graphene_chain graphene_protocol fc chainbase appbase ${PATCH_MERGE_LIB})
add_dependencies(graphene_chain graphene_protocol graphene_utilities build_hardfork_hpp)
target_link_libraries(graphene_chain graphene_protocol graphene_utilities fc chainbase appbase ${PATCH_MERGE_LIB})
target_include_directories(graphene_chain PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_BINARY_DIR}/include")

if(MSVC)
@@ -117,7 +117,7 @@ namespace graphene { namespace chain {

void account_update_evaluator::do_apply(const account_update_operation &o) {
database &_db = db();
FC_ASSERT(o.account != CHAIN_TEMP_ACCOUNT, "Cannot update temp account.");
FC_ASSERT(o.account != CHAIN_INVITE_ACCOUNT, "Cannot update invite account.");

if (o.posting) {
o.posting->validate();
@@ -19,6 +19,7 @@
#include <graphene/chain/operation_notification.hpp>
#include <graphene/chain/proposal_object.hpp>
#include <graphene/chain/committee_objects.hpp>
#include <graphene/chain/invite_objects.hpp>

#include <fc/smart_ref_impl.hpp>

@@ -2332,6 +2333,9 @@ namespace graphene { namespace chain {
_my->_evaluator_registry.register_evaluator<committee_worker_create_request_evaluator>();
_my->_evaluator_registry.register_evaluator<committee_worker_cancel_request_evaluator>();
_my->_evaluator_registry.register_evaluator<committee_vote_request_evaluator>();
_my->_evaluator_registry.register_evaluator<create_invite_evaluator>();
_my->_evaluator_registry.register_evaluator<claim_invite_balance_evaluator>();
_my->_evaluator_registry.register_evaluator<invite_registration_evaluator>();
}

void database::set_custom_operation_interpreter(const std::string &id, std::shared_ptr<custom_operation_interpreter> registry) {
@@ -2373,6 +2377,7 @@ namespace graphene { namespace chain {
add_core_index<required_approval_index>(*this);
add_core_index<committee_request_index>(*this);
add_core_index<committee_vote_index>(*this);
add_core_index<invite_index>(*this);

_plugin_index_signal();
}
@@ -2499,18 +2504,27 @@ namespace graphene { namespace chain {
auth.posting.weight_threshold = 1;
});

create<account_object>([&](account_object &a) {
a.name = CHAIN_TEMP_ACCOUNT;
// VIZ: invite account
public_key_type invite_public_key(CHAIN_INVITE_PUBLIC_KEY);
create<account_object>([&](account_object& a)
{
a.name = CHAIN_INVITE_ACCOUNT;
a.balance = asset(0, TOKEN_SYMBOL);
});
#ifndef IS_LOW_MEM
create<account_metadata_object>([&](account_metadata_object& m) {
m.account = CHAIN_TEMP_ACCOUNT;
++bandwidth_reserve_candidates;

#ifndef IS_LOW_MEM
create< account_metadata_object >([&](account_metadata_object& m) {
m.account = CHAIN_INVITE_ACCOUNT;
});
#endif
create<account_authority_object>([&](account_authority_object &auth) {
auth.account = CHAIN_TEMP_ACCOUNT;
auth.owner.weight_threshold = 0;
auth.active.weight_threshold = 0;
#endif

create<account_authority_object>([&](account_authority_object& auth)
{
auth.account = CHAIN_INVITE_ACCOUNT;
auth.owner.weight_threshold = 1;
auth.active.add_authority( invite_public_key, 1 );
auth.active.weight_threshold = 1;
auth.posting.weight_threshold = 1;
});

@@ -37,6 +37,9 @@ namespace graphene { namespace chain {
DEFINE_EVALUATOR(committee_worker_create_request)
DEFINE_EVALUATOR(committee_worker_cancel_request)
DEFINE_EVALUATOR(committee_vote_request)
DEFINE_EVALUATOR(create_invite)
DEFINE_EVALUATOR(claim_invite_balance)
DEFINE_EVALUATOR(invite_registration)

class proposal_create_evaluator: public evaluator_impl<proposal_create_evaluator> {
public:
@@ -66,7 +66,8 @@ namespace graphene { namespace chain {
proposal_object_type,
required_approval_object_type,
committee_request_object_type,
committee_vote_object_type
committee_vote_object_type,
invite_object_type
};

class dynamic_global_property_object;
@@ -95,6 +96,7 @@ namespace graphene { namespace chain {
class proposal_object;
class committee_request_object;
class committee_vote_object;
class invite_object;

typedef object_id<dynamic_global_property_object> dynamic_global_property_id_type;
typedef object_id<account_object> account_id_type;
@@ -121,6 +123,7 @@ namespace graphene { namespace chain {
typedef object_id<required_approval_object> required_approval_object_id_type;
typedef object_id<committee_request_object> committee_request_object_id_type;
typedef object_id<committee_vote_object> committee_vote_object_id_type;
typedef object_id<invite_object> invite_object_id_type;

} } //graphene::chain

@@ -211,6 +214,7 @@ FC_REFLECT_ENUM(graphene::chain::object_type,
(required_approval_object_type)
(committee_request_object_type)
(committee_vote_object_type)
(invite_object_type)
)

FC_REFLECT_TYPENAME((graphene::chain::shared_string))
@@ -0,0 +1,62 @@
#pragma once

#include <graphene/protocol/authority.hpp>
#include <graphene/protocol/chain_operations.hpp>

#include <graphene/chain/chain_object_types.hpp>
#include <graphene/chain/shared_authority.hpp>
#include <graphene/chain/witness_objects.hpp>

#include <boost/multi_index/composite_key.hpp>

namespace graphene {
namespace chain {
class invite_object
: public object<invite_object_type, invite_object> {
public:
invite_object() = delete;

template<typename Constructor, typename Allocator>
invite_object(Constructor &&c, allocator <Allocator> a) {
c(*this);
}

id_type id;

account_name_type creator;
account_name_type receiver;
public_key_type invite_key;
string invite_secret;

asset balance = asset(0, TOKEN_SYMBOL);
asset claimed_balance = asset(0, TOKEN_SYMBOL);

time_point_sec create_time;
time_point_sec claim_time;
uint16_t status;
};

struct by_invite_key;
struct by_status;
typedef multi_index_container <
invite_object,
indexed_by<
ordered_unique<
tag<by_id>,
member<invite_object, invite_object_id_type, &invite_object::id>
>,
ordered_non_unique<tag<by_invite_key>,
member<invite_object, public_key_type, &invite_object::invite_key>
>,
ordered_non_unique<tag<by_status>,
member<invite_object, uint16_t, &invite_object::status>
>
>,
allocator <invite_object>
>
invite_index;
}
} // graphene::chain

FC_REFLECT((graphene::chain::invite_object),(id)(creator)(receiver)(invite_key)(invite_secret)(balance)(claimed_balance)(create_time)(claim_time)(status))
CHAINBASE_SET_INDEX_TYPE(graphene::chain::invite_object, graphene::chain::invite_index)
@@ -0,0 +1,107 @@
#include <graphene/chain/chain_evaluator.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/chain_objects.hpp>
#include <graphene/chain/invite_objects.hpp>

#include <graphene/utilities/key_conversion.hpp>

namespace graphene { namespace chain {

void create_invite_evaluator::do_apply(const create_invite_operation& o) {
const auto& creator = _db.get_account(o.creator);
const auto& median_props = _db.get_witness_schedule_object().median_props;

FC_ASSERT(creator.balance >= o.balance, "Insufficient balance to create invite.",
("creator.balance", creator.balance)("invite.balance", o.balance));
FC_ASSERT(o.invite_key != public_key_type(), "Invite key cannot be blank.");
FC_ASSERT(o.balance >= median_props.account_creation_fee, "Invite balance must be more or equal consensus account_creation_fee.");

const auto &idx = _db.get_index<invite_index>().indices().get<by_invite_key>();
auto itr = idx.find(o.invite_key);
FC_ASSERT(itr == idx.end(), "Invite with same key was found. Use another invite key.");

_db.adjust_balance(creator, -o.balance);
_db.create<invite_object>([&](invite_object& c) {
c.creator = o.creator;
c.invite_key = o.invite_key;
c.balance = o.balance;
c.create_time = _db.head_block_time();
c.status = 0;
});
}

void claim_invite_balance_evaluator::do_apply(const claim_invite_balance_operation& o) {
const auto& receiver = _db.get_account(o.receiver);
FC_ASSERT(o.invite_secret.size(), "Invite secret cannot be blank.");

fc::optional<fc::ecc::private_key> invite_secret = graphene::utilities::wif_to_key(o.invite_secret);
FC_ASSERT(invite_secret, "Invite secret must be WIF.");

public_key_type check_invite_key = invite_secret->get_public_key();

const auto &idx = _db.get_index<invite_index>().indices().get<by_invite_key>();
auto itr = idx.find(check_invite_key);
FC_ASSERT(itr != idx.end(), "Invite was not found.");

_db.adjust_balance(receiver, itr->balance);
if(itr->status == 0){
_db.modify(*itr, [&](invite_object& c) {
c.status = 1;
c.receiver = o.receiver;
c.claimed_balance=c.balance;
c.balance=asset(0, TOKEN_SYMBOL);
c.claim_time = _db.head_block_time();
});
}
else{
FC_ASSERT(false, "Invite already claimed.");
}
}

void invite_registration_evaluator::do_apply(const invite_registration_operation& o) {
FC_ASSERT(o.invite_secret.size(), "Invite secret cannot be blank.");

fc::optional<fc::ecc::private_key> invite_secret = graphene::utilities::wif_to_key(o.invite_secret);
FC_ASSERT(invite_secret, "Invite secret must be WIF.");

public_key_type check_invite_key = invite_secret->get_public_key();

const auto &idx = _db.get_index<invite_index>().indices().get<by_invite_key>();
auto itr = idx.find(check_invite_key);
FC_ASSERT(itr != idx.end(), "Invite was not found.");

if(itr->status == 0){
public_key_type key_from_operation(o.new_account_key);

_db.create<account_object>([&](account_object &acc) {
acc.name = o.new_account_name;
acc.memo_key = key_from_operation;
acc.created = _db.head_block_time();
acc.recovery_account = itr->creator;
acc.referrer = itr->creator;
});
_db.create<account_authority_object>([&](account_authority_object &auth) {
auth.account = o.new_account_name;
auth.owner.add_authority(key_from_operation, 1);
auth.owner.weight_threshold = 1;
auth.active = auth.owner;
auth.posting = auth.active;
});
_db.create<account_metadata_object>([&](account_metadata_object& m) {
m.account = o.new_account_name;
});
const auto &new_account = _db.get_account(o.new_account_name);
_db.create_vesting(new_account, itr->balance);
_db.modify(*itr, [&](invite_object& c) {
c.status = 2;
c.receiver = o.new_account_name;
c.claimed_balance=c.balance;
c.balance=asset(0, TOKEN_SYMBOL);
c.claim_time = _db.head_block_time();
});
}
else{
FC_ASSERT(false, "Invite already claimed.");
}
}
} } // graphene::chain
@@ -298,4 +298,21 @@ namespace graphene { namespace protocol {
FC_ASSERT(vesting_shares.amount >= 0, "Delegation cannot be negative");
}

void create_invite_operation::validate() const {
validate_account_name(creator);
FC_ASSERT(is_asset_type(balance, TOKEN_SYMBOL), "Invite creation balance must be TOKEN_SYMBOL");
FC_ASSERT(balance > asset(0, TOKEN_SYMBOL), "Invite creation balance must be nonzero amount");
}

void claim_invite_balance_operation::validate() const {
validate_account_name(initiator);
validate_account_name(receiver);
}

void invite_registration_operation::validate() const {
validate_account_name(initiator);
validate_account_name(new_account_name);
validate_domain_name(new_account_name, initiator);
}

} } // graphene::protocol
@@ -56,7 +56,6 @@ namespace graphene {
result["CHAIN_NUM_INITIATORS"] = CHAIN_NUM_INITIATORS;
result["CHAIN_PROXY_TO_SELF_ACCOUNT"] = CHAIN_PROXY_TO_SELF_ACCOUNT;
result["CHAIN_SECONDS_PER_YEAR"] = CHAIN_SECONDS_PER_YEAR;
result["CHAIN_TEMP_ACCOUNT"] = CHAIN_TEMP_ACCOUNT;
result["CHAIN_UPVOTE_LOCKOUT"] = CHAIN_UPVOTE_LOCKOUT;
result["CHAIN_VESTING_WITHDRAW_INTERVALS"] = CHAIN_VESTING_WITHDRAW_INTERVALS;
result["CHAIN_VESTING_WITHDRAW_INTERVAL_SECONDS"] = CHAIN_VESTING_WITHDRAW_INTERVAL_SECONDS;
Oops, something went wrong.

0 comments on commit 1604894

Please sign in to comment.