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 80aab46..a2ee65b 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 @@ -271,6 +271,11 @@ static String gLastRegisterDiagStatus = "none"; static String gLastRegisterDiagSummary; static String gLastRegisterDiagDetails; static String gLastRegisterDiagTime; +static String gRegisterTriggerSource = "manual"; +static unsigned long gBootMillis = 0; +static bool gAutoRegisterTestArmed = true; +static bool gAutoRegisterTestStarted = false; +static bool gAutoRegisterTestFinished = false; static String gSerialCommandBuffer; static String gShineSessionId; static String gShineSessionKey; @@ -423,6 +428,7 @@ 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 executeRegisterAccountFlow(const char *triggerSource, bool showResultScreen); static void loadRegisterDiagDetailsFromPrefs(); static void saveRegisterDiagDetailsToPrefs(const String &details); static void clearRegisterDiagDetailsFromPrefs(); @@ -668,6 +674,18 @@ static String bytesToBase64String(const uint8_t *data, size_t len) { return base64Std(data, len); } +static String bytesToHexString(const uint8_t *data, size_t len) { + static const char *kHex = "0123456789abcdef"; + String out; + out.reserve(len * 2); + for (size_t i = 0; i < len; ++i) { + uint8_t v = data[i]; + out += kHex[(v >> 4) & 0x0F]; + out += kHex[v & 0x0F]; + } + return out; +} + static String normalizeLoginValue(const String &value) { String out = value; out.trim(); @@ -1212,7 +1230,7 @@ static std::vector buildUnsignedCreateRecord( out.push_back(kBlockTypeServerProfile); out.push_back(0); out.push_back(1); - out.push_back(1); + out.push_back(0); out.push_back(0); pushStrU8(out, serverAddress); out.push_back(0); @@ -1525,11 +1543,11 @@ static std::vector buildLegacyMessage( accountKeys.emplace_back(userPda, userPda + 32); accountKeys.emplace_back(inflowVault, inflowVault + 32); accountKeys.emplace_back(systemProgram, systemProgram + 32); - accountKeys.emplace_back(sysvarInstructions, sysvarInstructions + 32); - accountKeys.emplace_back(economyConfig, economyConfig + 32); accountKeys.emplace_back(loginGuardProgram, loginGuardProgram + 32); + accountKeys.emplace_back(economyConfig, economyConfig + 32); accountKeys.emplace_back(ed25519Program, ed25519Program + 32); accountKeys.emplace_back(usersProgram, usersProgram + 32); + accountKeys.emplace_back(sysvarInstructions, sysvarInstructions + 32); std::vector msg; msg.reserve(512); @@ -1543,25 +1561,25 @@ static std::vector buildLegacyMessage( msg.insert(msg.end(), recentBlockhash, recentBlockhash + 32); shortVecEncode(3, msg); - msg.push_back(7); + msg.push_back(6); msg.push_back(0); shortVecEncode(edRootData.size(), msg); msg.insert(msg.end(), edRootData.begin(), edRootData.end()); - msg.push_back(7); + msg.push_back(6); msg.push_back(0); shortVecEncode(edBchData.size(), msg); msg.insert(msg.end(), edBchData.begin(), edBchData.end()); - msg.push_back(8); + msg.push_back(7); msg.push_back(7); msg.push_back(0); msg.push_back(1); msg.push_back(3); msg.push_back(2); - msg.push_back(4); + msg.push_back(8); msg.push_back(5); - msg.push_back(6); + msg.push_back(4); shortVecEncode(createData.size(), msg); msg.insert(msg.end(), createData.begin(), createData.end()); return msg; @@ -1613,6 +1631,9 @@ static bool registerHomeserverOnSolana(String &messageOut) { }; String cleanLogin = normalizeLoginValue(gLoginValue); + diagDetails += String("trigger=") + gRegisterTriggerSource + "\n"; + diagDetails += String("boot_millis=") + String(gBootMillis) + "\n"; + diagDetails += String("test_uptime_ms=") + String(millis()) + "\n"; diagDetails += String("login=") + cleanLogin + "\n"; diagDetails += String("rpc=") + gSolanaRpcUrl + "\n"; diagDetails += String("shine_server=") + gShineServerUrl + "\n"; @@ -1724,6 +1745,7 @@ static bool registerHomeserverOnSolana(String &messageOut) { diagDetails += String("device_pub=") + bytesToBase58(devicePub, 32) + "\n"; String blockchainName = cleanLogin + "-001"; + diagDetails += String("blockchain_name=") + blockchainName + "\n"; std::vector lastBlockState = buildLastBlockStateBytes(cleanLogin, blockchainName); uint8_t lastBlockHash[32]; uint8_t lastBlockSignature[64]; @@ -1731,8 +1753,11 @@ static bool registerHomeserverOnSolana(String &messageOut) { if (!signMessageEd25519(std::vector(lastBlockHash, lastBlockHash + 32), blockchainSec, lastBlockSignature)) { return failWithDiag("Failed to sign LastBlockState"); } + diagDetails += String("last_block_hash=") + bytesToHexString(lastBlockHash, 32) + "\n"; + diagDetails += String("last_block_signature_b64=") + bytesToBase64String(lastBlockSignature, 64) + "\n"; uint64_t createdAtMs = shineNowMs(); + diagDetails += String("created_at_ms=") + String((unsigned long long)createdAtMs) + "\n"; std::vector unsignedRecord = buildUnsignedCreateRecord( cleanLogin, blockchainName, gShineServerUrl, rootPub, devicePub, blockchainPub, @@ -1743,6 +1768,9 @@ static bool registerHomeserverOnSolana(String &messageOut) { if (!signMessageEd25519(std::vector(unsignedHash, unsignedHash + 32), rootSec, rootSignature)) { return failWithDiag("Failed to sign PDA record"); } + diagDetails += String("unsigned_record_len=") + String((unsigned long)unsignedRecord.size()) + "\n"; + diagDetails += String("unsigned_record_hash=") + bytesToHexString(unsignedHash, 32) + "\n"; + diagDetails += String("root_signature_b64=") + bytesToBase64String(rootSignature, 64) + "\n"; std::vector createData = buildCreateInstructionData( cleanLogin, blockchainName, gShineServerUrl, @@ -1824,6 +1852,31 @@ static bool registerHomeserverOnSolana(String &messageOut) { return true; } +static void executeRegisterAccountFlow(const char *triggerSource, bool showResultScreen) { + gRegisterTriggerSource = triggerSource ? String(triggerSource) : String("manual"); + prepareRegisterAccountScreen(); + String registerMessage; + if (registerHomeserverOnSolana(registerMessage)) { + gRegisterResultSuccess = true; + gRegisterResultMessage = registerMessage; + gRegisterResultDetails = String("user_pda and tx signature were saved"); + gAccountStatusMessage = "Registration completed"; + } else { + gRegisterResultSuccess = false; + gRegisterResultMessage = registerMessage; + gRegisterResultDetails = ""; + gAccountStatusMessage = registerMessage; + } + gRegisterConfirmMessage = ""; + gRegisterConfirmBalanceLine = ""; + gRegisterConfirmPdaLine = ""; + gRegisterConfirmHomeserverLine = ""; + gRegisterConfirmCanSubmit = false; + if (showResultScreen) { + showScreen(SCREEN_REGISTER_ACCOUNT_RESULT); + } +} + static void prepareRegisterAccountScreen() { gRegisterResultMessage = ""; gRegisterResultDetails = ""; @@ -2884,7 +2937,7 @@ static void loadRegisterDiagDetailsFromPrefs() { static void saveRegisterDiagDetailsToPrefs(const String &details) { const int chunkSize = 1400; - const int maxChunks = 12; + const int maxChunks = 20; gPrefs.remove("reg_diag_details"); for (int i = 0; i < maxChunks; ++i) { String key = String("rdd") + i; @@ -2916,7 +2969,7 @@ static void saveRegisterDiagDetailsToPrefs(const String &details) { static void clearRegisterDiagDetailsFromPrefs() { gPrefs.remove("reg_diag_details"); gPrefs.remove("rddn"); - for (int i = 0; i < 12; ++i) { + for (int i = 0; i < 20; ++i) { String key = String("rdd") + i; gPrefs.remove(key.c_str()); } @@ -3478,27 +3531,9 @@ static void actionButtonCb(lv_event_t *event) { prepareRegisterAccountScreen(); showScreen(SCREEN_REGISTER_ACCOUNT_CONFIRM); break; - case ACTION_REGISTER_ACCOUNT_EXECUTE: { - String registerMessage; - if (registerHomeserverOnSolana(registerMessage)) { - gRegisterResultSuccess = true; - gRegisterResultMessage = registerMessage; - gRegisterResultDetails = String("user_pda and tx signature were saved"); - gAccountStatusMessage = "Registration completed"; - } else { - gRegisterResultSuccess = false; - gRegisterResultMessage = registerMessage; - gRegisterResultDetails = ""; - gAccountStatusMessage = registerMessage; - } - gRegisterConfirmMessage = ""; - gRegisterConfirmBalanceLine = ""; - gRegisterConfirmPdaLine = ""; - gRegisterConfirmHomeserverLine = ""; - gRegisterConfirmCanSubmit = false; - showScreen(SCREEN_REGISTER_ACCOUNT_RESULT); + case ACTION_REGISTER_ACCOUNT_EXECUTE: + executeRegisterAccountFlow("manual", true); break; - } case ACTION_OPEN_WIFI: gWifiViewMode = WIFI_VIEW_OVERVIEW; showScreen(SCREEN_WIFI); @@ -4376,6 +4411,7 @@ static void handleSwipe(SwipeDirection swipe) { void setup() { Serial.begin(115200); sodium_init(); + gBootMillis = millis(); Wire.begin(PIN_I2C_SDA, PIN_I2C_SCL); initPowerManagement(); @@ -4437,6 +4473,15 @@ void loop() { manageAccountPdaRefresh(); manageShineConnection(); + if (gAutoRegisterTestArmed && !gAutoRegisterTestStarted && millis() - gBootMillis >= 15000UL) { + gAutoRegisterTestStarted = true; + gAutoRegisterTestArmed = false; + Serial.println("AUTO_REGISTER_TEST_BEGIN"); + executeRegisterAccountFlow("auto-boot-15s", false); + gAutoRegisterTestFinished = true; + Serial.println("AUTO_REGISTER_TEST_END"); + } + static unsigned long lastHomeRefreshMs = 0; if (gCurrentScreen == SCREEN_HOME && !gTouchDown && millis() - lastHomeRefreshMs >= HOME_REFRESH_MS) { lastHomeRefreshMs = millis(); diff --git a/VERSION.properties b/VERSION.properties index 44d1b3f..5b5e63c 100644 --- a/VERSION.properties +++ b/VERSION.properties @@ -1,2 +1,2 @@ -client.version=1.2.172 -server.version=1.2.161 +client.version=1.2.175 +server.version=1.2.164