peerplays_migrated/tests/tests/sidechain_transaction_tests.cpp

386 lines
13 KiB
C++

#include <boost/test/unit_test.hpp>
#include "../common/database_fixture.hpp"
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/sidechain_transaction_object.hpp>
#include <graphene/chain/proposal_object.hpp>
#include <graphene/chain/son_object.hpp>
#include <graphene/peerplays_sidechain/defs.hpp>
using namespace graphene;
using namespace graphene::chain;
using namespace graphene::chain::test;
BOOST_FIXTURE_TEST_SUITE(sidechain_transaction_tests, database_fixture)
BOOST_AUTO_TEST_CASE(bitcoin_transaction_send_test)
{
try
{
BOOST_TEST_MESSAGE("bitcoin_transaction_send_test");
generate_blocks(HARDFORK_SON_TIME);
generate_block();
set_expiration(db, trx);
ACTORS((alice)(bob));
upgrade_to_lifetime_member(alice);
upgrade_to_lifetime_member(bob);
transfer(committee_account, alice_id, asset(500000 * GRAPHENE_BLOCKCHAIN_PRECISION));
transfer(committee_account, bob_id, asset(500000 * GRAPHENE_BLOCKCHAIN_PRECISION));
generate_block();
set_expiration(db, trx);
std::string test_url = "https://create_son_test";
// create deposit vesting
vesting_balance_id_type deposit_alice;
{
vesting_balance_create_operation op;
op.creator = alice_id;
op.owner = alice_id;
op.amount = asset(500 * GRAPHENE_BLOCKCHAIN_PRECISION);
op.balance_type = vesting_balance_type::son;
op.policy = dormant_vesting_policy_initializer{};
trx.operations.push_back(op);
sign(trx, alice_private_key);
processed_transaction ptx = PUSH_TX(db, trx, ~0);
trx.clear();
deposit_alice = ptx.operation_results[0].get<object_id_type>();
}
generate_block();
set_expiration(db, trx);
// create payment normal vesting
vesting_balance_id_type payment_alice;
{
vesting_balance_create_operation op;
op.creator = alice_id;
op.owner = alice_id;
op.amount = asset(500 * GRAPHENE_BLOCKCHAIN_PRECISION);
op.balance_type = vesting_balance_type::normal;
trx.operations.push_back(op);
sign(trx, alice_private_key);
processed_transaction ptx = PUSH_TX(db, trx, ~0);
trx.clear();
payment_alice = ptx.operation_results[0].get<object_id_type>();
}
generate_block();
set_expiration(db, trx);
// alice becomes son
{
flat_map<graphene::peerplays_sidechain::sidechain_type, string> sidechain_public_keys;
sidechain_public_keys[graphene::peerplays_sidechain::sidechain_type::bitcoin] = "bitcoin address";
son_create_operation op;
op.owner_account = alice_id;
op.url = test_url;
op.deposit = deposit_alice;
op.pay_vb = payment_alice;
op.signing_key = alice_public_key;
op.sidechain_public_keys = sidechain_public_keys;
trx.operations.push_back(op);
sign(trx, alice_private_key);
PUSH_TX(db, trx, ~0);
trx.clear();
}
generate_block();
set_expiration(db, trx);
// create deposit vesting
vesting_balance_id_type deposit_bob;
{
vesting_balance_create_operation op;
op.creator = bob_id;
op.owner = bob_id;
op.amount = asset(500 * GRAPHENE_BLOCKCHAIN_PRECISION);
op.balance_type = vesting_balance_type::son;
op.policy = dormant_vesting_policy_initializer{};
trx.operations.push_back(op);
sign(trx, bob_private_key);
processed_transaction ptx = PUSH_TX(db, trx, ~0);
trx.clear();
deposit_bob = ptx.operation_results[0].get<object_id_type>();
}
generate_block();
set_expiration(db, trx);
// create payment normal vesting
vesting_balance_id_type payment_bob;
{
vesting_balance_create_operation op;
op.creator = bob_id;
op.owner = bob_id;
op.amount = asset(500 * GRAPHENE_BLOCKCHAIN_PRECISION);
op.balance_type = vesting_balance_type::normal;
trx.operations.push_back(op);
sign(trx, bob_private_key);
processed_transaction ptx = PUSH_TX(db, trx, ~0);
trx.clear();
payment_bob = ptx.operation_results[0].get<object_id_type>();
}
generate_block();
set_expiration(db, trx);
// bob becomes son
{
flat_map<graphene::peerplays_sidechain::sidechain_type, string> sidechain_public_keys;
sidechain_public_keys[graphene::peerplays_sidechain::sidechain_type::bitcoin] = "bitcoin address";
son_create_operation op;
op.owner_account = bob_id;
op.url = test_url;
op.deposit = deposit_bob;
op.pay_vb = payment_bob;
op.signing_key = bob_public_key;
op.sidechain_public_keys = sidechain_public_keys;
trx.operations.push_back(op);
sign(trx, alice_private_key);
PUSH_TX(db, trx, ~0);
trx.clear();
}
generate_block();
generate_block();
const auto& acc_idx = db.get_index_type<account_index>().indices().get<by_id>();
auto acc_itr = acc_idx.find(GRAPHENE_SON_ACCOUNT);
BOOST_REQUIRE(acc_itr != acc_idx.end());
db.modify(*acc_itr, [&](account_object &obj) {
obj.active.account_auths.clear();
obj.active.add_authority(bob_id, 1);
obj.active.add_authority(alice_id, 1);
obj.active.weight_threshold = 2;
obj.owner.account_auths.clear();
obj.owner.add_authority(bob_id, 1);
obj.owner.add_authority(alice_id, 1);
obj.owner.weight_threshold = 2;
});
/*const auto &son_btc_account = db.create<account_object>([&](account_object &obj) {
obj.name = "son_btc_account";
obj.statistics = db.create<account_statistics_object>([&](account_statistics_object &acc_stat) { acc_stat.owner = obj.id; }).id;
obj.membership_expiration_date = time_point_sec::maximum();
obj.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
obj.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
obj.owner.add_authority(bob_id, 1);
obj.active.add_authority(bob_id, 1);
obj.owner.add_authority(alice_id, 1);
obj.active.add_authority(alice_id, 1);
obj.active.weight_threshold = 2;
obj.owner.weight_threshold = 2;
});
db.modify( db.get_global_properties(), [&]( global_property_object& _gpo )
{
_gpo.parameters.extensions.value.son_btc_account = son_btc_account.get_id();
if( _gpo.pending_parameters )
_gpo.pending_parameters->extensions.value.son_btc_account = son_btc_account.get_id();
});*/
generate_block();
const global_property_object &gpo = db.get_global_properties();
{
BOOST_TEST_MESSAGE("Send bitcoin_transaction_send_operation");
bitcoin_transaction_send_operation send_op;
send_op.payer = GRAPHENE_SON_ACCOUNT;
proposal_create_operation proposal_op;
proposal_op.fee_paying_account = alice_id;
proposal_op.proposed_ops.push_back(op_wrapper(send_op));
uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
proposal_op.expiration_time = time_point_sec(db.head_block_time().sec_since_epoch() + lifetime);
trx.operations.push_back(proposal_op);
set_expiration(db, trx);
sign(trx, alice_private_key);
PUSH_TX(db, trx, ~0);
trx.clear();
}
generate_block();
BOOST_TEST_MESSAGE("Check proposal results");
const auto &idx = db.get_index_type<proposal_index>().indices().get<by_id>();
BOOST_REQUIRE(idx.size() == 1);
auto obj = idx.find(proposal_id_type(0));
BOOST_REQUIRE(obj != idx.end());
const auto& btidx = db.get_index_type<bitcoin_transaction_index>().indices().get<by_id>();
BOOST_REQUIRE(btidx.size() == 0);
std::vector<unsigned char> a1 = {'a', 'l', 'i', 'c', 'e', '1'};
std::vector<unsigned char> a2 = {'a', 'l', 'i', 'c', 'e', '2'};
std::vector<unsigned char> a3 = {'a', 'l', 'i', 'c', 'e', '3'};
{
BOOST_TEST_MESSAGE("Send bitcoin_transaction_sign_operation");
bitcoin_transaction_sign_operation sign_op;
sign_op.payer = alice_id;
sign_op.proposal_id = proposal_id_type(0);
sign_op.signatures.push_back(a1);
sign_op.signatures.push_back(a2);
sign_op.signatures.push_back(a3);
trx.operations.push_back(sign_op);
set_expiration(db, trx);
sign(trx, alice_private_key);
PUSH_TX(db, trx, ~0);
trx.clear();
}
generate_block();
BOOST_REQUIRE(idx.size() == 1);
BOOST_REQUIRE(btidx.size() == 0);
auto pobj = idx.find(proposal_id_type(0));
BOOST_REQUIRE(pobj != idx.end());
const auto& sidx = db.get_index_type<son_index>().indices().get<graphene::chain::by_account>();
const auto son_obj1 = sidx.find( alice_id );
BOOST_REQUIRE(son_obj1 != sidx.end());
auto bitcoin_transaction_send_op = pobj->proposed_transaction.operations[0].get<bitcoin_transaction_send_operation>();
BOOST_REQUIRE(bitcoin_transaction_send_op.signatures.size() == 1);
BOOST_REQUIRE(bitcoin_transaction_send_op.signatures[son_obj1->id][0] == a1);
BOOST_REQUIRE(bitcoin_transaction_send_op.signatures[son_obj1->id][1] == a2);
BOOST_REQUIRE(bitcoin_transaction_send_op.signatures[son_obj1->id][2] == a3);
std::vector<unsigned char> b1 = {'b', 'o', 'b', '1'};
std::vector<unsigned char> b2 = {'b', 'o', 'b', '2'};
std::vector<unsigned char> b3 = {'b', 'o', 'b', '3'};
{
BOOST_TEST_MESSAGE("Send bitcoin_transaction_sign_operation");
bitcoin_transaction_sign_operation sign_op;
sign_op.payer = bob_id;
sign_op.proposal_id = proposal_id_type(0);
sign_op.signatures.push_back(b1);
sign_op.signatures.push_back(b2);
sign_op.signatures.push_back(b3);
trx.operations.push_back(sign_op);
set_expiration(db, trx);
sign(trx, bob_private_key);
PUSH_TX(db, trx, ~0);
trx.clear();
}
generate_block();
BOOST_REQUIRE(idx.size() == 0);
const auto son_obj2 = sidx.find( bob_id );
BOOST_REQUIRE(son_obj2 != sidx.end());
BOOST_REQUIRE(btidx.size() == 1);
const auto btobj = btidx.find(bitcoin_transaction_id_type(0));
BOOST_REQUIRE(btobj != btidx.end());
BOOST_REQUIRE(btobj->processed == false);
auto stats1 = son_obj1->statistics( db );
auto stats2 = son_obj2->statistics( db );
BOOST_REQUIRE(stats1.txs_signed == 1);
BOOST_REQUIRE(stats2.txs_signed == 1);
auto sigs = btobj->signatures;
BOOST_REQUIRE(sigs[son_obj1->id][0] == a1);
BOOST_REQUIRE(sigs[son_obj1->id][1] == a2);
BOOST_REQUIRE(sigs[son_obj1->id][2] == a3);
BOOST_REQUIRE(sigs[son_obj2->id][0] == b1);
BOOST_REQUIRE(sigs[son_obj2->id][1] == b2);
BOOST_REQUIRE(sigs[son_obj2->id][2] == b3);
{
BOOST_TEST_MESSAGE("Send bitcoin_send_transaction_process_operation");
bitcoin_send_transaction_process_operation process_op;
process_op.bitcoin_transaction_id = bitcoin_transaction_id_type(0);
process_op.payer = GRAPHENE_SON_ACCOUNT;
proposal_create_operation proposal_op;
proposal_op.fee_paying_account = alice_id;
proposal_op.proposed_ops.push_back(op_wrapper(process_op));
uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
proposal_op.expiration_time = time_point_sec(db.head_block_time().sec_since_epoch() + lifetime);
trx.operations.push_back(proposal_op);
set_expiration(db, trx);
sign(trx, alice_private_key);
PUSH_TX(db, trx, ~0);
trx.clear();
}
generate_block();
BOOST_REQUIRE(idx.size() == 1);
obj = idx.find(proposal_id_type(1));
BOOST_REQUIRE(obj != idx.end());
{
BOOST_TEST_MESSAGE("Send proposal_update_operation");
proposal_update_operation puo;
puo.fee_paying_account = bob_id;
puo.proposal = obj->id;
puo.active_approvals_to_add = { bob_id };
trx.operations.push_back(puo);
set_expiration(db, trx);
sign(trx, bob_private_key);
PUSH_TX(db, trx, ~0);
trx.clear();
}
generate_block();
BOOST_REQUIRE(idx.size() == 1);
obj = idx.find(proposal_id_type(1));
BOOST_REQUIRE(obj != idx.end());
BOOST_REQUIRE(btobj != btidx.end());
BOOST_REQUIRE(btobj->processed == false);
{
BOOST_TEST_MESSAGE("Send proposal_update_operation");
proposal_update_operation puo;
puo.fee_paying_account = alice_id;
puo.proposal = obj->id;
puo.active_approvals_to_add = { alice_id };
trx.operations.push_back(puo);
set_expiration(db, trx);
sign(trx, alice_private_key);
PUSH_TX(db, trx, ~0);
trx.clear();
}
generate_block();
BOOST_REQUIRE(idx.size() == 0);
BOOST_REQUIRE(btobj != btidx.end());
BOOST_REQUIRE(btobj->processed == true);
}
FC_LOG_AND_RETHROW()
}
BOOST_AUTO_TEST_SUITE_END()