Exemple #1
0
    async def _periodically_self_advertise_and_clean_data(self):
        while not self.is_closed:
            try:
                try:
                    await asyncio.sleep(24 * 3600)
                except asyncio.CancelledError:
                    return None
                # Clean up known nodes for neighbours every 24 hours.
                async with self.lock:
                    for neighbour in list(self.neighbour_known_peers.keys()):
                        self.neighbour_known_peers[neighbour].clear()
                # Self advertise every 24 hours.
                peer = await self.server.get_peer_info()
                if peer is None:
                    continue
                timestamped_peer = [
                    TimestampedPeerInfo(
                        peer.host,
                        peer.port,
                        uint64(int(time.time())),
                    )
                ]
                msg = make_msg(
                    ProtocolMessageTypes.respond_peers,
                    full_node_protocol.RespondPeers(timestamped_peer),
                )
                await self.server.send_to_all([msg], NodeType.FULL_NODE)

                async with self.lock:
                    for host in list(self.received_count_from_peers.keys()):
                        self.received_count_from_peers[host] = 0
            except Exception as e:
                self.log.error(f"Exception in self advertise: {e}")
                self.log.error(f"Traceback: {traceback.format_exc()}")
 async def _query_dns(self, dns_address):
     try:
         if self.default_port is None:
             self.log.error(
                 "Network id not supported in NETWORK_ID_DEFAULT_PORTS neither in config. Skipping DNS query."
             )
             return
         if self.resolver is None:
             self.log.warn(
                 "Skipping DNS query: asyncresolver not initialized.")
             return
         peers: List[TimestampedPeerInfo] = []
         result = await self.resolver.resolve(qname=dns_address,
                                              lifetime=30)
         for ip in result:
             peers.append(
                 TimestampedPeerInfo(
                     ip.to_text(),
                     self.default_port,
                     0,
                 ))
         self.log.info(f"Received {len(peers)} peers from DNS seeder.")
         if len(peers) == 0:
             return
         await self._respond_peers_common(
             full_node_protocol.RespondPeers(peers), None, False)
     except Exception as e:
         self.log.warn(f"querying DNS introducer failed: {e}")
Exemple #3
0
 async def _address_relay(self):
     while not self.is_closed:
         try:
             try:
                 relay_peer, num_peers = await self.relay_queue.get()
             except asyncio.CancelledError:
                 return None
             relay_peer_info = PeerInfo(relay_peer.host, relay_peer.port)
             if not relay_peer_info.is_valid():
                 continue
             # https://en.bitcoin.it/wiki/Satoshi_Client_Node_Discovery#Address_Relay
             connections = self.server.get_full_node_connections()
             hashes = []
             cur_day = int(time.time()) // (24 * 60 * 60)
             for connection in connections:
                 peer_info = connection.get_peer_info()
                 if peer_info is None:
                     continue
                 cur_hash = int.from_bytes(
                     bytes(
                         std_hash(
                             self.key.to_bytes(32, byteorder="big")
                             + peer_info.get_key()
                             + cur_day.to_bytes(3, byteorder="big")
                         )
                     ),
                     byteorder="big",
                 )
                 hashes.append((cur_hash, connection))
             hashes.sort(key=lambda x: x[0])
             for index, (_, connection) in enumerate(hashes):
                 if index >= num_peers:
                     break
                 peer_info = connection.get_peer_info()
                 pair = (peer_info.host, peer_info.port)
                 async with self.lock:
                     if pair in self.neighbour_known_peers and relay_peer.host in self.neighbour_known_peers[pair]:
                         continue
                     if pair not in self.neighbour_known_peers:
                         self.neighbour_known_peers[pair] = set()
                     self.neighbour_known_peers[pair].add(relay_peer.host)
                 if connection.peer_node_id is None:
                     continue
                 msg = make_msg(
                     ProtocolMessageTypes.respond_peers,
                     full_node_protocol.RespondPeers([relay_peer]),
                 )
                 await connection.send_message(msg)
         except Exception as e:
             self.log.error(f"Exception in address relay: {e}")
             self.log.error(f"Traceback: {traceback.format_exc()}")
Exemple #4
0
 async def _query_dns(self, dns_address):
     try:
         peers: List[TimestampedPeerInfo] = []
         result = await self.resolver.resolve(qname=dns_address, lifetime=30)
         for ip in result:
             peers.append(
                 TimestampedPeerInfo(
                     ip.to_text(),
                     8444,
                     0,
                 )
             )
         self.log.info(f"Received {len(peers)} peers from DNS seeder.")
         if len(peers) == 0:
             return
         await self._respond_peers_common(full_node_protocol.RespondPeers(peers), None, False)
     except Exception as e:
         self.log.error(f"Exception while querying DNS server: {e}")
Exemple #5
0
    async def request_peers(self, peer_info: PeerInfo):
        try:

            # Prevent a fingerprint attack: do not send peers to inbound connections.
            # This asymmetric behavior for inbound and outbound connections was introduced
            # to prevent a fingerprinting attack: an attacker can send specific fake addresses
            # to users' AddrMan and later request them by sending getaddr messages.
            # Making nodes which are behind NAT and can only make outgoing connections ignore
            # the request_peers message mitigates the attack.
            if self.address_manager is None:
                return None
            peers = await self.address_manager.get_peers()
            await self.add_peers_neighbour(peers, peer_info)

            msg = make_msg(
                ProtocolMessageTypes.respond_peers,
                full_node_protocol.RespondPeers(peers),
            )

            return msg
        except Exception as e:
            self.log.error(f"Request peers exception: {e}")
    uint32(2759248594),
    bytes32(
        bytes.fromhex(
            "51f2e23ac76179d69bc9232420f47e2a332b8c2495c24ceef7f730feb53c9117")
    ),
    uint8(167),
    vdf_info,
    vdf_proof,
)

request_peers = full_node_protocol.RequestPeers()

timestamped_peer_info = TimestampedPeerInfo("127.0.0.1", uint16(8444),
                                            uint64(10796))

respond_peers = full_node_protocol.RespondPeers([timestamped_peer_info])

## WALLET PROTOCOL
request_puzzle_solution = wallet_protocol.RequestPuzzleSolution(
    bytes32(
        bytes.fromhex(
            "6edddb46bd154f50566b49c95812e0f1131a0a7162630349fc8d1d696e463e47")
    ),
    uint32(3905474497),
)

program = Program.from_serialized_program(
    SerializedProgram.from_bytes(
        bytes.fromhex(
            "ff01ffff33ffa0f8912302fb33b8188046662785704afc3dd945074e4b45499a7173946e044695ff8203e880ffff33ffa03eaa52e850322dbc281c6b922e9d8819c7b4120ee054c4aa79db50be516a2bcaff8207d08080"
        )), )