예제 #1
1
        public void handle(PeerMessage event) {
          PeerAddress oldFriend;
          PeerAddress sender = event.getMSPeerSource();
          PeerAddress newFriend = event.getNewFriend();

          // add the sender address to the list of friends
          if (!friends.contains(sender)) {
            if (friends.size() == viewSize) {
              oldFriend = friends.get(rand.nextInt(viewSize));
              friends.remove(oldFriend);
              fdUnregister(oldFriend);
              Snapshot.removeFriend(serverPeerAddress, oldFriend);
            }

            friends.addElement(sender);
            fdRegister(sender);
            Snapshot.addFriend(serverPeerAddress, sender);
          }

          // add the received new friend from the sender to the list of friends
          if (!friends.contains(newFriend) && !serverPeerAddress.equals(newFriend)) {
            if (friends.size() == viewSize) {
              oldFriend = friends.get(rand.nextInt(viewSize));
              friends.remove(oldFriend);
              fdUnregister(oldFriend);
              Snapshot.removeFriend(serverPeerAddress, oldFriend);
            }

            friends.addElement(newFriend);
            fdRegister(newFriend);
            Snapshot.addFriend(serverPeerAddress, newFriend);
          }
        }
예제 #2
0
파일: PeerMap.java 프로젝트: xzqttt/TomP2P
 /**
  * Remove a peer from the list. In order to not reappear, the node is put for a certain time in a
  * cache list to keep the node removed. This method is thread-safe.
  *
  * @param remotePeer The node that should be removed
  * @param force A flag that removes a peer immediately.
  * @return True if the neighbor was removed and added to a cache list. False if peer has not been
  *     removed or is already in the peer removed temporarly list.
  */
 public boolean peerOffline(final PeerAddress remotePeer, final boolean force) {
   if (logger.isDebugEnabled()) {
     logger.debug("peer " + remotePeer + " is offline");
   }
   if (remotePeer.getID().isZero() || self().equals(remotePeer.getID())) {
     return false;
   }
   notifyPeerFail(remotePeer, force);
   Log log;
   synchronized (peerOfflineLogs) {
     log = peerOfflineLogs.get(remotePeer);
     if (log == null) {
       log = new Log();
       peerOfflineLogs.put(remotePeer, log);
     }
   }
   synchronized (log) {
     if (!force) {
       if (shouldPeerBeRemoved(log)) {
         remove(remotePeer, Reason.NOT_REACHABLE);
         return true;
       }
       log.inc();
       if (!shouldPeerBeRemoved(log)) {
         peerMapStat.removeStat(remotePeer);
         addToMaintenanceQueue(remotePeer);
         return false;
       }
     } else {
       log.set(maxFail);
     }
   }
   remove(remotePeer, Reason.NOT_REACHABLE);
   return true;
 }
예제 #3
0
파일: PeerMap.java 프로젝트: xzqttt/TomP2P
 public boolean contains(PeerAddress peerAddress) {
   final int classMember = classMember(peerAddress.getID());
   if (classMember == -1) {
     // -1 means we searched for ourself and we never are our neighbor
     return false;
   }
   Map<Number160, PeerAddress> tmp = peerMap.get(classMember);
   return tmp.containsKey(peerAddress.getID());
 }
예제 #4
0
 public static ChannelFuture connect(PeerAddress peerAddress, byte[] hashinfo)
     throws InterruptedException {
   if (bootstrap == null) {
     init();
   }
   bootstrap.handler(HandlerFactory.client(hashinfo));
   ChannelFuture channelFuture =
       bootstrap.connect(peerAddress.getAddress(), peerAddress.getPort()).sync();
   register(peerAddress, channelFuture.channel());
   return channelFuture;
 }
예제 #5
0
파일: PeerMap.java 프로젝트: xzqttt/TomP2P
 /**
  * Checks if a peer already existis in this map and if it does, it will update the entry becaues
  * the peer address (e.g. port) may have changed.
  *
  * @param peerAddress The address of the peer that may have been changed.
  * @return True if we have updated the peer, false otherwise
  */
 public boolean updateExistingPeerAddress(PeerAddress peerAddress) {
   final int classMember = classMember(peerAddress.getID());
   Map<Number160, PeerAddress> tmp = peerMap.get(classMember);
   synchronized (tmp) {
     if (tmp.containsKey(peerAddress.getID())) {
       tmp.put(peerAddress.getID(), peerAddress);
       return true;
     }
   }
   return false;
 }
