мелкие исправления. Убрал оставшиеся странные связи линии
This commit is contained in:
AidarKC 2026-01-13 17:54:10 +03:00
parent 9cf6fabe64
commit 5fe41c7656
4 changed files with 116 additions and 112 deletions

View File

@ -1,17 +1,17 @@
package blockchain; //package blockchain;
//
/** ///**
* LineIndex канонические номера линий блокчейна. // * LineIndex канонические номера линий блокчейна.
* // *
* Линия = независимая последовательность блоков внутри одного блокчейна. // * Линия = независимая последовательность блоков внутри одного блокчейна.
*/ // */
public final class LineIndex { //public final class LineIndex {
//
private LineIndex() {} // private LineIndex() {}
//
public static final short HEADER = 0; // genesis / идентификация // public static final short HEADER = 0; // genesis / идентификация
public static final short TEXT = 1; // сообщения да надо // public static final short TEXT = 1; // сообщения да надо
public static final short REACTION = 2; // реакции не надо // public static final short REACTION = 2; // реакции не надо
public static final short CONNECTION = 3; // связи (friend/contact/follow) да надо // public static final short CONNECTION = 3; // связи (friend/contact/follow) да надо
public static final short USER_PARAM = 4; // параметры профиля да надо // public static final short USER_PARAM = 4; // параметры профиля да надо
} //}

View File

@ -19,6 +19,10 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
* - block хранит только preimage + signature * - block хранит только preimage + signature
* - hash32 вычисляется как sha256(preimage) * - hash32 вычисляется как sha256(preimage)
* - signature = Ed25519.sign(hash32) * - signature = Ed25519.sign(hash32)
*
* ВАЖНО:
* - Линии (prevLine/thisLine) по ТЗ нужны только для TEXT/CONNECTION/USER_PARAM.
* - Здесь НЕТ обращения к blockchain.LineIndex.
*/ */
public final class AddBlockSender { public final class AddBlockSender {
@ -38,6 +42,7 @@ public final class AddBlockSender {
this.blockchainName = blockchainName; this.blockchainName = blockchainName;
this.loginPrivKey = (loginPrivKey == null ? null : loginPrivKey.clone()); this.loginPrivKey = (loginPrivKey == null ? null : loginPrivKey.clone());
if (this.ws == null) throw new IllegalArgumentException("ws == null"); if (this.ws == null) throw new IllegalArgumentException("ws == null");
if (this.state == null) throw new IllegalArgumentException("state == null");
if (this.loginPrivKey == null) throw new IllegalArgumentException("loginPrivKey == null"); if (this.loginPrivKey == null) throw new IllegalArgumentException("loginPrivKey == null");
} }
@ -97,7 +102,7 @@ public final class AddBlockSender {
String serverLastHash = JsonMini.extractPayloadString(resp, "serverLastBlockHash"); String serverLastHash = JsonMini.extractPayloadString(resp, "serverLastBlockHash");
if (serverLastHash == null) { if (serverLastHash == null) {
// на случай старого имени, но по твоей просьбе мы на это больше не опираемся // на всякий случай, но ты говорил старое не поддерживаем оставил мягко
serverLastHash = JsonMini.extractPayloadString(resp, "serverLastGlobalHash"); serverLastHash = JsonMini.extractPayloadString(resp, "serverLastGlobalHash");
} }
@ -113,13 +118,13 @@ public final class AddBlockSender {
assertEquals(localHashHex, serverLastHash, op + ": serverLastBlockHash must match local hash"); assertEquals(localHashHex, serverLastHash, op + ": serverLastBlockHash must match local hash");
// фиксируем в state глобальную цепочку + (если нужно) line-state по TYPE
state.applyAppendedBlock(blockNumber, entry.getHash32(), isHeader, type); state.applyAppendedBlock(blockNumber, entry.getHash32(), isHeader, type);
// если это line-body обновим thisLineNumber в state (для nextLine()) // если это line-body обновим thisLineNumber в state (для nextLineByType())
if (body instanceof BodyHasLine hl) { if (body instanceof BodyHasLine hl) {
short lineIndex = lineIndexByType(type); if (ChainState.isLineType(type)) {
if (lineIndex != -1) { state.applyThisLineNumberByType(type, hl.thisLineNumber());
state.applyThisLineNumber(lineIndex, hl.thisLineNumber());
} }
} }
@ -219,15 +224,4 @@ public final class AddBlockSender {
return bb.array(); return bb.array();
} }
private static short lineIndexByType(short type) {
int t = type & 0xFFFF;
return switch (t) {
case 0 -> blockchain.LineIndex.HEADER;
case 1 -> blockchain.LineIndex.TEXT;
case 3 -> blockchain.LineIndex.CONNECTION;
case 4 -> blockchain.LineIndex.USER_PARAM;
default -> (short) -1;
};
}
} }

