add additional fields to son object and operations
This commit is contained in:
parent
4d0a5b683f
commit
e2c579bb02
4 changed files with 130 additions and 114 deletions
|
|
@ -9,7 +9,10 @@ namespace graphene { namespace chain {
|
||||||
|
|
||||||
asset fee;
|
asset fee;
|
||||||
account_id_type owner_account;
|
account_id_type owner_account;
|
||||||
std::string url;
|
std::string url;
|
||||||
|
vesting_balance_id_type deposit;
|
||||||
|
public_key_type signing_key;
|
||||||
|
vesting_balance_id_type pay_vb;
|
||||||
|
|
||||||
account_id_type fee_payer()const { return owner_account; }
|
account_id_type fee_payer()const { return owner_account; }
|
||||||
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||||
|
|
@ -22,7 +25,10 @@ namespace graphene { namespace chain {
|
||||||
asset fee;
|
asset fee;
|
||||||
son_id_type son_id;
|
son_id_type son_id;
|
||||||
account_id_type owner_account;
|
account_id_type owner_account;
|
||||||
std::string new_url;
|
optional<std::string> new_url;
|
||||||
|
optional<vesting_balance_id_type> new_deposit;
|
||||||
|
optional<public_key_type> new_signing_key;
|
||||||
|
optional<vesting_balance_id_type> new_pay_vb;
|
||||||
|
|
||||||
account_id_type fee_payer()const { return owner_account; }
|
account_id_type fee_payer()const { return owner_account; }
|
||||||
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||||
|
|
@ -42,11 +48,13 @@ namespace graphene { namespace chain {
|
||||||
|
|
||||||
} } // namespace graphene::chain
|
} } // namespace graphene::chain
|
||||||
|
|
||||||
FC_REFLECT( graphene::chain::son_create_operation::fee_parameters_type, (fee) )
|
FC_REFLECT(graphene::chain::son_create_operation::fee_parameters_type, (fee) )
|
||||||
FC_REFLECT( graphene::chain::son_create_operation, (fee)(owner_account)(url) )
|
FC_REFLECT(graphene::chain::son_create_operation, (fee)(owner_account)(url)(deposit)(signing_key)
|
||||||
|
(pay_vb) )
|
||||||
|
|
||||||
FC_REFLECT( graphene::chain::son_update_operation::fee_parameters_type, (fee) )
|
FC_REFLECT(graphene::chain::son_update_operation::fee_parameters_type, (fee) )
|
||||||
FC_REFLECT( graphene::chain::son_update_operation, (fee)(son_id)(owner_account)(new_url) )
|
FC_REFLECT(graphene::chain::son_update_operation, (fee)(son_id)(owner_account)(new_url)(new_deposit)
|
||||||
|
(new_signing_key)(new_pay_vb) )
|
||||||
|
|
||||||
FC_REFLECT( graphene::chain::son_delete_operation::fee_parameters_type, (fee) )
|
FC_REFLECT(graphene::chain::son_delete_operation::fee_parameters_type, (fee) )
|
||||||
FC_REFLECT( graphene::chain::son_delete_operation, (fee)(son_id)(owner_account) )
|
FC_REFLECT(graphene::chain::son_delete_operation, (fee)(son_id)(owner_account) )
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,13 @@ namespace graphene { namespace chain {
|
||||||
static const uint8_t space_id = protocol_ids;
|
static const uint8_t space_id = protocol_ids;
|
||||||
static const uint8_t type_id = son_object_type;
|
static const uint8_t type_id = son_object_type;
|
||||||
|
|
||||||
account_id_type son_member_account;
|
account_id_type son_member_account;
|
||||||
vote_id_type vote_id;
|
vote_id_type vote_id;
|
||||||
uint64_t total_votes = 0;
|
uint64_t total_votes = 0;
|
||||||
string url;
|
string url;
|
||||||
|
vesting_balance_id_type deposit;
|
||||||
|
public_key_type signing_key;
|
||||||
|
vesting_balance_id_type pay_vb;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct by_account;
|
struct by_account;
|
||||||
|
|
@ -43,4 +46,4 @@ namespace graphene { namespace chain {
|
||||||
} } // graphene::chain
|
} } // graphene::chain
|
||||||
|
|
||||||
FC_REFLECT_DERIVED( graphene::chain::son_object, (graphene::db::object),
|
FC_REFLECT_DERIVED( graphene::chain::son_object, (graphene::db::object),
|
||||||
(son_member_account)(vote_id)(total_votes)(url) )
|
(son_member_account)(vote_id)(total_votes)(url)(deposit)(signing_key)(pay_vb) )
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,11 @@ object_id_type create_son_evaluator::do_apply(const son_create_operation& op)
|
||||||
|
|
||||||
const auto& new_son_object = db().create<son_object>( [&]( son_object& obj ){
|
const auto& new_son_object = db().create<son_object>( [&]( son_object& obj ){
|
||||||
obj.son_member_account = op.owner_account;
|
obj.son_member_account = op.owner_account;
|
||||||
obj.vote_id = vote_id;
|
obj.vote_id = vote_id;
|
||||||
obj.url = op.url;
|
obj.url = op.url;
|
||||||
|
obj.deposit = op.deposit;
|
||||||
|
obj.signing_key = op.signing_key;
|
||||||
|
obj.pay_vb = op.pay_vb;
|
||||||
});
|
});
|
||||||
return new_son_object.id;
|
return new_son_object.id;
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||||
|
|
@ -44,7 +47,10 @@ object_id_type update_son_evaluator::do_apply(const son_update_operation& op)
|
||||||
if(itr != idx.end())
|
if(itr != idx.end())
|
||||||
{
|
{
|
||||||
db().modify(*itr, [&op](son_object &so) {
|
db().modify(*itr, [&op](son_object &so) {
|
||||||
so.url = op.new_url;
|
if(op.new_url.valid()) so.url = *op.new_url;
|
||||||
|
if(op.new_deposit.valid()) so.deposit = *op.new_deposit;
|
||||||
|
if(op.new_signing_key.valid()) so.signing_key = *op.new_signing_key;
|
||||||
|
if(op.new_pay_vb.valid()) so.pay_vb = *op.new_pay_vb;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return op.son_id;
|
return op.son_id;
|
||||||
|
|
|
||||||
|
|
@ -8,100 +8,9 @@
|
||||||
using namespace graphene::chain;
|
using namespace graphene::chain;
|
||||||
using namespace graphene::chain::test;
|
using namespace graphene::chain::test;
|
||||||
|
|
||||||
class test_create_son_member_evaluator: public create_son_evaluator {
|
|
||||||
public:
|
|
||||||
test_create_son_member_evaluator( database& link_db ):
|
|
||||||
ptr_trx_state( new transaction_evaluation_state( &link_db ) )
|
|
||||||
{
|
|
||||||
trx_state = ptr_trx_state.get();
|
|
||||||
}
|
|
||||||
std::unique_ptr<transaction_evaluation_state> ptr_trx_state;
|
|
||||||
};
|
|
||||||
|
|
||||||
class test_update_son_member_evaluator: public update_son_evaluator {
|
|
||||||
public:
|
|
||||||
test_update_son_member_evaluator( database& link_db ):
|
|
||||||
ptr_trx_state( new transaction_evaluation_state( &link_db ) )
|
|
||||||
{
|
|
||||||
trx_state = ptr_trx_state.get();
|
|
||||||
}
|
|
||||||
std::unique_ptr<transaction_evaluation_state> ptr_trx_state;
|
|
||||||
};
|
|
||||||
|
|
||||||
class test_delete_son_member_evaluator: public delete_son_evaluator {
|
|
||||||
public:
|
|
||||||
test_delete_son_member_evaluator( database& link_db ):
|
|
||||||
ptr_trx_state( new transaction_evaluation_state( &link_db ) )
|
|
||||||
{
|
|
||||||
trx_state = ptr_trx_state.get();
|
|
||||||
}
|
|
||||||
std::unique_ptr<transaction_evaluation_state> ptr_trx_state;
|
|
||||||
};
|
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE( son_operation_tests, database_fixture )
|
BOOST_FIXTURE_TEST_SUITE( son_operation_tests, database_fixture )
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( create_son_test ) {
|
BOOST_AUTO_TEST_CASE( create_son_test ) {
|
||||||
generate_blocks( HARDFORK_SON_TIME );
|
|
||||||
while( db.head_block_time() <= HARDFORK_SON_TIME )
|
|
||||||
{
|
|
||||||
generate_block();
|
|
||||||
}
|
|
||||||
std::string test_url = "https://create_son_test";
|
|
||||||
test_create_son_member_evaluator test_eval( db );
|
|
||||||
son_create_operation op;
|
|
||||||
op.owner_account = account_id_type(1);
|
|
||||||
op.url = test_url;
|
|
||||||
|
|
||||||
BOOST_CHECK_NO_THROW( test_eval.do_evaluate( op ) );
|
|
||||||
auto id = test_eval.do_apply( op );
|
|
||||||
const auto& idx = db.get_index_type<son_member_index>().indices().get<by_account>();
|
|
||||||
|
|
||||||
BOOST_REQUIRE( idx.size() == 1 );
|
|
||||||
|
|
||||||
auto obj = idx.find( op.owner_account );
|
|
||||||
BOOST_REQUIRE( obj != idx.end() );
|
|
||||||
BOOST_CHECK( obj->url == test_url );
|
|
||||||
BOOST_CHECK( id == obj->id );
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( update_son_test ){
|
|
||||||
INVOKE(create_son_test);
|
|
||||||
std::string new_url = "https://anewurl.com";
|
|
||||||
test_update_son_member_evaluator test_eval( db );
|
|
||||||
son_update_operation op;
|
|
||||||
op.owner_account = account_id_type(1);
|
|
||||||
op.new_url = new_url;
|
|
||||||
op.son_id = son_id_type(0);
|
|
||||||
|
|
||||||
BOOST_CHECK_NO_THROW( test_eval.do_evaluate( op ) );
|
|
||||||
auto id = test_eval.do_apply( op );
|
|
||||||
const auto& idx = db.get_index_type<son_member_index>().indices().get<by_account>();
|
|
||||||
|
|
||||||
BOOST_REQUIRE( idx.size() == 1 );
|
|
||||||
|
|
||||||
auto obj = idx.find( op.owner_account );
|
|
||||||
BOOST_REQUIRE( obj != idx.end() );
|
|
||||||
BOOST_CHECK( obj->url == new_url );
|
|
||||||
BOOST_CHECK( id == obj->id );
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( delete_son_test ) {
|
|
||||||
INVOKE(create_son_test);
|
|
||||||
test_delete_son_member_evaluator test_eval( db );
|
|
||||||
|
|
||||||
son_delete_operation delete_op;
|
|
||||||
delete_op.owner_account = account_id_type(1);
|
|
||||||
delete_op.son_id = son_id_type(0);
|
|
||||||
|
|
||||||
BOOST_CHECK_NO_THROW( test_eval.do_evaluate( delete_op ) );
|
|
||||||
test_eval.do_apply( delete_op );
|
|
||||||
|
|
||||||
const auto& idx = db.get_index_type<son_member_index>().indices().get<by_account>();
|
|
||||||
BOOST_REQUIRE( idx.empty() );
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( update_delete_not_own ) { // fee payer needs to be the son object owner
|
|
||||||
try {
|
|
||||||
generate_blocks(HARDFORK_SON_TIME);
|
generate_blocks(HARDFORK_SON_TIME);
|
||||||
while (db.head_block_time() <= HARDFORK_SON_TIME) {
|
while (db.head_block_time() <= HARDFORK_SON_TIME) {
|
||||||
generate_block();
|
generate_block();
|
||||||
|
|
@ -114,28 +23,119 @@ try {
|
||||||
upgrade_to_lifetime_member(alice);
|
upgrade_to_lifetime_member(alice);
|
||||||
upgrade_to_lifetime_member(bob);
|
upgrade_to_lifetime_member(bob);
|
||||||
|
|
||||||
|
transfer( committee_account, alice_id, asset( 100000 ) );
|
||||||
|
transfer( committee_account, bob_id, asset( 100000 ) );
|
||||||
|
|
||||||
set_expiration(db, trx);
|
set_expiration(db, trx);
|
||||||
std::string test_url = "https://create_son_test";
|
std::string test_url = "https://create_son_test";
|
||||||
|
|
||||||
|
// create deposit vesting
|
||||||
|
vesting_balance_id_type deposit;
|
||||||
|
{
|
||||||
|
vesting_balance_create_operation op;
|
||||||
|
op.creator = alice_id;
|
||||||
|
op.owner = alice_id;
|
||||||
|
op.amount = asset(10);
|
||||||
|
op.balance_type = vesting_balance_type::unspecified;
|
||||||
|
|
||||||
|
trx.operations.push_back(op);
|
||||||
|
set_expiration(db, trx);
|
||||||
|
processed_transaction ptx = PUSH_TX(db, trx, ~0);
|
||||||
|
trx.clear();
|
||||||
|
deposit = ptx.operation_results[0].get<object_id_type>();
|
||||||
|
}
|
||||||
|
// create payment vesting
|
||||||
|
vesting_balance_id_type payment;
|
||||||
|
{
|
||||||
|
vesting_balance_create_operation op;
|
||||||
|
op.creator = alice_id;
|
||||||
|
op.owner = alice_id;
|
||||||
|
op.amount = asset(10);
|
||||||
|
op.balance_type = vesting_balance_type::unspecified;
|
||||||
|
|
||||||
|
trx.operations.push_back(op);
|
||||||
|
set_expiration(db, trx);
|
||||||
|
processed_transaction ptx = PUSH_TX(db, trx, ~0);
|
||||||
|
trx.clear();
|
||||||
|
payment = ptx.operation_results[0].get<object_id_type>();
|
||||||
|
}
|
||||||
|
|
||||||
// alice became son
|
// alice became son
|
||||||
{
|
{
|
||||||
son_create_operation op;
|
son_create_operation op;
|
||||||
op.owner_account = alice_id;
|
op.owner_account = alice_id;
|
||||||
op.url = test_url;
|
op.url = test_url;
|
||||||
|
op.deposit = deposit;
|
||||||
|
op.pay_vb = payment;
|
||||||
|
op.signing_key = alice_public_key;
|
||||||
trx.operations.push_back(op);
|
trx.operations.push_back(op);
|
||||||
sign(trx, alice_private_key);
|
sign(trx, alice_private_key);
|
||||||
PUSH_TX(db, trx, ~0);
|
PUSH_TX(db, trx, ~0);
|
||||||
}
|
}
|
||||||
generate_block();
|
generate_block();
|
||||||
|
|
||||||
set_expiration(db, trx);
|
|
||||||
trx.clear();
|
|
||||||
|
|
||||||
const auto& idx = db.get_index_type<son_member_index>().indices().get<by_account>();
|
const auto& idx = db.get_index_type<son_member_index>().indices().get<by_account>();
|
||||||
BOOST_REQUIRE( idx.size() == 1 );
|
BOOST_REQUIRE( idx.size() == 1 );
|
||||||
auto obj = idx.find( alice_id );
|
auto obj = idx.find( alice_id );
|
||||||
BOOST_REQUIRE( obj != idx.end() );
|
BOOST_REQUIRE( obj != idx.end() );
|
||||||
BOOST_CHECK( obj->url == test_url );
|
BOOST_CHECK( obj->url == test_url );
|
||||||
|
BOOST_CHECK( obj->signing_key == alice_public_key );
|
||||||
|
BOOST_CHECK( obj->deposit.instance == deposit.instance.value );
|
||||||
|
BOOST_CHECK( obj->pay_vb.instance == payment.instance.value );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( update_son_test ) {
|
||||||
|
|
||||||
|
INVOKE(create_son_test);
|
||||||
|
GET_ACTOR(alice);
|
||||||
|
|
||||||
|
std::string new_url = "https://anewurl.com";
|
||||||
|
|
||||||
|
{
|
||||||
|
son_update_operation op;
|
||||||
|
op.owner_account = alice_id;
|
||||||
|
op.new_url = new_url;
|
||||||
|
op.son_id = son_id_type(0);
|
||||||
|
|
||||||
|
trx.operations.push_back(op);
|
||||||
|
sign(trx, alice_private_key);
|
||||||
|
PUSH_TX(db, trx, ~0);
|
||||||
|
}
|
||||||
|
generate_block();
|
||||||
|
|
||||||
|
const auto& idx = db.get_index_type<son_member_index>().indices().get<by_account>();
|
||||||
|
BOOST_REQUIRE( idx.size() == 1 );
|
||||||
|
auto obj = idx.find( alice_id );
|
||||||
|
BOOST_REQUIRE( obj != idx.end() );
|
||||||
|
BOOST_CHECK( obj->url == new_url );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( delete_son_test ) {
|
||||||
|
|
||||||
|
INVOKE(create_son_test);
|
||||||
|
GET_ACTOR(alice);
|
||||||
|
|
||||||
|
{
|
||||||
|
son_delete_operation op;
|
||||||
|
op.owner_account = alice_id;
|
||||||
|
op.son_id = son_id_type(0);
|
||||||
|
|
||||||
|
trx.operations.push_back(op);
|
||||||
|
sign(trx, alice_private_key);
|
||||||
|
PUSH_TX(db, trx, ~0);
|
||||||
|
}
|
||||||
|
generate_block();
|
||||||
|
|
||||||
|
const auto& idx = db.get_index_type<son_member_index>().indices().get<by_account>();
|
||||||
|
BOOST_REQUIRE( idx.empty() );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( update_delete_not_own ) { // fee payer needs to be the son object owner
|
||||||
|
try {
|
||||||
|
|
||||||
|
INVOKE(create_son_test);
|
||||||
|
GET_ACTOR(alice);
|
||||||
|
GET_ACTOR(bob);
|
||||||
|
|
||||||
// bob tries to update a son object he dont own
|
// bob tries to update a son object he dont own
|
||||||
{
|
{
|
||||||
|
|
@ -153,7 +153,8 @@ try {
|
||||||
set_expiration(db, trx);
|
set_expiration(db, trx);
|
||||||
trx.clear();
|
trx.clear();
|
||||||
|
|
||||||
obj = idx.find( alice_id );
|
const auto& idx = db.get_index_type<son_member_index>().indices().get<by_account>();
|
||||||
|
auto obj = idx.find( alice_id );
|
||||||
BOOST_REQUIRE( obj != idx.end() );
|
BOOST_REQUIRE( obj != idx.end() );
|
||||||
// not changing
|
// not changing
|
||||||
BOOST_CHECK( obj->url == "https://create_son_test" );
|
BOOST_CHECK( obj->url == "https://create_son_test" );
|
||||||
|
|
@ -175,12 +176,10 @@ try {
|
||||||
// not deleting
|
// not deleting
|
||||||
BOOST_REQUIRE( obj != idx.end() );
|
BOOST_REQUIRE( obj != idx.end() );
|
||||||
BOOST_CHECK( obj->son_member_account.instance == alice_id.instance);
|
BOOST_CHECK( obj->son_member_account.instance == alice_id.instance);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (fc::exception &e) {
|
catch (fc::exception &e) {
|
||||||
edump((e.to_detail_string()));
|
edump((e.to_detail_string()));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
} BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue