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