View File

@ -1,29 +1,36 @@
package test.it.blockchain; package test.it.blockchain;
import blockchain.LineIndex;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* ChainState состояние цепочки + состояние линий (только тех, где они нужны): * ChainState состояние глобальной цепочки + состояние линий (только тех, где они нужны).
* *
* Глобальная цепочка: * Глобальная цепочка:
* - lastBlockNumber / lastBlockHashHex * - lastBlockNumber / lastBlockHashHex
* - map blockNumber -> hash32 (для ссылок reply/edit/reaction) * - map blockNumber -> hash32 (для ссылок reply/edit/reaction)
* *
* Линии (по ТЗ нужны): * Линии по ТЗ нужны только для:
* - TEXT (1) * - TEXT (type=1)
* - CONNECTION (3) * - CONNECTION (type=3)
* - USER_PARAM (4) * - USER_PARAM (type=4)
* *
* prevLineNumber по ТЗ это GLOBAL blockNumber предыдущего блока линии. * prevLineNumber по ТЗ это GLOBAL blockNumber предыдущего блока линии.
* thisLineNumber внутренний номер линии (мы ведём локально: 1,2,3...) * thisLineNumber внутренний номер линии (мы ведём локально: 1,2,3...)
*
* ВАЖНО:
* - Здесь НЕТ обращения к blockchain.LineIndex.
* - Линии адресуются по msg_type (type).
*/ */
public final class ChainState { public final class ChainState {
public static final int LINES_MAX = 8; // какие msg_type имеют линейную цепочку по ТЗ
public static final short TYPE_HEADER = 0;
public static final short TYPE_TEXT = 1;
public static final short TYPE_REACTION = 2;
public static final short TYPE_CONNECTION = 3;
public static final short TYPE_USER_PARAM = 4;
private static final byte[] ZERO32 = new byte[32]; private static final byte[] ZERO32 = new byte[32];
private static final String ZERO64 = "0".repeat(64); private static final String ZERO64 = "0".repeat(64);
@ -35,17 +42,34 @@ public final class ChainState {
// header (block#0) // header (block#0)
private byte[] headerHash32 = null; private byte[] headerHash32 = null;
// per-line state (только для LineIndex.TEXT/CONNECTION/USER_PARAM) /**
private final int[] lineLastGlobalNumber = new int[LINES_MAX]; // последний GLOBAL номер блока в линии * line state per TYPE (только для TEXT/CONNECTION/USER_PARAM):
private final String[] lineLastHashHex = new String[LINES_MAX]; // hash последнего блока линии * - lastGlobalNumber: последний GLOBAL blockNumber в линии
private final int[] lineLastThisLineNumber = new int[LINES_MAX]; // последний thisLineNumber (внутренний) * - lastHashHex: hash последнего блока линии
* - lastThisLineNumber: последний thisLineNumber (внутренний)
*/
private static final class LineState {
int lastGlobalNumber = -1;
String lastHashHex = "";
int lastThisLineNumber = 0;
void reset() {
lastGlobalNumber = -1;
lastHashHex = "";
lastThisLineNumber = 0;
}
}
private final LineState textLine = new LineState();
private final LineState connectionLine = new LineState();
private final LineState userParamLine = new LineState();
private final Map<Integer, byte[]> hash32ByNumber = new HashMap<>(); private final Map<Integer, byte[]> hash32ByNumber = new HashMap<>();
public ChainState() { public ChainState() {
Arrays.fill(lineLastGlobalNumber, -1); textLine.reset();
Arrays.fill(lineLastHashHex, ""); connectionLine.reset();
Arrays.fill(lineLastThisLineNumber, 0); userParamLine.reset();
} }
// -------------------- global getters -------------------- // -------------------- global getters --------------------
@ -89,30 +113,33 @@ public final class ChainState {
} }
} }
/** Следующие line-поля для указанной линии (только TEXT/CONNECTION/USER_PARAM). */ /** Является ли type "линейным" по ТЗ (т.е. нужно вести prevLine/thisLine). */
public NextLine nextLine(short lineIndex) { public static boolean isLineType(short type) {
checkLine(lineIndex); int t = type & 0xFFFF;
if (!isLineUsed(lineIndex)) { return t == TYPE_TEXT || t == TYPE_CONNECTION || t == TYPE_USER_PARAM;
throw new IllegalArgumentException("Line " + lineIndex + " не используется для BodyHasLine по ТЗ"); }
/** Следующие line-поля для указанного TYPE (только TEXT/CONNECTION/USER_PARAM). */
public NextLine nextLineByType(short type) {
if (!isLineType(type)) {
throw new IllegalArgumentException("Type " + (type & 0xFFFF) + " не использует line-поля по ТЗ");
} }
if (!hasHeader()) { if (!hasHeader()) {
throw new IllegalStateException("Нельзя формировать line-поля до HEADER (нет headerHash32)"); throw new IllegalStateException("Нельзя формировать line-поля до HEADER (нет headerHash32)");
} }
int lastGlobal = lineLastGlobalNumber[lineIndex]; LineState ls = lineStateByType(type);
int lastThis = lineLastThisLineNumber[lineIndex];
if (lastGlobal == -1) { if (ls.lastGlobalNumber == -1) {
// первый блок линии ссылается на HEADER (block#0) // первый блок линии ссылается на HEADER (block#0)
return new NextLine(0, headerHash32.clone(), 1); return new NextLine(0, headerHash32.clone(), 1);
} }
String lastHex = lineLastHashHex[lineIndex]; if (ls.lastHashHex == null || ls.lastHashHex.isBlank()) {
if (lastHex == null || lastHex.isBlank()) { throw new IllegalStateException("LineState.lastHashHex пуст, но lastGlobalNumber!=-1 (type=" + (type & 0xFFFF) + ")");
throw new IllegalStateException("lineLastHashHex[" + lineIndex + "] пуст, но lastGlobal!=-1");
} }
return new NextLine(lastGlobal, hexToBytes32(lastHex), lastThis + 1); return new NextLine(ls.lastGlobalNumber, hexToBytes32(ls.lastHashHex), ls.lastThisLineNumber + 1);
} }
// -------------------- apply -------------------- // -------------------- apply --------------------
@ -140,52 +167,32 @@ public final class ChainState {
hash32ByNumber.put(blockNumber, hash32.clone()); hash32ByNumber.put(blockNumber, hash32.clone());
// обновляем line-state только для линий, которые "надо" по ТЗ // обновляем line-state только если этот type по ТЗ линейный
short lineIndex = lineIndexByType(type); if (isLineType(type)) {
if (lineIndex != -1 && isLineUsed(lineIndex)) { LineState ls = lineStateByType(type);
lineLastGlobalNumber[lineIndex] = blockNumber; ls.lastGlobalNumber = blockNumber;
lineLastHashHex[lineIndex] = hex64; ls.lastHashHex = hex64;
// thisLineNumber обновляется отдельным вызовом (см. applyThisLineNumberByType)
// thisLineNumber мы берём из тела, но здесь его нет.
// Поэтому thisLineNumber должен обновляться там, где формируются тела (в тестах),
// либо AddBlockSender может прокинуть его отдельно.
// Чтобы не дублировать контракт здесь оставляем как есть.
} }
} }
/** В тестах удобно явно обновлять thisLineNumber после успешной отправки line-body. */ /** В тестах удобно явно обновлять thisLineNumber после успешной отправки line-body. */
public void applyThisLineNumber(short lineIndex, int thisLineNumber) { public void applyThisLineNumberByType(short type, int thisLineNumber) {
checkLine(lineIndex); if (!isLineType(type)) return;
if (!isLineUsed(lineIndex)) return; LineState ls = lineStateByType(type);
lineLastThisLineNumber[lineIndex] = thisLineNumber; ls.lastThisLineNumber = thisLineNumber;
} }
// -------------------- mapping -------------------- private LineState lineStateByType(short type) {
/** По type блока определяем lineIndex. Reaction line по твоему ТЗ "не надо". */
private static short lineIndexByType(short type) {
int t = type & 0xFFFF; int t = type & 0xFFFF;
return switch (t) { return switch (t) {
case 0 -> LineIndex.HEADER; case TYPE_TEXT -> textLine;
case 1 -> LineIndex.TEXT; case TYPE_CONNECTION -> connectionLine;
case 3 -> LineIndex.CONNECTION; case TYPE_USER_PARAM -> userParamLine;
case 4 -> LineIndex.USER_PARAM; default -> throw new IllegalArgumentException("Type " + t + " не имеет LineState по ТЗ");
default -> (short) -1; // reaction/unknown => line state not used
}; };
} }
private static boolean isLineUsed(short lineIndex) {
return lineIndex == LineIndex.TEXT
|| lineIndex == LineIndex.CONNECTION
|| lineIndex == LineIndex.USER_PARAM;
}
private static void checkLine(short lineIndex) {
if (lineIndex < 0 || lineIndex >= LINES_MAX) {
throw new IllegalArgumentException("lineIndex must be 0.." + (LINES_MAX - 1));
}
}
// -------------------- utils -------------------- // -------------------- utils --------------------
private static byte[] hexToBytes32(String hex) { private static byte[] hexToBytes32(String hex) {

View File

@ -1,6 +1,5 @@
package test.it.cases; package test.it.cases;
import blockchain.LineIndex;
import blockchain.body.*; import blockchain.body.*;
import blockchain.MsgSubType; import blockchain.MsgSubType;
import test.it.blockchain.AddBlockSender; import test.it.blockchain.AddBlockSender;
@ -16,6 +15,10 @@ import static org.junit.jupiter.api.Assertions.*;
/** /**
* IT_03_AddBlock_NoAuth обновлён под новый формат блоков (ТЗ). * IT_03_AddBlock_NoAuth обновлён под новый формат блоков (ТЗ).
*
* ВАЖНО:
* - НЕТ обращения к blockchain.LineIndex (можно удалить LineIndex.java).
* - Линии берём через ChainState.nextLineByType(TYPE_...).
*/ */
public class IT_03_AddBlock_NoAuth { public class IT_03_AddBlock_NoAuth {
@ -59,7 +62,7 @@ public class IT_03_AddBlock_NoAuth {
// TEXT_NEW x3 (с line) // TEXT_NEW x3 (с line)
{ {
var ln = st1.nextLine(LineIndex.TEXT); var ln = st1.nextLineByType(ChainState.TYPE_TEXT);
sender1.send(new TextBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber, sender1.send(new TextBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
MsgSubType.TEXT_NEW, MsgSubType.TEXT_NEW,
"Hello #1 (NEW) from IT_03 test", "Hello #1 (NEW) from IT_03 test",
@ -67,7 +70,7 @@ public class IT_03_AddBlock_NoAuth {
), t); ), t);
} }
{ {
var ln = st1.nextLine(LineIndex.TEXT); var ln = st1.nextLineByType(ChainState.TYPE_TEXT);
sender1.send(new TextBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber, sender1.send(new TextBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
MsgSubType.TEXT_NEW, MsgSubType.TEXT_NEW,
"Hello #2 (NEW) from IT_03 test", "Hello #2 (NEW) from IT_03 test",
@ -75,7 +78,7 @@ public class IT_03_AddBlock_NoAuth {
), t); ), t);
} }
{ {
var ln = st1.nextLine(LineIndex.TEXT); var ln = st1.nextLineByType(ChainState.TYPE_TEXT);
sender1.send(new TextBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber, sender1.send(new TextBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
MsgSubType.TEXT_NEW, MsgSubType.TEXT_NEW,
"Hello #3 (NEW) from IT_03 test", "Hello #3 (NEW) from IT_03 test",
@ -92,7 +95,7 @@ public class IT_03_AddBlock_NoAuth {
// TEXT_REPLY x2 (с line + target) // TEXT_REPLY x2 (с line + target)
{ {
var ln = st1.nextLine(LineIndex.TEXT); var ln = st1.nextLineByType(ChainState.TYPE_TEXT);
sender1.send(new TextBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber, sender1.send(new TextBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
MsgSubType.TEXT_REPLY, MsgSubType.TEXT_REPLY,
"Reply to TEXT#1", "Reply to TEXT#1",
@ -100,7 +103,7 @@ public class IT_03_AddBlock_NoAuth {
), t); ), t);
} }
{ {
var ln = st1.nextLine(LineIndex.TEXT); var ln = st1.nextLineByType(ChainState.TYPE_TEXT);
sender1.send(new TextBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber, sender1.send(new TextBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
MsgSubType.TEXT_REPLY, MsgSubType.TEXT_REPLY,
"Reply to TEXT#3", "Reply to TEXT#3",
@ -114,7 +117,7 @@ public class IT_03_AddBlock_NoAuth {
// TEXT_EDIT x3 (с line + target) // TEXT_EDIT x3 (с line + target)
{ {
var ln = st1.nextLine(LineIndex.TEXT); var ln = st1.nextLineByType(ChainState.TYPE_TEXT);
sender1.send(new TextBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber, sender1.send(new TextBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
MsgSubType.TEXT_EDIT, MsgSubType.TEXT_EDIT,
"Hello #2 (EDIT#1) from IT_03 test", "Hello #2 (EDIT#1) from IT_03 test",
@ -122,7 +125,7 @@ public class IT_03_AddBlock_NoAuth {
), t); ), t);
} }
{ {
var ln = st1.nextLine(LineIndex.TEXT); var ln = st1.nextLineByType(ChainState.TYPE_TEXT);
sender1.send(new TextBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber, sender1.send(new TextBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
MsgSubType.TEXT_EDIT, MsgSubType.TEXT_EDIT,
"Hello #2 (EDIT#2) from IT_03 test", "Hello #2 (EDIT#2) from IT_03 test",
@ -130,7 +133,7 @@ public class IT_03_AddBlock_NoAuth {
), t); ), t);
} }
{ {
var ln = st1.nextLine(LineIndex.TEXT); var ln = st1.nextLineByType(ChainState.TYPE_TEXT);
sender1.send(new TextBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber, sender1.send(new TextBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
MsgSubType.TEXT_EDIT, MsgSubType.TEXT_EDIT,
"Hello #3 (EDIT#1) from IT_03 test", "Hello #3 (EDIT#1) from IT_03 test",
@ -149,7 +152,7 @@ public class IT_03_AddBlock_NoAuth {
// USER_PARAM (с line) // USER_PARAM (с line)
{ {
var ln = st2.nextLine(LineIndex.USER_PARAM); var ln = st2.nextLineByType(ChainState.TYPE_USER_PARAM);
sender2.send(new UserParamBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber, sender2.send(new UserParamBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
"Anya", "Amsterdam, Example street 10" "Anya", "Amsterdam, Example street 10"
), t); ), t);
@ -171,7 +174,7 @@ public class IT_03_AddBlock_NoAuth {
// u1 -> follow u2 // u1 -> follow u2
{ {
var ln = st1.nextLine(LineIndex.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] u2, bch2, 0, new byte[32]
@ -180,7 +183,7 @@ public class IT_03_AddBlock_NoAuth {
// u1 -> follow u3 // u1 -> follow u3
{ {
var ln = st1.nextLine(LineIndex.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] u3, bch3, 0, new byte[32]
@ -189,7 +192,7 @@ public class IT_03_AddBlock_NoAuth {
// u2 -> follow u1 // u2 -> follow u1
{ {
var ln = st2.nextLine(LineIndex.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] u1, bch1, 0, new byte[32]
@ -198,7 +201,7 @@ public class IT_03_AddBlock_NoAuth {
// friend/unfriend как было, но тоже по CONNECTION линии // friend/unfriend как было, но тоже по CONNECTION линии
{ {
var ln = st2.nextLine(LineIndex.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] u1, bch1, 0, new byte[32]
@ -207,13 +210,13 @@ public class IT_03_AddBlock_NoAuth {
// user1 param + friend to u2 // user1 param + friend to u2
{ {
var ln = st1.nextLine(LineIndex.USER_PARAM); var ln = st1.nextLineByType(ChainState.TYPE_USER_PARAM);
sender1.send(new UserParamBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber, sender1.send(new UserParamBody(ln.prevLineNumber, ln.prevLineHash32, ln.thisLineNumber,
"Anna", "Gareeva" "Anna", "Gareeva"
), t); ), t);
} }
{ {
var ln = st1.nextLine(LineIndex.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] u2, bch2, 0, new byte[32]
@ -221,7 +224,7 @@ public class IT_03_AddBlock_NoAuth {
} }
{ {
var ln = st2.nextLine(LineIndex.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] u1, bch1, 0, new byte[32]