From 04252e006bbb74d3cc507f486d8206b6d946d6ab42f57907c442737d4a43e443 Mon Sep 17 00:00:00 2001 From: AidarKC Date: Sat, 13 Jun 2026 00:24:42 +0400 Subject: [PATCH] =?UTF-8?q?ESP32:=20=D1=81=D0=BE=D1=85=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D1=8F=D1=82=D1=8C=20=D0=BF=D0=BE=D0=BB=D0=BD=D1=8B=D0=B9=20?= =?UTF-8?q?=D1=82=D0=B5=D0=BA=D1=81=D1=82=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA?= =?UTF-8?q?=D0=B8=20=D1=80=D0=B5=D0=B3=D0=B8=D1=81=D1=82=D1=80=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...5_esp32_полный_текст_ошибки_регистрации.md | 26 ++++++ .../shine_homeserver_main.ino | 86 +++++++++++++++++-- VERSION.properties | 4 +- 3 files changed, 107 insertions(+), 9 deletions(-) create mode 100644 Dev_Docs/Pending_Features/2026-06-13_1235_esp32_полный_текст_ошибки_регистрации.md diff --git a/Dev_Docs/Pending_Features/2026-06-13_1235_esp32_полный_текст_ошибки_регистрации.md b/Dev_Docs/Pending_Features/2026-06-13_1235_esp32_полный_текст_ошибки_регистрации.md new file mode 100644 index 0000000..1d7168e --- /dev/null +++ b/Dev_Docs/Pending_Features/2026-06-13_1235_esp32_полный_текст_ошибки_регистрации.md @@ -0,0 +1,26 @@ +# ESP32 полный текст ошибки регистрации Solana + +- статус: `pending` + +## Что сделано + +- Локальные правки Solana-программ для диагностических `failed at ...` логов откатены. +- В основном ESP32-скетче сохранение последней ошибки регистрации переведено на полный текст RPC-диагностики. +- В `details` теперь сохраняются полные payload: + - `send_transaction_payload` + - `simulate_payload` +- Длинный текст ошибки сохраняется в `Preferences` по частям, чтобы не теряться из-за лимита одной строки. +- Чтение по USB-команде `last_error` / `last_diag` / `reg_diag` выводит сохранённый текст целиком. + +## Что проверять + +1. Запустить регистрацию на устройстве до ошибки. +2. По USB отправить `last_error`. +3. Проверить, что в ответе есть полный JSON/текст `sendTransaction` и `simulateTransaction`, а не только короткий summary. +4. Убедиться, что текст после перезагрузки устройства остаётся доступным через ту же команду. + +## Ожидаемый результат + +- Последняя ошибка регистрации читается по USB почти целиком. +- Если Solana уже вернула строку с местом падения, она не теряется из-за агрессивного обрезания на ESP32. + diff --git a/ESP32/esp32/ESP32-S3-Touch-AMOLED-2.16/main-device/shine_homeserver_main/shine_homeserver_main.ino b/ESP32/esp32/ESP32-S3-Touch-AMOLED-2.16/main-device/shine_homeserver_main/shine_homeserver_main.ino index 2355b1a..2b7c6ac 100644 --- a/ESP32/esp32/ESP32-S3-Touch-AMOLED-2.16/main-device/shine_homeserver_main/shine_homeserver_main.ino +++ b/ESP32/esp32/ESP32-S3-Touch-AMOLED-2.16/main-device/shine_homeserver_main/shine_homeserver_main.ino @@ -375,6 +375,7 @@ static bool loadUsersEconomyConfigState(const String &economyConfigAddress, static bool loadAccountOwner(const String &address, String &ownerOut, bool &existsOut, String &messageOut); static bool extractRpcErrorSummary(const String &payload, String &messageOut); static String compactRpcLogs(const String &payload, int maxLines = 3); +static bool simulateTransactionPayload(const String &txBase64, String &payloadOut); static bool simulateTransactionForError(const String &txBase64, String &messageOut); static std::vector buildLastBlockStateBytes(const String &login, const String &blockchainName); static std::vector buildUnsignedCreateRecord( @@ -411,6 +412,9 @@ static bool signMessageEd25519(const std::vector &message, const uint8_ static String encodeTransactionBase64(const uint8_t signature[64], const std::vector &message); static bool awaitTransactionConfirmation(const String &signatureB58, String &messageOut); static bool registerHomeserverOnSolana(String &messageOut); +static void loadRegisterDiagDetailsFromPrefs(); +static void saveRegisterDiagDetailsToPrefs(const String &details); +static void clearRegisterDiagDetailsFromPrefs(); static void saveRegisterDiag(const String &status, const String &summary, const String &details); static void printRegisterDiagToSerial(); static void clearRegisterDiag(); @@ -1471,9 +1475,14 @@ static bool extractRpcErrorSummary(const String &payload, String &messageOut) { return !messageOut.isEmpty(); } +static bool simulateTransactionPayload(const String &txBase64, String &payloadOut) { + payloadOut = ""; + return rpcCallSolana("simulateTransaction", "[\"" + txBase64 + "\",{\"encoding\":\"base64\",\"sigVerify\":true,\"commitment\":\"processed\"}]", payloadOut); +} + static bool simulateTransactionForError(const String &txBase64, String &messageOut) { String payload; - if (!rpcCallSolana("simulateTransaction", "[\"" + txBase64 + "\",{\"encoding\":\"base64\",\"sigVerify\":true,\"commitment\":\"processed\"}]", payload)) { + if (!simulateTransactionPayload(txBase64, payload)) { return false; } return extractRpcErrorSummary(payload, messageOut); @@ -1764,13 +1773,21 @@ static bool registerHomeserverOnSolana(String &messageOut) { if (!extractRpcErrorSummary(payload, messageOut)) { messageOut = "RPC returned sendTransaction error"; } + diagDetails += "send_transaction_payload<<\n"; + diagDetails += payload; + diagDetails += "\n>>send_transaction_payload\n"; String simulated; - if (simulateTransactionForError(txBase64, simulated)) { + String simulatedPayload; + if (simulateTransactionPayload(txBase64, simulatedPayload)) { + extractRpcErrorSummary(simulatedPayload, simulated); if (messageOut.isEmpty()) { messageOut = simulated; } else if (messageOut.indexOf(simulated) < 0) { messageOut += " | simulate: " + simulated; } + diagDetails += "simulate_payload<<\n"; + diagDetails += simulatedPayload; + diagDetails += "\n>>simulate_payload\n"; } diagDetails += String("send_transaction_error=") + messageOut + "\n"; return failWithDiag(messageOut); @@ -2721,7 +2738,7 @@ static void loadPrefs() { gRegistrationSignature = gPrefs.getString("registration_sig", ""); gLastRegisterDiagStatus = gPrefs.getString("reg_diag_status", "none"); gLastRegisterDiagSummary = gPrefs.getString("reg_diag_summary", ""); - gLastRegisterDiagDetails = gPrefs.getString("reg_diag_details", ""); + loadRegisterDiagDetailsFromPrefs(); gLastRegisterDiagTime = gPrefs.getString("reg_diag_time", ""); gBalanceStatusMessage = gDevicePubB58.isEmpty() ? "Balance: secret not set" : "Balance: tap to load"; gAccountCheckPending = true; @@ -2837,15 +2854,70 @@ static String wifiHomeSummary() { return String("Wi-Fi (") + gWifiSavedSsid + ") disconnected"; } +static void loadRegisterDiagDetailsFromPrefs() { + gLastRegisterDiagDetails = ""; + int chunks = gPrefs.getInt("rddn", 0); + if (chunks <= 0) { + gLastRegisterDiagDetails = gPrefs.getString("reg_diag_details", ""); + return; + } + if (chunks > 12) { + chunks = 12; + } + for (int i = 0; i < chunks; ++i) { + String key = String("rdd") + i; + gLastRegisterDiagDetails += gPrefs.getString(key.c_str(), ""); + } +} + +static void saveRegisterDiagDetailsToPrefs(const String &details) { + const int chunkSize = 1400; + const int maxChunks = 12; + gPrefs.remove("reg_diag_details"); + for (int i = 0; i < maxChunks; ++i) { + String key = String("rdd") + i; + gPrefs.remove(key.c_str()); + } + + String stored = details; + int requiredChunks = (stored.length() + chunkSize - 1) / chunkSize; + if (requiredChunks > maxChunks) { + int maxLen = chunkSize * maxChunks; + stored = stored.substring(0, maxLen); + stored += "\n[truncated in NVS]\n"; + requiredChunks = (stored.length() + chunkSize - 1) / chunkSize; + if (requiredChunks > maxChunks) { + stored = stored.substring(0, chunkSize * maxChunks); + requiredChunks = maxChunks; + } + } + + for (int i = 0; i < requiredChunks; ++i) { + int start = i * chunkSize; + String key = String("rdd") + i; + gPrefs.putString(key.c_str(), stored.substring(start, min((int)stored.length(), start + chunkSize))); + } + gPrefs.putInt("rddn", requiredChunks); + gLastRegisterDiagDetails = stored; +} + +static void clearRegisterDiagDetailsFromPrefs() { + gPrefs.remove("reg_diag_details"); + gPrefs.remove("rddn"); + for (int i = 0; i < 12; ++i) { + String key = String("rdd") + i; + gPrefs.remove(key.c_str()); + } +} + static void saveRegisterDiag(const String &status, const String &summary, const String &details) { gLastRegisterDiagStatus = status; - gLastRegisterDiagSummary = summary.length() > 240 ? summary.substring(0, 240) : summary; - gLastRegisterDiagDetails = details.length() > 1800 ? details.substring(0, 1800) : details; + gLastRegisterDiagSummary = summary; gLastRegisterDiagTime = String(shineNowMs()); gPrefs.putString("reg_diag_status", gLastRegisterDiagStatus); gPrefs.putString("reg_diag_summary", gLastRegisterDiagSummary); - gPrefs.putString("reg_diag_details", gLastRegisterDiagDetails); gPrefs.putString("reg_diag_time", gLastRegisterDiagTime); + saveRegisterDiagDetailsToPrefs(details); } static void clearRegisterDiag() { @@ -2855,8 +2927,8 @@ static void clearRegisterDiag() { gLastRegisterDiagTime = ""; gPrefs.remove("reg_diag_status"); gPrefs.remove("reg_diag_summary"); - gPrefs.remove("reg_diag_details"); gPrefs.remove("reg_diag_time"); + clearRegisterDiagDetailsFromPrefs(); } static void printRegisterDiagToSerial() { diff --git a/VERSION.properties b/VERSION.properties index e9b9027..0162f47 100644 --- a/VERSION.properties +++ b/VERSION.properties @@ -1,2 +1,2 @@ -client.version=1.2.169 -server.version=1.2.158 +client.version=1.2.170 +server.version=1.2.159