Skip to content
Permalink
Browse files

Version 541. Improvements to join process.

  • Loading branch information...
n-y-z-o committed Aug 13, 2019
1 parent e6d5f73 commit 36666cae0ace8a33368d54e1f9aca7d8d19c0625
@@ -675,7 +675,7 @@ public long chainScore(long zeroBlockHeight) {

// This score is always relative to a provided block height. The zero block height has a score of zero, and
// each subsequent block affects the score as follows:
// - a new verifier subtracts 2 but adds 4 times the verifier's position in the new-verifier queue
// - the preferred new verifier subtracts 2; all others add 10,000
// - an existing verifier adds the difference in cycle length between the previous block and this block,
// multiplied by 4
// - an existing verifier that is no longer in the mesh or shares an IP with another verifier adds 5
@@ -698,15 +698,13 @@ public long chainScore(long zeroBlockHeight) {
score = (Math.abs(HashUtil.longSHA256(block.getVerifierIdentifier())) % 9000) * -1L - 1000L;

} else {
score -= 2L;

List<ByteBuffer> topNewVerifiers = NewVerifierVoteManager.topVerifiers();
ByteBuffer verifierIdentifier = ByteBuffer.wrap(block.getVerifierIdentifier());
int indexInQueue = topNewVerifiers.indexOf(verifierIdentifier);
if (indexInQueue < 0 || indexInQueue > 2) {
score += 12L; // maximum of three new in queue; this is behind the queue
// Only allow the top new verifier to join.
ByteBuffer topNewVerifier = NewVerifierVoteManager.topVerifier();
if (topNewVerifier != null &&
ByteUtil.arraysAreEqual(topNewVerifier.array(), block.getVerifierIdentifier())) {
score -= 2L;
} else {
score += indexInQueue * 4L;
score += 10000L;
}

// Penalize for each balance-list spam transaction.
@@ -656,7 +656,10 @@ private static synchronized void updateVerifiersInCurrentCycle(Block block,
// Build the cycle-and-near set.
Set<ByteBuffer> currentAndNearCycleSet = ConcurrentHashMap.newKeySet();
currentAndNearCycleSet.addAll(currentCycleList);
currentAndNearCycleSet.addAll(NewVerifierVoteManager.topVerifiers());
ByteBuffer topNewVerifier = NewVerifierVoteManager.topVerifier();
if (topNewVerifier != null) {
currentAndNearCycleSet.add(topNewVerifier);
}
BlockManager.currentAndNearCycleSet = currentAndNearCycleSet;

// Build the cycle-and-near node set.
@@ -44,7 +44,7 @@ public static synchronized void registerVote(Message message) {
// Get the map for the height.
Map<ByteBuffer, BlockVote> votesForHeight = voteMap.get(height);
if (votesForHeight == null) {
votesForHeight = new HashMap<>();
votesForHeight = new ConcurrentHashMap<>();
voteMap.put(height, votesForHeight);
}

@@ -62,7 +62,7 @@ public static synchronized void registerVote(Message message) {
// Get the flip map for the height.
Map<ByteBuffer, BlockVote> flipVotesForHeight = flipVoteMap.get(height);
if (flipVotesForHeight == null) {
flipVotesForHeight = new HashMap<>();
flipVotesForHeight = new ConcurrentHashMap<>();
flipVoteMap.put(height, flipVotesForHeight);
}

@@ -104,7 +104,7 @@ public static synchronized void removeOldVotes() {
}
}

public static synchronized String votesAtHeight(long height) {
public static String votesAtHeight(long height) {

int numberOfVotes = 0;
int maximumVotes = 0;
@@ -115,12 +115,7 @@ public static synchronized String votesAtHeight(long height) {
Map<ByteBuffer, Integer> voteCounts = new HashMap<>();
for (BlockVote vote : votesForHeight.values()) {
ByteBuffer hash = ByteBuffer.wrap(vote.getHash());
Integer count = voteCounts.get(hash);
if (count == null) {
count = 1;
} else {
count++;
}
int count = voteCounts.getOrDefault(hash, 0) + 1;
voteCounts.put(hash, count);
maximumVotes = Math.max(maximumVotes, count);
}
@@ -131,8 +126,7 @@ public static synchronized String votesAtHeight(long height) {

public static Map<ByteBuffer, BlockVote> votesForHeight(long height) {

Map<ByteBuffer, BlockVote> votesForHeight = voteMap.get(height);
return votesForHeight == null ? null : new HashMap<>(votesForHeight);
return voteMap.get(height);
}

public static byte[] voteForIdentifierAtHeight(byte[] identifier, long height) {
@@ -564,7 +564,8 @@ public static void main(String[] args) {

public static boolean isSubjectToLock(Transaction transaction) {

return transaction.getType() != Transaction.typeSeed &&
return transaction.getType() != Transaction.typeCoinGeneration &&
transaction.getType() != Transaction.typeSeed &&
lockedAccounts.contains(ByteBuffer.wrap(transaction.getSenderIdentifier())) &&
!ByteUtil.arraysAreEqual(transaction.getReceiverIdentifier(), BalanceListItem.cycleAccountIdentifier);
}
@@ -1,6 +1,8 @@
package co.nyzo.verifier;

import co.nyzo.verifier.messages.NewVerifierVote;
import co.nyzo.verifier.util.LogUtil;
import co.nyzo.verifier.util.PrintUtil;

import java.nio.ByteBuffer;
import java.util.*;
@@ -74,35 +76,30 @@ public static void removeOldVotes() {
return voteTotals;
}

public static List<ByteBuffer> topVerifiers() {
public static ByteBuffer topVerifier() {

// Make and sort the list descending on votes.
// Find the verifier with the most votes. The top vote count is initially at least half of the cycle length,
// which means that the top verifier will remain null if no verifier has the mojority of votes.
ByteBuffer topVerifier = null;
int topVoteCount = (BlockManager.currentCycleLength() + 1) / 2;
Map<ByteBuffer, Integer> voteTotals = voteTotals();
List<ByteBuffer> topVerifiers = new ArrayList<>(voteTotals.keySet());
Collections.sort(topVerifiers, new Comparator<ByteBuffer>() {
@Override
public int compare(ByteBuffer verifierVote1, ByteBuffer verifierVote2) {
Integer voteCount1 = voteTotals.get(verifierVote1);
Integer voteCount2 = voteTotals.get(verifierVote2);
return voteCount2.compareTo(voteCount1);
for (ByteBuffer verifier : voteTotals.keySet()) {
int voteCount = voteTotals.get(verifier);
if (voteCount > topVoteCount) {
topVoteCount = voteCount;
topVerifier = verifier;
}
});

// Limit the list to three verifiers. We do not consider ties, as they are inconsequential and do not
// justify additional logic complexity.
while (topVerifiers.size() > 3) {
topVerifiers.remove(topVerifiers.size() - 1);
}

// If the verifiers list is empty and this is a new verifier, add it to the list now.
if (topVerifiers.isEmpty()) {
ByteBuffer verifierIdentifier = ByteBuffer.wrap(Verifier.getIdentifier());
if (!BlockManager.verifierInCurrentCycle(verifierIdentifier)) {
topVerifiers.add(verifierIdentifier);
}
if (topVerifier == null) {
LogUtil.println("top verifier is null");
} else {
int cycleLength = BlockManager.currentCycleLength();
LogUtil.println(String.format("top verifier %s has %d votes with a cycle length of %d (%.1f%%)",
PrintUtil.compactPrintByteArray(topVerifier.array()), topVoteCount, cycleLength,
topVoteCount * 100.0 / cycleLength));
}

return topVerifiers;
return topVerifier;
}

public static NewVerifierVote getLocalVote() {
@@ -2,7 +2,7 @@

public class Version {

private static final int version = 540;
private static final int version = 541;

public static int getVersion() {

@@ -16,8 +16,9 @@

public BootstrapResponseV2() {

this.frozenEdgeHeight = BlockManager.getFrozenEdgeHeight();
this.frozenEdgeHash = BlockManager.frozenBlockForHeight(this.frozenEdgeHeight).getHash();
Block frozenEdge = BlockManager.getFrozenEdge();
this.frozenEdgeHeight = frozenEdge == null ? -1 : frozenEdge.getBlockHeight();
this.frozenEdgeHash = frozenEdge == null ? new byte[FieldByteSize.hash] : frozenEdge.getHash();
this.cycleVerifiers = BlockManager.verifiersInCurrentCycleList();
}

@@ -32,24 +32,19 @@ public int compare(Node node1, Node node2) {
}
});

// TODO: timestamp in-cycle verifiers with current timestamp to prevent promotion to top of queue when
// TODO: dropping out
// TODO: persist join timestamps to file -- this should be done based on identifier, and they should be
// TODO: reloaded when the verifier is restarted

ByteBuffer currentNewVerifierVote = NewVerifierQueueManager.getCurrentVote();
List<ByteBuffer> topVerifiers = NewVerifierVoteManager.topVerifiers();
ByteBuffer topVerifier = NewVerifierVoteManager.topVerifier();

List<String> lines = new ArrayList<>();
for (int i = 0; i < nodes.size() && lines.size() < maximumNumberOfLines; i++) {
Node node = nodes.get(i);
byte[] identifier = node.getIdentifier();
int topVerifierIndex = topVerifiers.indexOf(ByteBuffer.wrap(identifier));
boolean isTopVerifier = topVerifier != null && ByteUtil.arraysAreEqual(identifier, topVerifier.array());
boolean isCurrentVote = ByteBuffer.wrap(identifier).equals(currentNewVerifierVote);

lines.add((BlockManager.verifierInCurrentCycle(ByteBuffer.wrap(identifier)) ? "C, " : " , ") +
PrintUtil.compactPrintByteArray(identifier) + ", " + node.getQueueTimestamp() + ", " +
(topVerifierIndex < 0 ? "-" : topVerifierIndex + "") + ", " + (isCurrentVote ? "*" : "-") +
(isTopVerifier ? "*" : "-") + ", " + (isCurrentVote ? "*" : "-") +
", " + NicknameManager.get(identifier));
}

0 comments on commit 36666ca

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