diff --git a/.gitignore b/.gitignore index 765b55db..a641857c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ .gradle /build/ !gradle/wrapper/gradle-wrapper.jar - +.idea ### vi ### *.swp diff --git a/src/main/java/co/nyzo/verifier/BalanceListManager.java b/src/main/java/co/nyzo/verifier/BalanceListManager.java index 9d411be6..493a3dea 100644 --- a/src/main/java/co/nyzo/verifier/BalanceListManager.java +++ b/src/main/java/co/nyzo/verifier/BalanceListManager.java @@ -4,6 +4,7 @@ import java.nio.ByteBuffer; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import co.nyzo.verifier.util.*; // egg public class BalanceListManager { @@ -62,41 +63,70 @@ public static BalanceList balanceListForBlock(Block block) { // If the balance list was not in the map, try to derive it. if (balanceList == null) { + //System.out.println("X:BLM:Rewind from "+block.getBlockHeight()+ " " + block); + /* + for (ByteBuffer key: balanceListMap.keySet()) { + System.out.println("X:BLM:hash="+PrintUtil.compactPrintByteArray(key.array())+" h="+balanceListMap.get(key).getBlockHeight() ); + }*/ // Step back to previous blocks until we are able to find a balance list that we have. Block startBlock = block; List blocks = new ArrayList<>(Collections.singletonList(startBlock)); BalanceList startBalanceList = null; - while (startBlock != null && startBalanceList == null) { - startBlock = startBlock.getPreviousBlock(); + if (balanceListMap.size() > 0) { + long rewinded = 0L; + while (startBlock != null && startBalanceList == null) { + startBlock = startBlock.getPreviousBlock(); + rewinded++; + if (startBlock != null) { + blocks.add(0, startBlock); + // System.out.println("X:BLM:Previous is "+startBlock.getBlockHeight()); + startBalanceList = balanceListMap.get(ByteBuffer.wrap(startBlock.getBalanceListHash())); + } else { + //System.out.println("X:BLM:Previous was null"); + } + } if (startBlock != null) { - blocks.add(0, startBlock); - startBalanceList = balanceListMap.get(ByteBuffer.wrap(startBlock.getBalanceListHash())); + //System.out.println("X:BLM:Rewinded to "+startBlock); + } else { + System.out.println("X:BLM:Rewinded to null after " + rewinded); } + } else { + System.out.println("X:BLM:!Can't rewind, No BL at all"); } - // If a suitable start balance list was found, derive the desired list. if (startBalanceList != null) { balanceList = startBalanceList; for (int i = 0; i < blocks.size() - 1; i++) { + //System.out.println("X:BLM:Adding block "+blocks.get(i) ); + //System.out.println("X:BLM:and block "+blocks.get(i+1) ); balanceList = Block.balanceListForNextBlock(blocks.get(i), balanceList, blocks.get(i + 1).getTransactions(), blocks.get(i + 1).getVerifierIdentifier(), blocks.get(i + 1).getBlockchainVersion()); } - + //System.out.println("X:Resulting BL Hash="+PrintUtil.compactPrintByteArray(balanceList.getHash()) ); registerBalanceList(balanceList); + } else { + System.out.println("X:BLM:Rewinded BL is null"); } + } else { + //System.out.println("X:BLM:BL From map"); } } + } else { + System.out.println("X:BLM:Block is null"); } return balanceList; } public static void registerBalanceList(BalanceList balanceList) { - - if (balanceList != null && balanceListMap.size() < maximumMapSize) { + if (balanceList == null) { + System.out.println("X:BLM:Not registering null BL"); + } else if (balanceListMap.size() < maximumMapSize) { balanceListMap.put(ByteBuffer.wrap(balanceList.getHash()), balanceList); + } else { + System.out.println("X:BLM:Not registering BL, mapsize exceeded"); } } @@ -116,21 +146,28 @@ public static boolean accountIsInSystem(byte[] identifier) { public static void updateFrozenEdge(BalanceList frozenEdgeList) { if (frozenEdgeList != null) { - for (int i = numberOfRecentLists - 1; i > 0; i--) { - recentLists[i] = recentLists[i - 1]; - } - recentLists[0] = frozenEdgeList; - frozenEdgeBalanceMap = BalanceManager.makeBalanceMap(frozenEdgeList); + try { + for (int i = numberOfRecentLists - 1; i > 0; i--) { + recentLists[i] = recentLists[i - 1]; + } + recentLists[0] = frozenEdgeList; + frozenEdgeBalanceMap = BalanceManager.makeBalanceMap(frozenEdgeList); - Set accountsInSystem = ConcurrentHashMap.newKeySet(); - for (BalanceListItem item : frozenEdgeList.getItems()) { - accountsInSystem.add(ByteBuffer.wrap(item.getIdentifier())); - } + Set accountsInSystem = ConcurrentHashMap.newKeySet(); + for (BalanceListItem item : frozenEdgeList.getItems()) { + accountsInSystem.add(ByteBuffer.wrap(item.getIdentifier())); + } - BalanceListManager.accountsInSystem = accountsInSystem; + BalanceListManager.accountsInSystem = accountsInSystem; - balanceListMap.clear(); - balanceListMap.put(ByteBuffer.wrap(frozenEdgeList.getHash()), frozenEdgeList); + balanceListMap.clear(); + //System.out.println("X:BLM:balanceListMap.cleared, add "+ PrintUtil.compactPrintByteArray(frozenEdgeList.getHash())+" for h="+frozenEdgeList.getBlockHeight()); + balanceListMap.put(ByteBuffer.wrap(frozenEdgeList.getHash()), frozenEdgeList); + } catch (Exception e) { + System.out.println("X:Exception BLM.updateFrozenEdge " + PrintUtil.printException(e)); + } + } else { + System.out.println("X:BLM:updateFrozenEdge BL is null"); } } } diff --git a/src/main/java/co/nyzo/verifier/Block.java b/src/main/java/co/nyzo/verifier/Block.java index 9a3acb3d..dc862ecd 100644 --- a/src/main/java/co/nyzo/verifier/Block.java +++ b/src/main/java/co/nyzo/verifier/Block.java @@ -172,10 +172,19 @@ public Block getPreviousBlock() { Block frozenBlock = BlockManager.frozenBlockForHeight(height - 1); if (frozenBlock != null && ByteUtil.arraysAreEqual(frozenBlock.getHash(), previousBlockHash)) { previousBlock = frozenBlock; + } else { + if (frozenBlock == null) { + System.out.println("X:GPB:Frozenblock is null"); + } + else if (!ByteUtil.arraysAreEqual(frozenBlock.getHash(), previousBlockHash)) { + System.out.println("X:GPB:arrays Are not Equal, frozen "+frozenBlock.getHash()+" vs "+previousBlockHash ); + } } } else { previousBlock = UnfrozenBlockManager.unfrozenBlockAtHeight(height - 1, previousBlockHash); } + } else { + System.out.println("X:GPB:getBlockHeight<=0"); } return previousBlock; @@ -620,7 +629,7 @@ public static BalanceList balanceListForNextBlock(Block previousBlock, BalanceLi long organicTransactionFees = 0L; long transactionSumFromLockedAccounts = 0L; for (Transaction transaction : transactions) { - + //System.out.println("X:AddTx "+transaction); // In blockchain version 1, cycle transactions are processed here. In later versions, cycle // transactions are incorporated in the blockchain before being approved for transfer, so they are // handled separately. @@ -1025,8 +1034,12 @@ public static void setBlockDelayHeight() { @Override public String toString() { - return "[Block: v=" + getBlockchainVersion() + ", height=" + getBlockHeight() + ", hash=" + + return "[Block: v=" + getBlockchainVersion() + ", height=" + getBlockHeight() + + " txcount=" + transactions.size() + + ", hash=" + PrintUtil.compactPrintByteArray(getHash()) + ", id=" + - PrintUtil.compactPrintByteArray(getVerifierIdentifier()) + "]"; + PrintUtil.compactPrintByteArray(getVerifierIdentifier()) + ", blh=" + + PrintUtil.compactPrintByteArray(getBalanceListHash())+ + "]"; } } diff --git a/src/main/java/co/nyzo/verifier/BlockManager.java b/src/main/java/co/nyzo/verifier/BlockManager.java index 71c053cf..5702c426 100644 --- a/src/main/java/co/nyzo/verifier/BlockManager.java +++ b/src/main/java/co/nyzo/verifier/BlockManager.java @@ -231,6 +231,8 @@ public static void freezeBlock(Block block) { if (previousBlock != null) { BalanceList balanceList = BalanceListManager.balanceListForBlock(block); freezeBlock(block, previousBlock.getHash(), balanceList, null); + } else { + System.out.println("X:Previous block is null "+ block.getBlockHeight()); } } @@ -239,23 +241,34 @@ public static synchronized void freezeBlock(Block block, byte[] previousBlockHas // Only continue if the block's previous hash is correct and the balance list is available. if (ByteUtil.arraysAreEqual(previousBlockHash, block.getPreviousBlockHash()) && balanceList != null) { + if (!ByteUtil.arraysAreEqual(balanceList.getHash(), block.getBalanceListHash())) { + System.out.println("X:!!BLHash mismatch "+ PrintUtil.compactPrintByteArray(balanceList.getHash()) + " vs block " + block) ; + } else { + try { + setFrozenEdge(block, cycleVerifiers); + BalanceListManager.updateFrozenEdge(balanceList); - try { - setFrozenEdge(block, cycleVerifiers); - BalanceListManager.updateFrozenEdge(balanceList); + writeBlocksToFile(Collections.singletonList(block), Collections.singletonList(balanceList), + individualFileForBlockHeight(block.getBlockHeight())); - writeBlocksToFile(Collections.singletonList(block), Collections.singletonList(balanceList), - individualFileForBlockHeight(block.getBlockHeight())); + if (block.getBlockHeight() == 0L) { - if (block.getBlockHeight() == 0L) { + genesisBlockStartTimestamp = block.getStartTimestamp(); + completedInitialization.set(true); + } - genesisBlockStartTimestamp = block.getStartTimestamp(); - completedInitialization.set(true); + } catch (Exception reportOnly) { + reportOnly.printStackTrace(); + System.err.println("exception writing block to file " + reportOnly.getMessage()); + System.out.println("X:exception writing block to file " + reportOnly.getMessage()); } - - } catch (Exception reportOnly) { - reportOnly.printStackTrace(); - System.err.println("exception writing block to file " + reportOnly.getMessage()); + } + } else { + if (balanceList == null) { + System.out.println("X:BalanceList is null"); + } + if (!ByteUtil.arraysAreEqual(previousBlockHash, block.getPreviousBlockHash())) { + System.out.println("X:Hashes mismatch "+ PrintUtil.compactPrintByteArray(previousBlockHash) + " vs block " + block.getPreviousBlock()); } } } diff --git a/src/main/java/co/nyzo/verifier/Message.java b/src/main/java/co/nyzo/verifier/Message.java index 31faea34..f32c7535 100644 --- a/src/main/java/co/nyzo/verifier/Message.java +++ b/src/main/java/co/nyzo/verifier/Message.java @@ -235,7 +235,8 @@ public void run() { response = readFromStream(socket.getInputStream(), socket.getInetAddress().getAddress(), message.getType()); } catch (Exception reportOnly) { - System.err.println("Exception sending message " + message.getType() + " to " + + // Egg: was err + System.out.println("Exception sending message " + message.getType() + " to " + hostNameOrIp + ":" + port + ": " + PrintUtil.printException(reportOnly)); } diff --git a/src/main/java/co/nyzo/verifier/Version.java b/src/main/java/co/nyzo/verifier/Version.java index a5055add..1e9a1ec9 100644 --- a/src/main/java/co/nyzo/verifier/Version.java +++ b/src/main/java/co/nyzo/verifier/Version.java @@ -2,7 +2,7 @@ public class Version { - private static final int version = 607; + private static final int version = 607111; public static int getVersion() { diff --git a/src/main/java/co/nyzo/verifier/sentinel/Sentinel.java b/src/main/java/co/nyzo/verifier/sentinel/Sentinel.java index 2625ac9a..c405e079 100644 --- a/src/main/java/co/nyzo/verifier/sentinel/Sentinel.java +++ b/src/main/java/co/nyzo/verifier/sentinel/Sentinel.java @@ -89,14 +89,13 @@ private static void start() { if (!loadedManagedVerifiers.getAndSet(true)) { loadManagedVerifiers(); } - // Send a whitelist request to each managed verifier. for (ManagedVerifier verifier : verifierList) { sendWhitelistRequest(verifier); } - // Sleep for 1.5 seconds to give the whitelist requests time to process. - ThreadUtil.sleep(1500L); + // Sleep for 2 seconds to give the whitelist requests time to process. + ThreadUtil.sleep(2000L); // Initialize the frozen edge. This process will repeat until it is successful. SentinelUtil.initializeFrozenEdge(verifierList); @@ -114,11 +113,12 @@ private static void start() { int querySlot = 0; for (ManagedVerifier verifier : verifierList) { startThreadForVerifier(verifier, querySlot++); + ThreadUtil.sleep(20L); // Will slow down init, but spread load when there are many managed verifiers } // Start a single thread as a fallback for fetching blocks from the full cycle if all managed verifiers become // unresponsive. - startFullCycleThread(); + startFullCycleThread(); // Egg: TODO: preferences param // Start a single thread for transmitting blocks for new verifiers. startNewVerifierThread(); @@ -184,6 +184,7 @@ public void run() { frozenEdge.getVerificationTimestamp() < System.currentTimeMillis() - 20000L) { lastBlockRequestedTimestamp = System.currentTimeMillis(); updateBlocks(verifier); + //System.out.println("X:updateBlocks " + NicknameManager.get(verifier.getIdentifier()) + " interval " + blockUpdateInterval); verifier.setQueriedLastInterval(true); } else { verifier.setQueriedLastInterval(false); @@ -222,7 +223,7 @@ public void run() { if (lastBlockRequestedTimestamp < System.currentTimeMillis() - blockUpdateIntervalStandard && (frozenEdge.getVerificationTimestamp() < System.currentTimeMillis() - 35000L)) { lastBlockRequestedTimestamp = System.currentTimeMillis(); - + System.out.println("X:fallback2, requestBlockWithVotes"); requestBlockWithVotes(); } } catch (Exception e) { @@ -255,6 +256,18 @@ public void responseReceived(Message message) { BlockWithVotesResponse response = message == null ? null : (BlockWithVotesResponse) message.getContent(); LogUtil.println("block-with-votes response is " + response); + if (response != null) { + if (response.getBlock() != null) { + LogUtil.println("X:getblock hash=" + response.getBlock().getHash() + " Height="+response.getBlock().getBlockHeight()); + } else { + LogUtil.println("X:getBlock is null"); + } + if (response.getVotes().isEmpty() ) { + LogUtil.println("X:getblock votes is empty"); + } else { + LogUtil.println("X:getBlock has votes"); + } + } if (response != null && response.getBlock() != null && !response.getVotes().isEmpty()) { int voteThreshold = BlockManager.currentCycleLength() * 3 / 4; @@ -279,7 +292,8 @@ public void responseReceived(Message message) { // If the vote count exceeds the threshold, freeze the block. System.out.println("block with votes: count=" + voteCount + ", threshold=" + voteThreshold); if (voteCount > voteThreshold) { - freezeBlock(response.getBlock()); + System.out.println("X:Freezing random fetched block"); + freezeBlock(response.getBlock(), null); } } } @@ -301,7 +315,7 @@ public static Node randomNode() { node = nodes.get(random.nextInt(nodes.size())); } } - + LogUtil.println("X:randomNode "+NicknameManager.get(node.getIdentifier())); return node; } @@ -471,6 +485,7 @@ private static void updateBlocks(ManagedVerifier verifier) { false), verifier.getSeed()); AtomicBoolean processedResponse = new AtomicBoolean(false); + //System.out.println("X:Requesting block from "+ NicknameManager.get(verifier.getIdentifier()) + " " + startHeightToFetch + " to " + endHeightToFetch); Message.fetchTcp(verifier.getHost(), verifier.getPort(), message, new MessageCallback() { @Override public void responseReceived(Message message) { @@ -505,8 +520,9 @@ public void responseReceived(Message message) { // If we obtained a block, freeze it. if (!blockList.isEmpty()) { + //System.out.println("X:Got "+blockList.size()+" blocks from "+ NicknameManager.get(verifier.getIdentifier()) ); for (Block block : blockList) { - freezeBlock(block); + freezeBlock(block, verifier.getIdentifier()); } lastBlockReceivedTimestamp.set(System.currentTimeMillis()); @@ -521,15 +537,16 @@ public void responseReceived(Message message) { BlockManager.getFrozenEdgeHeight() < BlockManager.openEdgeHeight(false) - 10) { if (!inFastFetchMode.get(identifier)) { inFastFetchMode.put(identifier, true); - System.out.println("***** fast-fetch mode activated *****"); + System.out.println("fast-fetch mode activated for "+ NicknameManager.get(verifier.getIdentifier())); } } } else { + //System.out.println("X:No blocks from "+ NicknameManager.get(verifier.getIdentifier())); // Two consecutive failures deactivate fast-fetch mode. if (consecutiveSuccessfulBlockFetches.get(identifier).get() == 0) { if (inFastFetchMode.get(identifier)) { inFastFetchMode.put(identifier, false); - System.out.println("***** fast-fetch mode deactivated *****"); + System.out.println("fast-fetch mode deactivated for " + NicknameManager.get(verifier.getIdentifier())); } } else { consecutiveSuccessfulBlockFetches.get(identifier).set(0); @@ -541,110 +558,113 @@ private static void transmitBlockIfNecessary() { long frozenEdgeHeight = frozenEdge.getBlockHeight(); long heightToProcess = frozenEdgeHeight + 1L; - - // The block creation delay prevents unnecessary work and unnecessary transmissions to the mesh when the - // sentinel is initializing. We also allow the condition to be entered at least once to confirm that the - // sentinel is able to calculate valid chain scores. - if (!calculatingValidChainScores || - lastBlockReceivedTimestamp.get() < System.currentTimeMillis() - blockCreationDelay) { - - // This loop is fully serial, so there is no concern about threading issues. Check if the blocks - // created are for the height to process. If not, clear them out. - if (!blocksCreatedForManagedVerifiers.isEmpty()) { - Block block = blocksCreatedForManagedVerifiers.iterator().next(); - if (block.getBlockHeight() != heightToProcess) { - blocksCreatedForManagedVerifiers.clear(); - } - } - - // If the map of blocks is empty, make the blocks now. - if (blocksCreatedForManagedVerifiers.isEmpty()) { - for (ManagedVerifier verifier : verifierList) { - Block block = createNextBlock(frozenEdge, verifier); - if (block != null) { - blocksCreatedForManagedVerifiers.add(block); + try { + // The block creation delay prevents unnecessary work and unnecessary transmissions to the mesh when the + // sentinel is initializing. We also allow the condition to be entered at least once to confirm that the + // sentinel is able to calculate valid chain scores. + if (!calculatingValidChainScores || + lastBlockReceivedTimestamp.get() < System.currentTimeMillis() - blockCreationDelay) { + // This loop is fully serial, so there is no concern about threading issues. Check if the blocks + // created are for the height to process. If not, clear them out. + if (!blocksCreatedForManagedVerifiers.isEmpty()) { + Block block = blocksCreatedForManagedVerifiers.iterator().next(); + if (block.getBlockHeight() != heightToProcess) { + blocksCreatedForManagedVerifiers.clear(); } } - } - // If we have not yet transmitted a block for a managed verifier, check the scores for all blocks at this - // height to see if one is suitable for transmission. There is no reasonable case where the sentinel should - // transmit more than one block per height, so we only consider transmitting the block with the lowest - // score. - if (lastBlockTransmissionHeight < heightToProcess) { - - Block lowestScoredBlock = null; - long lowestChainScore = Long.MAX_VALUE; - for (Block block : blocksCreatedForManagedVerifiers) { - long chainScore = block.chainScore(frozenEdgeHeight); - if (BlockManager.verifierInCurrentCycle(ByteBuffer.wrap(block.getVerifierIdentifier())) && - chainScore < lowestChainScore) { - lowestChainScore = chainScore; - lowestScoredBlock = block; + // If the map of blocks is empty, make the blocks now. + if (blocksCreatedForManagedVerifiers.isEmpty()) { + for (ManagedVerifier verifier : verifierList) { + Block block = createNextBlock(frozenEdge, verifier); + if (block != null) { + blocksCreatedForManagedVerifiers.add(block); + } } } - // If the block's minimum vote timestamp is in the past, transmit the block now. This is stricter - // than the verifier, which will transmit a block whose minimum vote timestamp is up to 10 seconds - // in the future. - if (lowestChainScore < Long.MAX_VALUE - 1L) { - - // Mark that we are able to create valid chain scores. - calculatingValidChainScores = true; - - long minimumVoteTimestamp = frozenEdge.getVerificationTimestamp() + - Block.minimumVerificationInterval + lowestChainScore * 20000L + blockTransmissionDelay; - - LogUtil.println(String.format("minimum vote timestamp is in %.1f seconds", - (minimumVoteTimestamp - System.currentTimeMillis()) / 1000.0) + " for chain score " + - lowestChainScore); - - if (minimumVoteTimestamp < System.currentTimeMillis() && lastBlockTransmissionTimestamp < - System.currentTimeMillis() - minimumBlockTransmissionInterval) { - - lastBlockTransmissionTimestamp = System.currentTimeMillis(); - - // 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. - ManagedVerifier verifier = - verifierMap.get(ByteBuffer.wrap(lowestScoredBlock.getVerifierIdentifier())); - Message message = new Message(MessageType.NewBlock9, new NewBlockMessage(lowestScoredBlock), - verifier.getSeed()); + // If we have not yet transmitted a block for a managed verifier, check the scores for all blocks at this + // height to see if one is suitable for transmission. There is no reasonable case where the sentinel should + // transmit more than one block per height, so we only consider transmitting the block with the lowest + // score. + if (lastBlockTransmissionHeight < heightToProcess) { + + Block lowestScoredBlock = null; + long lowestChainScore = Long.MAX_VALUE; + for (Block block : blocksCreatedForManagedVerifiers) { + long chainScore = block.chainScore(frozenEdgeHeight); + if (BlockManager.verifierInCurrentCycle(ByteBuffer.wrap(block.getVerifierIdentifier())) && + chainScore < lowestChainScore) { + lowestChainScore = chainScore; + lowestScoredBlock = block; + } + } - Set combinedCycle = combinedCycle(); - AtomicInteger responsesReceived = new AtomicInteger(0); - for (Node node : combinedCycle) { - Message.fetch(node, message, new MessageCallback() { - @Override - public void responseReceived(Message message) { - if (message != null && message.getType() == MessageType.NewBlockResponse10) { - responsesReceived.incrementAndGet(); + // If the block's minimum vote timestamp is in the past, transmit the block now. This is stricter + // than the verifier, which will transmit a block whose minimum vote timestamp is up to 10 seconds + // in the future. + if (lowestChainScore < Long.MAX_VALUE - 1L) { + + // Mark that we are able to create valid chain scores. + calculatingValidChainScores = true; + + long minimumVoteTimestamp = frozenEdge.getVerificationTimestamp() + + Block.minimumVerificationInterval + lowestChainScore * 20000L + blockTransmissionDelay; + + LogUtil.println(String.format("minimum vote timestamp is in %.1f seconds", + (minimumVoteTimestamp - System.currentTimeMillis()) / 1000.0) + " for chain score " + + lowestChainScore); + + if (minimumVoteTimestamp < System.currentTimeMillis() && lastBlockTransmissionTimestamp < + System.currentTimeMillis() - minimumBlockTransmissionInterval) { + + lastBlockTransmissionTimestamp = System.currentTimeMillis(); + + // 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. + ManagedVerifier verifier = + verifierMap.get(ByteBuffer.wrap(lowestScoredBlock.getVerifierIdentifier())); + Message message = new Message(MessageType.NewBlock9, new NewBlockMessage(lowestScoredBlock), + verifier.getSeed()); + + Set combinedCycle = combinedCycle(); + AtomicInteger responsesReceived = new AtomicInteger(0); + for (Node node : combinedCycle) { + Message.fetch(node, message, new MessageCallback() { + @Override + public void responseReceived(Message message) { + if (message != null && message.getType() == MessageType.NewBlockResponse10) { + responsesReceived.incrementAndGet(); + } } - } - }); + }); + } + lastBlockTransmissionHeight = lowestScoredBlock.getBlockHeight(); + lastBlockTransmissionString = lowestScoredBlock.toString(); + PersistentData.put(lastBlockTransmissionHeightKey, lastBlockTransmissionHeight); + PersistentData.put(lastBlockTransmissionStringKey, lastBlockTransmissionString); + LogUtil.println(ConsoleColor.Yellow.background() + "sent block for " + + PrintUtil.compactPrintByteArray(lowestScoredBlock.getVerifierIdentifier()) + + " with hash " + PrintUtil.compactPrintByteArray(lowestScoredBlock.getHash()) + + " at height " + lowestScoredBlock.getBlockHeight() + ConsoleColor.reset); + + // Wait 3 seconds for the responses and store the results for display. This is done to ensure + // that any problems that affect delivery of blocks, from network issues to bugs in the code, + // are detected promptly. + ThreadUtil.sleep(3000L); + int successes = responsesReceived.get(); + int failures = combinedCycle.size() - successes; + lastBlockTransmissionResults = successes + " success, " + failures + " fail"; + PersistentData.put(lastBlockTransmissionResultsKey, lastBlockTransmissionResults); + LogUtil.println(ConsoleColor.Yellow.background() + "transmission results: " + + lastBlockTransmissionResults + ConsoleColor.reset); } - lastBlockTransmissionHeight = lowestScoredBlock.getBlockHeight(); - lastBlockTransmissionString = lowestScoredBlock.toString(); - PersistentData.put(lastBlockTransmissionHeightKey, lastBlockTransmissionHeight); - PersistentData.put(lastBlockTransmissionStringKey, lastBlockTransmissionString); - LogUtil.println(ConsoleColor.Yellow.background() + "sent block for " + - PrintUtil.compactPrintByteArray(lowestScoredBlock.getVerifierIdentifier()) + - " with hash " + PrintUtil.compactPrintByteArray(lowestScoredBlock.getHash()) + - " at height " + lowestScoredBlock.getBlockHeight() + ConsoleColor.reset); - - // Wait 3 seconds for the responses and store the results for display. This is done to ensure - // that any problems that affect delivery of blocks, from network issues to bugs in the code, - // are detected promptly. - ThreadUtil.sleep(3000L); - int successes = responsesReceived.get(); - int failures = combinedCycle.size() - successes; - lastBlockTransmissionResults = successes + " success, " + failures + " fail"; - PersistentData.put(lastBlockTransmissionResultsKey, lastBlockTransmissionResults); - LogUtil.println(ConsoleColor.Yellow.background() + "transmission results: " + - lastBlockTransmissionResults + ConsoleColor.reset); } } } + + } catch (Exception e) { + LogUtil.println("Exception TBIN " + PrintUtil.printException(e)); } } @@ -734,15 +754,20 @@ private static Block createNextBlock(Block previousBlock, ManagedVerifier verifi return block; } - private static synchronized void freezeBlock(Block block) { + private static synchronized void freezeBlock(Block block, byte[] identifier) { numberOfBlocksReceived++; if (block.getBlockHeight() == BlockManager.getFrozenEdgeHeight() + 1L) { numberOfBlocksFrozen++; - BlockManager.freezeBlock(block); - frozenEdge = block; - - System.out.println("froze block " + block + String.format(", efficiency: %.1f%%", getEfficiency())); + BlockManager.freezeBlock(block); // this fails silently + if (block.getBlockHeight() > BlockManager.getFrozenEdgeHeight()) { + frozenEdge = BlockManager.getFrozenEdge(); + System.out.println("X:Block manager freeze fail, still at " + BlockManager.getFrozenEdgeHeight() + + " Wrong block "+ block + " from "+NicknameManager.get(identifier) ); + } else { + frozenEdge = block; // Egg: Wrong if block was not frozen + System.out.println("X:froze block " + block + " from " + NicknameManager.get(identifier) + String.format(", efficiency: %.1f%%", getEfficiency())); + } } } diff --git a/src/main/java/co/nyzo/verifier/web/SentinelController.java b/src/main/java/co/nyzo/verifier/web/SentinelController.java index 85f17985..8fe016b2 100644 --- a/src/main/java/co/nyzo/verifier/web/SentinelController.java +++ b/src/main/java/co/nyzo/verifier/web/SentinelController.java @@ -88,8 +88,10 @@ private static HtmlElement header() { header.append("
Protecting verifiers: "); if (!Sentinel.isCalculatingValidChainScores()) { header.append("no"); - } else if (frozenEdge == null || frozenEdge.getVerificationTimestamp() < System.currentTimeMillis() - 80000L) { - header.append("uncertain"); + } else if (frozenEdge == null) { + header.append("uncertain (frozen edge is null)"); + } else if(frozenEdge.getVerificationTimestamp() < System.currentTimeMillis() - 80000L) { + header.append("uncertain (frozen edge is older than 80sec)"); } else { header.append("yes"); }