ESP32: сохранять полный текст ошибки регистрации
This commit is contained in:
parent
436e1f0c53
commit
04252e006b
@ -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.
|
||||
|
||||
@ -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<uint8_t> buildLastBlockStateBytes(const String &login, const String &blockchainName);
|
||||
static std::vector<uint8_t> buildUnsignedCreateRecord(
|
||||
@ -411,6 +412,9 @@ static bool signMessageEd25519(const std::vector<uint8_t> &message, const uint8_
|
||||
static String encodeTransactionBase64(const uint8_t signature[64], const std::vector<uint8_t> &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() {
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
client.version=1.2.169
|
||||
server.version=1.2.158
|
||||
client.version=1.2.170
|
||||
server.version=1.2.159
|
||||
|
||||
Loading…
Reference in New Issue
Block a user