Skip to content
Permalink
Browse files

Version 574. Added trusted-message verification.

  • Loading branch information
n-y-z-o committed Mar 17, 2020
1 parent 9ab319d commit b72063fdd1d15bdccaf6e4ebb2ee9094be40dae6
@@ -975,8 +975,8 @@ private int excessTransactionCount() {

@Override
public String toString() {
return "[Block:v=" + getBlockchainVersion() + ",height=" + getBlockHeight() + ",hash=" +
PrintUtil.compactPrintByteArray(getHash()) + ",id=" +
return "[Block: v=" + getBlockchainVersion() + ", height=" + getBlockHeight() + ", hash=" +
PrintUtil.compactPrintByteArray(getHash()) + ", id=" +
PrintUtil.compactPrintByteArray(getVerifierIdentifier()) + "]";
}
}
@@ -2,7 +2,7 @@

public class Version {

private static final int version = 573;
private static final int version = 574;

public static int getVersion() {

@@ -14,6 +14,7 @@
private byte[] seed;
private byte[] identifier;
private boolean sentinelTransactionEnabled;
private byte[] responseIdentifier;

// These are used to track the health of the verifier.
private int[] queryResults;
@@ -58,6 +59,14 @@ public boolean isSentinelTransactionEnabled() {
return sentinelTransactionEnabled;
}

public byte[] getResponseIdentifier() {
return responseIdentifier;
}

public void setResponseIdentifier(byte[] responseIdentifier) {
this.responseIdentifier = responseIdentifier;
}

public static ManagedVerifier fromString(String value) {

ManagedVerifier result = null;
@@ -172,7 +172,6 @@ public void run() {
}
}


// Ensure a minimum interval between iterations. This includes processing time, so the actual sleep
// time may be zero.
while (System.currentTimeMillis() < loopStartTimestamp + minimumLoopInterval) {
@@ -386,17 +385,31 @@ private static void loadManagedVerifiers() {
private static void updateMesh(ManagedVerifier verifier) {

// Get the mesh.
Message message = new Message(MessageType.MeshRequest15, null);
Message message = new Message(MessageType.MeshRequest15, null, verifier.getSeed());
Message.fetchTcp(verifier.getHost(), verifier.getPort(), message, new MessageCallback() {
@Override
public void responseReceived(Message message) {

try {
if (message != null) {
MeshResponse response = (MeshResponse) message.getContent();
if (!response.getMesh().isEmpty()) {
verifierIdentifierToMeshMap.put(ByteBuffer.wrap(message.getSourceNodeIdentifier()),
response.getMesh());
// Set the response identifier. This is displayed in the interface if mismatched.
verifier.setResponseIdentifier(message.getSourceNodeIdentifier());

// Log if the identifier is mismatched, in case the operator does not use the web interface.
if (!ByteUtil.arraysAreEqual(verifier.getIdentifier(), message.getSourceNodeIdentifier())) {
LogUtil.println(NicknameManager.get(verifier.getIdentifier()) + " identifier mismatch: " +
ByteUtil.arrayAsStringWithDashes(verifier.getIdentifier()) + ", response identifier: " +
ByteUtil.arrayAsStringWithDashes(verifier.getResponseIdentifier()));
}

// If the response identifier is correct and the content type is correct, process the response.
if (ByteUtil.arraysAreEqual(verifier.getIdentifier(), message.getSourceNodeIdentifier()) &&
(message.getContent() instanceof MeshResponse)) {
MeshResponse response = (MeshResponse) message.getContent();
if (!response.getMesh().isEmpty()) {
verifierIdentifierToMeshMap.put(ByteBuffer.wrap(message.getSourceNodeIdentifier()),
response.getMesh());
}
}
}
} catch (Exception ignored) { }
@@ -413,7 +426,7 @@ private static void updateBlocks(ManagedVerifier verifier) {
long endHeightToFetch = startHeightToFetch + (inFastFetchMode.getOrDefault(identifier, false) ? 9 : 0);
List<Block> blockList = new ArrayList<>();
Message message = new Message(MessageType.BlockRequest11, new BlockRequest(startHeightToFetch, endHeightToFetch,
false));
false), verifier.getSeed());

AtomicBoolean processedResponse = new AtomicBoolean(false);
Message.fetchTcp(verifier.getHost(), verifier.getPort(), message, new MessageCallback() {
@@ -425,14 +438,23 @@ public void responseReceived(Message message) {
result = ManagedVerifier.queryResultErrorValue;
} else {
try {
BlockResponse blockResponse = (BlockResponse) message.getContent();
List<Block> blocks = blockResponse.getBlocks();
if (blocks.size() == 0) {
result = 0;
} else if (blocks.get(0).getBlockHeight() == startHeightToFetch &&
blocks.get(blocks.size() - 1).getBlockHeight() == endHeightToFetch) {
blockList.addAll(blocks);
result = blockList.size();
// Set the response identifier. This is displayed in the interface if mismatched.
verifier.setResponseIdentifier(message.getSourceNodeIdentifier());

// If the response identifier is correct and the content type is correct, process the response.
if (ByteUtil.arraysAreEqual(verifier.getIdentifier(), message.getSourceNodeIdentifier()) &&
(message.getContent() instanceof BlockResponse)) {
BlockResponse blockResponse = (BlockResponse) message.getContent();
List<Block> blocks = blockResponse.getBlocks();
if (blocks.size() == 0) {
result = 0;
} else if (blocks.get(0).getBlockHeight() == startHeightToFetch &&
blocks.get(blocks.size() - 1).getBlockHeight() == endHeightToFetch) {
blockList.addAll(blocks);
result = blockList.size();
} else {
result = ManagedVerifier.queryResultErrorValue;
}
} else {
result = ManagedVerifier.queryResultErrorValue;
}
@@ -553,10 +575,10 @@ private static void transmitBlockIfNecessary() {

// Make the message and resign with the appropriate verifier seed. The message must be signed
// by an in-cycle verifier to make it past the blacklist mechanism.
Message message = new Message(MessageType.NewBlock9, new NewBlockMessage(lowestScoredBlock));
ManagedVerifier verifier =
verifierMap.get(ByteBuffer.wrap(lowestScoredBlock.getVerifierIdentifier()));
message.sign(verifier.getSeed());
Message message = new Message(MessageType.NewBlock9, new NewBlockMessage(lowestScoredBlock),
verifier.getSeed());

Set<Node> combinedCycle = combinedCycle();
AtomicInteger responsesReceived = new AtomicInteger(0);
@@ -2,14 +2,14 @@

import co.nyzo.verifier.Block;
import co.nyzo.verifier.BlockManager;
import co.nyzo.verifier.ByteUtil;
import co.nyzo.verifier.Version;
import co.nyzo.verifier.sentinel.ManagedVerifier;
import co.nyzo.verifier.sentinel.Sentinel;
import co.nyzo.verifier.web.elements.*;

import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Map;

public class SentinelController {

@@ -43,6 +43,7 @@ private static HtmlElement divContent() {
HtmlElementList content = new HtmlElementList();
content.add(header());
content.add(verifierTable());
content.add(incorrectVerifierNotices());
content.add(new P("Nyzo sentinel, version " + Version.getVersion()).attr("style", "font-style: italic;"));
return content;
}
@@ -106,12 +107,14 @@ private static HtmlElement verifierTable() {
".verifier-label { display: table-cell; padding: 0.5rem 1.0rem 0 1.0rem; vertical-align: top; " +
"white-space: nowrap; height: 1.6rem; }" +
".verifier-label-active { background-color: #999; }" +
".verifier-label-incorrect-identifier { background-color: #f80; }" +
".verifier-tile { display: table-cell; width: 1.3rem; height: 2.1rem; }" +
".verifier-tile-line { position: relative; left: 0; width: 1.3rem; height: 0.2rem; " +
"background-color: rgba(0,0,0,0.3); }" +
".verifier-tile-label { color: white; width: 1.3rem; position: relative; display: table-cell; " +
"padding-top: 0.3rem; font-weight: bold; }" +
".separator-row { height: 1px; }"));
".separator-row { height: 1px; }" +
".incorrect-verifier-notice { color: #f80; font-style: italic; }"));

// Build the table.
Collection<ManagedVerifier> managedVerifiers = Sentinel.getManagedVerifiers();
@@ -126,7 +129,13 @@ private static HtmlElement verifierTable() {

Div row = (Div) div.add(new Div().attr("class", "verifier-row"));
String nickname = WebUtil.sanitizedNickname(verifier.getIdentifier());
String className = "verifier-label" + (verifier.isQueriedLastInterval() ? " verifier-label-active" : "");
String className = "verifier-label";
if (!ByteUtil.isAllZeros(verifier.getResponseIdentifier()) &&
!ByteUtil.arraysAreEqual(verifier.getIdentifier(), verifier.getResponseIdentifier())) {
className += " verifier-label-incorrect-identifier";
} else if (verifier.isQueriedLastInterval()) {
className += " verifier-label-active";
}
row.add(new Div().attr("class", className).addRaw(nickname));

// Build the div of color-coded tiles for the recent results, counting the results in the process.
@@ -171,4 +180,20 @@ private static HtmlElement verifierTable() {

return div;
}

private static HtmlElement incorrectVerifierNotices() {
HtmlElementList notices = new HtmlElementList();
Collection<ManagedVerifier> managedVerifiers = Sentinel.getManagedVerifiers();
for (ManagedVerifier verifier : managedVerifiers) {
if (!ByteUtil.isAllZeros(verifier.getResponseIdentifier()) &&
!ByteUtil.arraysAreEqual(verifier.getIdentifier(), verifier.getResponseIdentifier())) {
String nickname = WebUtil.sanitizedNickname(verifier.getIdentifier());
notices.add(new P().attr("class", "incorrect-verifier-notice").addRaw(nickname + " identifer: " +
ByteUtil.arrayAsStringWithDashes(verifier.getIdentifier()) + ", response identifier: " +
ByteUtil.arrayAsStringWithDashes(verifier.getResponseIdentifier())));
}
}

return notices;
}
}

0 comments on commit b72063f

Please sign in to comment.
You can’t perform that action at this time.