diff --git a/Dev_Docs/Pending_Features/2026-06-04_1433_lazy_import_solana_pda_актуальный_формат.md b/Dev_Docs/Pending_Features/2026-06-04_1433_lazy_import_solana_pda_актуальный_формат.md new file mode 100644 index 0000000..817e5c0 --- /dev/null +++ b/Dev_Docs/Pending_Features/2026-06-04_1433_lazy_import_solana_pda_актуальный_формат.md @@ -0,0 +1,15 @@ +# Lazy-import Solana PDA: актуальный формат + +- Краткое описание: + Серверный Java lazy-import пользователя из `shine_users` обновлён под актуальный формат `user_pda`. Убран RPC-фильтр по размеру PDA, добавлен разбор нового `ServerProfileBlock` (`block_type = 30`) без сохранения server-only полей в `solana_users`. +- Что проверять: + 1. Взять логин пользователя, который существует в Solana PDA, но отсутствует в локальной таблице `solana_users`. + 2. Выполнить вход этим логином через сервер. + 3. Убедиться, что lazy-import подтянул пользователя из Solana. + 4. Убедиться, что запись в `solana_users` создана с полями `login`, `blockchain_name`, `solana_key`, `blockchain_key`, `device_key`. + 5. Убедиться, что отсутствие/наличие server-полей в PDA не ломает импорт. +- Ожидаемый результат: + 1. Пользователь успешно находится и импортируется из Solana PDA независимо от фактического размера PDA. + 2. Новый `ServerProfileBlock` не ломает парсер. + 3. В БД не появляются лишние server-only поля. +- Статус: `pending` diff --git a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/SolanaUserPdaImportService.java b/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/SolanaUserPdaImportService.java index ae197e0..9e624cb 100644 --- a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/SolanaUserPdaImportService.java +++ b/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/SolanaUserPdaImportService.java @@ -25,7 +25,6 @@ public final class SolanaUserPdaImportService { private static final Logger log = LoggerFactory.getLogger(SolanaUserPdaImportService.class); private static final ObjectMapper MAPPER = new ObjectMapper(); private static final HttpClient HTTP = HttpClient.newHttpClient(); - private static final int USER_PDA_SPACE = 768; private static final String MAGIC = "SHiNE"; private SolanaUserPdaImportService() {} @@ -72,14 +71,13 @@ public final class SolanaUserPdaImportService { { "encoding":"base64", "filters":[ - {"dataSize":%d}, {"memcmp":{"offset":61,"bytes":"%s"}}, {"memcmp":{"offset":62,"bytes":"%s"}} ] } ] } - """.formatted(SolanaProgramsConfig.SHINE_USERS_PROGRAM_ID, USER_PDA_SPACE, lenB58, loginB58); + """.formatted(SolanaProgramsConfig.SHINE_USERS_PROGRAM_ID, lenB58, loginB58); HttpRequest req = HttpRequest.newBuilder() .uri(URI.create(SolanaProgramsConfig.SOLANA_RPC_URL)) @@ -171,14 +169,20 @@ public final class SolanaUserPdaImportService { return null; } } - } else if (blockType == 4) { - c += 1 + 32; - int addrLen = u8(raw, c++); - c += addrLen; - int syncCount = u8(raw, c++); - for (int j = 0; j < syncCount; j++) { - int n = u8(raw, c++); - c += n; + } else if (blockType == 30) { + int isServer = u8(raw, c++); + if (isServer == 1) { + c += 1; // address_format_type + c += 1; // address_format_version + int addrLen = u8(raw, c++); + c += addrLen; + int syncCount = u8(raw, c++); + for (int j = 0; j < syncCount; j++) { + int n = u8(raw, c++); + c += n; + } + } else if (isServer != 0) { + return null; } } else if (blockType == 40) { int accessCount = u8(raw, c++); @@ -264,4 +268,3 @@ public final class SolanaUserPdaImportService { long paidLimitBytes ) {} } - diff --git a/VERSION.properties b/VERSION.properties index 8d6ef7f..ed12268 100644 --- a/VERSION.properties +++ b/VERSION.properties @@ -1,2 +1,2 @@ -client.version=1.2.123 -server.version=1.2.115 +client.version=1.2.124 +server.version=1.2.116