예제 #6
0
파일: PeerMap.java 프로젝트: xzqttt/TomP2P
 /**
  * Removes the peer from the neighbor list if present in the list. Notifies listeners that a peer
  * is offline.
  *
  * @param remotePeer The peer that has gone offline.
  * @param reason The reason for going offline
  * @return True if the peer was in our map and was removed.
  */
 private boolean remove(final PeerAddress remotePeer, final Reason reason) {
   final int classMember = classMember(remotePeer.getID());
   final Map<Number160, PeerAddress> map = peerMap.get(classMember);
   final boolean retVal = map.remove(remotePeer.getID()) != null;
   if (retVal) {
     removeFromMaintenance(remotePeer);
     peerCount.decrementAndGet();
     notifyRemove(remotePeer);
   }
   notifyOffline(remotePeer, reason);
   return retVal;
 }
예제 #7
0
  /** Catch any exceptions, logging them and then closing the channel. */
  private void exceptionCaught(Exception e) {
    PeerAddress addr = getAddress();
    String s = addr == null ? "?" : addr.toString();
    if (e instanceof ConnectException || e instanceof IOException) {
      // Short message for network errors
      log.info(s + " - " + e.getMessage());
    } else {
      log.warn(s + " - ", e);
      Thread.UncaughtExceptionHandler handler = Threading.uncaughtExceptionHandler;
      if (handler != null) handler.uncaughtException(Thread.currentThread(), e);
    }

    close();
  }
  private static void writeConfidence(
      Protos.Transaction.Builder txBuilder,
      TransactionConfidence confidence,
      Protos.TransactionConfidence.Builder confidenceBuilder) {
    synchronized (confidence) {
      confidenceBuilder.setType(
          Protos.TransactionConfidence.Type.valueOf(confidence.getConfidenceType().getValue()));
      if (confidence.getConfidenceType() == ConfidenceType.BUILDING) {
        confidenceBuilder.setAppearedAtHeight(confidence.getAppearedAtChainHeight());
        confidenceBuilder.setDepth(confidence.getDepthInBlocks());
        if (confidence.getWorkDone() != null) {
          confidenceBuilder.setWorkDone(confidence.getWorkDone().longValue());
        }
      }
      if (confidence.getConfidenceType() == ConfidenceType.DEAD) {
        // Copy in the overriding transaction, if available.
        // (A dead coinbase transaction has no overriding transaction).
        if (confidence.getOverridingTransaction() != null) {
          Sha256Hash overridingHash = confidence.getOverridingTransaction().getHash();
          confidenceBuilder.setOverridingTransaction(hashToByteString(overridingHash));
        }
      }
      TransactionConfidence.Source source = confidence.getSource();
      switch (source) {
        case SELF:
          confidenceBuilder.setSource(Protos.TransactionConfidence.Source.SOURCE_SELF);
          break;
        case NETWORK:
          confidenceBuilder.setSource(Protos.TransactionConfidence.Source.SOURCE_NETWORK);
          break;
        case UNKNOWN:
          // Fall through.
        default:
          confidenceBuilder.setSource(Protos.TransactionConfidence.Source.SOURCE_UNKNOWN);
          break;
      }
    }

    for (ListIterator<PeerAddress> it = confidence.getBroadcastBy(); it.hasNext(); ) {
      PeerAddress address = it.next();
      Protos.PeerAddress proto =
          Protos.PeerAddress.newBuilder()
              .setIpAddress(ByteString.copyFrom(address.getAddr().getAddress()))
              .setPort(address.getPort())
              .setServices(address.getServices().longValue())
              .build();
      confidenceBuilder.addBroadcastBy(proto);
    }
    txBuilder.setConfidence(confidenceBuilder);
  }
예제 #9
0
파일: PeerMap.java 프로젝트: xzqttt/TomP2P
 /**
  * Adds a peer to the set. If a peer reaches the bag size, the class is reported to the
  * oversizebag. Furthermore, it notifies listeners about an insert.
  *
  * @param map The set to add the peer
  * @param remotePeer The remote peer to add
  * @param classMember The class member, which is used to report oversize.
  * @return True if the peer could be added. If the peer is already in, it returns false
  */
 private boolean insertOrUpdate(
     final Map<Number160, PeerAddress> map, final PeerAddress remotePeer, final int classMember) {
   boolean retVal;
   synchronized (map) {
     retVal = !map.containsKey(remotePeer.getID());
     map.put(remotePeer.getID(), remotePeer);
   }
   if (retVal) {
     peerCount.incrementAndGet();
     notifyInsert(remotePeer);
   } else {
     notifyUpdate(remotePeer);
   }
   return retVal;
 }
