n-y-z-o / nyzoVerifier

Verifier for the Nyzo cryptocurrency
The Unlicense
73 stars 42 forks source link

don't send removal vote if it is empty #21

Closed krypdkat closed 4 years ago

krypdkat commented 4 years ago

Currently, incycle verifiers are sending out a lot of empty Removal Votes (~7500 messages per hour) which somewhat eats CPU (for verifying the messages) and slow down the connection.

https://github.com/n-y-z-o/nyzoVerifier/blob/master/src/main/java/co/nyzo/verifier/VerifierPerformanceManager.java#L218

Suggestion:

if (vote.getIdentifiers().size() > 0)
        {
            // Send the messages.
            int numberOfMessages = 0;
            Message message = new Message(MessageType.VerifierRemovalVote39, vote);
            for (Node node : mesh) {
                ByteBuffer ipAddress = ByteBuffer.wrap(node.getIpAddress());
                if (numberOfMessages < messagesPerIteration &&
                        BlockManager.verifierInCurrentCycle(ByteBuffer.wrap(node.getIdentifier())) &&
                        voteMessageIpToTimestampMap.getOrDefault(ipAddress, Long.MAX_VALUE) <= cutoffTimestamp) {

                    voteMessageIpToTimestampMap.put(ipAddress, System.currentTimeMillis());
                    numberOfMessages++;
                    Message.fetch(node, message, null);
                }
            }
        }

stats from 1 incycle verifier:

   4356  NodeJoinV2_43 (49%)
   3361  VerifierRemovalVote39 (38%)
    458  NewBlock9
    367  MissingBlockRequest25
    168  BlockWithVotesRequest37
     39  BlockRequest11
     17  StatusRequest17
      3  MeshRequest15
      2  MissingBlockVoteRequest23
n-y-z-o commented 4 years ago

Thank you for this. It is an excellent observation.

However, holding back empty removal votes, without any other system changes, would be problematic. If the previous vote was non-empty, then the empty vote would be necessary information. Tracking states locally would require per-verifier tracking, and it would not be 100% accurate, as this verifier cannot guarantee that another verifier successfully processed a message. It could be close, by relying on the message response, but this solution adds a lot of design complication and some memory usage.

This is performed once per block frozen, and 10 messages are sent each iteration. At 7 seconds per block, the average rate of this message is 60 60 10 / 7 = 5,143/hour. If we reduced this to 1 message per iteration, this would be reduced to 60 * 60 / 7 = 514/hour.

One of the nice properties of this process is that it does not grow in resource consumption with cycle growth. The overall time to update the full cycle increases as the cycle grows, but the cycle will not be able to reach a size in the next decade where this will be a problem. So, if this is improved now, the solution will be long-lasting.