diff --git a/tests/tests/custom_permission_tests.cpp b/tests/tests/custom_permission_tests.cpp index e2015b58..695de208 100644 --- a/tests/tests/custom_permission_tests.cpp +++ b/tests/tests/custom_permission_tests.cpp @@ -133,6 +133,20 @@ BOOST_AUTO_TEST_CASE(permission_create_success_test) BOOST_REQUIRE(custom_permission_id_type(0)(db).permission_name == "abc"); BOOST_REQUIRE(custom_permission_id_type(0)(db).auth == authority(1, bob_id, 1)); } + // Alice creates a permission def + { + custom_permission_create_operation op; + op.permission_name = "def"; + op.owner_account = alice_id; + op.auth = authority(1, charlie_id, 1); + trx.operations.push_back(op); + sign(trx, alice_private_key); + PUSH_TX(db, trx); + trx.clear(); + BOOST_REQUIRE(pidx.size() == 2); + BOOST_REQUIRE(custom_permission_id_type(1)(db).permission_name == "def"); + BOOST_REQUIRE(custom_permission_id_type(1)(db).auth == authority(1, charlie_id, 1)); + } } FC_LOG_AND_RETHROW() } @@ -146,9 +160,7 @@ BOOST_AUTO_TEST_CASE(permission_update_test) GET_ACTOR(bob); GET_ACTOR(charlie); const auto &pidx = db.get_index_type().indices().get(); - BOOST_REQUIRE(pidx.size() == 1); - BOOST_REQUIRE(custom_permission_id_type(0)(db).permission_name == "abc"); - BOOST_REQUIRE(custom_permission_id_type(0)(db).auth == authority(1, bob_id, 1)); + BOOST_REQUIRE(pidx.size() == 2); // Alice tries to update permission with same auth but fails { custom_permission_update_operation op; @@ -159,7 +171,7 @@ BOOST_AUTO_TEST_CASE(permission_update_test) sign(trx, alice_private_key); BOOST_CHECK_THROW(PUSH_TX(db, trx), fc::exception); trx.clear(); - BOOST_REQUIRE(pidx.size() == 1); + BOOST_REQUIRE(pidx.size() == 2); } // Alice tries to update permission with no auth but fails { @@ -170,7 +182,7 @@ BOOST_AUTO_TEST_CASE(permission_update_test) sign(trx, alice_private_key); BOOST_CHECK_THROW(PUSH_TX(db, trx), fc::exception); trx.clear(); - BOOST_REQUIRE(pidx.size() == 1); + BOOST_REQUIRE(pidx.size() == 2); } // Alice tries to update permission with charlie onwer_account but fails { @@ -182,7 +194,7 @@ BOOST_AUTO_TEST_CASE(permission_update_test) sign(trx, charlie_private_key); BOOST_CHECK_THROW(PUSH_TX(db, trx), fc::exception); trx.clear(); - BOOST_REQUIRE(pidx.size() == 1); + BOOST_REQUIRE(pidx.size() == 2); } // Alice updates permission abc with wrong permission_id { @@ -194,7 +206,7 @@ BOOST_AUTO_TEST_CASE(permission_update_test) sign(trx, alice_private_key); BOOST_CHECK_THROW(PUSH_TX(db, trx), fc::exception); trx.clear(); - BOOST_REQUIRE(pidx.size() == 1); + BOOST_REQUIRE(pidx.size() == 2); } // Alice updates permission abc with new auth { @@ -208,7 +220,7 @@ BOOST_AUTO_TEST_CASE(permission_update_test) sign(trx, alice_private_key); PUSH_TX(db, trx); trx.clear(); - BOOST_REQUIRE(pidx.size() == 1); + BOOST_REQUIRE(pidx.size() == 2); BOOST_REQUIRE(custom_permission_id_type(0)(db).permission_name == "abc"); BOOST_REQUIRE(custom_permission_id_type(0)(db).auth == authority(1, charlie_id, 1)); } @@ -225,9 +237,7 @@ BOOST_AUTO_TEST_CASE(account_authority_create_test) GET_ACTOR(bob); const auto &pidx = db.get_index_type().indices().get(); const auto &cidx = db.get_index_type().indices().get(); - BOOST_REQUIRE(pidx.size() == 1); - BOOST_REQUIRE(custom_permission_id_type(0)(db).permission_name == "abc"); - BOOST_REQUIRE(custom_permission_id_type(0)(db).auth == authority(1, bob_id, 1)); + BOOST_REQUIRE(pidx.size() == 2); generate_block(); // Alice creates a new account auth linking with permission abc { @@ -272,7 +282,7 @@ BOOST_AUTO_TEST_CASE(account_authority_update_test) GET_ACTOR(bob); const auto &pidx = db.get_index_type().indices().get(); const auto &cidx = db.get_index_type().indices().get(); - BOOST_REQUIRE(pidx.size() == 1); + BOOST_REQUIRE(pidx.size() == 2); BOOST_REQUIRE(cidx.size() == 2); generate_block(); // Alice update the account auth linking with permission abc @@ -304,7 +314,7 @@ BOOST_AUTO_TEST_CASE(account_authority_delete_test) GET_ACTOR(bob); const auto &pidx = db.get_index_type().indices().get(); const auto &cidx = db.get_index_type().indices().get(); - BOOST_REQUIRE(pidx.size() == 1); + BOOST_REQUIRE(pidx.size() == 2); BOOST_REQUIRE(cidx.size() == 2); generate_block(); // Alice deletes account auth linking with permission abc @@ -344,7 +354,7 @@ BOOST_AUTO_TEST_CASE(permission_delete_test) GET_ACTOR(bob); const auto &pidx = db.get_index_type().indices().get(); const auto &cidx = db.get_index_type().indices().get(); - BOOST_REQUIRE(pidx.size() == 1); + BOOST_REQUIRE(pidx.size() == 2); BOOST_REQUIRE(custom_permission_id_type(0)(db).permission_name == "abc"); BOOST_REQUIRE(custom_permission_id_type(0)(db).auth == authority(1, bob_id, 1)); BOOST_REQUIRE(cidx.size() == 2); @@ -357,18 +367,18 @@ BOOST_AUTO_TEST_CASE(permission_delete_test) sign(trx, bob_private_key); BOOST_CHECK_THROW(PUSH_TX(db, trx), fc::exception); trx.clear(); - BOOST_REQUIRE(pidx.size() == 1); + BOOST_REQUIRE(pidx.size() == 2); } // Alice tries to delete permission abc with wrong permission_id { custom_permission_delete_operation op; - op.permission_id = custom_permission_id_type(1); + op.permission_id = custom_permission_id_type(2); op.owner_account = alice_id; trx.operations.push_back(op); sign(trx, alice_private_key); BOOST_CHECK_THROW(PUSH_TX(db, trx), fc::exception); trx.clear(); - BOOST_REQUIRE(pidx.size() == 1); + BOOST_REQUIRE(pidx.size() == 2); } // Alice deletes permission abc { @@ -379,7 +389,7 @@ BOOST_AUTO_TEST_CASE(permission_delete_test) sign(trx, alice_private_key); PUSH_TX(db, trx); trx.clear(); - BOOST_REQUIRE(pidx.size() == 0); + BOOST_REQUIRE(pidx.size() == 1); BOOST_REQUIRE(cidx.size() == 0); } } @@ -395,7 +405,7 @@ BOOST_AUTO_TEST_CASE(transfer_op_custom_permission_test) GET_ACTOR(bob); const auto &pidx = db.get_index_type().indices().get(); const auto &cidx = db.get_index_type().indices().get(); - BOOST_REQUIRE(pidx.size() == 1); + BOOST_REQUIRE(pidx.size() == 2); BOOST_REQUIRE(cidx.size() == 2); // alice->bob transfer_operation op with active auth, success generate_block(); @@ -469,6 +479,385 @@ BOOST_AUTO_TEST_CASE(transfer_op_custom_permission_test) trx.clear(); generate_block(); } + // Alice deletes permission abc + { + custom_permission_delete_operation op; + op.permission_id = custom_permission_id_type(0); + op.owner_account = alice_id; + trx.operations.push_back(op); + sign(trx, alice_private_key); + PUSH_TX(db, trx); + trx.clear(); + BOOST_REQUIRE(pidx.size() == 1); + BOOST_REQUIRE(cidx.size() == 0); + generate_block(); + } + // alice->bob transfer_operation op with active auth, success + { + transfer_operation op; + op.amount.asset_id = asset_id_type(0); + op.amount.amount = 100 * GRAPHENE_BLOCKCHAIN_PRECISION; + op.from = alice_id; + op.to = bob_id; + op.fee.asset_id = asset_id_type(0); + trx.operations.push_back(op); + sign(trx, alice_private_key); + PUSH_TX(db, trx); + trx.clear(); + generate_block(); + } + // alice->bob transfer_operation op with the deleted custom account auth, fail + { + transfer_operation op; + op.amount.asset_id = asset_id_type(0); + op.amount.amount = 100 * GRAPHENE_BLOCKCHAIN_PRECISION; + op.from = alice_id; + op.to = bob_id; + op.fee.asset_id = asset_id_type(0); + trx.operations.push_back(op); + sign(trx, bob_private_key); + BOOST_CHECK_THROW(PUSH_TX(db, trx), fc::exception); + trx.clear(); + generate_block(); + } + } + FC_LOG_AND_RETHROW() +} + +BOOST_AUTO_TEST_CASE(transfer_op_auhtorized_auth_change_test) +{ + try + { + INVOKE(account_authority_create_test); + GET_ACTOR(alice); + GET_ACTOR(bob); + const auto &pidx = db.get_index_type().indices().get(); + const auto &cidx = db.get_index_type().indices().get(); + BOOST_REQUIRE(pidx.size() == 2); + BOOST_REQUIRE(cidx.size() == 2); + // alice->bob transfer_operation op with the created custom account auth, success + { + transfer_operation op; + op.amount.asset_id = asset_id_type(0); + op.amount.amount = 100 * GRAPHENE_BLOCKCHAIN_PRECISION; + op.from = alice_id; + op.to = bob_id; + op.fee.asset_id = asset_id_type(0); + trx.operations.push_back(op); + sign(trx, bob_private_key); + PUSH_TX(db, trx); + trx.clear(); + generate_block(); + } + // bob changes his auth by changing his auth key + fc::ecc::private_key test_private_key = generate_private_key("test"); + public_key_type test_public_key = public_key_type(test_private_key.get_public_key()); + { + account_update_operation op; + op.account = bob.get_id(); + op.active = authority(1, test_public_key, 1); + trx.operations.push_back(op); + sign(trx, bob_private_key); + PUSH_TX(db, trx); + trx.clear(); + generate_block(); + } + // alice->bob transfer_operation op with bob first private key, fails + { + transfer_operation op; + op.amount.asset_id = asset_id_type(0); + op.amount.amount = 100 * GRAPHENE_BLOCKCHAIN_PRECISION; + op.from = alice_id; + op.to = bob_id; + op.fee.asset_id = asset_id_type(0); + trx.operations.push_back(op); + sign(trx, bob_private_key); + BOOST_CHECK_THROW(PUSH_TX(db, trx), fc::exception); + trx.clear(); + generate_block(); + } + // alice->bob transfer_operation op with bob first private key, fails + { + transfer_operation op; + op.amount.asset_id = asset_id_type(0); + op.amount.amount = 100 * GRAPHENE_BLOCKCHAIN_PRECISION; + op.from = alice_id; + op.to = bob_id; + op.fee.asset_id = asset_id_type(0); + trx.operations.push_back(op); + sign(trx, test_private_key); + PUSH_TX(db, trx); + trx.clear(); + generate_block(); + } + } + FC_LOG_AND_RETHROW() +} + +BOOST_AUTO_TEST_CASE(transfer_op_multi_ops_in_single_trx_test) +{ + try + { + INVOKE(account_authority_create_test); + GET_ACTOR(alice); + GET_ACTOR(bob); + GET_ACTOR(charlie); + { + // alice->bob xfer op + transfer_operation alice_to_bob_xfer_op; + alice_to_bob_xfer_op.amount.asset_id = asset_id_type(0); + alice_to_bob_xfer_op.amount.amount = 100 * GRAPHENE_BLOCKCHAIN_PRECISION; + alice_to_bob_xfer_op.from = alice_id; + alice_to_bob_xfer_op.to = bob_id; + alice_to_bob_xfer_op.fee.asset_id = asset_id_type(0); + // bob->alice xfer op + transfer_operation bob_to_alice_xfer_op; + bob_to_alice_xfer_op.amount.asset_id = asset_id_type(0); + bob_to_alice_xfer_op.amount.amount = 100 * GRAPHENE_BLOCKCHAIN_PRECISION; + bob_to_alice_xfer_op.from = bob_id; + bob_to_alice_xfer_op.to = alice_id; + bob_to_alice_xfer_op.fee.asset_id = asset_id_type(0); + // Change bob's active auth to alice's auth + { + account_update_operation op; + op.account = bob_id; + op.active = authority(1, alice_id, 1); + trx.operations.push_back(op); + sign(trx, bob_private_key); + PUSH_TX(db, trx); + trx.clear(); + generate_block(); + } + // Success -> alice active key + trx.operations = {alice_to_bob_xfer_op}; + sign(trx, alice_private_key); + PUSH_TX(db, trx); + trx.clear(); + generate_block(); + // Fail -> custom account auth is bob active auth which is alice active key + trx.operations = {alice_to_bob_xfer_op}; + sign(trx, bob_private_key); + BOOST_CHECK_THROW(PUSH_TX(db, trx), fc::exception); + trx.clear(); + generate_block(); + // Success -> bob's active key is alice's auth active key + trx.operations = {bob_to_alice_xfer_op}; + sign(trx, alice_private_key); + PUSH_TX(db, trx); + trx.clear(); + generate_block(); + // Success -> bob's owner key + trx.operations = {bob_to_alice_xfer_op}; + sign(trx, bob_private_key); + PUSH_TX(db, trx); + trx.clear(); + generate_block(); + // Success -> alice active key is auth for both alice and bob + trx.operations = {alice_to_bob_xfer_op, bob_to_alice_xfer_op}; + sign(trx, alice_private_key); + PUSH_TX(db, trx); + trx.clear(); + generate_block(); + // Fail -> custom account auth is bob active auth which is alice active key + trx.operations = {alice_to_bob_xfer_op, bob_to_alice_xfer_op}; + sign(trx, bob_private_key); + BOOST_CHECK_THROW(PUSH_TX(db, trx), fc::exception); + trx.clear(); + generate_block(); + // Fail -> alice active auth satisfies everything, bob owner key is not used + trx.operations = {alice_to_bob_xfer_op, bob_to_alice_xfer_op}; + sign(trx, bob_private_key); + sign(trx, alice_private_key); + BOOST_CHECK_THROW(PUSH_TX(db, trx), fc::exception); + trx.clear(); + generate_block(); + // Fail -> extra unnecessary signature of charlie + trx.operations = {alice_to_bob_xfer_op, bob_to_alice_xfer_op}; + sign(trx, bob_private_key); + sign(trx, alice_private_key); + sign(trx, charlie_private_key); + BOOST_CHECK_THROW(PUSH_TX(db, trx), fc::exception); + trx.clear(); + generate_block(); + } + } + FC_LOG_AND_RETHROW() +} + +BOOST_AUTO_TEST_CASE(transfer_op_multi_sig_with_common_auth_test) +{ + try + { + INVOKE(account_authority_create_test); + GET_ACTOR(alice); + GET_ACTOR(bob); + GET_ACTOR(charlie); + GET_ACTOR(dave); + { + // alice->bob xfer op + transfer_operation alice_to_bob_xfer_op; + alice_to_bob_xfer_op.amount.asset_id = asset_id_type(0); + alice_to_bob_xfer_op.amount.amount = 100 * GRAPHENE_BLOCKCHAIN_PRECISION; + alice_to_bob_xfer_op.from = alice_id; + alice_to_bob_xfer_op.to = bob_id; + alice_to_bob_xfer_op.fee.asset_id = asset_id_type(0); + // Change alice's active auth to multisig 2-of-3 bob, charlie, dave + { + account_update_operation op; + op.account = alice_id; + op.active = authority(2, bob_id, 1, charlie_id, 1, dave_id, 1); + trx.operations.push_back(op); + sign(trx, alice_private_key); + PUSH_TX(db, trx); + trx.clear(); + generate_block(); + } + // Success -> alice owner key + trx.operations = {alice_to_bob_xfer_op}; + sign(trx, alice_private_key); + PUSH_TX(db, trx); + trx.clear(); + generate_block(); + // Success -> alice custom auth is bob + trx.operations = {alice_to_bob_xfer_op}; + sign(trx, bob_private_key); + PUSH_TX(db, trx); + trx.clear(); + generate_block(); + // Success -> 2-of-3 auth satisfied + trx.operations = {alice_to_bob_xfer_op}; + sign(trx, charlie_private_key); + sign(trx, dave_private_key); + PUSH_TX(db, trx); + trx.clear(); + generate_block(); + // Fail -> Custom auth(bob private key) itself satisfies + trx.operations = {alice_to_bob_xfer_op}; + sign(trx, bob_private_key); + sign(trx, charlie_private_key); + BOOST_CHECK_THROW(PUSH_TX(db, trx), fc::exception); + trx.clear(); + generate_block(); + // Fail -> Custom auth(bob private key) itself satisfies + trx.operations = {alice_to_bob_xfer_op}; + sign(trx, bob_private_key); + sign(trx, dave_private_key); + BOOST_CHECK_THROW(PUSH_TX(db, trx), fc::exception); + trx.clear(); + generate_block(); + } + } + FC_LOG_AND_RETHROW() +} + +BOOST_AUTO_TEST_CASE(transfer_op_multi_sig_with_out_common_auth_test) +{ + try + { + generate_blocks(HARDFORK_RBAC_TIME); + generate_block(); + set_expiration(db, trx); + ACTORS((alice)(bob)(charlie)(dave)); + upgrade_to_lifetime_member(alice); + upgrade_to_lifetime_member(bob); + upgrade_to_lifetime_member(charlie); + upgrade_to_lifetime_member(dave); + transfer(committee_account, alice_id, asset(1000 * GRAPHENE_BLOCKCHAIN_PRECISION)); + transfer(committee_account, bob_id, asset(1000 * GRAPHENE_BLOCKCHAIN_PRECISION)); + transfer(committee_account, charlie_id, asset(1000 * GRAPHENE_BLOCKCHAIN_PRECISION)); + transfer(committee_account, dave_id, asset(1000 * GRAPHENE_BLOCKCHAIN_PRECISION)); + const auto &pidx = db.get_index_type().indices().get(); + const auto &cidx = db.get_index_type().indices().get(); + fc::ecc::private_key test_private_key = generate_private_key("test"); + public_key_type test_public_key = public_key_type(test_private_key.get_public_key()); + { + custom_permission_create_operation op; + op.permission_name = "abc"; + op.owner_account = alice_id; + op.auth = authority(1, test_public_key, 1); + trx.operations.push_back(op); + sign(trx, alice_private_key); + PUSH_TX(db, trx); + trx.clear(); + BOOST_REQUIRE(pidx.size() == 1); + BOOST_REQUIRE(custom_permission_id_type(0)(db).permission_name == "abc"); + BOOST_REQUIRE(custom_permission_id_type(0)(db).auth == authority(1, test_public_key, 1)); + generate_block(); + } + { + custom_account_authority_create_operation op; + op.permission_id = custom_permission_id_type(0); + op.valid_from = db.head_block_time(); + op.valid_to = db.head_block_time() + fc::seconds(10 * db.block_interval()); + op.operation_type = operation::tag::value; + op.owner_account = alice_id; + trx.operations.push_back(op); + sign(trx, alice_private_key); + PUSH_TX(db, trx); + trx.clear(); + BOOST_REQUIRE(cidx.size() == 1); + generate_block(); + } + // Multisig with common account auth + { + // alice->bob xfer op + transfer_operation alice_to_bob_xfer_op; + alice_to_bob_xfer_op.amount.asset_id = asset_id_type(0); + alice_to_bob_xfer_op.amount.amount = 100 * GRAPHENE_BLOCKCHAIN_PRECISION; + alice_to_bob_xfer_op.from = alice_id; + alice_to_bob_xfer_op.to = bob_id; + alice_to_bob_xfer_op.fee.asset_id = asset_id_type(0); + // Change alice's active auth to multisig 2-of-3 bob, charlie, dave + { + account_update_operation op; + op.account = alice_id; + op.active = authority(2, bob_id, 1, charlie_id, 1, dave_id, 1); + trx.operations.push_back(op); + sign(trx, alice_private_key); + PUSH_TX(db, trx); + trx.clear(); + generate_block(); + } + // Success -> alice owner key + trx.operations = {alice_to_bob_xfer_op}; + sign(trx, alice_private_key); + PUSH_TX(db, trx); + trx.clear(); + generate_block(); + // Fail -> auth not satisfied + trx.operations = {alice_to_bob_xfer_op}; + sign(trx, bob_private_key); + BOOST_CHECK_THROW(PUSH_TX(db, trx), fc::exception); + trx.clear(); + generate_block(); + // Success -> custom key auth satisfied + trx.operations = {alice_to_bob_xfer_op}; + sign(trx, test_private_key); + PUSH_TX(db, trx); + trx.clear(); + generate_block(); + // Success -> 2-of-3 auth satisfied + trx.operations = {alice_to_bob_xfer_op}; + sign(trx, charlie_private_key); + sign(trx, dave_private_key); + PUSH_TX(db, trx); + trx.clear(); + generate_block(); + // Success -> 2-of-3 auth satisfied + trx.operations = {alice_to_bob_xfer_op}; + sign(trx, bob_private_key); + sign(trx, charlie_private_key); + PUSH_TX(db, trx); + trx.clear(); + generate_block(); + // Success -> 2-of-3 auth satisfied + trx.operations = {alice_to_bob_xfer_op}; + sign(trx, bob_private_key); + sign(trx, dave_private_key); + PUSH_TX(db, trx); + trx.clear(); + generate_block(); + } } FC_LOG_AND_RETHROW() }