<commit_before>/**
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package com.google.bitcoin.core;

import com.google.bitcoin.core.Peer.PeerHandler;
import com.google.bitcoin.discovery.PeerDiscovery;
import com.google.bitcoin.discovery.PeerDiscoveryException;
import com.google.bitcoin.utils.EventListenerInvoker;
import com.google.common.base.Preconditions;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.*;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.*;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * <p>Runs a set of connections to the P2P network, brings up connections to replace disconnected nodes and manages
 * the interaction between them all. Most applications will want to use one of these.</p>
 * 
 * <p>PeerGroup tries to maintain a constant number of connections to a set of distinct peers.
 * Each peer runs a network listener in its own thread.  When a connection is lost, a new peer
 * will be tried after a delay as long as the number of connections less than the maximum.</p>
 * 
 * <p>Connections are made to addresses from a provided list.  When that list is exhausted,
 * we start again from the head of the list.</p>
 * 
 * <p>The PeerGroup can broadcast a transaction to the currently connected set of peers.  It can
 * also handle download of the blockchain from peers, restarting the process when peers die.</p>
 *
 * <p>PeerGroup implements the {@link Service} interface. This means before it will do anything,
 * you must call the {@link com.google.common.util.concurrent.Service#start()} method (which returns
 * a future) or {@link com.google.common.util.concurrent.Service#startAndWait()} method, which will block
 * until peer discovery is completed and some outbound connections have been initiated (it will return
 * before handshaking is done, however). You should call {@link com.google.common.util.concurrent.Service#stop()}
 * when finished. Note that not all methods of PeerGroup are safe to call from a UI thread as some may do
 * network IO, but starting and stopping the service should be fine.</p>
 */
public class PeerGroup extends AbstractIdleService {
    private static final int DEFAULT_CONNECTIONS = 4;

    private static final Logger log = LoggerFactory.getLogger(PeerGroup.class);

    // These lists are all thread-safe so do not have to be accessed under the PeerGroup lock.
    // Addresses to try to connect to, excluding active peers.
    private List<PeerAddress> inactives;
    // Currently active peers. This is an ordered list rather than a set to make unit tests predictable. This is a
    // synchronized list. Locking order is: PeerGroup < Peer < peers. Same for pendingPeers.
    private List<Peer> peers;
    // Currently connecting peers.
    private List<Peer> pendingPeers;
    private ChannelGroup channels;

    // The peer that has been selected for the purposes of downloading announced data.
    private Peer downloadPeer;
    // Callback for events related to chain download
    private PeerEventListener downloadListener;
    // Callbacks for events related to peer connection/disconnection
    private List<PeerEventListener> peerEventListeners;
    // Peer discovery sources, will be polled occasionally if there aren't enough inactives.
    private Set<PeerDiscovery> peerDiscoverers;
    // The version message to use for new connections.
    private VersionMessage versionMessage;
    // A class that tracks recent transactions that have been broadcast across the network, counts how many
    // peers announced them and updates the transaction confidence data. It is passed to each Peer.
    private final MemoryPool memoryPool;
    // How many connections we want to have open at the current time. If we lose connections, we'll try opening more
    // until we reach this count.
    private int maxConnections;

    // Runs a background thread that we use for scheduling pings to our peers, so we can measure their performance
    // and network latency. We ping peers every pingIntervalMsec milliseconds.
    private Timer pingTimer;
    /** How many milliseconds to wait after receiving a pong before sending another ping. */
    public static final long DEFAULT_PING_INTERVAL_MSEC = 1000;
    private long pingIntervalMsec = DEFAULT_PING_INTERVAL_MSEC;

    private final NetworkParameters params;
    private final AbstractBlockChain chain;
    private long fastCatchupTimeSecs;
    private ArrayList<Wallet> wallets;

    private AbstractPeerEventListener getDataListener;
    private ClientBootstrap bootstrap;
    private int minBroadcastConnections = 0;

    private class PeerStartupListener implements Peer.PeerLifecycleListener {
        public void onPeerConnected(Peer peer) {
            pendingPeers.remove(peer);
            peers.add(peer);
            handleNewPeer(peer);
        }

