SHA256
Добавить ListBlockchainHeads для межсерверной сверки
This commit is contained in:
@@ -4,6 +4,8 @@ import shine.db.SqliteDbController;
|
||||
import shine.db.entities.BlockchainStateEntry;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class BlockchainStateDAO {
|
||||
|
||||
@@ -53,6 +55,39 @@ public final class BlockchainStateDAO {
|
||||
}
|
||||
}
|
||||
|
||||
/** Получить все blockchain_state записи. */
|
||||
public List<BlockchainStateEntry> listAll() throws SQLException {
|
||||
try (Connection c = db.getConnection()) {
|
||||
return listAll(c);
|
||||
}
|
||||
}
|
||||
|
||||
/** Получить все blockchain_state записи с внешним соединением. Соединение НЕ закрывает. */
|
||||
public List<BlockchainStateEntry> listAll(Connection c) throws SQLException {
|
||||
String sql = """
|
||||
SELECT
|
||||
blockchain_name,
|
||||
login,
|
||||
blockchain_key,
|
||||
size_limit,
|
||||
file_size_bytes,
|
||||
last_block_number,
|
||||
last_block_hash,
|
||||
updated_at_ms
|
||||
FROM blockchain_state
|
||||
ORDER BY blockchain_name COLLATE NOCASE
|
||||
""";
|
||||
|
||||
List<BlockchainStateEntry> result = new ArrayList<>();
|
||||
try (PreparedStatement ps = c.prepareStatement(sql);
|
||||
ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
result.add(mapRow(rs));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** UPSERT без внешнего соединения. Сам открывает/закрывает. */
|
||||
public void upsert(BlockchainStateEntry e) throws SQLException {
|
||||
try (Connection c = db.getConnection()) {
|
||||
@@ -150,4 +185,4 @@ public final class BlockchainStateDAO {
|
||||
}
|
||||
|
||||
private static String nn(String s) { return s == null ? "" : s; }
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -106,6 +106,7 @@ import server.logic.ws_protocol.JSON.handlers.system.Net_GetServerInfo_Handler;
|
||||
import server.logic.ws_protocol.JSON.handlers.system.Net_GetCallIceConfig_Handler;
|
||||
import server.logic.ws_protocol.JSON.handlers.system.Net_ClientErrorLog_Handler;
|
||||
import server.logic.ws_protocol.JSON.handlers.system.Net_ClientDebugLog_Handler;
|
||||
import server.logic.ws_protocol.JSON.handlers.system.Net_ListBlockchainHeads_Handler;
|
||||
import server.logic.ws_protocol.JSON.handlers.system.Net_CallDeliveryReport_Handler;
|
||||
import server.logic.ws_protocol.JSON.handlers.system.Net_Ping_Handler;
|
||||
import server.logic.ws_protocol.JSON.handlers.system.entyties.Net_CallDeliveryReport_Request;
|
||||
@@ -113,6 +114,7 @@ import server.logic.ws_protocol.JSON.handlers.system.entyties.Net_ClientErrorLog
|
||||
import server.logic.ws_protocol.JSON.handlers.system.entyties.Net_ClientDebugLog_Request;
|
||||
import server.logic.ws_protocol.JSON.handlers.system.entyties.Net_GetCallIceConfig_Request;
|
||||
import server.logic.ws_protocol.JSON.handlers.system.entyties.Net_GetServerInfo_Request;
|
||||
import server.logic.ws_protocol.JSON.handlers.system.entyties.Net_ListBlockchainHeads_Request;
|
||||
import server.logic.ws_protocol.JSON.handlers.system.entyties.Net_Ping_Request;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -193,6 +195,7 @@ public final class JsonHandlerRegistry {
|
||||
// --- system ---
|
||||
Map.entry("Ping", new Net_Ping_Handler()),
|
||||
Map.entry("GetServerInfo", new Net_GetServerInfo_Handler()),
|
||||
Map.entry("ListBlockchainHeads", new Net_ListBlockchainHeads_Handler()),
|
||||
Map.entry("GetCallIceConfig", new Net_GetCallIceConfig_Handler()),
|
||||
Map.entry("ClientErrorLog", new Net_ClientErrorLog_Handler()),
|
||||
Map.entry("ClientDebugLog", new Net_ClientDebugLog_Handler()),
|
||||
@@ -268,6 +271,7 @@ public final class JsonHandlerRegistry {
|
||||
// --- system ---
|
||||
Map.entry("Ping", Net_Ping_Request.class),
|
||||
Map.entry("GetServerInfo", Net_GetServerInfo_Request.class),
|
||||
Map.entry("ListBlockchainHeads", Net_ListBlockchainHeads_Request.class),
|
||||
Map.entry("GetCallIceConfig", Net_GetCallIceConfig_Request.class),
|
||||
Map.entry("ClientErrorLog", Net_ClientErrorLog_Request.class),
|
||||
Map.entry("ClientDebugLog", Net_ClientDebugLog_Request.class),
|
||||
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package server.logic.ws_protocol.JSON.handlers.system;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import server.logic.ws_protocol.JSON.ConnectionContext;
|
||||
import server.logic.ws_protocol.JSON.entyties.Net_Request;
|
||||
import server.logic.ws_protocol.JSON.entyties.Net_Response;
|
||||
import server.logic.ws_protocol.JSON.handlers.JsonMessageHandler;
|
||||
import server.logic.ws_protocol.JSON.handlers.system.entyties.Net_ListBlockchainHeads_Request;
|
||||
import server.logic.ws_protocol.JSON.handlers.system.entyties.Net_ListBlockchainHeads_Response;
|
||||
import server.logic.ws_protocol.JSON.utils.NetExceptionResponseFactory;
|
||||
import server.logic.ws_protocol.WireCodes;
|
||||
import shine.db.dao.BlockchainStateDAO;
|
||||
import shine.db.entities.BlockchainStateEntry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ListBlockchainHeads — получить краткую сводку по всем blockchain_state.
|
||||
* Используется для межсерверной сверки heads перед догоняющей синхронизацией.
|
||||
*/
|
||||
public class Net_ListBlockchainHeads_Handler implements JsonMessageHandler {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(Net_ListBlockchainHeads_Handler.class);
|
||||
|
||||
@Override
|
||||
public Net_Response handle(Net_Request baseRequest, ConnectionContext ctx) {
|
||||
Net_ListBlockchainHeads_Request req = (Net_ListBlockchainHeads_Request) baseRequest;
|
||||
|
||||
try {
|
||||
List<BlockchainStateEntry> states = BlockchainStateDAO.getInstance().listAll();
|
||||
|
||||
Net_ListBlockchainHeads_Response resp = new Net_ListBlockchainHeads_Response();
|
||||
resp.setOp(req.getOp());
|
||||
resp.setRequestId(req.getRequestId());
|
||||
resp.setStatus(WireCodes.Status.OK);
|
||||
|
||||
List<Net_ListBlockchainHeads_Response.Item> items = new ArrayList<>(states.size());
|
||||
for (BlockchainStateEntry state : states) {
|
||||
Net_ListBlockchainHeads_Response.Item item = new Net_ListBlockchainHeads_Response.Item();
|
||||
item.setBlockchainName(state.getBlockchainName());
|
||||
item.setLastBlockNumber(state.getLastBlockNumber());
|
||||
item.setLastBlockHash(toHex32(state.getLastBlockHash()));
|
||||
item.setFileSizeBytes(state.getFileSizeBytes());
|
||||
items.add(item);
|
||||
}
|
||||
resp.setBlockchains(items);
|
||||
|
||||
return resp;
|
||||
} catch (Exception e) {
|
||||
log.error("❌ Internal error ListBlockchainHeads", e);
|
||||
return NetExceptionResponseFactory.error(
|
||||
req,
|
||||
WireCodes.Status.INTERNAL_ERROR,
|
||||
"INTERNAL_ERROR",
|
||||
NetExceptionResponseFactory.detailedMessage("Внутренняя ошибка сервера при ListBlockchainHeads", e)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static String toHex32(byte[] bytes32) {
|
||||
byte[] b = bytes32;
|
||||
if (b == null || b.length != 32) {
|
||||
b = new byte[32];
|
||||
}
|
||||
final char[] hex = "0123456789abcdef".toCharArray();
|
||||
char[] out = new char[64];
|
||||
for (int i = 0; i < 32; i++) {
|
||||
int v = b[i] & 0xFF;
|
||||
out[i * 2] = hex[v >>> 4];
|
||||
out[i * 2 + 1] = hex[v & 0x0F];
|
||||
}
|
||||
return new String(out);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package server.logic.ws_protocol.JSON.handlers.system.entyties;
|
||||
|
||||
import server.logic.ws_protocol.JSON.entyties.Net_Request;
|
||||
|
||||
/**
|
||||
* Пустой запрос для получения списка heads всех blockchain_state.
|
||||
*/
|
||||
public class Net_ListBlockchainHeads_Request extends Net_Request {
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package server.logic.ws_protocol.JSON.handlers.system.entyties;
|
||||
|
||||
import server.logic.ws_protocol.JSON.entyties.Net_Response;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Net_ListBlockchainHeads_Response extends Net_Response {
|
||||
|
||||
public static final class Item {
|
||||
private String blockchainName;
|
||||
private int lastBlockNumber;
|
||||
private String lastBlockHash;
|
||||
private long fileSizeBytes;
|
||||
|
||||
public String getBlockchainName() { return blockchainName; }
|
||||
public void setBlockchainName(String blockchainName) { this.blockchainName = blockchainName; }
|
||||
|
||||
public int getLastBlockNumber() { return lastBlockNumber; }
|
||||
public void setLastBlockNumber(int lastBlockNumber) { this.lastBlockNumber = lastBlockNumber; }
|
||||
|
||||
public String getLastBlockHash() { return lastBlockHash; }
|
||||
public void setLastBlockHash(String lastBlockHash) { this.lastBlockHash = lastBlockHash; }
|
||||
|
||||
public long getFileSizeBytes() { return fileSizeBytes; }
|
||||
public void setFileSizeBytes(long fileSizeBytes) { this.fileSizeBytes = fileSizeBytes; }
|
||||
}
|
||||
|
||||
private List<Item> blockchains = new ArrayList<>();
|
||||
|
||||
public List<Item> getBlockchains() { return blockchains; }
|
||||
public void setBlockchains(List<Item> blockchains) { this.blockchains = blockchains; }
|
||||
}
|
||||
Reference in New Issue
Block a user