<commit_before>#!/usr/bin/env python3
# Copyright (c) 2022 The Bitcoin developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test getavaaddr p2p message"""
import time
from decimal import Decimal

from test_framework.avatools import AvaP2PInterface, gen_proof
from test_framework.messages import (
    NODE_AVALANCHE,
    NODE_NETWORK,
    AvalancheVote,
    AvalancheVoteError,
    msg_avahello,
    msg_getaddr,
    msg_getavaaddr,
    msg_verack,
)
from test_framework.p2p import P2PInterface, p2p_lock
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import MAX_NODES, assert_equal, p2p_port, uint256_hex

# getavaaddr time interval in seconds, as defined in net_processing.cpp
# A node will ignore repeated getavaaddr during this interval
GETAVAADDR_INTERVAL = 2 * 60

# Address are sent every 30s on average, with a Poisson filter. Use a large
# enough delay so it's very unlikely we don't get the message within this time.
MAX_ADDR_SEND_DELAY = 10 * 60

# The interval between avalanche statistics computation
AVALANCHE_STATISTICS_INTERVAL = 10 * 60

# The getavaaddr messages are sent every 2 to 5 minutes
MAX_GETAVAADDR_DELAY = 5 * 60


class AddrReceiver(P2PInterface):
    def __init__(self):
        super().__init__()
        self.received_addrs = None

    def get_received_addrs(self):
        with p2p_lock:
            return self.received_addrs

    def on_addr(self, message):
        self.received_addrs = []
        for addr in message.addrs:
            self.received_addrs.append(f"{addr.ip}:{addr.port}")

    def addr_received(self):
        return self.received_addrs is not None


class MutedAvaP2PInterface(AvaP2PInterface):
    def __init__(self, test_framework=None, node=None):
        super().__init__(test_framework, node)
        self.is_responding = False
        self.privkey = None
        self.addr = None
        self.poll_received = 0

    def set_addr(self, addr):
        self.addr = addr

    def on_avapoll(self, message):
        self.poll_received += 1


class AllYesAvaP2PInterface(MutedAvaP2PInterface):
    def __init__(self, test_framework=None, node=None):
        super().__init__(test_framework, node)
        self.is_responding = True

    def on_avapoll(self, message):
        self.send_avaresponse(
            message.poll.round, [
                AvalancheVote(
                    AvalancheVoteError.ACCEPTED, inv.hash) for inv in message.poll.invs],
            self.master_privkey if self.delegation is None else self.delegated_privkey)
        super().on_avapoll(message)


class AvaHelloInterface(AvaP2PInterface):
    def __init__(self):
        super().__init__()

    def on_version(self, message):
        self.send_message(msg_verack())
        self.send_message(msg_avahello())


class AvaAddrTest(BitcoinTestFramework):
    def set_test_params(self):
        self.setup_clean_chain = False
        self.num_nodes = 1
        self.extra_args = [
            [
                '-avalanche=1',
                '-avaproofstakeutxodustthreshold=1000000',
                '-avaproofstakeutxoconfirmations=1',
                '-avacooldown=0',
                '-avaminquorumstake=0',
                '-avaminavaproofsnodecount=0',
                '-whitelist=noban@127.0.0.1',
            ]
        ]

    def check_all_peers_received_getavaaddr_once(self, avapeers):
        def received_all_getavaaddr(avapeers):
            with p2p_lock:
                return all([p.last_message.get("getavaaddr")
                           for p in avapeers])
        self.wait_until(lambda: received_all_getavaaddr(avapeers))

        with p2p_lock:
            assert all([p.message_count.get(
                "getavaaddr", 0) == 1 for p in avapeers])

    def getavaaddr_interval_test(self):
        node = self.nodes[0]

        # Init mock time
        mock_time = int(time.time())
        node.setmocktime(mock_time)

        # Add some avalanche peers to the node
        for _ in range(10):
            node.add_p2p_connection(AllYesAvaP2PInterface(self, node))

        # Build some statistics to ensure some addresses will be returned
        def all_peers_received_poll():
            with p2p_lock:
                return all([avanode.poll_received >
                           0 for avanode in node.p2ps])
        self.wait_until(all_peers_received_poll)
        node.mockscheduler(AVALANCHE_STATISTICS_INTERVAL)

        requester = node.add_p2p_connection(AddrReceiver())
        requester.send_message(msg_getavaaddr())
        # Remember the time we sent the getavaaddr message
        getavaddr_time = mock_time

        # Spamming more get getavaaddr has no effect
        for _ in range(10):
            with node.assert_debug_log(["Ignoring repeated getavaaddr from peer"]):
                requester.send_message(msg_getavaaddr())

        # Move the time so we get an addr response
        mock_time += MAX_ADDR_SEND_DELAY
        node.setmocktime(mock_time)
        requester.wait_until(requester.addr_received)

        # Elapse the getavaaddr interval and check our message is now accepted
        # again
        mock_time = getavaddr_time + GETAVAADDR_INTERVAL
        node.setmocktime(mock_time)

        requester.send_message(msg_getavaaddr())

        # We can get an addr message again
        mock_time += MAX_ADDR_SEND_DELAY
        node.setmocktime(mock_time)
        requester.wait_until(requester.addr_received)

    def address_test(self, maxaddrtosend, num_proof, num_avanode):
        self.restart_node(
            0,
            extra_args=self.extra_args[0] +
            [f'-maxaddrtosend={maxaddrtosend}'])
        node = self.nodes[0]

        # Init mock time<commit_msg>[avalanche] make the mocktime increase monotonically<commit_after>#!/usr/bin/env python3
