15 01 25
Исправил что бы в интерфейсе BodyHasTarget не требывалось хранить в блоках BodyHasTarget и в блоках коннекстин не зранилась поле тоЛогин в байты блока. (Все тесты тесты проходят)
This commit is contained in:
parent
5fe41c7656
commit
d9fe1f02b8
@ -1,20 +1,25 @@
|
|||||||
package blockchain.body;
|
package blockchain.body;
|
||||||
|
|
||||||
|
import utils.blockchain.BlockchainNameUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BodyHasTarget — дополнительный интерфейс для body, которые "ссылаются" на цель (to-поля).
|
* BodyHasTarget — контракт для body, которые "ссылаются" на цель (to-поля).
|
||||||
*
|
*
|
||||||
* Идея:
|
* ВАЖНО (новое правило):
|
||||||
* - Не все body имеют "to".
|
* - toLogin НЕ храним в байтах блока.
|
||||||
* - Но для индексации и удобства запросов в БД мы хотим единообразно доставать:
|
* - toLogin всегда вычисляем из toBchName по стандарту:
|
||||||
* toLogin, toBchName, toBlockGlobalNumber, toBlockHashe
|
* toBchName = login + "-NNN" => toLogin = login
|
||||||
*
|
*
|
||||||
* Важно:
|
* Все методы могут возвращать null (если target отсутствует).
|
||||||
* - Все методы могут возвращать null.
|
|
||||||
*/
|
*/
|
||||||
public interface BodyHasTarget {
|
public interface BodyHasTarget {
|
||||||
|
|
||||||
/** login цели (nullable). */
|
/** login цели (nullable). */
|
||||||
String toLogin();
|
default String toLogin() {
|
||||||
|
String bch = toBchName();
|
||||||
|
if (bch == null) return null;
|
||||||
|
return BlockchainNameUtil.loginFromBlockchainName(bch);
|
||||||
|
}
|
||||||
|
|
||||||
/** blockchainName цели (nullable). */
|
/** blockchainName цели (nullable). */
|
||||||
String toBchName();
|
String toBchName();
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package blockchain.body;
|
package blockchain.body;
|
||||||
|
|
||||||
import blockchain.MsgSubType;
|
import blockchain.MsgSubType;
|
||||||
|
import utils.blockchain.BlockchainNameUtil;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
@ -16,18 +17,18 @@ import java.util.Objects;
|
|||||||
* CONTACT=20, UNCONTACT=21
|
* CONTACT=20, UNCONTACT=21
|
||||||
* FOLLOW=30, UNFOLLOW=31
|
* FOLLOW=30, UNFOLLOW=31
|
||||||
*
|
*
|
||||||
* bodyBytes (BigEndian), новый формат:
|
* bodyBytes (BigEndian), новый формат (toLogin НЕ ХРАНИМ):
|
||||||
* [4] prevLineNumber
|
* [4] prevLineNumber
|
||||||
* [32] prevLineHash32
|
* [32] prevLineHash32
|
||||||
* [4] thisLineNumber
|
* [4] thisLineNumber
|
||||||
*
|
*
|
||||||
* [1] toLoginLen (uint8)
|
|
||||||
* [N] toLogin UTF-8
|
|
||||||
*
|
|
||||||
* [1] toBlockchainNameLen (uint8)
|
* [1] toBlockchainNameLen (uint8)
|
||||||
* [M] toBlockchainName UTF-8
|
* [N] toBlockchainName UTF-8
|
||||||
* [4] toBlockGlobalNumber (int32)
|
* [4] toBlockGlobalNumber (int32)
|
||||||
* [32] toBlockHash32 (raw 32 bytes)
|
* [32] toBlockHash32 (raw 32 bytes)
|
||||||
|
*
|
||||||
|
* toLogin вычисляется автоматически из toBlockchainName:
|
||||||
|
* toLogin = BlockchainNameUtil.loginFromBlockchainName(toBlockchainName)
|
||||||
*/
|
*/
|
||||||
public final class ConnectionBody implements BodyRecord, BodyHasTarget, BodyHasLine {
|
public final class ConnectionBody implements BodyRecord, BodyHasTarget, BodyHasLine {
|
||||||
|
|
||||||
@ -45,7 +46,6 @@ public final class ConnectionBody implements BodyRecord, BodyHasTarget, BodyHasL
|
|||||||
public final int thisLineNumber;
|
public final int thisLineNumber;
|
||||||
|
|
||||||
// payload
|
// payload
|
||||||
public final String toLogin;
|
|
||||||
public final String toBlockchainName;
|
public final String toBlockchainName;
|
||||||
public final int toBlockGlobalNumber;
|
public final int toBlockGlobalNumber;
|
||||||
public final byte[] toBlockHash32;
|
public final byte[] toBlockHash32;
|
||||||
@ -64,8 +64,8 @@ public final class ConnectionBody implements BodyRecord, BodyHasTarget, BodyHasL
|
|||||||
}
|
}
|
||||||
|
|
||||||
// минимум:
|
// минимум:
|
||||||
// line(4+32+4) + toLoginLen[1]+toLogin[1] + toBchLen[1]+toBch[1] + global[4] + hash[32]
|
// line(4+32+4) + toBchLen[1]+toBch[1] + global[4] + hash[32]
|
||||||
if (bodyBytes.length < (4 + 32 + 4) + 1 + 1 + 1 + 1 + 4 + 32) {
|
if (bodyBytes.length < (4 + 32 + 4) + 1 + 1 + 4 + 32) {
|
||||||
throw new IllegalArgumentException("ConnectionBody too short");
|
throw new IllegalArgumentException("ConnectionBody too short");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,14 +78,6 @@ public final class ConnectionBody implements BodyRecord, BodyHasTarget, BodyHasL
|
|||||||
|
|
||||||
this.thisLineNumber = bb.getInt();
|
this.thisLineNumber = bb.getInt();
|
||||||
|
|
||||||
int toLoginLen = Byte.toUnsignedInt(bb.get());
|
|
||||||
if (toLoginLen <= 0) throw new IllegalArgumentException("toLoginLen is 0");
|
|
||||||
if (bb.remaining() < toLoginLen) throw new IllegalArgumentException("toLogin payload too short");
|
|
||||||
|
|
||||||
byte[] toLoginBytes = new byte[toLoginLen];
|
|
||||||
bb.get(toLoginBytes);
|
|
||||||
this.toLogin = new String(toLoginBytes, StandardCharsets.UTF_8);
|
|
||||||
|
|
||||||
int bchLen = Byte.toUnsignedInt(bb.get());
|
int bchLen = Byte.toUnsignedInt(bb.get());
|
||||||
if (bchLen <= 0) throw new IllegalArgumentException("toBlockchainNameLen is 0");
|
if (bchLen <= 0) throw new IllegalArgumentException("toBlockchainNameLen is 0");
|
||||||
if (bb.remaining() < bchLen + 4 + 32) throw new IllegalArgumentException("Connection payload too short");
|
if (bb.remaining() < bchLen + 4 + 32) throw new IllegalArgumentException("Connection payload too short");
|
||||||
@ -106,20 +98,21 @@ public final class ConnectionBody implements BodyRecord, BodyHasTarget, BodyHasL
|
|||||||
byte[] prevLineHash32,
|
byte[] prevLineHash32,
|
||||||
int thisLineNumber,
|
int thisLineNumber,
|
||||||
short subType,
|
short subType,
|
||||||
String toLogin,
|
|
||||||
String toBlockchainName,
|
String toBlockchainName,
|
||||||
int toBlockGlobalNumber,
|
int toBlockGlobalNumber,
|
||||||
byte[] toBlockHash32) {
|
byte[] toBlockHash32) {
|
||||||
|
|
||||||
Objects.requireNonNull(toLogin, "toLogin == null");
|
|
||||||
Objects.requireNonNull(toBlockchainName, "toBlockchainName == null");
|
Objects.requireNonNull(toBlockchainName, "toBlockchainName == null");
|
||||||
Objects.requireNonNull(toBlockHash32, "toBlockHash32 == null");
|
Objects.requireNonNull(toBlockHash32, "toBlockHash32 == null");
|
||||||
|
|
||||||
if (!isValidSubType(subType)) throw new IllegalArgumentException("Bad connection subType: " + (subType & 0xFFFF));
|
if (!isValidSubType(subType)) throw new IllegalArgumentException("Bad connection subType: " + (subType & 0xFFFF));
|
||||||
if (toLogin.isBlank()) throw new IllegalArgumentException("toLogin is blank");
|
|
||||||
if (!toLogin.matches("^[A-Za-z0-9_]+$")) throw new IllegalArgumentException("toLogin must match ^[A-Za-z0-9_]+$");
|
|
||||||
|
|
||||||
if (toBlockchainName.isBlank()) throw new IllegalArgumentException("toBlockchainName is blank");
|
if (toBlockchainName.isBlank()) throw new IllegalArgumentException("toBlockchainName is blank");
|
||||||
|
// Железное правило формата: bchName -> login + "-NNN"
|
||||||
|
if (BlockchainNameUtil.loginFromBlockchainName(toBlockchainName) == null) {
|
||||||
|
throw new IllegalArgumentException("toBlockchainName must match login+\"-NNN\": " + toBlockchainName);
|
||||||
|
}
|
||||||
|
|
||||||
if (toBlockGlobalNumber < 0) throw new IllegalArgumentException("toBlockGlobalNumber < 0");
|
if (toBlockGlobalNumber < 0) throw new IllegalArgumentException("toBlockGlobalNumber < 0");
|
||||||
if (toBlockHash32.length != 32) throw new IllegalArgumentException("toBlockHash32 != 32");
|
if (toBlockHash32.length != 32) throw new IllegalArgumentException("toBlockHash32 != 32");
|
||||||
|
|
||||||
@ -130,7 +123,6 @@ public final class ConnectionBody implements BodyRecord, BodyHasTarget, BodyHasL
|
|||||||
this.subType = subType;
|
this.subType = subType;
|
||||||
this.version = VER;
|
this.version = VER;
|
||||||
|
|
||||||
this.toLogin = toLogin;
|
|
||||||
this.toBlockchainName = toBlockchainName;
|
this.toBlockchainName = toBlockchainName;
|
||||||
this.toBlockGlobalNumber = toBlockGlobalNumber;
|
this.toBlockGlobalNumber = toBlockGlobalNumber;
|
||||||
this.toBlockHash32 = Arrays.copyOf(toBlockHash32, 32);
|
this.toBlockHash32 = Arrays.copyOf(toBlockHash32, 32);
|
||||||
@ -158,10 +150,13 @@ public final class ConnectionBody implements BodyRecord, BodyHasTarget, BodyHasL
|
|||||||
if (prevLineHash32 == null || prevLineHash32.length != 32) throw new IllegalArgumentException("prevLineHash32 invalid");
|
if (prevLineHash32 == null || prevLineHash32.length != 32) throw new IllegalArgumentException("prevLineHash32 invalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toLogin == null || toLogin.isBlank()) throw new IllegalArgumentException("toLogin is blank");
|
if (toBlockchainName == null || toBlockchainName.isBlank())
|
||||||
if (!toLogin.matches("^[A-Za-z0-9_]+$")) throw new IllegalArgumentException("toLogin must match ^[A-Za-z0-9_]+$");
|
throw new IllegalArgumentException("toBlockchainName is blank");
|
||||||
|
|
||||||
|
// гарантируем вычислимый toLogin (иначе target “битый” по стандарту)
|
||||||
|
if (BlockchainNameUtil.loginFromBlockchainName(toBlockchainName) == null)
|
||||||
|
throw new IllegalArgumentException("toBlockchainName must match login+\"-NNN\": " + toBlockchainName);
|
||||||
|
|
||||||
if (toBlockchainName == null || toBlockchainName.isBlank()) throw new IllegalArgumentException("toBlockchainName is blank");
|
|
||||||
if (toBlockGlobalNumber < 0) throw new IllegalArgumentException("toBlockGlobalNumber < 0");
|
if (toBlockGlobalNumber < 0) throw new IllegalArgumentException("toBlockGlobalNumber < 0");
|
||||||
if (toBlockHash32 == null || toBlockHash32.length != 32) throw new IllegalArgumentException("toBlockHash32 invalid");
|
if (toBlockHash32 == null || toBlockHash32.length != 32) throw new IllegalArgumentException("toBlockHash32 invalid");
|
||||||
|
|
||||||
@ -170,10 +165,6 @@ public final class ConnectionBody implements BodyRecord, BodyHasTarget, BodyHasL
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] toBytes() {
|
public byte[] toBytes() {
|
||||||
byte[] toLoginBytes = toLogin.getBytes(StandardCharsets.UTF_8);
|
|
||||||
if (toLoginBytes.length == 0 || toLoginBytes.length > 255)
|
|
||||||
throw new IllegalArgumentException("toLogin utf8 len must be 1..255");
|
|
||||||
|
|
||||||
byte[] bchBytes = toBlockchainName.getBytes(StandardCharsets.UTF_8);
|
byte[] bchBytes = toBlockchainName.getBytes(StandardCharsets.UTF_8);
|
||||||
if (bchBytes.length == 0 || bchBytes.length > 255)
|
if (bchBytes.length == 0 || bchBytes.length > 255)
|
||||||
throw new IllegalArgumentException("toBlockchainName utf8 len must be 1..255");
|
throw new IllegalArgumentException("toBlockchainName utf8 len must be 1..255");
|
||||||
@ -182,7 +173,6 @@ public final class ConnectionBody implements BodyRecord, BodyHasTarget, BodyHasL
|
|||||||
throw new IllegalArgumentException("toBlockHash32 != 32");
|
throw new IllegalArgumentException("toBlockHash32 != 32");
|
||||||
|
|
||||||
int cap = (4 + 32 + 4)
|
int cap = (4 + 32 + 4)
|
||||||
+ 1 + toLoginBytes.length
|
|
||||||
+ 1 + bchBytes.length
|
+ 1 + bchBytes.length
|
||||||
+ 4 + 32;
|
+ 4 + 32;
|
||||||
|
|
||||||
@ -192,9 +182,6 @@ public final class ConnectionBody implements BodyRecord, BodyHasTarget, BodyHasL
|
|||||||
bb.put(prevLineHash32 == null ? new byte[32] : Arrays.copyOf(prevLineHash32, 32));
|
bb.put(prevLineHash32 == null ? new byte[32] : Arrays.copyOf(prevLineHash32, 32));
|
||||||
bb.putInt(thisLineNumber);
|
bb.putInt(thisLineNumber);
|
||||||
|
|
||||||
bb.put((byte) toLoginBytes.length);
|
|
||||||
bb.put(toLoginBytes);
|
|
||||||
|
|
||||||
bb.put((byte) bchBytes.length);
|
bb.put((byte) bchBytes.length);
|
||||||
bb.put(bchBytes);
|
bb.put(bchBytes);
|
||||||
|
|
||||||
@ -216,7 +203,8 @@ public final class ConnectionBody implements BodyRecord, BodyHasTarget, BodyHasL
|
|||||||
@Override public int thisLineNumber() { return thisLineNumber; }
|
@Override public int thisLineNumber() { return thisLineNumber; }
|
||||||
|
|
||||||
/* ====================== BodyHasTarget ===================== */
|
/* ====================== BodyHasTarget ===================== */
|
||||||
@Override public String toLogin() { return toLogin; }
|
// toLogin() теперь default в интерфейсе и вычисляется из toBchName()
|
||||||
|
|
||||||
@Override public String toBchName() { return toBlockchainName; }
|
@Override public String toBchName() { return toBlockchainName; }
|
||||||
@Override public Integer toBlockGlobalNumber() { return toBlockGlobalNumber; }
|
@Override public Integer toBlockGlobalNumber() { return toBlockGlobalNumber; }
|
||||||
@Override public byte[] toBlockHasheBytes() { return toBlockHash32; }
|
@Override public byte[] toBlockHasheBytes() { return toBlockHash32; }
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import static org.junit.jupiter.api.Assertions.*;
|
|||||||
* ВАЖНО:
|
* ВАЖНО:
|
||||||
* - НЕТ обращения к blockchain.LineIndex (можно удалить LineIndex.java).
|
* - НЕТ обращения к blockchain.LineIndex (можно удалить LineIndex.java).
|
||||||
* - Линии берём через ChainState.nextLineByType(TYPE_...).
|
* - Линии берём через ChainState.nextLineByType(TYPE_...).
|
||||||
|
* - ConnectionBody: toLogin в байтах НЕ хранится, вычисляется из toBlockchainName.
|
||||||
*/
|
*/
|
||||||
public class IT_03_AddBlock_NoAuth {
|
public class IT_03_AddBlock_NoAuth {
|
||||||
|
|
||||||
@ -177,7 +178,7 @@ public class IT_03_AddBlock_NoAuth {
|
|||||||
var ln = st1.nextLineByType(ChainState.TYPE_CONNECTION);
|
var ln = st1.nextLineByType(ChainState.TYPE_CONNECTION);
|
||||||
sender1.send(new ConnectionBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
|
sender1.send(new ConnectionBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
|
||||||
MsgSubType.CONNECTION_FOLLOW,
|
MsgSubType.CONNECTION_FOLLOW,
|
||||||
u2, bch2, 0, new byte[32]
|
bch2, 0, new byte[32]
|
||||||
), t);
|
), t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +187,7 @@ public class IT_03_AddBlock_NoAuth {
|
|||||||
var ln = st1.nextLineByType(ChainState.TYPE_CONNECTION);
|
var ln = st1.nextLineByType(ChainState.TYPE_CONNECTION);
|
||||||
sender1.send(new ConnectionBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
|
sender1.send(new ConnectionBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
|
||||||
MsgSubType.CONNECTION_FOLLOW,
|
MsgSubType.CONNECTION_FOLLOW,
|
||||||
u3, bch3, 0, new byte[32]
|
bch3, 0, new byte[32]
|
||||||
), t);
|
), t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +196,7 @@ public class IT_03_AddBlock_NoAuth {
|
|||||||
var ln = st2.nextLineByType(ChainState.TYPE_CONNECTION);
|
var ln = st2.nextLineByType(ChainState.TYPE_CONNECTION);
|
||||||
sender2.send(new ConnectionBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
|
sender2.send(new ConnectionBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
|
||||||
MsgSubType.CONNECTION_FOLLOW,
|
MsgSubType.CONNECTION_FOLLOW,
|
||||||
u1, bch1, 0, new byte[32]
|
bch1, 0, new byte[32]
|
||||||
), t);
|
), t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +205,7 @@ public class IT_03_AddBlock_NoAuth {
|
|||||||
var ln = st2.nextLineByType(ChainState.TYPE_CONNECTION);
|
var ln = st2.nextLineByType(ChainState.TYPE_CONNECTION);
|
||||||
sender2.send(new ConnectionBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
|
sender2.send(new ConnectionBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
|
||||||
MsgSubType.CONNECTION_FRIEND,
|
MsgSubType.CONNECTION_FRIEND,
|
||||||
u1, bch1, 0, new byte[32]
|
bch1, 0, new byte[32]
|
||||||
), t);
|
), t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,7 +220,7 @@ public class IT_03_AddBlock_NoAuth {
|
|||||||
var ln = st1.nextLineByType(ChainState.TYPE_CONNECTION);
|
var ln = st1.nextLineByType(ChainState.TYPE_CONNECTION);
|
||||||
sender1.send(new ConnectionBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
|
sender1.send(new ConnectionBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
|
||||||
MsgSubType.CONNECTION_FRIEND,
|
MsgSubType.CONNECTION_FRIEND,
|
||||||
u2, bch2, 0, new byte[32]
|
bch2, 0, new byte[32]
|
||||||
), t);
|
), t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,7 +228,7 @@ public class IT_03_AddBlock_NoAuth {
|
|||||||
var ln = st2.nextLineByType(ChainState.TYPE_CONNECTION);
|
var ln = st2.nextLineByType(ChainState.TYPE_CONNECTION);
|
||||||
sender2.send(new ConnectionBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
|
sender2.send(new ConnectionBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
|
||||||
MsgSubType.CONNECTION_UNFRIEND,
|
MsgSubType.CONNECTION_UNFRIEND,
|
||||||
u1, bch1, 0, new byte[32]
|
bch1, 0, new byte[32]
|
||||||
), t);
|
), t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user