From bead78b372dfb83da8385652f384830051b118c84353ca976df9c71cdf0a9ff5 Mon Sep 17 00:00:00 2001 From: AidarKC Date: Wed, 24 Dec 2025 17:29:50 +0300 Subject: [PATCH] =?UTF-8?q?24=2012=2025=20=D0=94=D0=BE=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=B0=D1=82=D1=8B=D0=B2=D0=B0=D1=8E=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B1=D0=BB=D0=BE=D0=BA?= =?UTF-8?q?=D0=BE=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/blockchain/BchBlockEntry.java | 13 ++ .../handlers/blockchain/BlockchainWriter.java | 22 +-- .../blockchain/Net_AddBlock_Handler.java | 10 +- .../server/logic/InboundMessageProcessor.java | 6 +- .../handlers/GetLastBlockInfoHandler.java | 132 +++++++++--------- .../binary/handlers/SearchUsersHandler.java | 118 ++++++++-------- 6 files changed, 156 insertions(+), 145 deletions(-) diff --git a/shine-server-blockchain/src/main/java/blockchain/BchBlockEntry.java b/shine-server-blockchain/src/main/java/blockchain/BchBlockEntry.java index 2f489ad..f624691 100644 --- a/shine-server-blockchain/src/main/java/blockchain/BchBlockEntry.java +++ b/shine-server-blockchain/src/main/java/blockchain/BchBlockEntry.java @@ -1,5 +1,8 @@ package blockchain; +import blockchain.body.BodyRecord; +import blockchain.body.BodyRecordParser; + import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Arrays; @@ -36,6 +39,9 @@ public final class BchBlockEntry { public final int lineNumber; public final byte[] bodyBytes; + /** Распарсенное тело (создаётся сразу при парсинге блока). */ + public final BodyRecord body; + // --- TAIL --- private final byte[] signature64; private final byte[] hash32; @@ -70,6 +76,9 @@ public final class BchBlockEntry { this.bodyBytes = new byte[bodyLen]; bb.get(this.bodyBytes); + // ✅ Сразу парсим BodyRecord (и если неизвестный type/version — тут же упадём) + this.body = BodyRecordParser.parse(this.bodyBytes); + this.signature64 = new byte[SIGNATURE_LEN]; bb.get(this.signature64); @@ -105,6 +114,10 @@ public final class BchBlockEntry { this.lineIndex = lineIndex; this.lineNumber = lineNumber; this.bodyBytes = Arrays.copyOf(bodyBytes, bodyBytes.length); + + // ✅ И при сборке — тоже сразу парсим body (чтобы объект был цельным) + this.body = BodyRecordParser.parse(this.bodyBytes); + this.signature64 = Arrays.copyOf(signature64, SIGNATURE_LEN); this.hash32 = Arrays.copyOf(hash32, HASH_LEN); diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/BlockchainWriter.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/BlockchainWriter.java index 905f04f..b97ca0b 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/BlockchainWriter.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/BlockchainWriter.java @@ -1,5 +1,6 @@ package server.logic.ws_protocol.JSON.handlers.blockchain; +import blockchain.BchBlockEntry; import shine.db.SqliteDbController; import shine.db.dao.BlockchainStateDAO; import shine.db.dao.BlocksDAO; @@ -31,9 +32,8 @@ public final class BlockchainWriter { public void appendBlockAndState( String login, String blockchainName, - int globalNumber, String prevGlobalHashHex, - byte[] blockBytes, + BchBlockEntry block, BlockchainStateEntry stOrNull, String newHashHex ) throws SQLException { @@ -45,10 +45,10 @@ public final class BlockchainWriter { try { // 1) блок - insertBlockRow(c, login, blockchainName, globalNumber, prevGlobalHashHex, blockBytes); + insertBlockRow(c, login, blockchainName, prevGlobalHashHex, block); // 2) state - appendState(c, blockchainName, globalNumber, stOrNull, newHashHex); + appendState(c, blockchainName, block.recordNumber, stOrNull, newHashHex); // 3) commit c.commit(); @@ -105,9 +105,8 @@ public final class BlockchainWriter { Connection c, String login, String blockchainName, - int globalNumber, String prevGlobalHashHex, - byte[] blockBytes + BchBlockEntry block ) throws SQLException { BlockEntry e = new BlockEntry(); @@ -117,19 +116,20 @@ public final class BlockchainWriter { e.setBchName(blockchainName); // Глобальная нумерация - e.setBlockGlobalNumber(globalNumber); + e.setBlockGlobalNumber(block.recordNumber); e.setBlockGlobalPreHashe(prevGlobalHashHex); // Линии пока не используются: lineIndex=0, lineNumber=globalNumber e.setBlockLineIndex(0); - e.setBlockLineNumber(globalNumber); + e.setBlockLineNumber(block.recordNumber); e.setBlockLinePreHashe(prevGlobalHashHex); // msgType у тебя пока 0 (при желании позже можно ставить по Body/type) - e.setMsgType(0); + // ✅ Теперь сохраняем тип блока + e.setMsgType(block.body.type()); // Сырые байты полного блока - e.setBlockByte(blockBytes); + e.setBlockByte(block.toBytes()); // Поля "кому" (для сообщений/трансферов) пока пустые e.setToLogin(null); @@ -140,4 +140,4 @@ public final class BlockchainWriter { // UPSERT блока blocksDAO.upsert(c, e); } -} +} \ No newline at end of file diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/Net_AddBlock_Handler.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/Net_AddBlock_Handler.java index f54fb8b..920134c 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/Net_AddBlock_Handler.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/Net_AddBlock_Handler.java @@ -2,7 +2,6 @@ package server.logic.ws_protocol.JSON.handlers.blockchain; import blockchain.BchBlockEntry; import blockchain.BchCryptoVerifier; -import blockchain.body.BodyRecordParser; 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; @@ -124,9 +123,9 @@ public final class Net_AddBlock_Handler implements JsonMessageHandler { return new AddBlockResult(WireCodes.Status.BAD_REQUEST, "bad_block_format", 0, ""); } - // 5) Парсим и валидируем body (type/version + содержимое) + // 5) Валидируем body (type/version + содержимое) — теперь body уже распарсен внутри BchBlockEntry try { - BodyRecordParser.parse(block.bodyBytes).check(); + block.body.check(); } catch (Exception e) { return new AddBlockResult(WireCodes.Status.BAD_REQUEST, "bad_block_body", 0, ""); } @@ -221,9 +220,8 @@ public final class Net_AddBlock_Handler implements JsonMessageHandler { dbWriter.appendBlockAndState( login, blockchainName, - globalNumber, nn(prevGlobalHashHex), - blockBytes, + block, // ✅ передаём целиком объект блока st, newHashHex ); @@ -303,4 +301,4 @@ public final class Net_AddBlock_Handler implements JsonMessageHandler { } return new String(out); } -} +} \ No newline at end of file diff --git a/src/main/java/server/logic/InboundMessageProcessor.java b/src/main/java/server/logic/InboundMessageProcessor.java index be2e404..9d956a9 100644 --- a/src/main/java/server/logic/InboundMessageProcessor.java +++ b/src/main/java/server/logic/InboundMessageProcessor.java @@ -20,9 +20,9 @@ public final class InboundMessageProcessor { private static final Map HANDLERS = Map.of( WireCodes.Op.PING, new PingHandler(), // WireCodes.Op.ADD_BLOCK, new AddBlockHandler(), - WireCodes.Op.GET_BLOCKCHAIN,new GetBlockchainHandler(), - WireCodes.Op.SEARCH_USERS, new SearchUsersHandler(), - WireCodes.Op.GET_LAST_BLOCK_INFO,new GetLastBlockInfoHandler() + WireCodes.Op.GET_BLOCKCHAIN,new GetBlockchainHandler() +// WireCodes.Op.SEARCH_USERS, new SearchUsersHandler(), +// WireCodes.Op.GET_LAST_BLOCK_INFO,new GetLastBlockInfoHandler() ); diff --git a/src/main/java/server/logic/ws_protocol/binary/handlers/GetLastBlockInfoHandler.java b/src/main/java/server/logic/ws_protocol/binary/handlers/GetLastBlockInfoHandler.java index aff0e34..7657aa5 100644 --- a/src/main/java/server/logic/ws_protocol/binary/handlers/GetLastBlockInfoHandler.java +++ b/src/main/java/server/logic/ws_protocol/binary/handlers/GetLastBlockInfoHandler.java @@ -1,66 +1,66 @@ -package server.logic.ws_protocol.binary.handlers; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import server.logic.ws_protocol.WireCodes; -import utils.blockchain.BchInfoEntry; -import utils.blockchain.BchInfoManager; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.Arrays; - -/** - * Возврат информации о последнем блоке цепочки (GET_LAST_BLOCK_INFO). - */ -public class GetLastBlockInfoHandler implements MessageHandler { - private static final Logger log = LoggerFactory.getLogger(GetLastBlockInfoHandler.class); - - @Override - public byte[] handle(byte[] msg) { - try { - if (msg.length < 12) - return intTo4Bytes(WireCodes.Status.BAD_REQUEST); - - long blockchainId = ByteBuffer.wrap(msg, 4, 8) - .order(ByteOrder.BIG_ENDIAN) - .getLong(); - - BchInfoManager mgr = BchInfoManager.getInstance(); - BchInfoEntry entry = mgr.getBchInfo(blockchainId); - if (entry == null) - return intTo4Bytes(WireCodes.Status.CHAIN_NOT_FOUND); - - int lastNum = entry.lastBlockNumber; - byte[] hash = hexToBytes(entry.lastBlockHash); - - ByteBuffer out = ByteBuffer.allocate(4 + 4 + 32).order(ByteOrder.BIG_ENDIAN); - out.putInt(WireCodes.Status.OK); - out.putInt(lastNum); - out.put(hash); - return out.array(); - - } catch (Exception e) { - log.error("GET_LAST_BLOCK_INFO: ошибка", e); - return intTo4Bytes(WireCodes.Status.INTERNAL_ERROR); - } - } - - private static byte[] intTo4Bytes(int code) { - return ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(code).array(); - } - - private static byte[] hexToBytes(String hex) { - if (hex == null || hex.isEmpty()) return new byte[32]; - int len = hex.length(); - byte[] out = new byte[len / 2]; - for (int i = 0; i < len; i += 2) - out[i / 2] = (byte) Integer.parseInt(hex.substring(i, i + 2), 16); - if (out.length < 32) { // добиваем нулями - byte[] full = new byte[32]; - System.arraycopy(out, 0, full, 32 - out.length, out.length); - return full; - } - return Arrays.copyOf(out, 32); - } -} +//package server.logic.ws_protocol.binary.handlers; +// +//import org.slf4j.Logger; +//import org.slf4j.LoggerFactory; +//import server.logic.ws_protocol.WireCodes; +//import utils.blockchain.BchInfoEntry; +//import utils.blockchain.BchInfoManager; +// +//import java.nio.ByteBuffer; +//import java.nio.ByteOrder; +//import java.util.Arrays; +// +///** +// * Возврат информации о последнем блоке цепочки (GET_LAST_BLOCK_INFO). +// */ +//public class GetLastBlockInfoHandler implements MessageHandler { +// private static final Logger log = LoggerFactory.getLogger(GetLastBlockInfoHandler.class); +// +// @Override +// public byte[] handle(byte[] msg) { +// try { +// if (msg.length < 12) +// return intTo4Bytes(WireCodes.Status.BAD_REQUEST); +// +// long blockchainId = ByteBuffer.wrap(msg, 4, 8) +// .order(ByteOrder.BIG_ENDIAN) +// .getLong(); +// +// BchInfoManager mgr = BchInfoManager.getInstance(); +// BchInfoEntry entry = mgr.getBchInfo(blockchainId); +// if (entry == null) +// return intTo4Bytes(WireCodes.Status.CHAIN_NOT_FOUND); +// +// int lastNum = entry.lastBlockNumber; +// byte[] hash = hexToBytes(entry.lastBlockHash); +// +// ByteBuffer out = ByteBuffer.allocate(4 + 4 + 32).order(ByteOrder.BIG_ENDIAN); +// out.putInt(WireCodes.Status.OK); +// out.putInt(lastNum); +// out.put(hash); +// return out.array(); +// +// } catch (Exception e) { +// log.error("GET_LAST_BLOCK_INFO: ошибка", e); +// return intTo4Bytes(WireCodes.Status.INTERNAL_ERROR); +// } +// } +// +// private static byte[] intTo4Bytes(int code) { +// return ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(code).array(); +// } +// +// private static byte[] hexToBytes(String hex) { +// if (hex == null || hex.isEmpty()) return new byte[32]; +// int len = hex.length(); +// byte[] out = new byte[len / 2]; +// for (int i = 0; i < len; i += 2) +// out[i / 2] = (byte) Integer.parseInt(hex.substring(i, i + 2), 16); +// if (out.length < 32) { // добиваем нулями +// byte[] full = new byte[32]; +// System.arraycopy(out, 0, full, 32 - out.length, out.length); +// return full; +// } +// return Arrays.copyOf(out, 32); +// } +//} diff --git a/src/main/java/server/logic/ws_protocol/binary/handlers/SearchUsersHandler.java b/src/main/java/server/logic/ws_protocol/binary/handlers/SearchUsersHandler.java index 31b6ef2..514dcb0 100644 --- a/src/main/java/server/logic/ws_protocol/binary/handlers/SearchUsersHandler.java +++ b/src/main/java/server/logic/ws_protocol/binary/handlers/SearchUsersHandler.java @@ -1,59 +1,59 @@ -package server.logic.ws_protocol.binary.handlers; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import server.logic.ws_protocol.WireCodes; -import utils.search.UserSearchService; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.charset.StandardCharsets; -import java.util.List; - -/** - * Поиск пользователей по логину (SEARCH_USERS). - */ -public class SearchUsersHandler implements MessageHandler { - private static final Logger log = LoggerFactory.getLogger(SearchUsersHandler.class); - - @Override - public byte[] handle(byte[] msg) { - try { - if (msg.length < 8) - return intTo4Bytes(WireCodes.Status.BAD_REQUEST); - - int N = ByteBuffer.wrap(msg, 4, 4).order(ByteOrder.BIG_ENDIAN).getInt(); - if (N < 0 || msg.length < 8 + N) - return intTo4Bytes(WireCodes.Status.BAD_REQUEST); - - String query = new String(msg, 8, N, StandardCharsets.UTF_8); - List found = UserSearchService.getInstance().searchFirst5(query); - return pack(found); - - } catch (Exception e) { - log.error("SEARCH_USERS: ошибка", e); - return intTo4Bytes(WireCodes.Status.INTERNAL_ERROR); - } - } - - private static byte[] pack(List pairs) { - if (pairs == null) pairs = List.of(); - int total = 8; - var chunks = new java.util.ArrayList(); - for (var p : pairs) { - byte[] packed = UserSearchService.packPair(p); - chunks.add(packed); - total += packed.length; - } - - ByteBuffer out = ByteBuffer.allocate(total).order(ByteOrder.BIG_ENDIAN); - out.putInt(WireCodes.Status.OK); - out.putInt(pairs.size()); - for (var c : chunks) out.put(c); - return out.array(); - } - - private static byte[] intTo4Bytes(int code) { - return ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(code).array(); - } -} +//package server.logic.ws_protocol.binary.handlers; +// +//import org.slf4j.Logger; +//import org.slf4j.LoggerFactory; +//import server.logic.ws_protocol.WireCodes; +//import utils.search.UserSearchService; +// +//import java.nio.ByteBuffer; +//import java.nio.ByteOrder; +//import java.nio.charset.StandardCharsets; +//import java.util.List; +// +///** +// * Поиск пользователей по логину (SEARCH_USERS). +// */ +//public class SearchUsersHandler implements MessageHandler { +// private static final Logger log = LoggerFactory.getLogger(SearchUsersHandler.class); +// +// @Override +// public byte[] handle(byte[] msg) { +// try { +// if (msg.length < 8) +// return intTo4Bytes(WireCodes.Status.BAD_REQUEST); +// +// int N = ByteBuffer.wrap(msg, 4, 4).order(ByteOrder.BIG_ENDIAN).getInt(); +// if (N < 0 || msg.length < 8 + N) +// return intTo4Bytes(WireCodes.Status.BAD_REQUEST); +// +// String query = new String(msg, 8, N, StandardCharsets.UTF_8); +// List found = UserSearchService.getInstance().searchFirst5(query); +// return pack(found); +// +// } catch (Exception e) { +// log.error("SEARCH_USERS: ошибка", e); +// return intTo4Bytes(WireCodes.Status.INTERNAL_ERROR); +// } +// } +// +// private static byte[] pack(List pairs) { +// if (pairs == null) pairs = List.of(); +// int total = 8; +// var chunks = new java.util.ArrayList(); +// for (var p : pairs) { +// byte[] packed = UserSearchService.packPair(p); +// chunks.add(packed); +// total += packed.length; +// } +// +// ByteBuffer out = ByteBuffer.allocate(total).order(ByteOrder.BIG_ENDIAN); +// out.putInt(WireCodes.Status.OK); +// out.putInt(pairs.size()); +// for (var c : chunks) out.put(c); +// return out.array(); +// } +// +// private static byte[] intTo4Bytes(int code) { +// return ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(code).array(); +// } +//}