From 342012ea440d271c21a226ffbc0a08c21835c911 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Wed, 16 Sep 2026 18:45:40 +0000 Subject: [PATCH 1/2] fix(roa): increase account name retries Change-Id: I920a29ab8cb377bb1571c29c4b414d04f9205ce1 --- contracts/sysio.msgch/sysio.msgch.abi | 12 +++++++ contracts/sysio.msgch/sysio.msgch.wasm | Bin 157530 -> 160395 bytes contracts/sysio.roa/sysio.roa.cpp | 9 ++++-- contracts/sysio.roa/sysio.roa.wasm | Bin 50583 -> 50584 bytes contracts/sysio.uwrit/sysio.uwrit.abi | 12 +++++++ .../test_contracts/sendinline/sendinline.wasm | Bin 4346 -> 4346 bytes contracts/tests/sysio.roa_tests.cpp | 30 ++++++++++++++++++ 7 files changed, 60 insertions(+), 3 deletions(-) diff --git a/contracts/sysio.msgch/sysio.msgch.abi b/contracts/sysio.msgch/sysio.msgch.abi index 1a423908ef..d273339ee9 100644 --- a/contracts/sysio.msgch/sysio.msgch.abi +++ b/contracts/sysio.msgch/sysio.msgch.abi @@ -681,6 +681,18 @@ { "name": "ATTESTATION_TYPE_EMISSIONS_BLOCKED", "value": 60962 + }, + { + "name": "ATTESTATION_TYPE_SYNDICATE_LIQ", + "value": 60963 + }, + { + "name": "ATTESTATION_TYPE_LIQ_YIELD", + "value": 60964 + }, + { + "name": "ATTESTATION_TYPE_DESYNDICATE_LIQ", + "value": 60965 } ] }, diff --git a/contracts/sysio.msgch/sysio.msgch.wasm b/contracts/sysio.msgch/sysio.msgch.wasm index b581f28a4f6c2d039c3f9a103e3d3b01ddea705b..e625184a3c4f59032ac298aa1827d24cbc85d885 100755 GIT binary patch delta 24903 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 GY5xNU(m-4Q diff --git a/contracts/sysio.roa/sysio.roa.cpp b/contracts/sysio.roa/sysio.roa.cpp index 3f996c7766..9b0a91b413 100644 --- a/contracts/sysio.roa/sysio.roa.cpp +++ b/contracts/sysio.roa/sysio.roa.cpp @@ -13,6 +13,9 @@ namespace sysio { // literals -- a contract rename is one change here, not scattered across call sites). constexpr name AUTHEX_ACCOUNT = "sysio.authex"_n; constexpr name AUTHEX_RECORDLINK = "recordlink"_n; + + /// Maximum number of generated account names checked before newuser gives up. + constexpr uint8_t MAX_ACCOUNT_NAME_ATTEMPTS = 100; } // anonymous namespace static bool is_sysio_account(const name& account) { @@ -1032,7 +1035,7 @@ namespace sysio { check(prefix_len + 2 <= NAME_LENGTH, "Creator name is too long to generate a sub-account under it"); size_t gen_len = NAME_LENGTH - prefix_len - 1; // chars after "." - // Try up to 3 times to generate a unique username + // Try a bounded number of times to generate a unique username. name new_username; bool created = false; uint32_t block_num = current_block_number(); @@ -1060,7 +1063,7 @@ namespace sysio { return z ^ (z >> 31); }; - for (uint8_t attempt = 0; attempt < 3; ++attempt) { + for (uint8_t attempt = 0; attempt < MAX_ACCOUNT_NAME_ATTEMPTS; ++attempt) { uint64_t x = nonce.value ^ (static_cast(block_num) << 32) ^ (static_cast(attempt) * 0x9E3779B97F4A7C15ULL); @@ -1078,7 +1081,7 @@ namespace sysio { break; } } - check(created, "Failed to generate a unique account name after 3 attempts"); + check(created, "Failed to generate a unique account name after 100 attempts"); auto owner_auth = sysiosystem::authority{1, {{pubkey, 1}}, {}}; auto active_auth = sysiosystem::authority{1, {{pubkey, 1}}, {}}; diff --git a/contracts/sysio.roa/sysio.roa.wasm b/contracts/sysio.roa/sysio.roa.wasm index 8a56d5de3058d45dab58f210da19ce89274881d1..161b205b79d8713d9c86c103d46ceed42f9c10e5 100755 GIT binary patch delta 248 zcmbQ<%{-%ad5)#aW)IDF7RD8mFX(DB-MBn?g02GNyUlWX zz05#rjp2KCAT`IbmydDVW-X72qKuO_?}^Q1VtT@`SuG)gg>m-g`jp3Wd5)#aW)IDF7RF_hFX(DBUAsJag02GNo6T~1 zz05#rjp2KCAT`IbmydDFW-X72qKuO^?}^Q1Vr1T|o)E#pICFDD%41F-m6B&J$arva z{zBEw2kYJ07!PjdY)fMVQU&c5qCkn4a~y!A)?6UDIeYF;pv>g#xvG=9=9dEnm=-94 k1XLD!0Xg{#x3GgXsBZRLc~zXzc(dZc&y1Ue4!1D@04Q8xa{vGU diff --git a/contracts/sysio.uwrit/sysio.uwrit.abi b/contracts/sysio.uwrit/sysio.uwrit.abi index c9d953a937..709769d98f 100644 --- a/contracts/sysio.uwrit/sysio.uwrit.abi +++ b/contracts/sysio.uwrit/sysio.uwrit.abi @@ -849,6 +849,18 @@ { "name": "ATTESTATION_TYPE_EMISSIONS_BLOCKED", "value": 60962 + }, + { + "name": "ATTESTATION_TYPE_SYNDICATE_LIQ", + "value": 60963 + }, + { + "name": "ATTESTATION_TYPE_LIQ_YIELD", + "value": 60964 + }, + { + "name": "ATTESTATION_TYPE_DESYNDICATE_LIQ", + "value": 60965 } ] }, diff --git a/contracts/test_contracts/sendinline/sendinline.wasm b/contracts/test_contracts/sendinline/sendinline.wasm index 3073cc831ca587eaef57d492cf4ffba4b5fe7b4c..f1f6de4289754b3536f98408089803ea4abcedf5 100755 GIT binary patch delta 464 zcmYjNJx?1!5Z$@m`#$466B}}N@ZMoN#_oa;DFDeS(gh)!NGY&UxWbpjU=CSIb0=4j zB8tgK)YNI+Alsw-TUx9oUJ#sEF%Lw&$2ux1DY#j z5_8B0AQhTP{qp6>uA9cAqyBL8b~uU&(0DZQ)A#A{xPO?Y@#$Ir_3=?mblPeX!<1!$ z#niDGI3@rvCQCKA;1vq`s;VW8& zMV!zce-LScO7&^N%aOq=_>KN_mjVGoYik}~M&SjPFAbKueZw~X6N|W@Poau4{Qy7d zPf!^9@DNkuIRyCC_yLdSA58|*@Y&iaJrdB?SVR&KZ v|1506+Pqub0^cD$BIKW3^xPde@D7gcI&i$SD@D_FJ;G%$^>W_Dl%M|v@@`?L delta 477 zcmYjMO-mb56n*!-m-)y{^d>dYj$bc{(NUowmBxhxriiOn#f>|o=s+_m@ncG%n+Sr~ z?kbnMwo6woveczNK-?6%YQdej7gxTqP`uoG58QLOobyn8D1Lvzzv7$_N1dc#S$|Tk$%_}DAKt-0%P>YUMiFoB*qfJ2uCyw zL|CEu^c{@Sv~$9J?Py@eHb$2*S&}ml{COdz-X2EqCYAZ=<9HJNx9|6@a BVv+y= diff --git a/contracts/tests/sysio.roa_tests.cpp b/contracts/tests/sysio.roa_tests.cpp index 7eb4c8dc20..907a249f9d 100644 --- a/contracts/tests/sysio.roa_tests.cpp +++ b/contracts/tests/sysio.roa_tests.cpp @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include @@ -350,6 +352,34 @@ BOOST_FIXTURE_TEST_CASE( newuser_twice_test, sysio_roa_tester ) try { } FC_LOG_AND_RETHROW() +/// Verifies newuser continues past the former three-attempt limit when generated names collide. +/// Each isolated tester starts from the same chain state and block number. Names returned by the +/// earlier testers are pre-created in the next tester, deterministically forcing one additional +/// collision without duplicating the contract's name-generation algorithm in test code. +BOOST_AUTO_TEST_CASE( newuser_retries_after_three_name_collisions ) try { + std::vector occupied_names; + + for (size_t collision_count = 0; collision_count <= 3; ++collision_count) { + auto chain = std::make_unique(); + BOOST_REQUIRE_EQUAL(chain->success(), chain->regnodeowner("alice"_n, 1)); + chain->produce_blocks(1); + + for (const auto occupied_name : occupied_names) + chain->create_account(occupied_name, config::system_account_name, false, false, false, false); + + auto result = chain->newuser("alice"_n, "retrynonce"_n, + chain->get_public_key("alice"_n, "active")); + BOOST_REQUIRE(result && !result->action_traces.empty()); + + const auto generated_name = fc::raw::unpack(result->action_traces[0].return_value); + BOOST_REQUIRE(std::find(occupied_names.begin(), occupied_names.end(), generated_name) + == occupied_names.end()); + occupied_names.push_back(generated_name); + } + + BOOST_REQUIRE_EQUAL(occupied_names.size(), 4u); +} FC_LOG_AND_RETHROW() + BOOST_FIXTURE_TEST_CASE( newuser_creator_permission_test, sysio_roa_tester ) try { auto result = regnodeowner("alice"_n, 2); BOOST_REQUIRE_EQUAL(success(), result); From 320578183457fd8666fe51c8dbc02ebc672bb504 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Thu, 17 Sep 2026 14:50:11 +0000 Subject: [PATCH 2/2] Address account-name retry review feedback Change-Id: I05208d94d0ffa8aff28d7a84190b60e34cbf3707 --- contracts/sysio.roa/sysio.roa.cpp | 46 ++++++--- contracts/sysio.roa/sysio.roa.hpp | 4 +- contracts/sysio.roa/sysio.roa.wasm | Bin 50584 -> 52880 bytes contracts/tests/sysio.roa_tests.cpp | 149 ++++++++++++++++++++++++++++ 4 files changed, 183 insertions(+), 16 deletions(-) diff --git a/contracts/sysio.roa/sysio.roa.cpp b/contracts/sysio.roa/sysio.roa.cpp index 9b0a91b413..18f33656a4 100644 --- a/contracts/sysio.roa/sysio.roa.cpp +++ b/contracts/sysio.roa/sysio.roa.cpp @@ -15,7 +15,26 @@ namespace sysio { constexpr name AUTHEX_RECORDLINK = "recordlink"_n; /// Maximum number of generated account names checked before newuser gives up. - constexpr uint8_t MAX_ACCOUNT_NAME_ATTEMPTS = 100; + constexpr uint32_t MAX_ACCOUNT_NAME_ATTEMPTS{100}; + + /// SplitMix64's Weyl-sequence increment, used to decorrelate account-name generator inputs. + constexpr uint64_t ACCOUNT_NAME_MIX_INCREMENT{0x9E3779B97F4A7C15ULL}; + /// First SplitMix64 avalanche multiplier. + constexpr uint64_t ACCOUNT_NAME_MIX_MULTIPLIER_1{0xBF58476D1CE4E5B9ULL}; + /// Second SplitMix64 avalanche multiplier. + constexpr uint64_t ACCOUNT_NAME_MIX_MULTIPLIER_2{0x94D049BB133111EBULL}; + /// SplitMix64's three avalanche shifts, in application order. + constexpr uint32_t ACCOUNT_NAME_MIX_SHIFT_1{30}; + constexpr uint32_t ACCOUNT_NAME_MIX_SHIFT_2{27}; + constexpr uint32_t ACCOUNT_NAME_MIX_SHIFT_3{31}; + + /// Applies the SplitMix64 finalizer to one account-name generator input. + uint64_t mix_account_name_seed(uint64_t value) { + value += ACCOUNT_NAME_MIX_INCREMENT; + value = (value ^ (value >> ACCOUNT_NAME_MIX_SHIFT_1)) * ACCOUNT_NAME_MIX_MULTIPLIER_1; + value = (value ^ (value >> ACCOUNT_NAME_MIX_SHIFT_2)) * ACCOUNT_NAME_MIX_MULTIPLIER_2; + return value ^ (value >> ACCOUNT_NAME_MIX_SHIFT_3); + } } // anonymous namespace static bool is_sysio_account(const name& account) { @@ -1053,23 +1072,17 @@ namespace sysio { 'p','q','r','s','t','u','v','w','x','y','z'}; constexpr size_t charmap_len = sizeof(charmap) / sizeof(charmap[0]); - // Cheap pseudo-random generator: a splitmix64 finalizer over nonce/attempt/block_num. No - // crypto is needed here — uniqueness is enforced by the is_account retry below; we only - // need variation — so this avoids a sha256 intrinsic call per attempt. - auto mix = [](uint64_t z) { - z += 0x9E3779B97F4A7C15ULL; - z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9ULL; - z = (z ^ (z >> 27)) * 0x94D049BB133111EBULL; - return z ^ (z >> 31); - }; + // Mix the block number before combining it with the nonce. A linear shifted combination + // lets related name-valued nonces in different blocks produce the same candidate sequence. + // No cryptographic strength is needed: is_account enforces uniqueness below. + const uint64_t seed = nonce.value ^ mix_account_name_seed(static_cast(block_num)); - for (uint8_t attempt = 0; attempt < MAX_ACCOUNT_NAME_ATTEMPTS; ++attempt) { - uint64_t x = nonce.value ^ (static_cast(block_num) << 32) - ^ (static_cast(attempt) * 0x9E3779B97F4A7C15ULL); + for (uint32_t attempt = 0; attempt < MAX_ACCOUNT_NAME_ATTEMPTS; ++attempt) { + uint64_t x = seed ^ (static_cast(attempt) * ACCOUNT_NAME_MIX_INCREMENT); // Fill the generated portion after "." for (size_t i = 0; i < gen_len; ++i) { - x = mix(x); + x = mix_account_name_seed(x); uname_str[prefix_len + 1 + i] = charmap[x % charmap_len]; } @@ -1081,7 +1094,10 @@ namespace sysio { break; } } - check(created, "Failed to generate a unique account name after 100 attempts"); + check(created, [] { + return "Failed to generate a unique account name after " + + std::to_string(MAX_ACCOUNT_NAME_ATTEMPTS) + " attempts"; + }); auto owner_auth = sysiosystem::authority{1, {{pubkey, 1}}, {}}; auto active_auth = sysiosystem::authority{1, {{pubkey, 1}}, {}}; diff --git a/contracts/sysio.roa/sysio.roa.hpp b/contracts/sysio.roa/sysio.roa.hpp index 71cf972ceb..93b0f14118 100644 --- a/contracts/sysio.roa/sysio.roa.hpp +++ b/contracts/sysio.roa/sysio.roa.hpp @@ -160,7 +160,9 @@ namespace sysio { * - The action will create a new account utilizing a new randomly generated username with the provided `pubkey` as its authority. * - The registration count for the `creator` will be incremented. * - The sponsor mapping (creator, nonce -> username) will be recorded in the sponsors table. - * - The action will fail if the `creator` is not a tier-1 node owner or if the account already exists. + * - The action fails if ROA is inactive, the `creator` is not a tier-1 node owner, the + * creator name cannot fit a generated suffix, the nonce was already used by that creator, + * or no unused generated name is found within the bounded candidate search. * * ### Rights Granted * - The new user account is granted access to the network with the specified public key. diff --git a/contracts/sysio.roa/sysio.roa.wasm b/contracts/sysio.roa/sysio.roa.wasm index 161b205b79d8713d9c86c103d46ceed42f9c10e5..9dd9979dd090f0d9981216359cc634eb4da5b2f1 100755 GIT binary patch delta 17518 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 DQhTk} delta 15129 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 STj+x~d(zOOgZ0J&MfpDgLhG9V diff --git a/contracts/tests/sysio.roa_tests.cpp b/contracts/tests/sysio.roa_tests.cpp index 907a249f9d..fa127aadc5 100644 --- a/contracts/tests/sysio.roa_tests.cpp +++ b/contracts/tests/sysio.roa_tests.cpp @@ -15,7 +15,9 @@ #include #include #include +#include #include +#include #include using namespace sysio::testing; @@ -33,6 +35,21 @@ using sysio::chain::compute_table_id; constexpr account_name ROA = "sysio.roa"_n; constexpr uint64_t NETWORK_GEN = 0; +/// Generated sub-account names newuser checks before giving up. +constexpr size_t NEWUSER_MAX_NAME_ATTEMPTS = 100; +/// newuser's abort when the nonce was already used by the same creator. +constexpr auto NEWUSER_DUPLICATE_NONCE = "Sponsor entry for this nonce already exists"; +/// Every character newuser can place in a generated sub-account name: the name alphabet without '.'. +constexpr std::string_view GENERATED_NAME_CHARS = "12345abcdefghijklmnopqrstuvwxyz"; +/// Longest account name supported by the contract. +constexpr size_t MAX_ACCOUNT_NAME_LENGTH = 12; + +/// Returns newuser's error after its bounded generated-name search is exhausted. +static std::string newuser_names_exhausted_message() { + return "Failed to generate a unique account name after " + + std::to_string(NEWUSER_MAX_NAME_ATTEMPTS) + " attempts"; +} + class sysio_roa_tester : public tester { public: @@ -259,6 +276,53 @@ class sysio_roa_tester : public tester { return new_name; } + /// Runs newuser with every account in `occupied` created first, committing nothing. + /// A second call with the same nonce aborts the transaction after the first call returns its + /// generated name, so every probe observes identical state in the same pending block. + transaction_trace_ptr push_newuser_probe( account_name creator, name nonce, + const vector& occupied ) + { + signed_transaction trx; + for (const auto& account : occupied) { + trx.actions.emplace_back( vector{{config::system_account_name, + config::active_name}}, + newaccount{ + .creator = config::system_account_name, + .name = account, + .owner = authority( get_public_key( account, "owner" ) ), + .active = authority( get_public_key( account, "active" ) ), + }); + } + const auto call = get_action( ROA, "newuser"_n, + vector{{creator, config::sysio_payer_name}, + {creator, config::active_name}}, + mvo()("creator", creator)("nonce", nonce) + ("pubkey", get_public_key(creator, "active")) ); + trx.actions.push_back( call ); + trx.actions.push_back( call ); + set_transaction_headers( trx ); + if (!occupied.empty()) + trx.sign( get_private_key( config::system_account_name, "active" ), control->get_chain_id() ); + trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); + return push_transaction( trx, fc::time_point::maximum(), DEFAULT_BILLED_CPU_TIME_US, + true /* no_throw */ ); + } + + /// Returns the first newuser call's generated name from a rolled-back probe transaction. + static account_name newuser_probe_name( const transaction_trace& trace ) + { + BOOST_REQUIRE( trace.except_ptr ); + BOOST_REQUIRE_EXCEPTION( std::rethrow_exception( trace.except_ptr ), + sysio_assert_message_exception, + sysio_assert_message_is( NEWUSER_DUPLICATE_NONCE ) ); + const auto it = std::find_if( trace.action_traces.begin(), trace.action_traces.end(), + []( const auto& at ) { + return at.receiver == ROA && at.act.name == "newuser"_n; + }); + BOOST_REQUIRE( it != trace.action_traces.end() ); + return fc::raw::unpack( it->return_value ); + } + action_result regnodeowner( account_name owner, uint8_t tier ) { return push_action(ROA, "forcereg"_n, mvo() @@ -358,6 +422,7 @@ BOOST_FIXTURE_TEST_CASE( newuser_twice_test, sysio_roa_tester ) try { /// collision without duplicating the contract's name-generation algorithm in test code. BOOST_AUTO_TEST_CASE( newuser_retries_after_three_name_collisions ) try { std::vector occupied_names; + std::optional newuser_block_num; for (size_t collision_count = 0; collision_count <= 3; ++collision_count) { auto chain = std::make_unique(); @@ -371,6 +436,12 @@ BOOST_AUTO_TEST_CASE( newuser_retries_after_three_name_collisions ) try { chain->get_public_key("alice"_n, "active")); BOOST_REQUIRE(result && !result->action_traces.empty()); + // A different block draws an unrelated sequence, so pin the generator input that makes the + // accounts collected from earlier fixtures collide in later fixtures. + if (!newuser_block_num) + newuser_block_num = result->block_num; + BOOST_REQUIRE_EQUAL(*newuser_block_num, result->block_num); + const auto generated_name = fc::raw::unpack(result->action_traces[0].return_value); BOOST_REQUIRE(std::find(occupied_names.begin(), occupied_names.end(), generated_name) == occupied_names.end()); @@ -380,6 +451,84 @@ BOOST_AUTO_TEST_CASE( newuser_retries_after_three_name_collisions ) try { BOOST_REQUIRE_EQUAL(occupied_names.size(), 4u); } FC_LOG_AND_RETHROW() +/// Verifies mixing the block number prevents related name nonces in different blocks from aliasing. +BOOST_AUTO_TEST_CASE( newuser_mixes_block_number_before_combining_nonce ) try { + // In Antelope name encoding, user1 ^ user2 equals this block delta shifted left 32 bits. + // The former linear seed therefore gave both calls the same candidate sequence. + constexpr uint32_t aliasing_block_distance = 384; + auto first = std::make_unique(); + auto second = std::make_unique(); + BOOST_REQUIRE_EQUAL(first->success(), first->regnodeowner("alice"_n, 1)); + BOOST_REQUIRE_EQUAL(second->success(), second->regnodeowner("alice"_n, 1)); + first->produce_blocks(1); + second->produce_blocks(1 + aliasing_block_distance); + + const auto first_result = first->newuser("alice"_n, "user1"_n, + first->get_public_key("alice"_n, "active")); + const auto second_result = second->newuser("alice"_n, "user2"_n, + second->get_public_key("alice"_n, "active")); + BOOST_REQUIRE_EQUAL(first_result->block_num + aliasing_block_distance, second_result->block_num); + + const auto first_name = fc::raw::unpack(first_result->action_traces[0].return_value); + const auto second_name = fc::raw::unpack(second_result->action_traces[0].return_value); + BOOST_REQUIRE_NE(first_name, second_name); +} FC_LOG_AND_RETHROW() + +/// Pins newuser's generated-name search at exactly NEWUSER_MAX_NAME_ATTEMPTS attempts. +/// Probes roll back in one pending block. Occupying each returned candidate moves the next probe +/// one step farther through the deterministic sequence without duplicating the generator in test code. +BOOST_FIXTURE_TEST_CASE( newuser_tries_exactly_max_name_attempts, sysio_roa_tester ) try { + constexpr account_name creator = "alice"_n; + constexpr name nonce = "boundnonce"_n; + BOOST_REQUIRE_EQUAL(success(), regnodeowner(creator, 1)); + produce_blocks(1); + + std::vector occupied; + std::optional probe_block_num; + for (size_t attempt = 0; attempt < NEWUSER_MAX_NAME_ATTEMPTS; ++attempt) { + BOOST_TEST_CONTEXT("probe " << attempt) { + const auto trace = push_newuser_probe(creator, nonce, occupied); + if (!probe_block_num) + probe_block_num = trace->block_num; + BOOST_REQUIRE_EQUAL(*probe_block_num, trace->block_num); + + const auto generated = newuser_probe_name(*trace); + BOOST_REQUIRE(std::find(occupied.begin(), occupied.end(), generated) == occupied.end()); + occupied.push_back(generated); + } + } + + const auto trace = push_newuser_probe(creator, nonce, occupied); + BOOST_REQUIRE_EQUAL(*probe_block_num, trace->block_num); + BOOST_REQUIRE(trace->except_ptr); + BOOST_REQUIRE_EXCEPTION(std::rethrow_exception(trace->except_ptr), + sysio_assert_message_exception, + sysio_assert_message_is(newuser_names_exhausted_message())); + BOOST_REQUIRE(get_sponsorship(creator, nonce).is_null()); + BOOST_REQUIRE_EQUAL(0, get_sponsor_count(creator)); +} FC_LOG_AND_RETHROW() + +/// Verifies newuser records no sponsorship when the creator's entire generated namespace is occupied. +BOOST_FIXTURE_TEST_CASE( newuser_fails_when_generated_names_exhausted, sysio_roa_tester ) try { + constexpr account_name creator = "nodeowner1"_n; + constexpr name nonce = "fullspace"_n; + const std::string prefix = creator.to_string() + '.'; + BOOST_REQUIRE_EQUAL(prefix.size() + 1, MAX_ACCOUNT_NAME_LENGTH); + + create_account(creator, config::system_account_name, false, false, false, false); + BOOST_REQUIRE_EQUAL(success(), regnodeowner(creator, 1)); + + for (const char c : GENERATED_NAME_CHARS) + create_account(name(prefix + c), config::system_account_name, false, false, false, false); + produce_blocks(1); + + BOOST_REQUIRE_EXCEPTION(newuser(creator, nonce, get_public_key(creator, "active")), + sysio_assert_message_exception, + sysio_assert_message_is(newuser_names_exhausted_message())); + BOOST_REQUIRE(get_sponsorship(creator, nonce).is_null()); + BOOST_REQUIRE_EQUAL(0, get_sponsor_count(creator)); +} FC_LOG_AND_RETHROW() + BOOST_FIXTURE_TEST_CASE( newuser_creator_permission_test, sysio_roa_tester ) try { auto result = regnodeowner("alice"_n, 2); BOOST_REQUIRE_EQUAL(success(), result);