SHiNE-server/shine-server-blockchain/src/main/java/blockchain_new/BchBlockEntry_new.java
AidarKC eb37b43de4 17 12 25
Промежуточный комит верии которая может быть работает :)
2025-12-17 13:32:06 +03:00

151 lines
5.0 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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[] getRawBytes() {
int rawLen = recordSize - SIGNATURE_LEN - HASH_LEN;
byte[] raw = new byte[rawLen];
System.arraycopy(fullBytes, 0, raw, 0, rawLen);
return raw;
}
/* ===================================================================== */
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);
}
}