From 7d44c3abb3621b1237254ad887bb09d74d62f8ab Mon Sep 17 00:00:00 2001 From: John Jones Date: Tue, 16 Oct 2018 11:06:54 -0500 Subject: [PATCH 01/10] initial fix for verify_account_authority --- libraries/app/database_api.cpp | 34 +++++++++++++------ .../app/include/graphene/app/database_api.hpp | 7 ++-- tests/tests/wallet_tests.cpp | 19 +++++++++++ 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index 77407e1045..d2ec51c2b4 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -167,7 +167,7 @@ class database_api_impl : public std::enable_shared_from_this vector get_withdraw_permissions_by_giver(const std::string account_id_or_name, withdraw_permission_id_type start, uint32_t limit)const; vector get_withdraw_permissions_by_recipient(const std::string account_id_or_name, withdraw_permission_id_type start, uint32_t limit)const; - //private: + // private: static string price_to_string( const price& _price, const asset_object& _base, const asset_object& _quote ); template @@ -272,7 +272,9 @@ class database_api_impl : public std::enable_shared_from_this map< pair, std::function > _market_subscriptions; graphene::chain::database& _db; const application_options* _app_options = nullptr; - + private: + bool public_key_found(const flat_set& to_be_found, + const vector& collection_to_search)const; }; ////////////////////////////////////////////////////////////////////// @@ -2068,17 +2070,29 @@ bool database_api::verify_account_authority( const string& account_name_or_id, c return my->verify_account_authority( account_name_or_id, signers ); } -bool database_api_impl::verify_account_authority( const string& account_name_or_id, const flat_set& keys )const +bool database_api_impl::public_key_found(const flat_set& to_be_found, + const vector& collection_to_search) const { - const account_object* account = get_account_from_string(account_name_or_id); + for (public_key_type from_collection : collection_to_search) + { + for(public_key_type passed_in : to_be_found ) + { + if (passed_in == from_collection) + { + return true; + } + } + } + return false; +} - /// reuse trx.verify_authority by creating a dummy transfer - signed_transaction trx; - transfer_operation op; - op.from = account->id; - trx.operations.emplace_back(op); +bool database_api_impl::verify_account_authority( const string& account_name_or_id, + const flat_set& keys )const +{ + const account_object* account = get_account_from_string(account_name_or_id); - return verify_authority( trx ); + return public_key_found(keys, account->active.get_keys()) + && public_key_found(keys, account->owner.get_keys()); } processed_transaction database_api::validate_transaction( const signed_transaction& trx )const diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index 7102ffe62c..1e4e296d2b 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -663,9 +663,12 @@ class database_api bool verify_authority( const signed_transaction& trx )const; /** - * @return true if the signers have enough authority to authorize an account + * @brief Verify that the public keys have enough authority to authorize a transaction + * @param account_name_or_id the account to check + * @param signers the public keys + * @return true if the passed in keys have enough authority to authorize a transaction */ - bool verify_account_authority( const string& account_name_or_id, const flat_set& signers )const; + bool verify_account_authority( const string& account_name_or_id, const flat_set& signers )const; /** * Validates a transaction against the current state without broadcasting it on the network. diff --git a/tests/tests/wallet_tests.cpp b/tests/tests/wallet_tests.cpp index 554b729703..c95e39d741 100644 --- a/tests/tests/wallet_tests.cpp +++ b/tests/tests/wallet_tests.cpp @@ -76,4 +76,23 @@ BOOST_FIXTURE_TEST_SUITE(wallet_tests, database_fixture) } FC_LOG_AND_RETHROW() } + BOOST_AUTO_TEST_CASE(verify_account_authority) { + try { + + ACTORS( (nathan) ); + graphene::app::database_api db_api(db); + + // good keys + flat_set public_keys; + public_keys.emplace(nathan_public_key); + BOOST_CHECK(db_api.verify_account_authority( "nathan", public_keys)); + + // bad keys + flat_set bad_public_keys; + bad_public_keys.emplace(public_key_type("BTS6MkMxwBjFWmcDjXRoJ4mW9Hd4LCSPwtv9tKG1qYW5Kgu4AhoZy")); + BOOST_CHECK(!db_api.verify_account_authority( "nathan", bad_public_keys)); + + } FC_LOG_AND_RETHROW() + } + BOOST_AUTO_TEST_SUITE_END() From 824ed4f2cc5eddee2af8361be8ee8c626739af7d Mon Sep 17 00:00:00 2001 From: John Jones Date: Fri, 19 Oct 2018 16:09:31 -0500 Subject: [PATCH 02/10] improved way to verify account and keys --- libraries/app/database_api.cpp | 36 ++++++++++++++++------------------ 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index d2ec51c2b4..fb240c4316 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -2070,29 +2070,27 @@ bool database_api::verify_account_authority( const string& account_name_or_id, c return my->verify_account_authority( account_name_or_id, signers ); } -bool database_api_impl::public_key_found(const flat_set& to_be_found, - const vector& collection_to_search) const -{ - for (public_key_type from_collection : collection_to_search) - { - for(public_key_type passed_in : to_be_found ) - { - if (passed_in == from_collection) - { - return true; - } - } - } - return false; -} - bool database_api_impl::verify_account_authority( const string& account_name_or_id, const flat_set& keys )const { - const account_object* account = get_account_from_string(account_name_or_id); + // create a dummy transfer + transfer_operation op; + op.from = get_account_from_string(account_name_or_id)->id; + std::vector ops; + ops.emplace_back(op); + + try + { + graphene::chain::verify_authority(ops, keys, + [this]( account_id_type id ){ return &id(_db).active; }, + [this]( account_id_type id ){ return &id(_db).owner; } ); + } + catch (fc::exception& ex) + { + return false; + } - return public_key_found(keys, account->active.get_keys()) - && public_key_found(keys, account->owner.get_keys()); + return true; } processed_transaction database_api::validate_transaction( const signed_transaction& trx )const From 48fa40023a57496fb438a0f5f640d0ec06c969c9 Mon Sep 17 00:00:00 2001 From: John Jones Date: Fri, 19 Oct 2018 16:13:44 -0500 Subject: [PATCH 03/10] Removed unneeded method definition --- libraries/app/database_api.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index fb240c4316..acb90c8af5 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -167,7 +167,7 @@ class database_api_impl : public std::enable_shared_from_this vector get_withdraw_permissions_by_giver(const std::string account_id_or_name, withdraw_permission_id_type start, uint32_t limit)const; vector get_withdraw_permissions_by_recipient(const std::string account_id_or_name, withdraw_permission_id_type start, uint32_t limit)const; - // private: + //private: static string price_to_string( const price& _price, const asset_object& _base, const asset_object& _quote ); template @@ -272,9 +272,6 @@ class database_api_impl : public std::enable_shared_from_this map< pair, std::function > _market_subscriptions; graphene::chain::database& _db; const application_options* _app_options = nullptr; - private: - bool public_key_found(const flat_set& to_be_found, - const vector& collection_to_search)const; }; ////////////////////////////////////////////////////////////////////// From c2b63f561bb1e54703c75053f56cbbcc8c304d86 Mon Sep 17 00:00:00 2001 From: John Jones Date: Mon, 22 Oct 2018 20:10:59 -0500 Subject: [PATCH 04/10] Added multiple signatures to test --- tests/tests/wallet_tests.cpp | 55 ++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/tests/tests/wallet_tests.cpp b/tests/tests/wallet_tests.cpp index c95e39d741..7311a43ce3 100644 --- a/tests/tests/wallet_tests.cpp +++ b/tests/tests/wallet_tests.cpp @@ -26,6 +26,7 @@ #include #include +#include #include @@ -45,7 +46,7 @@ BOOST_FIXTURE_TEST_SUITE(wallet_tests, database_fixture) /*** * Act */ - int nbr_keys_desired = 3; + unsigned int nbr_keys_desired = 3; vector derived_keys = graphene::wallet::utility::derive_owner_keys_from_brain_key("SOME WORDS GO HERE", nbr_keys_desired); @@ -70,7 +71,7 @@ BOOST_FIXTURE_TEST_SUITE(wallet_tests, database_fixture) string expected_prefix = GRAPHENE_ADDRESS_PREFIX; for (auto info : derived_keys) { string description = (string) info.pub_key; - BOOST_CHECK_EQUAL(0, description.find(expected_prefix)); + BOOST_CHECK_EQUAL(0u, description.find(expected_prefix)); } } FC_LOG_AND_RETHROW() @@ -95,4 +96,54 @@ BOOST_FIXTURE_TEST_SUITE(wallet_tests, database_fixture) } FC_LOG_AND_RETHROW() } +BOOST_AUTO_TEST_CASE( any_two_of_three ) +{ + try { + fc::ecc::private_key nathan_key1 = fc::ecc::private_key::regenerate(fc::digest("key1")); + fc::ecc::private_key nathan_key2 = fc::ecc::private_key::regenerate(fc::digest("key2")); + fc::ecc::private_key nathan_key3 = fc::ecc::private_key::regenerate(fc::digest("key3")); + const account_object& nathan = create_account("nathan", nathan_key1.get_public_key() ); + fund(nathan); + graphene::app::database_api db_api(db); + + try { + account_update_operation op; + op.account = nathan.id; + op.active = authority(2, public_key_type(nathan_key1.get_public_key()), 1, public_key_type(nathan_key2.get_public_key()), 1, public_key_type(nathan_key3.get_public_key()), 1); + op.owner = *op.active; + trx.operations.push_back(op); + sign(trx, nathan_key1); + PUSH_TX( db, trx, database::skip_transaction_dupe_check ); + trx.clear(); + } FC_CAPTURE_AND_RETHROW ((nathan.active)) + + // two keys should work + { + flat_set public_keys; + public_keys.emplace(nathan_key1.get_public_key()); + public_keys.emplace(nathan_key2.get_public_key()); + BOOST_CHECK(db_api.verify_account_authority("nathan", public_keys)); + } + + // the other two keys should work + { + flat_set public_keys; + public_keys.emplace(nathan_key2.get_public_key()); + public_keys.emplace(nathan_key3.get_public_key()); + BOOST_CHECK(db_api.verify_account_authority("nathan", public_keys)); + } + + // just one key should not work + { + flat_set public_keys; + public_keys.emplace(nathan_key1.get_public_key()); + BOOST_CHECK(!db_api.verify_account_authority("nathan", public_keys)); + } + } catch (fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} + BOOST_AUTO_TEST_SUITE_END() + From 5db31f5e8f2d27427825d28fb68d3763d295f572 Mon Sep 17 00:00:00 2001 From: John Jones Date: Tue, 23 Oct 2018 05:06:58 -0500 Subject: [PATCH 05/10] shorten line length --- tests/tests/wallet_tests.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/tests/wallet_tests.cpp b/tests/tests/wallet_tests.cpp index 7311a43ce3..4e91969e10 100644 --- a/tests/tests/wallet_tests.cpp +++ b/tests/tests/wallet_tests.cpp @@ -109,7 +109,8 @@ BOOST_AUTO_TEST_CASE( any_two_of_three ) try { account_update_operation op; op.account = nathan.id; - op.active = authority(2, public_key_type(nathan_key1.get_public_key()), 1, public_key_type(nathan_key2.get_public_key()), 1, public_key_type(nathan_key3.get_public_key()), 1); + op.active = authority(2, public_key_type(nathan_key1.get_public_key()), 1, + public_key_type(nathan_key2.get_public_key()), 1, public_key_type(nathan_key3.get_public_key()), 1); op.owner = *op.active; trx.operations.push_back(op); sign(trx, nathan_key1); From 7e4e033039bc52a339370954a68d4082a0cd5929 Mon Sep 17 00:00:00 2001 From: John Jones Date: Tue, 23 Oct 2018 12:47:26 -0500 Subject: [PATCH 06/10] add test for multisig --- tests/tests/wallet_tests.cpp | 42 ++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/tests/wallet_tests.cpp b/tests/tests/wallet_tests.cpp index 4e91969e10..766435e974 100644 --- a/tests/tests/wallet_tests.cpp +++ b/tests/tests/wallet_tests.cpp @@ -146,5 +146,47 @@ BOOST_AUTO_TEST_CASE( any_two_of_three ) } } +BOOST_AUTO_TEST_CASE( verify_authority_multiple_accounts ) +{ + try { + fc::ecc::private_key nathan_key = fc::ecc::private_key::regenerate(fc::digest("key1")); + fc::ecc::private_key alice_key = fc::ecc::private_key::regenerate(fc::digest("key2")); + fc::ecc::private_key bob_key = fc::ecc::private_key::regenerate(fc::digest("key3")); + + const account_object& nathan = create_account("nathan", nathan_key.get_public_key() ); + fund(nathan); + + create_account("alice", alice_key.get_public_key() ); + create_account("bob", bob_key.get_public_key() ); + + graphene::app::database_api db_api(db); + + try { + account_update_operation op; + op.account = nathan.id; + op.active = authority(3, public_key_type(nathan_key.get_public_key()), 1, + public_key_type(alice_key.get_public_key()), 1, public_key_type(bob_key.get_public_key()), 1); + op.owner = *op.active; + trx.operations.push_back(op); + sign(trx, nathan_key); + PUSH_TX( db, trx, database::skip_transaction_dupe_check ); + trx.clear(); + } FC_CAPTURE_AND_RETHROW ((nathan.active)) + + // requires 3 signatures + { + flat_set public_keys; + public_keys.emplace(nathan_key.get_public_key()); + public_keys.emplace(alice_key.get_public_key()); + public_keys.emplace(bob_key.get_public_key()); + BOOST_CHECK(db_api.verify_account_authority("nathan", public_keys)); + } + + } catch (fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} + BOOST_AUTO_TEST_SUITE_END() From e03d32914540a8e82fca37504f82aa3715c9d647 Mon Sep 17 00:00:00 2001 From: John Jones Date: Tue, 23 Oct 2018 13:21:38 -0500 Subject: [PATCH 07/10] improved multisig test --- tests/tests/wallet_tests.cpp | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/tests/tests/wallet_tests.cpp b/tests/tests/wallet_tests.cpp index 766435e974..569c090ba8 100644 --- a/tests/tests/wallet_tests.cpp +++ b/tests/tests/wallet_tests.cpp @@ -149,26 +149,18 @@ BOOST_AUTO_TEST_CASE( any_two_of_three ) BOOST_AUTO_TEST_CASE( verify_authority_multiple_accounts ) { try { - fc::ecc::private_key nathan_key = fc::ecc::private_key::regenerate(fc::digest("key1")); - fc::ecc::private_key alice_key = fc::ecc::private_key::regenerate(fc::digest("key2")); - fc::ecc::private_key bob_key = fc::ecc::private_key::regenerate(fc::digest("key3")); - - const account_object& nathan = create_account("nathan", nathan_key.get_public_key() ); - fund(nathan); - - create_account("alice", alice_key.get_public_key() ); - create_account("bob", bob_key.get_public_key() ); + ACTORS( (nathan) (alice) (bob) ); graphene::app::database_api db_api(db); try { account_update_operation op; op.account = nathan.id; - op.active = authority(3, public_key_type(nathan_key.get_public_key()), 1, - public_key_type(alice_key.get_public_key()), 1, public_key_type(bob_key.get_public_key()), 1); + op.active = authority(3, nathan_public_key, 1, + alice.id, 1, bob.id, 1); op.owner = *op.active; trx.operations.push_back(op); - sign(trx, nathan_key); + sign(trx, nathan_private_key); PUSH_TX( db, trx, database::skip_transaction_dupe_check ); trx.clear(); } FC_CAPTURE_AND_RETHROW ((nathan.active)) @@ -176,12 +168,19 @@ BOOST_AUTO_TEST_CASE( verify_authority_multiple_accounts ) // requires 3 signatures { flat_set public_keys; - public_keys.emplace(nathan_key.get_public_key()); - public_keys.emplace(alice_key.get_public_key()); - public_keys.emplace(bob_key.get_public_key()); + public_keys.emplace(nathan_public_key); + public_keys.emplace(alice_public_key); + public_keys.emplace(bob_public_key); BOOST_CHECK(db_api.verify_account_authority("nathan", public_keys)); } + // only 2 signatures given + { + flat_set public_keys; + public_keys.emplace(nathan_public_key); + public_keys.emplace(bob_public_key); + BOOST_CHECK(!db_api.verify_account_authority("nathan", public_keys)); + } } catch (fc::exception& e) { edump((e.to_detail_string())); throw; From 673ac2b86574f39fbe420c71c5829c15ef9664a6 Mon Sep 17 00:00:00 2001 From: John Jones Date: Tue, 23 Oct 2018 13:49:54 -0500 Subject: [PATCH 08/10] fix short line --- tests/tests/wallet_tests.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/tests/wallet_tests.cpp b/tests/tests/wallet_tests.cpp index 569c090ba8..02babadb9c 100644 --- a/tests/tests/wallet_tests.cpp +++ b/tests/tests/wallet_tests.cpp @@ -156,8 +156,7 @@ BOOST_AUTO_TEST_CASE( verify_authority_multiple_accounts ) try { account_update_operation op; op.account = nathan.id; - op.active = authority(3, nathan_public_key, 1, - alice.id, 1, bob.id, 1); + op.active = authority(3, nathan_public_key, 1, alice.id, 1, bob.id, 1); op.owner = *op.active; trx.operations.push_back(op); sign(trx, nathan_private_key); From f523ad6eb9c535ad04cb0cfeec96b26f575847e2 Mon Sep 17 00:00:00 2001 From: John Jones Date: Tue, 23 Oct 2018 14:51:27 -0500 Subject: [PATCH 09/10] moved tests, fixed comments --- .../app/include/graphene/app/database_api.hpp | 4 +- tests/tests/database_api_tests.cpp | 110 +++++++++++++++++ tests/tests/wallet_tests.cpp | 111 +----------------- 3 files changed, 113 insertions(+), 112 deletions(-) diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index 1e4e296d2b..65de6e2ff6 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -663,10 +663,10 @@ class database_api bool verify_authority( const signed_transaction& trx )const; /** - * @brief Verify that the public keys have enough authority to authorize a transaction + * @brief Verify that the public keys have enough authority to approve an operation * @param account_name_or_id the account to check * @param signers the public keys - * @return true if the passed in keys have enough authority to authorize a transaction + * @return true if the passed in keys have enough authority to approve an operation */ bool verify_account_authority( const string& account_name_or_id, const flat_set& signers )const; diff --git a/tests/tests/database_api_tests.cpp b/tests/tests/database_api_tests.cpp index 2577f57710..1eeb177b42 100644 --- a/tests/tests/database_api_tests.cpp +++ b/tests/tests/database_api_tests.cpp @@ -831,4 +831,114 @@ BOOST_AUTO_TEST_CASE( get_transaction_hex ) } FC_LOG_AND_RETHROW() } +BOOST_AUTO_TEST_CASE(verify_account_authority) +{ + try { + + ACTORS( (nathan) ); + graphene::app::database_api db_api(db); + + // good keys + flat_set public_keys; + public_keys.emplace(nathan_public_key); + BOOST_CHECK(db_api.verify_account_authority( "nathan", public_keys)); + + // bad keys + flat_set bad_public_keys; + bad_public_keys.emplace(public_key_type("BTS6MkMxwBjFWmcDjXRoJ4mW9Hd4LCSPwtv9tKG1qYW5Kgu4AhoZy")); + BOOST_CHECK(!db_api.verify_account_authority( "nathan", bad_public_keys)); + + } FC_LOG_AND_RETHROW() +} + +BOOST_AUTO_TEST_CASE( any_two_of_three ) +{ + try { + fc::ecc::private_key nathan_key1 = fc::ecc::private_key::regenerate(fc::digest("key1")); + fc::ecc::private_key nathan_key2 = fc::ecc::private_key::regenerate(fc::digest("key2")); + fc::ecc::private_key nathan_key3 = fc::ecc::private_key::regenerate(fc::digest("key3")); + const account_object& nathan = create_account("nathan", nathan_key1.get_public_key() ); + fund(nathan); + graphene::app::database_api db_api(db); + + try { + account_update_operation op; + op.account = nathan.id; + op.active = authority(2, public_key_type(nathan_key1.get_public_key()), 1, + public_key_type(nathan_key2.get_public_key()), 1, public_key_type(nathan_key3.get_public_key()), 1); + op.owner = *op.active; + trx.operations.push_back(op); + sign(trx, nathan_key1); + PUSH_TX( db, trx, database::skip_transaction_dupe_check ); + trx.clear(); + } FC_CAPTURE_AND_RETHROW ((nathan.active)) + + // two keys should work + { + flat_set public_keys; + public_keys.emplace(nathan_key1.get_public_key()); + public_keys.emplace(nathan_key2.get_public_key()); + BOOST_CHECK(db_api.verify_account_authority("nathan", public_keys)); + } + + // the other two keys should work + { + flat_set public_keys; + public_keys.emplace(nathan_key2.get_public_key()); + public_keys.emplace(nathan_key3.get_public_key()); + BOOST_CHECK(db_api.verify_account_authority("nathan", public_keys)); + } + + // just one key should not work + { + flat_set public_keys; + public_keys.emplace(nathan_key1.get_public_key()); + BOOST_CHECK(!db_api.verify_account_authority("nathan", public_keys)); + } + } catch (fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_AUTO_TEST_CASE( verify_authority_multiple_accounts ) +{ + try { + ACTORS( (nathan) (alice) (bob) ); + + graphene::app::database_api db_api(db); + + try { + account_update_operation op; + op.account = nathan.id; + op.active = authority(3, nathan_public_key, 1, alice.id, 1, bob.id, 1); + op.owner = *op.active; + trx.operations.push_back(op); + sign(trx, nathan_private_key); + PUSH_TX( db, trx, database::skip_transaction_dupe_check ); + trx.clear(); + } FC_CAPTURE_AND_RETHROW ((nathan.active)) + + // requires 3 signatures + { + flat_set public_keys; + public_keys.emplace(nathan_public_key); + public_keys.emplace(alice_public_key); + public_keys.emplace(bob_public_key); + BOOST_CHECK(db_api.verify_account_authority("nathan", public_keys)); + } + + // only 2 signatures given + { + flat_set public_keys; + public_keys.emplace(nathan_public_key); + public_keys.emplace(bob_public_key); + BOOST_CHECK(!db_api.verify_account_authority("nathan", public_keys)); + } + } catch (fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/tests/wallet_tests.cpp b/tests/tests/wallet_tests.cpp index 02babadb9c..8601f747d5 100644 --- a/tests/tests/wallet_tests.cpp +++ b/tests/tests/wallet_tests.cpp @@ -76,115 +76,6 @@ BOOST_FIXTURE_TEST_SUITE(wallet_tests, database_fixture) } FC_LOG_AND_RETHROW() } - - BOOST_AUTO_TEST_CASE(verify_account_authority) { - try { - - ACTORS( (nathan) ); - graphene::app::database_api db_api(db); - - // good keys - flat_set public_keys; - public_keys.emplace(nathan_public_key); - BOOST_CHECK(db_api.verify_account_authority( "nathan", public_keys)); - - // bad keys - flat_set bad_public_keys; - bad_public_keys.emplace(public_key_type("BTS6MkMxwBjFWmcDjXRoJ4mW9Hd4LCSPwtv9tKG1qYW5Kgu4AhoZy")); - BOOST_CHECK(!db_api.verify_account_authority( "nathan", bad_public_keys)); - - } FC_LOG_AND_RETHROW() - } - -BOOST_AUTO_TEST_CASE( any_two_of_three ) -{ - try { - fc::ecc::private_key nathan_key1 = fc::ecc::private_key::regenerate(fc::digest("key1")); - fc::ecc::private_key nathan_key2 = fc::ecc::private_key::regenerate(fc::digest("key2")); - fc::ecc::private_key nathan_key3 = fc::ecc::private_key::regenerate(fc::digest("key3")); - const account_object& nathan = create_account("nathan", nathan_key1.get_public_key() ); - fund(nathan); - graphene::app::database_api db_api(db); - - try { - account_update_operation op; - op.account = nathan.id; - op.active = authority(2, public_key_type(nathan_key1.get_public_key()), 1, - public_key_type(nathan_key2.get_public_key()), 1, public_key_type(nathan_key3.get_public_key()), 1); - op.owner = *op.active; - trx.operations.push_back(op); - sign(trx, nathan_key1); - PUSH_TX( db, trx, database::skip_transaction_dupe_check ); - trx.clear(); - } FC_CAPTURE_AND_RETHROW ((nathan.active)) - - // two keys should work - { - flat_set public_keys; - public_keys.emplace(nathan_key1.get_public_key()); - public_keys.emplace(nathan_key2.get_public_key()); - BOOST_CHECK(db_api.verify_account_authority("nathan", public_keys)); - } - - // the other two keys should work - { - flat_set public_keys; - public_keys.emplace(nathan_key2.get_public_key()); - public_keys.emplace(nathan_key3.get_public_key()); - BOOST_CHECK(db_api.verify_account_authority("nathan", public_keys)); - } - - // just one key should not work - { - flat_set public_keys; - public_keys.emplace(nathan_key1.get_public_key()); - BOOST_CHECK(!db_api.verify_account_authority("nathan", public_keys)); - } - } catch (fc::exception& e) { - edump((e.to_detail_string())); - throw; - } -} - -BOOST_AUTO_TEST_CASE( verify_authority_multiple_accounts ) -{ - try { - ACTORS( (nathan) (alice) (bob) ); - - graphene::app::database_api db_api(db); - - try { - account_update_operation op; - op.account = nathan.id; - op.active = authority(3, nathan_public_key, 1, alice.id, 1, bob.id, 1); - op.owner = *op.active; - trx.operations.push_back(op); - sign(trx, nathan_private_key); - PUSH_TX( db, trx, database::skip_transaction_dupe_check ); - trx.clear(); - } FC_CAPTURE_AND_RETHROW ((nathan.active)) - - // requires 3 signatures - { - flat_set public_keys; - public_keys.emplace(nathan_public_key); - public_keys.emplace(alice_public_key); - public_keys.emplace(bob_public_key); - BOOST_CHECK(db_api.verify_account_authority("nathan", public_keys)); - } - - // only 2 signatures given - { - flat_set public_keys; - public_keys.emplace(nathan_public_key); - public_keys.emplace(bob_public_key); - BOOST_CHECK(!db_api.verify_account_authority("nathan", public_keys)); - } - } catch (fc::exception& e) { - edump((e.to_detail_string())); - throw; - } -} - + BOOST_AUTO_TEST_SUITE_END() From b0783108b72f8c784ff90c8a6101afc9ada0874f Mon Sep 17 00:00:00 2001 From: John Jones Date: Wed, 24 Oct 2018 07:12:00 -0500 Subject: [PATCH 10/10] clarify comment --- libraries/app/include/graphene/app/database_api.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index 65de6e2ff6..9a546eef42 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -663,10 +663,10 @@ class database_api bool verify_authority( const signed_transaction& trx )const; /** - * @brief Verify that the public keys have enough authority to approve an operation + * @brief Verify that the public keys have enough authority to approve an operation for this account * @param account_name_or_id the account to check * @param signers the public keys - * @return true if the passed in keys have enough authority to approve an operation + * @return true if the passed in keys have enough authority to approve an operation for this account */ bool verify_account_authority( const string& account_name_or_id, const flat_set& signers )const;