Package freenet.node.simulator

Source Code of freenet.node.simulator.RealNodeTest

/* This code is part of Freenet. It is distributed under the GNU General
* Public License, version 2 (or at your option any later version). See
* http://www.gnu.org/ for further details of the GPL. */
package freenet.node.simulator;

import freenet.crypt.RandomSource;
import freenet.io.comm.PeerParseException;
import freenet.node.FSParseException;
import freenet.node.Location;
import freenet.node.Node;
import freenet.node.NodeInitException;
import freenet.node.NodeStats;
import freenet.node.PeerNode;
import freenet.node.DarknetPeerNode.FRIEND_TRUST;
import freenet.node.DarknetPeerNode.FRIEND_VISIBILITY;
import freenet.support.LogThresholdCallback;
import freenet.support.Logger;
import freenet.support.Logger.LogLevel;

/**
* Optional base class for RealNode*Test.
* Has some useful utilities.
* @author toad
* @author robert
*/
public class RealNodeTest {

  static final int EXIT_BASE = NodeInitException.EXIT_NODE_UPPER_LIMIT;
  static final int EXIT_CANNOT_DELETE_OLD_DATA = EXIT_BASE + 3;
  static final int EXIT_PING_TARGET_NOT_REACHED = EXIT_BASE + 4;
  static final int EXIT_INSERT_FAILED = EXIT_BASE + 5;
  static final int EXIT_REQUEST_FAILED = EXIT_BASE + 6;
  static final int EXIT_BAD_DATA = EXIT_BASE + 7;
 
  static final FRIEND_TRUST trust = FRIEND_TRUST.LOW;
  static final FRIEND_VISIBILITY visibility = FRIEND_VISIBILITY.NO;

        private static volatile boolean logMINOR;
  static {
    Logger.registerLogThresholdCallback(new LogThresholdCallback(){
      @Override
      public void shouldUpdate(){
        logMINOR = Logger.shouldLog(LogLevel.MINOR, this);
      }
    });
  }
 
  /* Because we start a whole bunch of nodes at once, we will get many "Not reusing
   * tracker, so wiping old trackers" messages. This is normal, all the nodes start
   * handshaking straight off, they all send JFK(1)s, and we get race conditions. */
 
  /*
   Borrowed from mrogers simulation code (February 6, 2008)
   --
   FIXME: May not generate good networks. Presumably this is because the arrays are always scanned
          [0..n], some nodes tend to have *much* higher connections than the degree (the first few),
          starving the latter ones.
   */
  static void makeKleinbergNetwork (Node[] nodes, boolean idealLocations, int degree, boolean forceNeighbourConnections, RandomSource random)
  {
    if(idealLocations) {
      // First set the locations up so we don't spend a long time swapping just to stabilise each network.
      double div = 1.0 / nodes.length;
      double loc = 0.0;
      for (int i=0; i<nodes.length; i++) {
        nodes[i].setLocation(loc);
        loc += div;
      }
    }
    if(forceNeighbourConnections) {
      for(int i=0;i<nodes.length;i++) {
        int next = (i+1) % nodes.length;
        connect(nodes[i], nodes[next]);
      }
    }
    for (int i=0; i<nodes.length; i++) {
      Node a = nodes[i];
      // Normalise the probabilities
      double norm = 0.0;
      for (int j=0; j<nodes.length; j++) {
        Node b = nodes[j];
        if (a.getLocation() == b.getLocation()) continue;
        norm += 1.0 / distance (a, b);
      }
      // Create degree/2 outgoing connections
      for (int k=0; k<nodes.length; k++) {
        Node b = nodes[k];
        if (a.getLocation() == b.getLocation()) continue;
        double p = 1.0 / distance (a, b) / norm;
        for (int n = 0; n < degree / 2; n++) {
          if (random.nextFloat() < p) {
            connect(a, b);
            break;
          }
        }
      }
    }
  }
 
  static void connect(Node a, Node b) {
    try {
      a.connect (b, trust, visibility);
      b.connect (a, trust, visibility);
    } catch (FSParseException e) {
      Logger.error(RealNodeTest.class, "cannot connect!!!!", e);
    } catch (PeerParseException e) {
      Logger.error(RealNodeTest.class, "cannot connect #2!!!!", e);
    } catch (freenet.io.comm.ReferenceSignatureVerificationException e) {
      Logger.error(RealNodeTest.class, "cannot connect #3!!!!", e);
    }
  }
 
