Закомитил промежуточную почти работающую версию ...

This commit is contained in:
AidarKC
2026-04-07 13:57:09 +03:00
parent 4deaedf79f
commit 3016d25f73
43 changed files with 271 additions and 143 deletions
@@ -6,6 +6,7 @@ import blockchain.MsgSubType;
import blockchain.body.BodyHasLine;
import blockchain.body.BodyHasTarget;
import blockchain.body.CreateChannelBody;
import blockchain.body.UserParamBody;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import server.logic.ws_protocol.Base64Ws;
@@ -21,8 +22,10 @@ import server.logic.ws_protocol.JSON.handlers.blockchain.entyties.Net_AddBlock_R
import server.logic.ws_protocol.WireCodes;
import shine.db.dao.BlockchainStateDAO;
import shine.db.dao.BlocksDAO;
import shine.db.dao.UserParamsDAO;
import shine.db.entities.BlockchainStateEntry;
import shine.db.entities.BlockEntry;
import shine.db.entities.UserParamEntry;
import utils.blockchain.BlockchainNameUtil;
import java.util.Arrays;
@@ -45,8 +48,9 @@ public final class Net_AddBlock_Handler implements JsonMessageHandler {
private final BlocksDAO blocksDAO = BlocksDAO.getInstance();
private final BlockchainStateDAO stateDAO = BlockchainStateDAO.getInstance();
private final UserParamsDAO userParamsDAO = UserParamsDAO.getInstance();
private final BlockchainWriter dbWriter = new BlockchainWriter(blocksDAO, stateDAO);
private final BlockchainWriter dbWriter = new BlockchainWriter(blocksDAO, stateDAO, userParamsDAO);
@Override
public Net_Response handle(Net_Request baseReq, ConnectionContext ctx) {
@@ -370,7 +374,22 @@ public final class Net_AddBlock_Handler implements JsonMessageHandler {
be.setEditedByBlockNumber(be.getToBlockNumber());
}
dbWriter.appendBlockAndState(blockchainName, block, st, be);
UserParamEntry upsertedParam = null;
if (block.body instanceof UserParamBody upBody) {
String effectiveLogin = (st.getLogin() != null && !st.getLogin().isBlank())
? st.getLogin()
: login;
upsertedParam = new UserParamEntry(
effectiveLogin,
upBody.paramKey,
block.timestamp * 1000L,
upBody.paramValue,
null,
null
);
}
dbWriter.appendBlockAndState(blockchainName, block, st, be, upsertedParam);
} catch (Exception e) {
log.error("AddBlock: внутренняя ошибка при записи блока (login={}, blockchainName={}, blockNumber={})",
@@ -3,8 +3,10 @@ package server.logic.ws_protocol.JSON.handlers.blockchain.Net_AddBlock_Handler_u
import blockchain.BchBlockEntry;
import shine.db.dao.BlockchainStateDAO;
import shine.db.dao.BlocksDAO;
import shine.db.dao.UserParamsDAO;
import shine.db.entities.BlockchainStateEntry;
import shine.db.entities.BlockEntry;
import shine.db.entities.UserParamEntry;
import utils.files.FileStoreUtil;
import java.sql.Connection;
@@ -21,17 +23,20 @@ public final class BlockchainWriter {
private final BlocksDAO blocksDAO;
private final BlockchainStateDAO stateDAO;
private final UserParamsDAO userParamsDAO;
private final FileStoreUtil fs = FileStoreUtil.getInstance();
public BlockchainWriter(BlocksDAO blocksDAO, BlockchainStateDAO stateDAO) {
public BlockchainWriter(BlocksDAO blocksDAO, BlockchainStateDAO stateDAO, UserParamsDAO userParamsDAO) {
this.blocksDAO = blocksDAO;
this.stateDAO = stateDAO;
this.userParamsDAO = userParamsDAO;
}
public void appendBlockAndState(String blockchainName,
BchBlockEntry block,
BlockchainStateEntry st,
BlockEntry be) throws SQLException {
BlockEntry be,
UserParamEntry userParamEntry) throws SQLException {
long nowMs = System.currentTimeMillis();
@@ -49,6 +54,11 @@ public final class BlockchainWriter {
stateDAO.upsert(c, st);
// 2.1) Если блок — USER_PARAM, синхронизируем снимок в users_params в той же транзакции.
if (userParamEntry != null) {
userParamsDAO.upsertIfNewer(c, userParamEntry);
}
c.commit();
} catch (Exception e) {
try { c.rollback(); } catch (Exception ignored) {}
@@ -64,4 +74,4 @@ public final class BlockchainWriter {
String fileName = fs.buildBlockchainFileName(blockchainName);
fs.addDataToFile(fileName, block.toBytes());
}
}
}
@@ -10,10 +10,13 @@ import server.logic.ws_protocol.JSON.handlers.tempToTest.entyties.Net_GetUser_Re
import server.logic.ws_protocol.JSON.handlers.tempToTest.entyties.Net_GetUser_Response;
import server.logic.ws_protocol.JSON.utils.NetExceptionResponseFactory;
import server.logic.ws_protocol.WireCodes;
import shine.db.dao.BlockchainStateDAO;
import shine.db.dao.SolanaUsersDAO;
import shine.db.entities.BlockchainStateEntry;
import shine.db.entities.SolanaUserEntry;
import java.sql.SQLException;
import java.util.Arrays;
public class Net_GetUser_Handler implements JsonMessageHandler {
@@ -35,6 +38,7 @@ public class Net_GetUser_Handler implements JsonMessageHandler {
}
SolanaUsersDAO usersDAO = SolanaUsersDAO.getInstance();
BlockchainStateDAO stateDAO = BlockchainStateDAO.getInstance();
try {
SolanaUserEntry u = usersDAO.getByLogin(req.getLogin());
@@ -60,6 +64,32 @@ public class Net_GetUser_Handler implements JsonMessageHandler {
resp.setBlockchainKey(u.getBlockchainKey());
resp.setDeviceKey(u.getDeviceKey());
// Возвращаем актуальный курсор блокчейна и, если запись состояния потеряна,
// автоматически восстанавливаем её для существующего пользователя.
BlockchainStateEntry st = stateDAO.getByBlockchainName(u.getBlockchainName());
if (st == null) {
st = new BlockchainStateEntry();
st.setBlockchainName(u.getBlockchainName());
st.setLogin(u.getLogin());
st.setBlockchainKey(u.getBlockchainKey());
st.setLastBlockNumber(-1);
st.setLastBlockHash(new byte[32]);
st.setFileSizeBytes(0);
st.setSizeLimit(1_000_000L);
st.setUpdatedAtMs(System.currentTimeMillis());
stateDAO.upsert(st);
log.warn("GetUser: восстановлена запись blockchain_state для login={}, blockchainName={}",
u.getLogin(), u.getBlockchainName());
}
int lastNum = st.getLastBlockNumber();
byte[] lastHash = st.getLastBlockHash();
if (lastHash == null || lastHash.length != 32) {
lastHash = new byte[32];
}
resp.setServerLastGlobalNumber(lastNum);
resp.setServerLastGlobalHash(toHex32(lastHash));
log.info("✅ GetUser: found login={}, blockchainName={}", u.getLogin(), u.getBlockchainName());
return resp;
@@ -81,4 +111,16 @@ public class Net_GetUser_Handler implements JsonMessageHandler {
);
}
}
private static String toHex32(byte[] bytes32) {
byte[] b = (bytes32 == null) ? new byte[32] : Arrays.copyOf(bytes32, 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);
}
}
@@ -39,6 +39,8 @@ public class Net_GetUser_Response extends Net_Response {
private String solanaKey;
private String blockchainKey;
private String deviceKey;
private Integer serverLastGlobalNumber;
private String serverLastGlobalHash;
public Boolean getExists() { return exists; }
public void setExists(Boolean exists) { this.exists = exists; }
@@ -57,4 +59,10 @@ public class Net_GetUser_Response extends Net_Response {
public String getDeviceKey() { return deviceKey; }
public void setDeviceKey(String deviceKey) { this.deviceKey = deviceKey; }
}
public Integer getServerLastGlobalNumber() { return serverLastGlobalNumber; }
public void setServerLastGlobalNumber(Integer serverLastGlobalNumber) { this.serverLastGlobalNumber = serverLastGlobalNumber; }
public String getServerLastGlobalHash() { return serverLastGlobalHash; }
public void setServerLastGlobalHash(String serverLastGlobalHash) { this.serverLastGlobalHash = serverLastGlobalHash; }
}