ESP32 регистрация и архив тестового удаления PDA

This commit is contained in:
AidarKC 2026-06-23 20:31:05 +04:00
parent d2f45ff67a
commit 23e61cc182
3 changed files with 91 additions and 18 deletions

View File

@ -2206,20 +2206,20 @@ static std::vector<uint8_t> buildEd25519InstructionData(const uint8_t signature[
} }
static bool getLatestBlockhashBytes(uint8_t out[32], String &blockhashB58, String &messageOut) { static bool getLatestBlockhashBytes(uint8_t out[32], String &blockhashB58, String &messageOut) {
String payload; for (int attempt = 0; attempt < 3; ++attempt) {
if (!rpcCallSolana("getLatestBlockhash", "[{\"commitment\":\"confirmed\"}]", payload)) { String payload;
messageOut = "RPC did not return blockhash"; if (rpcCallSolana("getLatestBlockhash", "[{\"commitment\":\"confirmed\"}]", payload)
return false; && jsonStringField(payload, "blockhash", blockhashB58)
&& !blockhashB58.isEmpty()
&& base58ToFixed32(blockhashB58, out)) {
return true;
}
if (attempt < 2) {
delay(120);
}
} }
if (!jsonStringField(payload, "blockhash", blockhashB58) || blockhashB58.isEmpty()) { messageOut = "RPC did not return blockhash";
messageOut = "Blockhash missing in response"; return false;
return false;
}
if (!base58ToFixed32(blockhashB58, out)) {
messageOut = "Invalid blockhash";
return false;
}
return true;
} }
static bool pdaAlreadyExists(const String &login, String &pdaAddress, String &messageOut) { static bool pdaAlreadyExists(const String &login, String &pdaAddress, String &messageOut) {
@ -3215,6 +3215,10 @@ static bool updateHomeserverSessionOnSolana(bool requireExisting, String &messag
} }
diagDetails += String("wifi=connected:") + WiFi.localIP().toString() + "\n"; diagDetails += String("wifi=connected:") + WiFi.localIP().toString() + "\n";
Serial.println("HOMESERVER_UPDATE_WIFI_OK"); Serial.println("HOMESERVER_UPDATE_WIFI_OK");
if (gShineAuthenticated || gShineWs.connected) {
Serial.println("HOMESERVER_UPDATE_CLOSE_SHINE_SESSION");
clearShineSessionState(false);
}
ShinePdaUserState currentState; ShinePdaUserState currentState;
String stateError; String stateError;
@ -3224,6 +3228,7 @@ static bool updateHomeserverSessionOnSolana(bool requireExisting, String &messag
usedCachedPda = true; usedCachedPda = true;
diagDetails += "read_pda_source=cache\n"; diagDetails += "read_pda_source=cache\n";
} else { } else {
Serial.println("HOMESERVER_UPDATE_READ_PDA_CALL");
if (!readShineUserPda(cleanLogin, currentState, stateError)) { if (!readShineUserPda(cleanLogin, currentState, stateError)) {
diagDetails += String("read_pda_error=") + stateError + "\n"; diagDetails += String("read_pda_error=") + stateError + "\n";
return failWithDiag(stateError.isEmpty() ? "Failed to read user PDA" : stateError); return failWithDiag(stateError.isEmpty() ? "Failed to read user PDA" : stateError);
@ -3715,6 +3720,7 @@ static bool readShineUserPda(const String &login, ShinePdaUserState &outState, S
} }
String pdaB58 = base58From32(userPda); String pdaB58 = base58From32(userPda);
Serial.println(String("READ_PDA_RPC_START: ") + pdaB58);
int code = -1; int code = -1;
String payload; String payload;
String req = "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"getAccountInfo\",\"params\":[\"" + pdaB58 + "\",{\"encoding\":\"base64\",\"commitment\":\"confirmed\"}]}"; String req = "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"getAccountInfo\",\"params\":[\"" + pdaB58 + "\",{\"encoding\":\"base64\",\"commitment\":\"confirmed\"}]}";
@ -3722,6 +3728,7 @@ static bool readShineUserPda(const String &login, ShinePdaUserState &outState, S
errorOut = "Solana RPC unavailable"; errorOut = "Solana RPC unavailable";
return false; return false;
} }
Serial.println(String("READ_PDA_RPC_DONE_CODE: ") + String(code));
if (payload.indexOf("\"value\":null") >= 0) { if (payload.indexOf("\"value\":null") >= 0) {
outState.found = false; outState.found = false;
return true; return true;
@ -3777,6 +3784,10 @@ static void refreshAccountPdaStatus() {
return; return;
} }
gCachedAccountPdaState = pdaState;
gCachedAccountPdaLogin = normalizeLoginValue(gLoginValue);
gCachedAccountPdaValid = true;
uint8_t recoveryPub[32] = {}; uint8_t recoveryPub[32] = {};
uint8_t rootPub[32] = {}; uint8_t rootPub[32] = {};
uint8_t clientPub[32] = {}; uint8_t clientPub[32] = {};
@ -3845,9 +3856,6 @@ static void refreshAccountPdaStatus() {
return; return;
} }
gCachedAccountPdaState = pdaState;
gCachedAccountPdaLogin = normalizeLoginValue(gLoginValue);
gCachedAccountPdaValid = true;
gAccountPdaStatus = ACCOUNT_PDA_OK; gAccountPdaStatus = ACCOUNT_PDA_OK;
gAccountPdaStatusMessage = "ok"; gAccountPdaStatusMessage = "ok";
} }
@ -5691,24 +5699,30 @@ static void actionButtonCb(lv_event_t *event) {
showScreen(SCREEN_HOMESERVER_PDA_CONFIRM); showScreen(SCREEN_HOMESERVER_PDA_CONFIRM);
break; break;
case ACTION_HOMESERVER_PDA_ADD_EXECUTE: { case ACTION_HOMESERVER_PDA_ADD_EXECUTE: {
Serial.println("HOMESERVER_ADD_BUTTON_CLICK");
gRegisterTriggerSource = "manual-homeserver-add"; gRegisterTriggerSource = "manual-homeserver-add";
String updateMessage; String updateMessage;
Serial.println("HOMESERVER_ADD_CALL_BEGIN");
if (!updateHomeserverSessionOnSolana(false, updateMessage)) { if (!updateHomeserverSessionOnSolana(false, updateMessage)) {
gHomeserverPdaResultSuccess = false; gHomeserverPdaResultSuccess = false;
gHomeserverPdaResultMessage = updateMessage; gHomeserverPdaResultMessage = updateMessage;
gHomeserverPdaResultDetails = ""; gHomeserverPdaResultDetails = "";
} }
Serial.println(String("HOMESERVER_ADD_CALL_END: ") + updateMessage);
showScreen(SCREEN_HOMESERVER_PDA_RESULT); showScreen(SCREEN_HOMESERVER_PDA_RESULT);
break; break;
} }
case ACTION_HOMESERVER_PDA_FIX_EXECUTE: { case ACTION_HOMESERVER_PDA_FIX_EXECUTE: {
Serial.println("HOMESERVER_FIX_BUTTON_CLICK");
gRegisterTriggerSource = "manual-homeserver-fix"; gRegisterTriggerSource = "manual-homeserver-fix";
String updateMessage; String updateMessage;
Serial.println("HOMESERVER_FIX_CALL_BEGIN");
if (!updateHomeserverSessionOnSolana(true, updateMessage)) { if (!updateHomeserverSessionOnSolana(true, updateMessage)) {
gHomeserverPdaResultSuccess = false; gHomeserverPdaResultSuccess = false;
gHomeserverPdaResultMessage = updateMessage; gHomeserverPdaResultMessage = updateMessage;
gHomeserverPdaResultDetails = ""; gHomeserverPdaResultDetails = "";
} }
Serial.println(String("HOMESERVER_FIX_CALL_END: ") + updateMessage);
showScreen(SCREEN_HOMESERVER_PDA_RESULT); showScreen(SCREEN_HOMESERVER_PDA_RESULT);
break; break;
} }

View File

@ -1,2 +1,2 @@
client.version=1.2.253 client.version=1.2.258
server.version=1.2.238 server.version=1.2.243

View File

@ -0,0 +1,59 @@
# Временная версия `shine_users` с удалением `user_pda`
Статус: `только для тестов регистрации`
Этот файл хранит временную версию логики, которая была нужна для отладки регистрации
пользователей через ESP32. В основной программе `shine_users` удаление PDA **не должно
оставаться**.
## Зачем это нужно
- быстро очищать тестовые user PDA на devnet/localnet;
- сохранять рабочий вариант на случай, если понадобится снова проверять регистрацию
без ручной очистки цепочки;
- не смешивать временную отладочную логику с нормальным контрактом.
## Что было временно добавлено
В devnet-версии программы существовала инструкция:
```text
tag = 5
delete_user_pda_temp
```
Она:
- принимала любой `signer`;
- работала только с валидной `user_pda`;
- проверяла, что PDA действительно относится к `shine_users`;
- очищала данные PDA через `realloc(0, false)`;
- переносила лампорты тестового аккаунта в `DAO_AUTHORITY`.
## Важные ограничения
- это **не** часть нормальной модели `shine_users`;
- в основном контракте этой инструкции быть не должно;
- файл нужен только как архив для регрессионных тестов регистрации.
## Фрагмент логики
```rust
// Временная инструкция для ручной чистки тестовых user PDA на devnet/localnet.
// Любой signer мог удалить запись, но лампорты возвращались только в тестовый treasury.
//
// Порядок был таким:
// 1. найти и проверить user PDA;
// 2. обнулить data через realloc(0, false);
// 3. перенести лампорты в DAO_AUTHORITY;
// 4. завершить инструкцию.
```
## Что помнить при возврате этой фичи
Если временное удаление снова понадобится:
1. сначала отдельным патчем включить его в `shine_users`;
2. потом отдельно задеплоить в devnet;
3. после проверки удалить из основной программы снова.