ESP32: исправить ABI регистрации и подробные ошибки RPC
This commit is contained in:
parent
3262ec9b4a
commit
b583a86ade
@ -362,6 +362,9 @@ static bool rpcCallSolana(const char *method, const String ¶msJson, String &
|
||||
static bool rpcResponseHasError(const String &payload);
|
||||
static bool getLatestBlockhashBytes(uint8_t out[32], String &blockhashB58, String &messageOut);
|
||||
static bool pdaAlreadyExists(const String &login, String &pdaAddress, String &messageOut);
|
||||
static bool extractRpcErrorSummary(const String &payload, String &messageOut);
|
||||
static String compactRpcLogs(const String &payload, int maxLines = 3);
|
||||
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(
|
||||
const String &login,
|
||||
@ -1223,6 +1226,7 @@ static std::vector<uint8_t> buildCreateInstructionData(
|
||||
out.push_back(0);
|
||||
out.push_back(1);
|
||||
out.push_back(0);
|
||||
out.push_back(0);
|
||||
pushStrU8(out, serverAddress);
|
||||
out.push_back(0);
|
||||
out.push_back(0);
|
||||
@ -1298,6 +1302,86 @@ static bool pdaAlreadyExists(const String &login, String &pdaAddress, String &me
|
||||
return false;
|
||||
}
|
||||
|
||||
static String compactRpcLogs(const String &payload, int maxLines) {
|
||||
String out;
|
||||
int pos = payload.indexOf("\"logs\"");
|
||||
if (pos < 0) {
|
||||
return "";
|
||||
}
|
||||
int bracket = payload.indexOf('[', pos);
|
||||
if (bracket < 0) {
|
||||
return "";
|
||||
}
|
||||
int i = bracket + 1;
|
||||
int lines = 0;
|
||||
while (i < (int)payload.length() && lines < maxLines) {
|
||||
while (i < (int)payload.length() && payload[i] != '"' && payload[i] != ']') {
|
||||
i++;
|
||||
}
|
||||
if (i >= (int)payload.length() || payload[i] == ']') {
|
||||
break;
|
||||
}
|
||||
String line;
|
||||
bool escape = false;
|
||||
i++;
|
||||
for (; i < (int)payload.length(); ++i) {
|
||||
char ch = payload[i];
|
||||
if (escape) {
|
||||
switch (ch) {
|
||||
case 'n': line += ' '; break;
|
||||
case 'r': break;
|
||||
case 't': line += ' '; break;
|
||||
default: line += ch; break;
|
||||
}
|
||||
escape = false;
|
||||
continue;
|
||||
}
|
||||
if (ch == '\\') {
|
||||
escape = true;
|
||||
continue;
|
||||
}
|
||||
if (ch == '"') {
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
line += ch;
|
||||
}
|
||||
line.trim();
|
||||
if (!line.isEmpty()) {
|
||||
if (!out.isEmpty()) {
|
||||
out += " | ";
|
||||
}
|
||||
out += line;
|
||||
lines++;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static bool extractRpcErrorSummary(const String &payload, String &messageOut) {
|
||||
messageOut = "";
|
||||
String errorMessage;
|
||||
if (jsonStringField(payload, "message", errorMessage) && !errorMessage.isEmpty()) {
|
||||
messageOut = errorMessage;
|
||||
}
|
||||
String logs = compactRpcLogs(payload, 3);
|
||||
if (!logs.isEmpty()) {
|
||||
if (!messageOut.isEmpty()) {
|
||||
messageOut += " | ";
|
||||
}
|
||||
messageOut += logs;
|
||||
}
|
||||
return !messageOut.isEmpty();
|
||||
}
|
||||
|
||||
static bool simulateTransactionForError(const String &txBase64, String &messageOut) {
|
||||
String payload;
|
||||
if (!rpcCallSolana("simulateTransaction", "[\"" + txBase64 + "\",{\"encoding\":\"base64\",\"sigVerify\":true,\"commitment\":\"processed\"}]", payload)) {
|
||||
return false;
|
||||
}
|
||||
return extractRpcErrorSummary(payload, messageOut);
|
||||
}
|
||||
|
||||
static std::vector<uint8_t> buildLegacyMessage(
|
||||
const uint8_t recentBlockhash[32],
|
||||
const uint8_t devicePub[32],
|
||||
@ -1531,7 +1615,17 @@ static bool registerHomeserverOnSolana(String &messageOut) {
|
||||
return false;
|
||||
}
|
||||
if (rpcResponseHasError(payload)) {
|
||||
messageOut = "RPC returned sendTransaction error";
|
||||
if (!extractRpcErrorSummary(payload, messageOut)) {
|
||||
messageOut = "RPC returned sendTransaction error";
|
||||
}
|
||||
String simulated;
|
||||
if (simulateTransactionForError(txBase64, simulated)) {
|
||||
if (messageOut.isEmpty()) {
|
||||
messageOut = simulated;
|
||||
} else if (messageOut.indexOf(simulated) < 0) {
|
||||
messageOut += " | simulate: " + simulated;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (!awaitTransactionConfirmation(signatureB58, messageOut)) {
|
||||
@ -3085,13 +3179,13 @@ static void actionButtonCb(lv_event_t *event) {
|
||||
String registerMessage;
|
||||
if (registerHomeserverOnSolana(registerMessage)) {
|
||||
gRegisterResultSuccess = true;
|
||||
gRegisterResultMessage = "Registration in SHiNE completed";
|
||||
gRegisterResultDetails = registerMessage;
|
||||
gRegisterResultMessage = registerMessage;
|
||||
gRegisterResultDetails = String("user_pda and tx signature were saved");
|
||||
gAccountStatusMessage = "Registration completed";
|
||||
} else {
|
||||
gRegisterResultSuccess = false;
|
||||
gRegisterResultMessage = "Registration failed";
|
||||
gRegisterResultDetails = registerMessage;
|
||||
gRegisterResultMessage = registerMessage;
|
||||
gRegisterResultDetails = "";
|
||||
gAccountStatusMessage = registerMessage;
|
||||
}
|
||||
gRegisterConfirmMessage = "";
|
||||
|
||||
@ -212,7 +212,8 @@
|
||||
Поведение:
|
||||
|
||||
- после успешной регистрации данные `user_pda` и `tx signature` сохраняются в `NVS`;
|
||||
- при ошибке на экране показывается причина отказа.
|
||||
- при ошибке на экране показывается причина отказа;
|
||||
- если ошибку вернул `sendTransaction`, экран старается показать не только общий текст, но и детали `RPC`/preflight/simulate-логов.
|
||||
|
||||
## Экран STATUS
|
||||
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
client.version=1.2.166
|
||||
server.version=1.2.155
|
||||
client.version=1.2.167
|
||||
server.version=1.2.156
|
||||
|
||||
Loading…
Reference in New Issue
Block a user