# Copyright (c) 2022 The Bitcoin developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test getavaaddr p2p message"""
import time
from decimal import Decimal

from test_framework.avatools import AvaP2PInterface, gen_proof
from test_framework.messages import (
    NODE_AVALANCHE,
    NODE_NETWORK,
    AvalancheVote,
    AvalancheVoteError,
    msg_avahello,
    msg_getaddr,
    msg_getavaaddr,
    msg_verack,
)
from test_framework.p2p import P2PInterface, p2p_lock
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import MAX_NODES, assert_equal, p2p_port, uint256_hex

# getavaaddr time interval in seconds, as defined in net_processing.cpp
# A node will ignore repeated getavaaddr during this interval
GETAVAADDR_INTERVAL = 2 * 60

# Address are sent every 30s on average, with a Poisson filter. Use a large
# enough delay so it's very unlikely we don't get the message within this time.
MAX_ADDR_SEND_DELAY = 10 * 60

# The interval between avalanche statistics computation
AVALANCHE_STATISTICS_INTERVAL = 10 * 60

# The getavaaddr messages are sent every 2 to 5 minutes
MAX_GETAVAADDR_DELAY = 5 * 60


class AddrReceiver(P2PInterface):
    def __init__(self):
        super().__init__()
        self.received_addrs = None

    def get_received_addrs(self):
        with p2p_lock:
            return self.received_addrs

    def on_addr(self, message):
        self.received_addrs = []
        for addr in message.addrs:
            self.received_addrs.append(f"{addr.ip}:{addr.port}")

    def addr_received(self):
        return self.received_addrs is not None


class MutedAvaP2PInterface(AvaP2PInterface):
    def __init__(self, test_framework=None, node=None):
        super().__init__(test_framework, node)
        self.is_responding = False
        self.privkey = None
        self.addr = None
        self.poll_received = 0

    def set_addr(self, addr):
        self.addr = addr

    def on_avapoll(self, message):
        self.poll_received += 1


class AllYesAvaP2PInterface(MutedAvaP2PInterface):
    def __init__(self, test_framework=None, node=None):
        super().__init__(test_framework, node)
        self.is_responding = True

    def on_avapoll(self, message):
        self.send_avaresponse(
            message.poll.round, [
                AvalancheVote(
                    AvalancheVoteError.ACCEPTED, inv.hash) for inv in message.poll.invs],
            self.master_privkey if self.delegation is None else self.delegated_privkey)
        super().on_avapoll(message)


class AvaHelloInterface(AvaP2PInterface):
    def __init__(self):
        super().__init__()

    def on_version(self, message):
        self.send_message(msg_verack())
        self.send_message(msg_avahello())


class AvaAddrTest(BitcoinTestFramework):
    def set_test_params(self):
        self.setup_clean_chain = False
        self.num_nodes = 1
        self.extra_args = [
            [
                '-avalanche=1',
                '-avaproofstakeutxodustthreshold=1000000',
                '-avaproofstakeutxoconfirmations=1',
                '-avacooldown=0',
                '-avaminquorumstake=0',
                '-avaminavaproofsnodecount=0',
                '-whitelist=noban@127.0.0.1',
            ]
        ]

    def check_all_peers_received_getavaaddr_once(self, avapeers):
        def received_all_getavaaddr(avapeers):
            with p2p_lock:
                return all([p.last_message.get("getavaaddr")
                           for p in avapeers])
        self.wait_until(lambda: received_all_getavaaddr(avapeers))

        with p2p_lock:
            assert all([p.message_count.get(
                "getavaaddr", 0) == 1 for p in avapeers])

    def getavaaddr_interval_test(self):
        node = self.nodes[0]

        # Init mock time
        mock_time = int(time.time())
        node.setmocktime(mock_time)

        # Add some avalanche peers to the node
        for _ in range(10):
            node.add_p2p_connection(AllYesAvaP2PInterface(self, node))

        # Build some statistics to ensure some addresses will be returned
        def all_peers_received_poll():
            with p2p_lock:
                return all([avanode.poll_received >
                           0 for avanode in node.p2ps])
        self.wait_until(all_peers_received_poll)
        node.mockscheduler(AVALANCHE_STATISTICS_INTERVAL)

        requester = node.add_p2p_connection(AddrReceiver())
        requester.send_message(msg_getavaaddr())
        # Remember the time we sent the getavaaddr message
        getavaddr_time = mock_time

        # Spamming more get getavaaddr has no effect
        for _ in range(10):
            with node.assert_debug_log(["Ignoring repeated getavaaddr from peer"]):
                requester.send_message(msg_getavaaddr())

        # Move the time so we get an addr response
        mock_time += MAX_ADDR_SEND_DELAY
        node.setmocktime(mock_time)
        requester.wait_until(requester.addr_received)

        # Check our message is now accepted again now that the getavaaddr
        # interval is elapsed
        assert mock_time >= getavaddr_time + GETAVAADDR_INTERVAL
        requester.send_message(msg_getavaaddr())

        # We can get an addr message again
        mock_time += MAX_ADDR_SEND_DELAY
        node.setmocktime(mock_time)
        requester.wait_until(requester.addr_received)

    def address_test(self, maxaddrtosend, num_proof, num_avanode):
        self.restart_node(
            0,
            extra_args=self.extra_args[0] +
            [f'-maxaddrtosend={maxaddrtosend}'])
        node = self.nodes[0]

        # Init mock time
{'fraction_non_alphanumeric': 0.07768325169717281, 'fraction_numerical': 0.013405516885795308, 'mean_word_length': 2.655150753768844, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4424968', 'n_tokens_mistral': 3728, 'n_tokens_neox': 3511, 'n_words': 814}