Промежуточная версия и ТУДУ на чём остановился
This commit is contained in:
AidarKC
2025-12-16 17:56:36 +03:00
parent 19c4fd6cd1
commit ab44cc5282
30 changed files with 2511 additions and 3 deletions
@@ -0,0 +1,143 @@
package blockchain_new;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.Objects;
/**
* BchBlockEntry_new — универсальный блок нового формата.
*
* RAW (BigEndian):
* [4] recordSize (int) = RAW + signature + hash
* [4] recordNumber (int) глобальный номер блока
* [8] timestamp (long) unix seconds
* [2] line (short)
* [4] lineNumber (int)
* [N] bodyBytes (body, начинается с [type][version])
*
* TAIL:
* [64] signature64 (Ed25519)
* [32] hash32 (SHA-256)
*/
public final class BchBlockEntry_new {
public static final int SIGNATURE_LEN = 64;
public static final int HASH_LEN = 32;
/** Размер фиксированного RAW-заголовка без body */
public static final int RAW_HEADER_SIZE = 4 + 4 + 8 + 2 + 4;
// --- RAW ---
public final int recordSize;
public final int recordNumber;
public final long timestamp;
public final short line;
public final int lineNumber;
public final byte[] bodyBytes;
// --- TAIL ---
private final byte[] signature64;
private final byte[] hash32;
// --- cached ---
private final byte[] fullBytes;
/* ===================================================================== */
/* ====================== Конструктор из байт ========================== */
/* ===================================================================== */
public BchBlockEntry_new(byte[] fullBytes) {
Objects.requireNonNull(fullBytes, "fullBytes == null");
if (fullBytes.length < RAW_HEADER_SIZE + SIGNATURE_LEN + HASH_LEN)
throw new IllegalArgumentException("Block too short");
ByteBuffer bb = ByteBuffer.wrap(fullBytes).order(ByteOrder.BIG_ENDIAN);
this.recordSize = bb.getInt();
if (recordSize != fullBytes.length)
throw new IllegalArgumentException("recordSize mismatch");
this.recordNumber = bb.getInt();
this.timestamp = bb.getLong();
this.line = bb.getShort();
this.lineNumber = bb.getInt();
int bodyLen = recordSize - RAW_HEADER_SIZE - SIGNATURE_LEN - HASH_LEN;
if (bodyLen <= 0)
throw new IllegalArgumentException("Invalid body length");
this.bodyBytes = new byte[bodyLen];
bb.get(this.bodyBytes);
this.signature64 = new byte[SIGNATURE_LEN];
bb.get(this.signature64);
this.hash32 = new byte[HASH_LEN];
bb.get(this.hash32);
this.fullBytes = Arrays.copyOf(fullBytes, fullBytes.length);
}
/* ===================================================================== */
/* ====================== Конструктор сборки ============================ */
/* ===================================================================== */
public BchBlockEntry_new(int recordNumber,
long timestamp,
short line,
int lineNumber,
byte[] bodyBytes,
byte[] signature64,
byte[] hash32) {
Objects.requireNonNull(bodyBytes, "bodyBytes == null");
Objects.requireNonNull(signature64, "signature64 == null");
Objects.requireNonNull(hash32, "hash32 == null");
if (signature64.length != SIGNATURE_LEN)
throw new IllegalArgumentException("signature64 != 64");
if (hash32.length != HASH_LEN)
throw new IllegalArgumentException("hash32 != 32");
this.recordNumber = recordNumber;
this.timestamp = timestamp;
this.line = line;
this.lineNumber = lineNumber;
this.bodyBytes = Arrays.copyOf(bodyBytes, bodyBytes.length);
this.signature64 = Arrays.copyOf(signature64, SIGNATURE_LEN);
this.hash32 = Arrays.copyOf(hash32, HASH_LEN);
this.recordSize =
RAW_HEADER_SIZE +
bodyBytes.length +
SIGNATURE_LEN +
HASH_LEN;
ByteBuffer bb = ByteBuffer.allocate(recordSize).order(ByteOrder.BIG_ENDIAN);
bb.putInt(recordSize);
bb.putInt(recordNumber);
bb.putLong(timestamp);
bb.putShort(line);
bb.putInt(lineNumber);
bb.put(bodyBytes);
bb.put(this.signature64);
bb.put(this.hash32);
this.fullBytes = bb.array();
}
/* ===================================================================== */
public byte[] getSignature64() {
return Arrays.copyOf(signature64, SIGNATURE_LEN);
}
public byte[] getHash32() {
return Arrays.copyOf(hash32, HASH_LEN);
}
public byte[] toBytes() {
return Arrays.copyOf(fullBytes, fullBytes.length);
}
}