ESP32: добавить автотест регистрации и исправить signed server profile
This commit is contained in:
parent
556004a557
commit
19fd5611b2
@ -271,6 +271,11 @@ static String gLastRegisterDiagStatus = "none";
|
|||||||
static String gLastRegisterDiagSummary;
|
static String gLastRegisterDiagSummary;
|
||||||
static String gLastRegisterDiagDetails;
|
static String gLastRegisterDiagDetails;
|
||||||
static String gLastRegisterDiagTime;
|
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 gSerialCommandBuffer;
|
||||||
static String gShineSessionId;
|
static String gShineSessionId;
|
||||||
static String gShineSessionKey;
|
static String gShineSessionKey;
|
||||||
@ -423,6 +428,7 @@ 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 String encodeTransactionBase64(const uint8_t signature[64], const std::vector<uint8_t> &message);
|
||||||
static bool awaitTransactionConfirmation(const String &signatureB58, String &messageOut);
|
static bool awaitTransactionConfirmation(const String &signatureB58, String &messageOut);
|
||||||
static bool registerHomeserverOnSolana(String &messageOut);
|
static bool registerHomeserverOnSolana(String &messageOut);
|
||||||
|
static void executeRegisterAccountFlow(const char *triggerSource, bool showResultScreen);
|
||||||
static void loadRegisterDiagDetailsFromPrefs();
|
static void loadRegisterDiagDetailsFromPrefs();
|
||||||
static void saveRegisterDiagDetailsToPrefs(const String &details);
|
static void saveRegisterDiagDetailsToPrefs(const String &details);
|
||||||
static void clearRegisterDiagDetailsFromPrefs();
|
static void clearRegisterDiagDetailsFromPrefs();
|
||||||
@ -668,6 +674,18 @@ static String bytesToBase64String(const uint8_t *data, size_t len) {
|
|||||||
return base64Std(data, 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) {
|
static String normalizeLoginValue(const String &value) {
|
||||||
String out = value;
|
String out = value;
|
||||||
out.trim();
|
out.trim();
|
||||||
@ -1212,7 +1230,7 @@ static std::vector<uint8_t> buildUnsignedCreateRecord(
|
|||||||
out.push_back(kBlockTypeServerProfile);
|
out.push_back(kBlockTypeServerProfile);
|
||||||
out.push_back(0);
|
out.push_back(0);
|
||||||
out.push_back(1);
|
out.push_back(1);
|
||||||
out.push_back(1);
|
out.push_back(0);
|
||||||
out.push_back(0);
|
out.push_back(0);
|
||||||
pushStrU8(out, serverAddress);
|
pushStrU8(out, serverAddress);
|
||||||
out.push_back(0);
|
out.push_back(0);
|
||||||
@ -1525,11 +1543,11 @@ static std::vector<uint8_t> buildLegacyMessage(
|
|||||||
accountKeys.emplace_back(userPda, userPda + 32);
|
accountKeys.emplace_back(userPda, userPda + 32);
|
||||||
accountKeys.emplace_back(inflowVault, inflowVault + 32);
|
accountKeys.emplace_back(inflowVault, inflowVault + 32);
|
||||||
accountKeys.emplace_back(systemProgram, systemProgram + 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(loginGuardProgram, loginGuardProgram + 32);
|
||||||
|
accountKeys.emplace_back(economyConfig, economyConfig + 32);
|
||||||
accountKeys.emplace_back(ed25519Program, ed25519Program + 32);
|
accountKeys.emplace_back(ed25519Program, ed25519Program + 32);
|
||||||
accountKeys.emplace_back(usersProgram, usersProgram + 32);
|
accountKeys.emplace_back(usersProgram, usersProgram + 32);
|
||||||
|
accountKeys.emplace_back(sysvarInstructions, sysvarInstructions + 32);
|
||||||
|
|
||||||
std::vector<uint8_t> msg;
|
std::vector<uint8_t> msg;
|
||||||
msg.reserve(512);
|
msg.reserve(512);
|
||||||
@ -1543,25 +1561,25 @@ static std::vector<uint8_t> buildLegacyMessage(
|
|||||||
msg.insert(msg.end(), recentBlockhash, recentBlockhash + 32);
|
msg.insert(msg.end(), recentBlockhash, recentBlockhash + 32);
|
||||||
shortVecEncode(3, msg);
|
shortVecEncode(3, msg);
|
||||||
|
|
||||||
msg.push_back(7);
|
msg.push_back(6);
|
||||||
msg.push_back(0);
|
msg.push_back(0);
|
||||||
shortVecEncode(edRootData.size(), msg);
|
shortVecEncode(edRootData.size(), msg);
|
||||||
msg.insert(msg.end(), edRootData.begin(), edRootData.end());
|
msg.insert(msg.end(), edRootData.begin(), edRootData.end());
|
||||||
|
|
||||||
msg.push_back(7);
|
msg.push_back(6);
|
||||||
msg.push_back(0);
|
msg.push_back(0);
|
||||||
shortVecEncode(edBchData.size(), msg);
|
shortVecEncode(edBchData.size(), msg);
|
||||||
msg.insert(msg.end(), edBchData.begin(), edBchData.end());
|
msg.insert(msg.end(), edBchData.begin(), edBchData.end());
|
||||||
|
|
||||||
msg.push_back(8);
|
msg.push_back(7);
|
||||||
msg.push_back(7);
|
msg.push_back(7);
|
||||||
msg.push_back(0);
|
msg.push_back(0);
|
||||||
msg.push_back(1);
|
msg.push_back(1);
|
||||||
msg.push_back(3);
|
msg.push_back(3);
|
||||||
msg.push_back(2);
|
msg.push_back(2);
|
||||||
msg.push_back(4);
|
msg.push_back(8);
|
||||||
msg.push_back(5);
|
msg.push_back(5);
|
||||||
msg.push_back(6);
|
msg.push_back(4);
|
||||||
shortVecEncode(createData.size(), msg);
|
shortVecEncode(createData.size(), msg);
|
||||||
msg.insert(msg.end(), createData.begin(), createData.end());
|
msg.insert(msg.end(), createData.begin(), createData.end());
|
||||||
return msg;
|
return msg;
|
||||||
@ -1613,6 +1631,9 @@ static bool registerHomeserverOnSolana(String &messageOut) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
String cleanLogin = normalizeLoginValue(gLoginValue);
|
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("login=") + cleanLogin + "\n";
|
||||||
diagDetails += String("rpc=") + gSolanaRpcUrl + "\n";
|
diagDetails += String("rpc=") + gSolanaRpcUrl + "\n";
|
||||||
diagDetails += String("shine_server=") + gShineServerUrl + "\n";
|
diagDetails += String("shine_server=") + gShineServerUrl + "\n";
|
||||||
@ -1724,6 +1745,7 @@ static bool registerHomeserverOnSolana(String &messageOut) {
|
|||||||
diagDetails += String("device_pub=") + bytesToBase58(devicePub, 32) + "\n";
|
diagDetails += String("device_pub=") + bytesToBase58(devicePub, 32) + "\n";
|
||||||
|
|
||||||
String blockchainName = cleanLogin + "-001";
|
String blockchainName = cleanLogin + "-001";
|
||||||
|
diagDetails += String("blockchain_name=") + blockchainName + "\n";
|
||||||
std::vector<uint8_t> lastBlockState = buildLastBlockStateBytes(cleanLogin, blockchainName);
|
std::vector<uint8_t> lastBlockState = buildLastBlockStateBytes(cleanLogin, blockchainName);
|
||||||
uint8_t lastBlockHash[32];
|
uint8_t lastBlockHash[32];
|
||||||
uint8_t lastBlockSignature[64];
|
uint8_t lastBlockSignature[64];
|
||||||
@ -1731,8 +1753,11 @@ static bool registerHomeserverOnSolana(String &messageOut) {
|
|||||||
if (!signMessageEd25519(std::vector<uint8_t>(lastBlockHash, lastBlockHash + 32), blockchainSec, lastBlockSignature)) {
|
if (!signMessageEd25519(std::vector<uint8_t>(lastBlockHash, lastBlockHash + 32), blockchainSec, lastBlockSignature)) {
|
||||||
return failWithDiag("Failed to sign LastBlockState");
|
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();
|
uint64_t createdAtMs = shineNowMs();
|
||||||
|
diagDetails += String("created_at_ms=") + String((unsigned long long)createdAtMs) + "\n";
|
||||||
std::vector<uint8_t> unsignedRecord = buildUnsignedCreateRecord(
|
std::vector<uint8_t> unsignedRecord = buildUnsignedCreateRecord(
|
||||||
cleanLogin, blockchainName, gShineServerUrl,
|
cleanLogin, blockchainName, gShineServerUrl,
|
||||||
rootPub, devicePub, blockchainPub,
|
rootPub, devicePub, blockchainPub,
|
||||||
@ -1743,6 +1768,9 @@ static bool registerHomeserverOnSolana(String &messageOut) {
|
|||||||
if (!signMessageEd25519(std::vector<uint8_t>(unsignedHash, unsignedHash + 32), rootSec, rootSignature)) {
|
if (!signMessageEd25519(std::vector<uint8_t>(unsignedHash, unsignedHash + 32), rootSec, rootSignature)) {
|
||||||
return failWithDiag("Failed to sign PDA record");
|
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<uint8_t> createData = buildCreateInstructionData(
|
std::vector<uint8_t> createData = buildCreateInstructionData(
|
||||||
cleanLogin, blockchainName, gShineServerUrl,
|
cleanLogin, blockchainName, gShineServerUrl,
|
||||||
@ -1824,6 +1852,31 @@ static bool registerHomeserverOnSolana(String &messageOut) {
|
|||||||
return true;
|
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() {
|
static void prepareRegisterAccountScreen() {
|
||||||
gRegisterResultMessage = "";
|
gRegisterResultMessage = "";
|
||||||
gRegisterResultDetails = "";
|
gRegisterResultDetails = "";
|
||||||
@ -2884,7 +2937,7 @@ static void loadRegisterDiagDetailsFromPrefs() {
|
|||||||
|
|
||||||
static void saveRegisterDiagDetailsToPrefs(const String &details) {
|
static void saveRegisterDiagDetailsToPrefs(const String &details) {
|
||||||
const int chunkSize = 1400;
|
const int chunkSize = 1400;
|
||||||
const int maxChunks = 12;
|
const int maxChunks = 20;
|
||||||
gPrefs.remove("reg_diag_details");
|
gPrefs.remove("reg_diag_details");
|
||||||
for (int i = 0; i < maxChunks; ++i) {
|
for (int i = 0; i < maxChunks; ++i) {
|
||||||
String key = String("rdd") + i;
|
String key = String("rdd") + i;
|
||||||
@ -2916,7 +2969,7 @@ static void saveRegisterDiagDetailsToPrefs(const String &details) {
|
|||||||
static void clearRegisterDiagDetailsFromPrefs() {
|
static void clearRegisterDiagDetailsFromPrefs() {
|
||||||
gPrefs.remove("reg_diag_details");
|
gPrefs.remove("reg_diag_details");
|
||||||
gPrefs.remove("rddn");
|
gPrefs.remove("rddn");
|
||||||
for (int i = 0; i < 12; ++i) {
|
for (int i = 0; i < 20; ++i) {
|
||||||
String key = String("rdd") + i;
|
String key = String("rdd") + i;
|
||||||
gPrefs.remove(key.c_str());
|
gPrefs.remove(key.c_str());
|
||||||
}
|
}
|
||||||
@ -3478,27 +3531,9 @@ static void actionButtonCb(lv_event_t *event) {
|
|||||||
prepareRegisterAccountScreen();
|
prepareRegisterAccountScreen();
|
||||||
showScreen(SCREEN_REGISTER_ACCOUNT_CONFIRM);
|
showScreen(SCREEN_REGISTER_ACCOUNT_CONFIRM);
|
||||||
break;
|
break;
|
||||||
case ACTION_REGISTER_ACCOUNT_EXECUTE: {
|
case ACTION_REGISTER_ACCOUNT_EXECUTE:
|
||||||
String registerMessage;
|
executeRegisterAccountFlow("manual", true);
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case ACTION_OPEN_WIFI:
|
case ACTION_OPEN_WIFI:
|
||||||
gWifiViewMode = WIFI_VIEW_OVERVIEW;
|
gWifiViewMode = WIFI_VIEW_OVERVIEW;
|
||||||
showScreen(SCREEN_WIFI);
|
showScreen(SCREEN_WIFI);
|
||||||
@ -4376,6 +4411,7 @@ static void handleSwipe(SwipeDirection swipe) {
|
|||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
sodium_init();
|
sodium_init();
|
||||||
|
gBootMillis = millis();
|
||||||
Wire.begin(PIN_I2C_SDA, PIN_I2C_SCL);
|
Wire.begin(PIN_I2C_SDA, PIN_I2C_SCL);
|
||||||
initPowerManagement();
|
initPowerManagement();
|
||||||
|
|
||||||
@ -4437,6 +4473,15 @@ void loop() {
|
|||||||
manageAccountPdaRefresh();
|
manageAccountPdaRefresh();
|
||||||
manageShineConnection();
|
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;
|
static unsigned long lastHomeRefreshMs = 0;
|
||||||
if (gCurrentScreen == SCREEN_HOME && !gTouchDown && millis() - lastHomeRefreshMs >= HOME_REFRESH_MS) {
|
if (gCurrentScreen == SCREEN_HOME && !gTouchDown && millis() - lastHomeRefreshMs >= HOME_REFRESH_MS) {
|
||||||
lastHomeRefreshMs = millis();
|
lastHomeRefreshMs = millis();
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
client.version=1.2.172
|
client.version=1.2.175
|
||||||
server.version=1.2.161
|
server.version=1.2.164
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user