예제 #10
0
  // -------------------------------------------------------------------
  // This method shows how to register the failure detector for a node.
  // -------------------------------------------------------------------
  private void fdRegister(PeerAddress peer) {
    Address peerAddress = peer.getPeerAddress();
    StartProbingPeer spp = new StartProbingPeer(peerAddress, peer);
    fdRequests.put(peerAddress, spp.getRequestId());
    trigger(spp, fd.getPositive(FailureDetector.class));

    fdPeers.put(peerAddress, peer);
  }
예제 #11
0
  // -------------------------------------------------------------------
  // This method shows how to unregister the failure detector for a node.
  // -------------------------------------------------------------------
  private void fdUnregister(PeerAddress peer) {
    if (peer == null) return;

    Address peerAddress = peer.getPeerAddress();
    trigger(
        new StopProbingPeer(peerAddress, fdRequests.get(peerAddress)),
        fd.getPositive(FailureDetector.class));
    fdRequests.remove(peerAddress);

    fdPeers.remove(peerAddress);
  }
예제 #12
0
파일: PeerMap.java 프로젝트: xzqttt/TomP2P
  /**
   * Adds a neighbor to the neighbor list. If the bag is full, the id zero or the same as our id,
   * the neighbor is not added. This method is tread-safe
   *
   * @param remotePeer The node that should be added
   * @param referrer If we had direct contact and we know for sure that this node is online, we set
   *     firsthand to true. Information from 3rd party peers are always second hand and treated as
   *     such
   * @return True if the neighbor could be added or updated, otherwise false.
   */
  public boolean peerFound(final PeerAddress remotePeer, final PeerAddress referrer) {
    boolean firstHand = referrer == null;
    // always trust first hand information
    if (firstHand) {
      notifyPeerOnline(remotePeer);
      synchronized (peerOfflineLogs) {
        peerOfflineLogs.remove(remotePeer);
      }
    }
    // don't add nodes with zero node id, do not add myself and do not add
    // nodes marked as bad
    if (remotePeer.getID().isZero()
        || self().equals(remotePeer.getID())
        || isPeerRemovedTemporarly(remotePeer)
        || filteredAddresses.contains(remotePeer.getInetAddress())) {
      return false;
    }
    // the peer might have a new port
    if (updateExistingPeerAddress(remotePeer)) {
      // we update the peer, so we can exit here and report that we have
      // updated it.
      return true;
    }
    // check if we have should accept this peer in our peer map.
    if (!mapHandler.acceptPeer(firstHand, remotePeer)) {
      return false;
    }

    final int classMember = classMember(remotePeer.getID());
    final Map<Number160, PeerAddress> map = peerMap.get(classMember);
    if (size() < maxPeers) {
      // this updates stats and schedules peer for maintenance
      prepareInsertOrUpdate(remotePeer, firstHand);
      // fill it in, regardless of the bag size, also update if we
      // already have this peer, we update the last seen time with
      // this
      return insertOrUpdate(map, remotePeer, classMember);
    } else {
      // the class is not full, remove other nodes!
      PeerAddress toRemove = removeLatestEntryExceedingBagSize();
      if (classMember(toRemove.getID()) > classMember(remotePeer.getID())) {
        if (remove(toRemove, Reason.REMOVED_FROM_MAP)) {
          // this updates stats and schedules peer for maintenance
          prepareInsertOrUpdate(remotePeer, firstHand);
          return insertOrUpdate(map, remotePeer, classMember);
        }
      }
    }
    return false;
  }
