示例#1
0
  /**
   * Sleep every interval period, and send the keep alive if no other packets are sent. The
   * interrupt call is made on this thread when any other message is sent.
   */
  public void run() {
    while (this.isRunning) {
      try {
        Thread.sleep(interval);
      } catch (InterruptedException e) {
        continue;
      }

      try {
        peer.sendMessage(Message.KEEP_ALIVE_MSG);
      } catch (IOException e) {
        System.out.println("Couldn't send keep alive message");
      }
    }
  }
    public void run() {
      // We now have enough connected peers to send the transaction.
      // This can be called immediately if we already have enough. Otherwise it'll be called from a
      // peer
      // thread.

      // We will send the tx simultaneously to half the connected peers and wait to hear back from
      // at least half
      // of the other half, i.e., with 4 peers connected we will send the tx to 2 randomly chosen
      // peers, and then
      // wait for it to show up on one of the other two. This will be taken as sign of network
      // acceptance. As can
      // be seen, 4 peers is probably too little - it doesn't taken many broken peers for tx
      // propagation to have
      // a big effect.
      List<Peer> peers = peerGroup.getConnectedPeers(); // snapshots
      // We intern the tx here so we are using a canonical version of the object (as it's
      // unfortunately mutable).
      pinnedTx = peerGroup.getMemoryPool().intern(tx);
      // Prepare to send the transaction by adding a listener that'll be called when confidence
      // changes.
      // Only bother with this if we might actually hear back:
      if (minConnections > 1) pinnedTx.getConfidence().addEventListener(new ConfidenceChange());
      // Satoshis code sends an inv in this case and then lets the peer request the tx data. We just
      // blast out the TX here for a couple of reasons. Firstly it's simpler: in the case where we
      // have
      // just a single connection we don't have to wait for getdata to be received and handled
      // before
      // completing the future in the code immediately below. Secondly, it's faster. The reason the
      // Satoshi client sends an inv is privacy - it means you can't tell if the peer originated the
      // transaction or not. However, we are not a fully validating node and this is advertised in
      // our version message, as SPV nodes cannot relay it doesn't give away any additional
      // information
      // to skip the inv here - we wouldn't send invs anyway.
      int numConnected = peers.size();
      numToBroadcastTo = (int) Math.max(1, Math.round(Math.ceil(peers.size() / 2.0)));
      numWaitingFor = (int) Math.ceil((peers.size() - numToBroadcastTo) / 2.0);
      Collections.shuffle(peers, random);
      peers = peers.subList(0, numToBroadcastTo);
      log.info(
          "broadcastTransaction: We have {} peers, adding {} to the memory pool and sending to {} peers, will wait for {}: {}",
          numConnected,
          tx.getHashAsString(),
          numToBroadcastTo,
          numWaitingFor,
          Joiner.on(",").join(peers));
      for (Peer peer : peers) {
        try {
          peer.sendMessage(pinnedTx);
          // We don't record the peer as having seen the tx in the memory pool because we want to
          // track only
          // how many peers announced to us.
        } catch (Exception e) {
          log.error("Caught exception sending to {}", peer, e);
        }
      }
      // If we've been limited to talk to only one peer, we can't wait to hear back because the
      // remote peer won't tell us about transactions we just announced to it for obvious reasons.
      // So we just have to assume we're done, at that point. This happens when we're not given
      // any peer discovery source and the user just calls connectTo() once.
      if (minConnections == 1) {
        future.set(pinnedTx);
      }
    }