diff --git a/libraries/chain/include/graphene/chain/config.hpp b/libraries/chain/include/graphene/chain/config.hpp index 04fcffb4..75e6f54b 100644 --- a/libraries/chain/include/graphene/chain/config.hpp +++ b/libraries/chain/include/graphene/chain/config.hpp @@ -20,7 +20,7 @@ #define GRAPHENE_SYMBOL "CORE" #define GRAPHENE_ADDRESS_PREFIX "GPH" -#define GRAPHENE_MIN_ACCOUNT_NAME_LENGTH 1 +#define GRAPHENE_MIN_ACCOUNT_NAME_LENGTH 3 #define GRAPHENE_MAX_ACCOUNT_NAME_LENGTH 63 #define GRAPHENE_MIN_ASSET_SYMBOL_LENGTH 3 diff --git a/libraries/chain/include/graphene/chain/protocol/asset.hpp b/libraries/chain/include/graphene/chain/protocol/asset.hpp index 4c116c37..967a5c8e 100644 --- a/libraries/chain/include/graphene/chain/protocol/asset.hpp +++ b/libraries/chain/include/graphene/chain/protocol/asset.hpp @@ -203,4 +203,3 @@ FC_REFLECT( graphene::chain::price, (base)(quote) ) (core_exchange_rate) FC_REFLECT( graphene::chain::price_feed, GRAPHENE_PRICE_FEED_FIELDS ) - diff --git a/libraries/chain/include/graphene/chain/protocol/asset_ops.hpp b/libraries/chain/include/graphene/chain/protocol/asset_ops.hpp index d64f4474..b79345af 100644 --- a/libraries/chain/include/graphene/chain/protocol/asset_ops.hpp +++ b/libraries/chain/include/graphene/chain/protocol/asset_ops.hpp @@ -458,4 +458,3 @@ FC_REFLECT( graphene::chain::asset_reserve_operation, (fee)(payer)(amount_to_reserve)(extensions) ) FC_REFLECT( graphene::chain::asset_fund_fee_pool_operation, (fee)(from_account)(asset_id)(amount)(extensions) ); - diff --git a/libraries/chain/include/graphene/chain/protocol/fee_schedule.hpp b/libraries/chain/include/graphene/chain/protocol/fee_schedule.hpp index 5cbb5abd..93caecf9 100644 --- a/libraries/chain/include/graphene/chain/protocol/fee_schedule.hpp +++ b/libraries/chain/include/graphene/chain/protocol/fee_schedule.hpp @@ -55,4 +55,3 @@ namespace graphene { namespace chain { FC_REFLECT_TYPENAME( graphene::chain::fee_parameters ) FC_REFLECT( graphene::chain::fee_schedule, (parameters)(scale) ) - diff --git a/libraries/chain/include/graphene/chain/protocol/operations.hpp b/libraries/chain/include/graphene/chain/protocol/operations.hpp index 853e9c5c..dac09e6a 100644 --- a/libraries/chain/include/graphene/chain/protocol/operations.hpp +++ b/libraries/chain/include/graphene/chain/protocol/operations.hpp @@ -108,9 +108,3 @@ namespace graphene { namespace chain { FC_REFLECT_TYPENAME( graphene::chain::operation ) FC_REFLECT( graphene::chain::op_wrapper, (op) ) - - - - - - diff --git a/libraries/chain/include/graphene/chain/protocol/transfer.hpp b/libraries/chain/include/graphene/chain/protocol/transfer.hpp index 46fc1b2a..46251fd0 100644 --- a/libraries/chain/include/graphene/chain/protocol/transfer.hpp +++ b/libraries/chain/include/graphene/chain/protocol/transfer.hpp @@ -90,4 +90,3 @@ FC_REFLECT( graphene::chain::override_transfer_operation::fee_parameters_type, ( FC_REFLECT( graphene::chain::override_transfer_operation, (fee)(issuer)(from)(to)(amount)(memo)(extensions) ) FC_REFLECT( graphene::chain::transfer_operation, (fee)(from)(to)(amount)(memo)(extensions) ) - diff --git a/libraries/chain/protocol/account.cpp b/libraries/chain/protocol/account.cpp index 1a4726ae..693720c3 100644 --- a/libraries/chain/protocol/account.cpp +++ b/libraries/chain/protocol/account.cpp @@ -34,6 +34,10 @@ namespace graphene { namespace chain { */ bool is_valid_name( const string& name ) { +#if GRAPHENE_MIN_ACCOUNT_NAME_LENGTH < 3 +#error This is_valid_name implementation implicitly enforces minimum name length of 3. +#endif + const size_t len = name.size(); if( len < GRAPHENE_MIN_ACCOUNT_NAME_LENGTH ) return false; diff --git a/tests/common/database_fixture.hpp b/tests/common/database_fixture.hpp index 366d95a9..dc73047c 100644 --- a/tests/common/database_fixture.hpp +++ b/tests/common/database_fixture.hpp @@ -117,11 +117,12 @@ using namespace graphene::db; #define INVOKE(test) ((struct test*)this)->test_method(); trx.clear() #define PREP_ACTOR(name) \ - fc::ecc::private_key name ## _private_key = generate_private_key(BOOST_PP_STRINGIZE(name)); + fc::ecc::private_key name ## _private_key = generate_private_key(BOOST_PP_STRINGIZE(name)); \ + public_key_type name ## _public_key = name ## _private_key.get_public_key(); #define ACTOR(name) \ PREP_ACTOR(name) \ - const auto& name = create_account(BOOST_PP_STRINGIZE(name), name ## _private_key.get_public_key()); \ + const auto& name = create_account(BOOST_PP_STRINGIZE(name), name ## _public_key); \ account_id_type name ## _id = name.id; (void)name ## _id; #define GET_ACTOR(name) \ diff --git a/tests/tests/authority_tests.cpp b/tests/tests/authority_tests.cpp index dfabf40a..54947428 100644 --- a/tests/tests/authority_tests.cpp +++ b/tests/tests/authority_tests.cpp @@ -1085,4 +1085,124 @@ BOOST_FIXTURE_TEST_CASE( voting_account, database_fixture ) vikram_committee_member) != db.get_global_properties().active_committee_members.end()); } FC_LOG_AND_RETHROW() } +/** + * Simple corporate accounts: + * + * Well Corp. Alice 50, Bob 50 T=60 + * Xylo Company Alice 30, Cindy 50 T=40 + * Yaya Inc. Bob 10, Dan 10, Edy 10 T=20 + * Zyzz Co. Dan 50 T=40 + * + * Complex corporate accounts: + * + * Mega Corp. Well 30, Yes 30 T=40 + * Nova Ltd. Alice 10, Well 10 T=20 + * Odle Intl. Dan 10, Yes 10, Zyzz 10 T=20 + * Poxx LLC Well 10, Xylo 10, Yes 20, Zyzz 20 T=40 + */ + +BOOST_FIXTURE_TEST_CASE( get_required_signatures_test, database_fixture ) +{ + try + { + ACTORS( + (alice)(bob)(cindy)(dan)(edy) + (mega)(nova)(odle)(poxx) + (well)(xylo)(yaya)(zyzz) + ); + + auto set_auth = [&]( + account_id_type aid, + const authority& auth + ) + { + signed_transaction tx; + account_update_operation op; + op.account = aid; + op.active = auth; + op.owner = auth; + tx.operations.push_back( op ); + tx.set_expiration( db.head_block_time() + fc::minutes( 5 ) ); + PUSH_TX( db, tx, database::skip_transaction_signatures | database::skip_authority_check ); + } ; + + auto get_active = [&]( + account_id_type aid + ) -> const authority* + { + return &(aid(db).active); + } ; + + auto get_owner = [&]( + account_id_type aid + ) -> const authority* + { + return &(aid(db).owner); + } ; + + auto chk = [&]( + const signed_transaction& tx, + flat_set available_keys, + set ref_set + ) -> bool + { + //wdump( (tx)(available_keys) ); + set result_set = tx.get_required_signatures( available_keys, get_active, get_owner ); + //wdump( (result_set)(ref_set) ); + return result_set == ref_set; + } ; + + set_auth( well_id, authority( 60, alice_id, 50, bob_id, 50 ) ); + set_auth( xylo_id, authority( 40, alice_id, 30, cindy_id, 50 ) ); + set_auth( yaya_id, authority( 20, bob_id, 10, dan_id, 10, edy_id, 10 ) ); + set_auth( zyzz_id, authority( 40, dan_id, 50 ) ); + + set_auth( mega_id, authority( 40, well_id, 30, yaya_id, 30 ) ); + set_auth( nova_id, authority( 20, alice_id, 10, well_id, 10 ) ); + set_auth( odle_id, authority( 20, dan_id, 10, yaya_id, 10, zyzz_id, 10 ) ); + set_auth( poxx_id, authority( 40, well_id, 10, xylo_id, 10, yaya_id, 20, zyzz_id, 20 ) ); + + signed_transaction tx; + flat_set< public_key_type > all_keys + { alice_public_key, bob_public_key, cindy_public_key, dan_public_key, edy_public_key }; + + tx.operations.push_back( transfer_operation() ); + transfer_operation& op = tx.operations.back().get(); + op.to = edy_id; + op.amount = asset(1); + + op.from = alice_id; + BOOST_CHECK( chk( tx, all_keys, { alice_public_key } ) ); + op.from = bob_id; + BOOST_CHECK( chk( tx, all_keys, { bob_public_key } ) ); + op.from = well_id; + BOOST_CHECK( chk( tx, all_keys, { alice_public_key, bob_public_key } ) ); + op.from = xylo_id; + BOOST_CHECK( chk( tx, all_keys, { alice_public_key, cindy_public_key } ) ); + op.from = yaya_id; + BOOST_CHECK( chk( tx, all_keys, { bob_public_key, dan_public_key } ) ); + op.from = zyzz_id; + BOOST_CHECK( chk( tx, all_keys, { dan_public_key } ) ); + + op.from = mega_id; + BOOST_CHECK( chk( tx, all_keys, { alice_public_key, bob_public_key, dan_public_key } ) ); + op.from = nova_id; + BOOST_CHECK( chk( tx, all_keys, { alice_public_key, bob_public_key } ) ); + op.from = odle_id; + BOOST_CHECK( chk( tx, all_keys, { bob_public_key, dan_public_key } ) ); + op.from = poxx_id; + BOOST_CHECK( chk( tx, all_keys, { alice_public_key, bob_public_key, cindy_public_key, dan_public_key } ) ); + + // TODO: Add sigs to tx, then check + // TODO: Check removing sigs + // TODO: Accounts with mix of keys and accounts in their authority + // TODO: Tx with multiple ops requiring different sigs + } + catch(fc::exception& e) + { + edump((e.to_detail_string())); + throw; + } +} + BOOST_AUTO_TEST_SUITE_END()