  static double distance(Node a, Node b) {
    double aL=a.getLocation();
    double bL=b.getLocation();
    return Location.distance(aL, bL);
  }
 
  static String getPortNumber(PeerNode p) {
    if (p == null || p.getPeer() == null)
      return "null";
    return Integer.toString(p.getPeer().getPort());
  }
 
  static String getPortNumber(Node n) {
    if (n == null)
      return "null";
    return Integer.toString(n.getDarknetPortNumber());
  }
 
  static void waitForAllConnected(Node[] nodes) throws InterruptedException {
    long tStart = System.currentTimeMillis();
    while(true) {
      int countFullyConnected = 0;
      int countReallyConnected = 0;
      int totalPeers = 0;
      int totalConnections = 0;
      int totalPartialConnections = 0;
      int totalCompatibleConnections = 0;
      int totalBackedOff = 0;
      double totalPingTime = 0.0;
      double maxPingTime = 0.0;
      double minPingTime = Double.MAX_VALUE;
      for(int i=0;i<nodes.length;i++) {
        int countConnected = nodes[i].peers.countConnectedDarknetPeers();
        int countAlmostConnected = nodes[i].peers.countAlmostConnectedDarknetPeers();
        int countTotal = nodes[i].peers.countValidPeers();
        int countBackedOff = nodes[i].peers.countBackedOffPeers(false);
        int countCompatible = nodes[i].peers.countCompatibleDarknetPeers();
        totalPeers += countTotal;
        totalConnections += countConnected;
        totalPartialConnections += countAlmostConnected;
        totalCompatibleConnections += countCompatible;
        totalBackedOff += countBackedOff;
        double pingTime = nodes[i].nodeStats.getNodeAveragePingTime();
        totalPingTime += pingTime;
        if(pingTime > maxPingTime) maxPingTime = pingTime;
        if(pingTime < minPingTime) minPingTime = pingTime;
        if(countConnected == countTotal) {
          countFullyConnected++;
          if(countBackedOff == 0) countReallyConnected++;
        } else {
          if(logMINOR)
            Logger.minor(RealNodeTest.class, "Connection count for "+nodes[i]+" : "+countConnected+" partial "+countAlmostConnected);
        }
        if(countBackedOff > 0) {
          if(logMINOR)
            Logger.minor(RealNodeTest.class, "Backed off: "+nodes[i]+" : "+countBackedOff);
        }
      }
      double avgPingTime = totalPingTime / nodes.length;
      if(countFullyConnected == nodes.length && countReallyConnected == nodes.length && totalBackedOff == 0 &&
          minPingTime < NodeStats.DEFAULT_SUB_MAX_PING_TIME && maxPingTime < NodeStats.DEFAULT_SUB_MAX_PING_TIME && avgPingTime < NodeStats.DEFAULT_SUB_MAX_PING_TIME) {
        System.err.println("All nodes fully connected");
        Logger.normal(RealNodeTest.class, "All nodes fully connected");
        System.err.println();
        return;
      } else {
        long tDelta = (System.currentTimeMillis() - tStart)/1000;
        System.err.println("Waiting for nodes to be fully connected: "+countFullyConnected+" / "+nodes.length+" ("+totalConnections+" / "+totalPeers+" connections total partial "+totalPartialConnections+" compatible "+totalCompatibleConnections+") - backed off "+totalBackedOff+" ping min/avg/max "+(int)minPingTime+"/"+(int)avgPingTime+"/"+(int)maxPingTime+" at "+tDelta+'s');
        Logger.normal(RealNodeTest.class, "Waiting for nodes to be fully connected: "+countFullyConnected+" / "+nodes.length+" ("+totalConnections+" / "+totalPeers+" connections total partial "+totalPartialConnections+" compatible "+totalCompatibleConnections+") - backed off "+totalBackedOff+" ping min/avg/max "+(int)minPingTime+"/"+(int)avgPingTime+"/"+(int)maxPingTime+" at "+tDelta+'s');
        Thread.sleep(1000);
      }
    }
  }

}
TOP

Related Classes of freenet.node.simulator.RealNodeTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.