예제 #13
0
        public void handle(PeerInit init) {
          System.out.println("  Server is initiated.");
          serverPeerAddress = init.getMSPeerSelf();
          serverAddress = serverPeerAddress.getPeerAddress();
          // serverAddress ??
          friends = new Vector<PeerAddress>();
          msgPeriod = init.getMSConfiguration().getSnapshotPeriod();

          viewSize = init.getMSConfiguration().getViewSize();

          trigger(
              new BootstrapClientInit(serverAddress, init.getBootstrapConfiguration()),
              bootstrap.getControl());
          trigger(
              new PingFailureDetectorInit(serverAddress, init.getFdConfiguration()),
              fd.getControl());
        }
 private void readConfidence(
     Transaction tx,
     Protos.TransactionConfidence confidenceProto,
     TransactionConfidence confidence)
     throws UnreadableWalletException {
   // We are lenient here because tx confidence is not an essential part of the wallet.
   // If the tx has an unknown type of confidence, ignore.
   if (!confidenceProto.hasType()) {
     log.warn("Unknown confidence type for tx {}", tx.getHashAsString());
     return;
   }
   ConfidenceType confidenceType;
   switch (confidenceProto.getType()) {
     case BUILDING:
       confidenceType = ConfidenceType.BUILDING;
       break;
     case DEAD:
       confidenceType = ConfidenceType.DEAD;
       break;
       // These two are equivalent (must be able to read old wallets).
     case NOT_IN_BEST_CHAIN:
       confidenceType = ConfidenceType.PENDING;
       break;
     case PENDING:
       confidenceType = ConfidenceType.PENDING;
       break;
     case UNKNOWN:
       // Fall through.
     default:
       confidenceType = ConfidenceType.UNKNOWN;
       break;
   }
   confidence.setConfidenceType(confidenceType);
   if (confidenceProto.hasAppearedAtHeight()) {
     if (confidence.getConfidenceType() != ConfidenceType.BUILDING) {
       log.warn("Have appearedAtHeight but not BUILDING for tx {}", tx.getHashAsString());
       return;
     }
     confidence.setAppearedAtChainHeight(confidenceProto.getAppearedAtHeight());
   }
   if (confidenceProto.hasDepth()) {
     if (confidence.getConfidenceType() != ConfidenceType.BUILDING) {
       log.warn("Have depth but not BUILDING for tx {}", tx.getHashAsString());
       return;
     }
     confidence.setDepthInBlocks(confidenceProto.getDepth());
   }
   if (confidenceProto.hasOverridingTransaction()) {
     if (confidence.getConfidenceType() != ConfidenceType.DEAD) {
       log.warn("Have overridingTransaction but not OVERRIDDEN for tx {}", tx.getHashAsString());
       return;
     }
     Transaction overridingTransaction = txMap.get(confidenceProto.getOverridingTransaction());
     if (overridingTransaction == null) {
       log.warn(
           "Have overridingTransaction that is not in wallet for tx {}", tx.getHashAsString());
       return;
     }
     confidence.setOverridingTransaction(overridingTransaction);
   }
   for (Protos.PeerAddress proto : confidenceProto.getBroadcastByList()) {
     InetAddress ip;
     try {
       ip = InetAddress.getByAddress(proto.getIpAddress().toByteArray());
     } catch (UnknownHostException e) {
       throw new UnreadableWalletException("Peer IP address does not have the right length", e);
     }
     int port = proto.getPort();
     int protocolVersion = tx.getParams().getProtocolVersion();
     PeerAddress address = new PeerAddress(ip, port, protocolVersion);
     address.setServices(BigInteger.valueOf(proto.getServices()));
     confidence.markBroadcastBy(address);
   }
   switch (confidenceProto.getSource()) {
     case SOURCE_SELF:
       confidence.setSource(TransactionConfidence.Source.SELF);
       break;
     case SOURCE_NETWORK:
       confidence.setSource(TransactionConfidence.Source.NETWORK);
       break;
     case SOURCE_UNKNOWN:
       // Fall through.
     default:
       confidence.setSource(TransactionConfidence.Source.UNKNOWN);
       break;
   }
 }
예제 #15
0
파일: PeerMap.java 프로젝트: xzqttt/TomP2P
 /**
  * Returns -1 if the first remote node is closer to the key, if the secondBITS is closer, then 1
  * is returned. If both are equal, 0 is returned
  *
  * @param id The id as a distance reference
  * @param rn The peer to test if closer to the id
  * @param rn2 The other peer to test if closer to the id
  * @return -1 if first peer is closer, 1 otherwise, 0 if both are equal
  */
 public static int isKadCloser(Number160 id, PeerAddress rn, PeerAddress rn2) {
   return distance(id, rn.getID()).compareTo(distance(id, rn2.getID()));
 }