24 12 25
Дорабатываю добавление блоков. Промежуточный исправления (не работают)
This commit is contained in:
parent
5ecaf67bcb
commit
80ea016687
@ -4,15 +4,11 @@ import server.logic.ws_protocol.JSON.entyties.Net_Request;
|
||||
|
||||
public final class Net_AddBlock_Request extends Net_Request {
|
||||
|
||||
private String login; // обязателен
|
||||
private String blockchainName; // обязателен
|
||||
private int globalNumber; // обязателен
|
||||
private String prevGlobalHash; // HEX(64) или "" для нулевого
|
||||
private String blockBytesB64; // байты FULL-блока (raw+sig+hash) в Base64
|
||||
|
||||
public String getLogin() { return login; }
|
||||
public void setLogin(String login) { this.login = login; }
|
||||
|
||||
public String getBlockchainName() { return blockchainName; }
|
||||
public void setBlockchainName(String blockchainName) { this.blockchainName = blockchainName; }
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ package server.logic.ws_protocol.JSON.handlers.blockchain;
|
||||
|
||||
import blockchain.BchBlockEntry;
|
||||
import blockchain.BchCryptoVerifier;
|
||||
import blockchain.body.BodyRecordParser;
|
||||
import server.logic.ws_protocol.WireCodes;
|
||||
import shine.db.SqliteDbController;
|
||||
import shine.db.dao.BlockchainStateDAO;
|
||||
@ -68,7 +69,6 @@ public final class BlockchainStateService {
|
||||
}
|
||||
|
||||
public AddBlockResult addBlockAtomically(
|
||||
String login,
|
||||
String blockchainName,
|
||||
int globalNumber,
|
||||
String prevGlobalHashHex,
|
||||
@ -84,18 +84,8 @@ public final class BlockchainStateService {
|
||||
if (loginFromBlockchainName == null || loginFromBlockchainName.isBlank())
|
||||
return new AddBlockResult(WireCodes.Status.BAD_REQUEST, "bad_blockchain_name", 0, "");
|
||||
|
||||
|
||||
// todo действительно давай прото брать логин из имени блокчена и не передавать его отдельно в запросе!
|
||||
if (login == null || login.isBlank()) {
|
||||
// раз уж у нас есть loginFromName — можно принимать login пустым,
|
||||
// но ты явно передаёшь login, поэтому пока так:
|
||||
return new AddBlockResult(WireCodes.Status.BAD_REQUEST, "empty_login", 0, "");
|
||||
}
|
||||
|
||||
// (опционально) сверка
|
||||
if (!loginFromBlockchainName.equals(login)) {
|
||||
return new AddBlockResult(WireCodes.Status.BAD_REQUEST, "login_not_match_blockchain_name", 0, "");
|
||||
}
|
||||
String login = loginFromBlockchainName;
|
||||
|
||||
byte[] blockBytes;
|
||||
try {
|
||||
@ -104,13 +94,14 @@ public final class BlockchainStateService {
|
||||
return new AddBlockResult(WireCodes.Status.BAD_REQUEST, "bad_block_base64", 0, "");
|
||||
}
|
||||
|
||||
// todo ну и ещё тут нужно проверить что не только сам формат блока верный, но и запись в этом блоке верная - тоесть что её можно распарсить!
|
||||
|
||||
|
||||
|
||||
// todo ну и ещё тут нужно проверить что не только сам формат блока верный, но и запись в этом блоке верная - тоесть что её можно распарсить!
|
||||
final BchBlockEntry block;
|
||||
try {
|
||||
block = new BchBlockEntry(blockBytes);
|
||||
|
||||
// проверяем, что body распарсится и валидируется
|
||||
BodyRecordParser.parse(block.bodyBytes).check();
|
||||
|
||||
} catch (Exception e) {
|
||||
return new AddBlockResult(WireCodes.Status.BAD_REQUEST, "bad_block_format", 0, "");
|
||||
}
|
||||
@ -141,9 +132,20 @@ public final class BlockchainStateService {
|
||||
BlockchainStateEntry st = stateDAO.getByBlockchainName(c, blockchainName);
|
||||
|
||||
//todo тут надо учесть тот случай что если это 0 блок тоесть начало блокчейна то логично что ещё нет самого файла блокчейна и по этому нет и BlockchainStateEntry
|
||||
boolean isGenesis = (globalNumber == 0);
|
||||
|
||||
if (st == null) {
|
||||
c.rollback();
|
||||
return new AddBlockResult(WireCodes.Status.NOT_FOUND, "blockchain_state_not_found", 0, "");
|
||||
if (!isGenesis) {
|
||||
c.rollback();
|
||||
return new AddBlockResult(WireCodes.Status.NOT_FOUND, "blockchain_state_not_found", 0, "");
|
||||
}
|
||||
st = new BlockchainStateEntry();
|
||||
st.setBlockchainName(blockchainName);
|
||||
st.setLogin(login);
|
||||
st.setLastGlobalNumber(-1);
|
||||
st.setLastGlobalHash("");
|
||||
st.setLastLineNumber(0, -1);
|
||||
st.setLastLineHash(0, "");
|
||||
}
|
||||
|
||||
// 3) проверяем последовательность глобального номера
|
||||
@ -175,8 +177,8 @@ public final class BlockchainStateService {
|
||||
prevLineHash32,
|
||||
block.getRawBytes(),
|
||||
block.getSignature64(),
|
||||
block.getHash32(),
|
||||
loginKey32
|
||||
loginKey32,
|
||||
block.getHash32()
|
||||
);
|
||||
|
||||
if (!ok) {
|
||||
|
||||
@ -8,6 +8,8 @@ import server.logic.ws_protocol.JSON.entyties.blockchain.Net_AddBlock_Response;
|
||||
import server.logic.ws_protocol.JSON.handlers.JsonMessageHandler;
|
||||
import server.logic.ws_protocol.WireCodes;
|
||||
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public final class Net_AddBlock_Handler implements JsonMessageHandler {
|
||||
|
||||
@Override
|
||||
@ -15,36 +17,41 @@ public final class Net_AddBlock_Handler implements JsonMessageHandler {
|
||||
|
||||
Net_AddBlock_Request req = (Net_AddBlock_Request) baseReq;
|
||||
|
||||
var r = BlockchainStateService.getInstance().addBlockAtomically(
|
||||
req.getLogin(),
|
||||
req.getBlockchainName(),
|
||||
req.getGlobalNumber(),
|
||||
req.getPrevGlobalHash(),
|
||||
req.getBlockBytesB64()
|
||||
);
|
||||
|
||||
// todo если пришёл запрос на добавление то надо блочить работу с этим блокчейном по req.getBlockchainName(),
|
||||
// с помощью класса BlockchainLocks и разлочивать работу только в конце завершения работы этого хэндлера, что бы не случилось паралельной работы двух потоков с одним и тем же блокчейном!
|
||||
ReentrantLock lock = BlockchainLocks.lockFor(req.getBlockchainName());
|
||||
lock.lock();
|
||||
try {
|
||||
|
||||
var r = BlockchainStateService.getInstance().addBlockAtomically(
|
||||
req.getBlockchainName(),
|
||||
req.getGlobalNumber(),
|
||||
req.getPrevGlobalHash(),
|
||||
req.getBlockBytesB64()
|
||||
);
|
||||
|
||||
Net_AddBlock_Response resp = new Net_AddBlock_Response();
|
||||
resp.setOp(req.getOp());
|
||||
resp.setRequestId(req.getRequestId());
|
||||
Net_AddBlock_Response resp = new Net_AddBlock_Response();
|
||||
resp.setOp(req.getOp());
|
||||
resp.setRequestId(req.getRequestId());
|
||||
|
||||
if (r.isOk()) {
|
||||
resp.setStatus(WireCodes.Status.OK);
|
||||
resp.setReasonCode(null);
|
||||
} else {
|
||||
resp.setStatus(r.httpStatus);
|
||||
resp.setReasonCode(r.reasonCode);
|
||||
if (r.isOk()) {
|
||||
resp.setStatus(WireCodes.Status.OK);
|
||||
resp.setReasonCode(null);
|
||||
} else {
|
||||
resp.setStatus(r.httpStatus);
|
||||
resp.setReasonCode(r.reasonCode);
|
||||
}
|
||||
|
||||
// Даже при ошибке (например bad_global_sequence) можно вернуть “что сервер считает последним”
|
||||
resp.setServerLastGlobalNumber(r.serverLastGlobalNumber);
|
||||
if (r.serverLastGlobalHash != null) {
|
||||
resp.setServerLastGlobalHash(r.serverLastGlobalHash);
|
||||
}
|
||||
|
||||
return resp;
|
||||
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
// Даже при ошибке (например bad_global_sequence) можно вернуть “что сервер считает последним”
|
||||
resp.setServerLastGlobalNumber(r.serverLastGlobalNumber);
|
||||
if (r.serverLastGlobalHash != null) {
|
||||
resp.setServerLastGlobalHash(r.serverLastGlobalHash);
|
||||
}
|
||||
|
||||
return resp;
|
||||
}
|
||||
}
|
||||
@ -19,7 +19,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class Test_AddBlock_new_NoAuth {
|
||||
public class Test_AddBlock_NoAuth {
|
||||
|
||||
private static final ObjectMapper JSON = new ObjectMapper();
|
||||
|
||||
@ -36,7 +36,6 @@ public class Test_AddBlock_new_NoAuth {
|
||||
private int step = 0;
|
||||
|
||||
private String lastGlobalHashHex = ZERO64;
|
||||
private String lastLineHashHex = ZERO64;
|
||||
|
||||
@Override
|
||||
public void onOpen(WebSocket ws) {
|
||||
@ -54,7 +53,6 @@ public class Test_AddBlock_new_NoAuth {
|
||||
|
||||
String json = buildAddBlockJson(
|
||||
"test-add-header",
|
||||
TestConfig.TEST_LOGIN,
|
||||
TestConfig.TEST_BCH_NAME,
|
||||
0,
|
||||
ZERO64,
|
||||
@ -82,22 +80,17 @@ public class Test_AddBlock_new_NoAuth {
|
||||
}
|
||||
|
||||
String serverLastGlobalHash = extractPayloadString(msg, "serverLastGlobalHash");
|
||||
String serverLastLineHash = extractPayloadString(msg, "serverLastLineHash");
|
||||
|
||||
if (serverLastGlobalHash == null || serverLastGlobalHash.isBlank()) {
|
||||
System.out.println("❌ No serverLastGlobalHash in response");
|
||||
ws.sendClose(WebSocket.NORMAL_CLOSURE, "bad-response");
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
if (serverLastLineHash == null || serverLastLineHash.isBlank()) {
|
||||
serverLastLineHash = serverLastGlobalHash;
|
||||
}
|
||||
|
||||
lastGlobalHashHex = serverLastGlobalHash;
|
||||
lastLineHashHex = serverLastLineHash;
|
||||
|
||||
byte[] prevGlobal32 = hexToBytes32(lastGlobalHashHex);
|
||||
byte[] prevLine32 = hexToBytes32(lastLineHashHex);
|
||||
byte[] prevLine32 = prevGlobal32;
|
||||
|
||||
// 2) TEXT block: global=1, line=0, lineNumber=1
|
||||
byte[] textFull = buildTextBlockFullBytes(
|
||||
@ -111,7 +104,6 @@ public class Test_AddBlock_new_NoAuth {
|
||||
|
||||
String json2 = buildAddBlockJson(
|
||||
"test-add-text",
|
||||
TestConfig.TEST_LOGIN,
|
||||
TestConfig.TEST_BCH_NAME,
|
||||
1,
|
||||
lastGlobalHashHex,
|
||||
@ -238,7 +230,6 @@ public class Test_AddBlock_new_NoAuth {
|
||||
// =================================================================================
|
||||
|
||||
private static String buildAddBlockJson(String requestId,
|
||||
String login,
|
||||
String blockchainName,
|
||||
int globalNumber,
|
||||
String prevGlobalHashHex,
|
||||
@ -248,14 +239,13 @@ public class Test_AddBlock_new_NoAuth {
|
||||
"op": "AddBlock",
|
||||
"requestId": "%s",
|
||||
"payload": {
|
||||
"login": "%s",
|
||||
"blockchainName": "%s",
|
||||
"globalNumber": %d,
|
||||
"prevGlobalHash": "%s",
|
||||
"blockBytesB64": "%s"
|
||||
}
|
||||
}
|
||||
""".formatted(requestId, login, blockchainName, globalNumber, prevGlobalHashHex, blockBytesB64);
|
||||
""".formatted(requestId, blockchainName, globalNumber, prevGlobalHashHex, blockBytesB64);
|
||||
}
|
||||
|
||||
// =================================================================================
|
||||
Loading…
Reference in New Issue
Block a user