        public void onPeerDisconnected(Peer peer) {
            // The channel will be automatically removed from channels.
            pendingPeers.remove(peer);
            peers.remove(peer);
            handlePeerDeath(peer);<commit_msg>Change default ping time to 2sec<commit_after>/**
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package com.google.bitcoin.core;

import com.google.bitcoin.core.Peer.PeerHandler;
import com.google.bitcoin.discovery.PeerDiscovery;
import com.google.bitcoin.discovery.PeerDiscoveryException;
import com.google.bitcoin.utils.EventListenerInvoker;
import com.google.common.base.Preconditions;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.*;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.*;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * <p>Runs a set of connections to the P2P network, brings up connections to replace disconnected nodes and manages
 * the interaction between them all. Most applications will want to use one of these.</p>
 * 
 * <p>PeerGroup tries to maintain a constant number of connections to a set of distinct peers.
 * Each peer runs a network listener in its own thread.  When a connection is lost, a new peer
 * will be tried after a delay as long as the number of connections less than the maximum.</p>
 * 
 * <p>Connections are made to addresses from a provided list.  When that list is exhausted,
 * we start again from the head of the list.</p>
 * 
 * <p>The PeerGroup can broadcast a transaction to the currently connected set of peers.  It can
 * also handle download of the blockchain from peers, restarting the process when peers die.</p>
 *
 * <p>PeerGroup implements the {@link Service} interface. This means before it will do anything,
 * you must call the {@link com.google.common.util.concurrent.Service#start()} method (which returns
 * a future) or {@link com.google.common.util.concurrent.Service#startAndWait()} method, which will block
 * until peer discovery is completed and some outbound connections have been initiated (it will return
 * before handshaking is done, however). You should call {@link com.google.common.util.concurrent.Service#stop()}
 * when finished. Note that not all methods of PeerGroup are safe to call from a UI thread as some may do
 * network IO, but starting and stopping the service should be fine.</p>
 */
public class PeerGroup extends AbstractIdleService {
    private static final int DEFAULT_CONNECTIONS = 4;

    private static final Logger log = LoggerFactory.getLogger(PeerGroup.class);

    // These lists are all thread-safe so do not have to be accessed under the PeerGroup lock.
    // Addresses to try to connect to, excluding active peers.
    private List<PeerAddress> inactives;
    // Currently active peers. This is an ordered list rather than a set to make unit tests predictable. This is a
    // synchronized list. Locking order is: PeerGroup < Peer < peers. Same for pendingPeers.
    private List<Peer> peers;
    // Currently connecting peers.
    private List<Peer> pendingPeers;
    private ChannelGroup channels;

    // The peer that has been selected for the purposes of downloading announced data.
    private Peer downloadPeer;
    // Callback for events related to chain download
    private PeerEventListener downloadListener;
    // Callbacks for events related to peer connection/disconnection
    private List<PeerEventListener> peerEventListeners;
    // Peer discovery sources, will be polled occasionally if there aren't enough inactives.
    private Set<PeerDiscovery> peerDiscoverers;
    // The version message to use for new connections.
    private VersionMessage versionMessage;
    // A class that tracks recent transactions that have been broadcast across the network, counts how many
    // peers announced them and updates the transaction confidence data. It is passed to each Peer.
    private final MemoryPool memoryPool;
    // How many connections we want to have open at the current time. If we lose connections, we'll try opening more
    // until we reach this count.
    private int maxConnections;

    // Runs a background thread that we use for scheduling pings to our peers, so we can measure their performance
    // and network latency. We ping peers every pingIntervalMsec milliseconds.
    private Timer pingTimer;
    /** How many milliseconds to wait after receiving a pong before sending another ping. */
    public static final long DEFAULT_PING_INTERVAL_MSEC = 2000;
    private long pingIntervalMsec = DEFAULT_PING_INTERVAL_MSEC;

    private final NetworkParameters params;
    private final AbstractBlockChain chain;
    private long fastCatchupTimeSecs;
    private ArrayList<Wallet> wallets;

    private AbstractPeerEventListener getDataListener;
    private ClientBootstrap bootstrap;
    private int minBroadcastConnections = 0;

    private class PeerStartupListener implements Peer.PeerLifecycleListener {
        public void onPeerConnected(Peer peer) {
            pendingPeers.remove(peer);
            peers.add(peer);
            handleNewPeer(peer);
        }

        public void onPeerDisconnected(Peer peer) {
            // The channel will be automatically removed from channels.
            pendingPeers.remove(peer);
            peers.remove(peer);
            handlePeerDeath(peer);
{'fraction_non_alphanumeric': 0.06748812112426512, 'fraction_numerical': 0.0028187162760731255, 'mean_word_length': 3.8736263736263736, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5030349', 'n_tokens_mistral': 3187, 'n_tokens_neox': 3068, 'n_words': 1350}