aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/README.md2
-rw-r--r--contrib/completions/bash/bitcoin-cli.bash (renamed from contrib/completions/bash/bitcoin-cli.bash-completion)0
-rw-r--r--contrib/completions/bash/bitcoin-tx.bash (renamed from contrib/completions/bash/bitcoin-tx.bash-completion)0
-rw-r--r--contrib/completions/bash/bitcoind.bash (renamed from contrib/completions/bash/bitcoind.bash-completion)0
-rw-r--r--contrib/debian/copyright2
-rw-r--r--contrib/devtools/README.md12
-rw-r--r--contrib/devtools/bitcoin-tidy/CMakeLists.txt67
-rw-r--r--contrib/devtools/bitcoin-tidy/README.md11
-rw-r--r--contrib/devtools/bitcoin-tidy/bitcoin-tidy.cpp22
-rw-r--r--contrib/devtools/bitcoin-tidy/example_logprintf.cpp108
-rw-r--r--contrib/devtools/bitcoin-tidy/logprintf.cpp60
-rw-r--r--contrib/devtools/bitcoin-tidy/logprintf.h29
-rwxr-xr-xcontrib/devtools/circular-dependencies.py5
-rwxr-xr-xcontrib/devtools/clang-format-diff.py314
-rw-r--r--contrib/devtools/headerssync-params.py357
-rw-r--r--contrib/devtools/iwyu/bitcoin.core.imp3
-rwxr-xr-xcontrib/devtools/security-check.py32
-rwxr-xr-xcontrib/devtools/symbol-check.py56
-rwxr-xr-xcontrib/devtools/test-security-check.py45
-rwxr-xr-xcontrib/devtools/test-symbol-check.py9
-rwxr-xr-xcontrib/devtools/test_deterministic_coverage.sh26
-rwxr-xr-xcontrib/devtools/test_utxo_snapshots.sh209
-rwxr-xr-xcontrib/devtools/utils.py3
-rwxr-xr-xcontrib/devtools/utxo_snapshot.sh60
-rw-r--r--contrib/guix/INSTALL.md178
-rw-r--r--contrib/guix/README.md6
-rwxr-xr-xcontrib/guix/guix-build7
-rwxr-xr-xcontrib/guix/guix-codesign4
-rwxr-xr-xcontrib/guix/libexec/build.sh32
-rwxr-xr-xcontrib/guix/libexec/codesign.sh13
-rw-r--r--contrib/guix/libexec/prelude.bash2
-rw-r--r--contrib/guix/manifest.scm418
-rw-r--r--contrib/guix/patches/binutils-unaligned-default.patch22
-rw-r--r--contrib/guix/patches/gcc-broken-longjmp.patch68
-rw-r--r--contrib/guix/patches/gcc-remap-guix-store.patch (renamed from contrib/guix/patches/gcc-10-remap-guix-store.patch)0
-rw-r--r--contrib/guix/patches/glibc-2.27-fcommon.patch4
-rw-r--r--contrib/guix/patches/glibc-2.27-guix-prefix.patch2
-rw-r--r--contrib/guix/patches/glibc-2.27-no-librt.patch53
-rw-r--r--contrib/guix/patches/glibc-2.27-powerpc-ldbrx.patch245
-rw-r--r--contrib/guix/patches/glibc-2.27-riscv64-Use-__has_include-to-include-asm-syscalls.h.patch2
-rw-r--r--contrib/guix/patches/glibc-ldd-x86_64.patch10
-rw-r--r--contrib/guix/patches/glibc-versioned-locpath.patch240
-rw-r--r--contrib/guix/patches/lief-fix-ppc64-nx-default.patch29
-rw-r--r--contrib/guix/patches/nsis-disable-installer-reloc.patch30
-rw-r--r--contrib/guix/patches/nsis-gcc-10-memmove.patch23
-rw-r--r--contrib/guix/patches/vmov-alignment.patch267
-rw-r--r--contrib/init/bitcoind.service11
-rw-r--r--contrib/macdeploy/README.md53
-rw-r--r--contrib/macdeploy/background.tiffbin18464 -> 0 bytes
-rwxr-xr-xcontrib/macdeploy/detached-sig-create.sh2
-rwxr-xr-xcontrib/macdeploy/gen-sdk7
-rwxr-xr-xcontrib/macdeploy/macdeployqtplus111
-rwxr-xr-xcontrib/message-capture/message-capture-parser.py6
-rw-r--r--contrib/seeds/README.md14
-rw-r--r--contrib/seeds/asmap.py81
-rwxr-xr-xcontrib/seeds/generate-seeds.py2
-rwxr-xr-xcontrib/seeds/makeseeds.py51
-rw-r--r--contrib/seeds/nodes_main.txt2317
-rw-r--r--contrib/seeds/nodes_main_manual.txt1079
-rw-r--r--contrib/seeds/nodes_test.txt112
-rwxr-xr-xcontrib/signet/miner2
-rwxr-xr-xcontrib/tracing/mempool_monitor.py8
-rw-r--r--contrib/valgrind.supp27
-rw-r--r--contrib/verify-binaries/README.md88
-rwxr-xr-xcontrib/verify-binaries/test.py59
-rwxr-xr-xcontrib/verify-binaries/verify.py713
-rw-r--r--contrib/verify-commits/trusted-keys1
-rwxr-xr-xcontrib/verify-commits/verify-commits.py15
-rw-r--r--contrib/verifybinaries/README.md30
-rwxr-xr-xcontrib/verifybinaries/verify.py183
70 files changed, 5457 insertions, 2602 deletions
diff --git a/contrib/README.md b/contrib/README.md
index 3c6e978061..f375993ac4 100644
--- a/contrib/README.md
+++ b/contrib/README.md
@@ -35,7 +35,7 @@ Test and Verify Tools
### [TestGen](/contrib/testgen) ###
Utilities to generate test vectors for the data-driven Bitcoin tests.
-### [Verify Binaries](/contrib/verifybinaries) ###
+### [Verify-Binaries](/contrib/verify-binaries) ###
This script attempts to download and verify the signature file SHA256SUMS.asc from bitcoin.org.
Command Line Tools
diff --git a/contrib/completions/bash/bitcoin-cli.bash-completion b/contrib/completions/bash/bitcoin-cli.bash
index 89e01bc09a..89e01bc09a 100644
--- a/contrib/completions/bash/bitcoin-cli.bash-completion
+++ b/contrib/completions/bash/bitcoin-cli.bash
diff --git a/contrib/completions/bash/bitcoin-tx.bash-completion b/contrib/completions/bash/bitcoin-tx.bash
index 51a9fe31cb..51a9fe31cb 100644
--- a/contrib/completions/bash/bitcoin-tx.bash-completion
+++ b/contrib/completions/bash/bitcoin-tx.bash
diff --git a/contrib/completions/bash/bitcoind.bash-completion b/contrib/completions/bash/bitcoind.bash
index c11d99ef31..c11d99ef31 100644
--- a/contrib/completions/bash/bitcoind.bash-completion
+++ b/contrib/completions/bash/bitcoind.bash
diff --git a/contrib/debian/copyright b/contrib/debian/copyright
index ca430170a1..dafc92f8ad 100644
--- a/contrib/debian/copyright
+++ b/contrib/debian/copyright
@@ -5,7 +5,7 @@ Upstream-Contact: Satoshi Nakamoto <satoshin@gmx.com>
Source: https://github.com/bitcoin/bitcoin
Files: *
-Copyright: 2009-2023, Bitcoin Core Developers
+Copyright: 2009-2024, Bitcoin Core Developers
License: Expat
Comment: The Bitcoin Core Developers encompasses all contributors to the
project, listed in the release notes or the git log.
diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md
index 54b1a85588..56eaeef815 100644
--- a/contrib/devtools/README.md
+++ b/contrib/devtools/README.md
@@ -83,13 +83,23 @@ A small script to automatically create manpages in ../../doc/man by running the
This requires help2man which can be found at: https://www.gnu.org/software/help2man/
With in-tree builds this tool can be run from any directory within the
-repostitory. To use this tool with out-of-tree builds set `BUILDDIR`. For
+repository. To use this tool with out-of-tree builds set `BUILDDIR`. For
example:
```bash
BUILDDIR=$PWD/build contrib/devtools/gen-manpages.py
```
+headerssync-params.py
+=====================
+
+A script to generate optimal parameters for the headerssync module (src/headerssync.cpp). It takes no command-line
+options, as all its configuration is set at the top of the file. It runs many times faster inside PyPy. Invocation:
+
+```bash
+pypy3 contrib/devtools/headerssync-params.py
+```
+
gen-bitcoin-conf.sh
===================
diff --git a/contrib/devtools/bitcoin-tidy/CMakeLists.txt b/contrib/devtools/bitcoin-tidy/CMakeLists.txt
new file mode 100644
index 0000000000..1260c71423
--- /dev/null
+++ b/contrib/devtools/bitcoin-tidy/CMakeLists.txt
@@ -0,0 +1,67 @@
+cmake_minimum_required(VERSION 3.22)
+
+project(bitcoin-tidy
+ VERSION
+ 1.0.0
+ DESCRIPTION "clang-tidy checks for Bitcoin Core"
+ LANGUAGES CXX)
+
+include(GNUInstallDirs)
+
+set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD_REQUIRED True)
+set(CMAKE_CXX_EXTENSIONS False)
+
+set(CMAKE_DISABLE_FIND_PACKAGE_CURL ON)
+set(CMAKE_DISABLE_FIND_PACKAGE_FFI ON)
+set(CMAKE_DISABLE_FIND_PACKAGE_LibEdit ON)
+set(CMAKE_DISABLE_FIND_PACKAGE_LibXml2 ON)
+set(CMAKE_DISABLE_FIND_PACKAGE_Terminfo ON)
+set(CMAKE_DISABLE_FIND_PACKAGE_ZLIB ON)
+set(CMAKE_DISABLE_FIND_PACKAGE_zstd ON)
+
+find_package(LLVM REQUIRED CONFIG)
+find_program(CLANG_TIDY_EXE NAMES "clang-tidy-${LLVM_VERSION_MAJOR}" "clang-tidy" HINTS ${LLVM_TOOLS_BINARY_DIR})
+message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
+message(STATUS "Found clang-tidy: ${CLANG_TIDY_EXE}")
+
+add_library(bitcoin-tidy MODULE bitcoin-tidy.cpp logprintf.cpp)
+target_include_directories(bitcoin-tidy SYSTEM PRIVATE ${LLVM_INCLUDE_DIRS})
+
+# Disable RTTI and exceptions as necessary
+if (MSVC)
+ target_compile_options(bitcoin-tidy PRIVATE /GR-)
+else()
+ target_compile_options(bitcoin-tidy PRIVATE -fno-rtti)
+ target_compile_options(bitcoin-tidy PRIVATE -fno-exceptions)
+endif()
+
+if(CMAKE_HOST_APPLE)
+ # ld64 expects no undefined symbols by default
+ target_link_options(bitcoin-tidy PRIVATE -Wl,-flat_namespace)
+ target_link_options(bitcoin-tidy PRIVATE -Wl,-undefined -Wl,suppress)
+endif()
+
+# Add warnings
+if (MSVC)
+ target_compile_options(bitcoin-tidy PRIVATE /W4)
+else()
+ target_compile_options(bitcoin-tidy PRIVATE -Wall)
+ target_compile_options(bitcoin-tidy PRIVATE -Wextra)
+endif()
+
+if(CMAKE_VERSION VERSION_LESS 3.27)
+ set(CLANG_TIDY_COMMAND "${CLANG_TIDY_EXE}" "--load=${CMAKE_BINARY_DIR}/${CMAKE_SHARED_MODULE_PREFIX}bitcoin-tidy${CMAKE_SHARED_MODULE_SUFFIX}" "-checks=-*,bitcoin-*")
+else()
+ # CLANG_TIDY_COMMAND supports generator expressions as of 3.27
+ set(CLANG_TIDY_COMMAND "${CLANG_TIDY_EXE}" "--load=$<TARGET_FILE:bitcoin-tidy>" "-checks=-*,bitcoin-*")
+endif()
+
+# Create a dummy library that runs clang-tidy tests as a side-effect of building
+add_library(bitcoin-tidy-tests OBJECT EXCLUDE_FROM_ALL example_logprintf.cpp)
+add_dependencies(bitcoin-tidy-tests bitcoin-tidy)
+
+set_target_properties(bitcoin-tidy-tests PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}")
+
+
+install(TARGETS bitcoin-tidy LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
diff --git a/contrib/devtools/bitcoin-tidy/README.md b/contrib/devtools/bitcoin-tidy/README.md
new file mode 100644
index 0000000000..c15e07c4ed
--- /dev/null
+++ b/contrib/devtools/bitcoin-tidy/README.md
@@ -0,0 +1,11 @@
+# Bitcoin Tidy
+
+Example Usage:
+
+```bash
+cmake -S . -B build -DLLVM_DIR=$(llvm-config --cmakedir) -DCMAKE_BUILD_TYPE=Release
+
+cmake --build build -j$(nproc)
+
+cmake --build build --target bitcoin-tidy-tests -j$(nproc)
+```
diff --git a/contrib/devtools/bitcoin-tidy/bitcoin-tidy.cpp b/contrib/devtools/bitcoin-tidy/bitcoin-tidy.cpp
new file mode 100644
index 0000000000..0f34d37793
--- /dev/null
+++ b/contrib/devtools/bitcoin-tidy/bitcoin-tidy.cpp
@@ -0,0 +1,22 @@
+// Copyright (c) 2023 Bitcoin Developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "logprintf.h"
+
+#include <clang-tidy/ClangTidyModule.h>
+#include <clang-tidy/ClangTidyModuleRegistry.h>
+
+class BitcoinModule final : public clang::tidy::ClangTidyModule
+{
+public:
+ void addCheckFactories(clang::tidy::ClangTidyCheckFactories& CheckFactories) override
+ {
+ CheckFactories.registerCheck<bitcoin::LogPrintfCheck>("bitcoin-unterminated-logprintf");
+ }
+};
+
+static clang::tidy::ClangTidyModuleRegistry::Add<BitcoinModule>
+ X("bitcoin-module", "Adds bitcoin checks.");
+
+volatile int BitcoinModuleAnchorSource = 0;
diff --git a/contrib/devtools/bitcoin-tidy/example_logprintf.cpp b/contrib/devtools/bitcoin-tidy/example_logprintf.cpp
new file mode 100644
index 0000000000..a12a666c08
--- /dev/null
+++ b/contrib/devtools/bitcoin-tidy/example_logprintf.cpp
@@ -0,0 +1,108 @@
+// Copyright (c) 2023 Bitcoin Developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <string>
+
+// Test for bitcoin-unterminated-logprintf
+
+enum LogFlags {
+ NONE
+};
+
+enum Level {
+ None
+};
+
+template <typename... Args>
+static inline void LogPrintf_(const std::string& logging_function, const std::string& source_file, const int source_line, const LogFlags flag, const Level level, const char* fmt, const Args&... args)
+{
+}
+
+#define LogPrintLevel_(category, level, ...) LogPrintf_(__func__, __FILE__, __LINE__, category, level, __VA_ARGS__)
+#define LogPrintf(...) LogPrintLevel_(LogFlags::NONE, Level::None, __VA_ARGS__)
+
+#define LogPrint(category, ...) \
+ do { \
+ LogPrintf(__VA_ARGS__); \
+ } while (0)
+
+
+class CWallet
+{
+ std::string GetDisplayName() const
+ {
+ return "default wallet";
+ }
+
+public:
+ template <typename... Params>
+ void WalletLogPrintf(const char* fmt, Params... parameters) const
+ {
+ LogPrintf(("%s " + std::string{fmt}).c_str(), GetDisplayName(), parameters...);
+ };
+};
+
+struct ScriptPubKeyMan
+{
+ std::string GetDisplayName() const
+ {
+ return "default wallet";
+ }
+
+ template <typename... Params>
+ void WalletLogPrintf(const char* fmt, Params... parameters) const
+ {
+ LogPrintf(("%s " + std::string{fmt}).c_str(), GetDisplayName(), parameters...);
+ };
+};
+
+void good_func()
+{
+ LogPrintf("hello world!\n");
+}
+void good_func2()
+{
+ CWallet wallet;
+ wallet.WalletLogPrintf("hi\n");
+ ScriptPubKeyMan spkm;
+ spkm.WalletLogPrintf("hi\n");
+
+ const CWallet& walletref = wallet;
+ walletref.WalletLogPrintf("hi\n");
+
+ auto* walletptr = new CWallet();
+ walletptr->WalletLogPrintf("hi\n");
+ delete walletptr;
+}
+void bad_func()
+{
+ LogPrintf("hello world!");
+}
+void bad_func2()
+{
+ LogPrintf("");
+}
+void bad_func3()
+{
+ // Ending in "..." has no special meaning.
+ LogPrintf("hello world!...");
+}
+void bad_func4_ignored()
+{
+ LogPrintf("hello world!"); // NOLINT(bitcoin-unterminated-logprintf)
+}
+void bad_func5()
+{
+ CWallet wallet;
+ wallet.WalletLogPrintf("hi");
+ ScriptPubKeyMan spkm;
+ spkm.WalletLogPrintf("hi");
+
+ const CWallet& walletref = wallet;
+ walletref.WalletLogPrintf("hi");
+
+ auto* walletptr = new CWallet();
+ walletptr->WalletLogPrintf("hi");
+ delete walletptr;
+}
diff --git a/contrib/devtools/bitcoin-tidy/logprintf.cpp b/contrib/devtools/bitcoin-tidy/logprintf.cpp
new file mode 100644
index 0000000000..36beac28c8
--- /dev/null
+++ b/contrib/devtools/bitcoin-tidy/logprintf.cpp
@@ -0,0 +1,60 @@
+// Copyright (c) 2023 Bitcoin Developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "logprintf.h"
+
+#include <clang/AST/ASTContext.h>
+#include <clang/ASTMatchers/ASTMatchFinder.h>
+
+
+namespace {
+AST_MATCHER(clang::StringLiteral, unterminated)
+{
+ size_t len = Node.getLength();
+ if (len > 0 && Node.getCodeUnit(len - 1) == '\n') {
+ return false;
+ }
+ return true;
+}
+} // namespace
+
+namespace bitcoin {
+
+void LogPrintfCheck::registerMatchers(clang::ast_matchers::MatchFinder* finder)
+{
+ using namespace clang::ast_matchers;
+
+ /*
+ Logprintf(..., ..., ..., ..., ..., "foo", ...)
+ */
+
+ finder->addMatcher(
+ callExpr(
+ callee(functionDecl(hasName("LogPrintf_"))),
+ hasArgument(5, stringLiteral(unterminated()).bind("logstring"))),
+ this);
+
+ /*
+ auto walletptr = &wallet;
+ wallet.WalletLogPrintf("foo");
+ wallet->WalletLogPrintf("foo");
+ */
+ finder->addMatcher(
+ cxxMemberCallExpr(
+ callee(cxxMethodDecl(hasName("WalletLogPrintf"))),
+ hasArgument(0, stringLiteral(unterminated()).bind("logstring"))),
+ this);
+}
+
+void LogPrintfCheck::check(const clang::ast_matchers::MatchFinder::MatchResult& Result)
+{
+ if (const clang::StringLiteral* lit = Result.Nodes.getNodeAs<clang::StringLiteral>("logstring")) {
+ const clang::ASTContext& ctx = *Result.Context;
+ const auto user_diag = diag(lit->getEndLoc(), "Unterminated format string used with LogPrintf");
+ const auto& loc = lit->getLocationOfByte(lit->getByteLength(), *Result.SourceManager, ctx.getLangOpts(), ctx.getTargetInfo());
+ user_diag << clang::FixItHint::CreateInsertion(loc, "\\n");
+ }
+}
+
+} // namespace bitcoin
diff --git a/contrib/devtools/bitcoin-tidy/logprintf.h b/contrib/devtools/bitcoin-tidy/logprintf.h
new file mode 100644
index 0000000000..db95dfe143
--- /dev/null
+++ b/contrib/devtools/bitcoin-tidy/logprintf.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2023 Bitcoin Developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef LOGPRINTF_CHECK_H
+#define LOGPRINTF_CHECK_H
+
+#include <clang-tidy/ClangTidyCheck.h>
+
+namespace bitcoin {
+
+// Warn about any use of LogPrintf that does not end with a newline.
+class LogPrintfCheck final : public clang::tidy::ClangTidyCheck
+{
+public:
+ LogPrintfCheck(clang::StringRef Name, clang::tidy::ClangTidyContext* Context)
+ : clang::tidy::ClangTidyCheck(Name, Context) {}
+
+ bool isLanguageVersionSupported(const clang::LangOptions& LangOpts) const override
+ {
+ return LangOpts.CPlusPlus;
+ }
+ void registerMatchers(clang::ast_matchers::MatchFinder* Finder) override;
+ void check(const clang::ast_matchers::MatchFinder::MatchResult& Result) override;
+};
+
+} // namespace bitcoin
+
+#endif // LOGPRINTF_CHECK_H
diff --git a/contrib/devtools/circular-dependencies.py b/contrib/devtools/circular-dependencies.py
index b1d9f2b7db..b742a8cea6 100755
--- a/contrib/devtools/circular-dependencies.py
+++ b/contrib/devtools/circular-dependencies.py
@@ -5,7 +5,6 @@
import sys
import re
-from typing import Dict, List, Set
MAPPING = {
'core_read.cpp': 'core_io.cpp',
@@ -33,7 +32,7 @@ def module_name(path):
return None
files = dict()
-deps: Dict[str, Set[str]] = dict()
+deps: dict[str, set[str]] = dict()
RE = re.compile("^#include <(.*)>")
@@ -65,7 +64,7 @@ while True:
shortest_cycle = None
for module in sorted(deps.keys()):
# Build the transitive closure of dependencies of module
- closure: Dict[str, List[str]] = dict()
+ closure: dict[str, list[str]] = dict()
for dep in deps[module]:
closure[dep] = []
while True:
diff --git a/contrib/devtools/clang-format-diff.py b/contrib/devtools/clang-format-diff.py
index 420bf7ff33..e2b661d65d 100755
--- a/contrib/devtools/clang-format-diff.py
+++ b/contrib/devtools/clang-format-diff.py
@@ -1,166 +1,190 @@
#!/usr/bin/env python3
#
-#===- clang-format-diff.py - ClangFormat Diff Reformatter ----*- python -*--===#
+# ===- clang-format-diff.py - ClangFormat Diff Reformatter ----*- python -*--===#
#
-# The LLVM Compiler Infrastructure
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
-# This file is distributed under the University of Illinois Open Source
-# License.
-#
-# ============================================================
-#
-# University of Illinois/NCSA
-# Open Source License
-#
-# Copyright (c) 2007-2015 University of Illinois at Urbana-Champaign.
-# All rights reserved.
-#
-# Developed by:
-#
-# LLVM Team
-#
-# University of Illinois at Urbana-Champaign
-#
-# http://llvm.org
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy of
-# this software and associated documentation files (the "Software"), to deal with
-# the Software without restriction, including without limitation the rights to
-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-# of the Software, and to permit persons to whom the Software is furnished to do
-# so, subject to the following conditions:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimers.
-#
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimers in the
-# documentation and/or other materials provided with the distribution.
-#
-# * Neither the names of the LLVM Team, University of Illinois at
-# Urbana-Champaign, nor the names of its contributors may be used to
-# endorse or promote products derived from this Software without specific
-# prior written permission.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
-# SOFTWARE.
-#
-# ============================================================
-#
-#===------------------------------------------------------------------------===#
-
-r"""
-ClangFormat Diff Reformatter
-============================
+# ===------------------------------------------------------------------------===#
+"""
This script reads input from a unified diff and reformats all the changed
lines. This is useful to reformat all the lines touched by a specific patch.
Example usage for git/svn users:
- git diff -U0 HEAD^ | clang-format-diff.py -p1 -i
- svn diff --diff-cmd=diff -x-U0 | clang-format-diff.py -i
+ git diff -U0 --no-color --relative HEAD^ | {clang_format_diff} -p1 -i
+ svn diff --diff-cmd=diff -x-U0 | {clang_format_diff} -i
+It should be noted that the filename contained in the diff is used unmodified
+to determine the source file to update. Users calling this script directly
+should be careful to ensure that the path in the diff is correct relative to the
+current working directory.
"""
+from __future__ import absolute_import, division, print_function
import argparse
import difflib
-import io
import re
import subprocess
import sys
-
-# Change this to the full path if clang-format is not on the path.
-binary = 'clang-format'
+from io import StringIO
def main():
- parser = argparse.ArgumentParser(description=
- 'Reformat changed lines in diff. Without -i '
- 'option just output the diff that would be '
- 'introduced.')
- parser.add_argument('-i', action='store_true', default=False,
- help='apply edits to files instead of displaying a diff')
- parser.add_argument('-p', metavar='NUM', default=0,
- help='strip the smallest prefix containing P slashes')
- parser.add_argument('-regex', metavar='PATTERN', default=None,
- help='custom pattern selecting file paths to reformat '
- '(case sensitive, overrides -iregex)')
- parser.add_argument('-iregex', metavar='PATTERN', default=
- r'.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hpp|m|mm|inc|js|ts|proto'
- r'|protodevel|java)',
- help='custom pattern selecting file paths to reformat '
- '(case insensitive, overridden by -regex)')
- parser.add_argument('-sort-includes', action='store_true', default=False,
- help='let clang-format sort include blocks')
- parser.add_argument('-v', '--verbose', action='store_true',
- help='be more verbose, ineffective without -i')
- args = parser.parse_args()
-
- # Extract changed lines for each file.
- filename = None
- lines_by_file = {}
- for line in sys.stdin:
- match = re.search(r'^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line)
- if match:
- filename = match.group(2)
- if filename is None:
- continue
-
- if args.regex is not None:
- if not re.match('^%s$' % args.regex, filename):
- continue
- else:
- if not re.match('^%s$' % args.iregex, filename, re.IGNORECASE):
- continue
-
- match = re.search(r'^@@.*\+(\d+)(,(\d+))?', line)
- if match:
- start_line = int(match.group(1))
- line_count = 1
- if match.group(3):
- line_count = int(match.group(3))
- if line_count == 0:
- continue
- end_line = start_line + line_count - 1
- lines_by_file.setdefault(filename, []).extend(
- ['-lines', str(start_line) + ':' + str(end_line)])
-
- # Reformat files containing changes in place.
- for filename, lines in lines_by_file.items():
- if args.i and args.verbose:
- print('Formatting {}'.format(filename))
- command = [binary, filename]
- if args.i:
- command.append('-i')
- if args.sort_includes:
- command.append('-sort-includes')
- command.extend(lines)
- command.extend(['-style=file', '-fallback-style=none'])
- p = subprocess.Popen(command,
- stdout=subprocess.PIPE,
- stderr=None,
- stdin=subprocess.PIPE,
- text=True)
- stdout, stderr = p.communicate()
- if p.returncode != 0:
- sys.exit(p.returncode)
-
- if not args.i:
- with open(filename, encoding="utf8") as f:
- code = f.readlines()
- formatted_code = io.StringIO(stdout).readlines()
- diff = difflib.unified_diff(code, formatted_code,
- filename, filename,
- '(before formatting)', '(after formatting)')
- diff_string = ''.join(diff)
- if len(diff_string) > 0:
- sys.stdout.write(diff_string)
-
-if __name__ == '__main__':
- main()
+ parser = argparse.ArgumentParser(
+ description=__doc__.format(clang_format_diff="%(prog)s"),
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+ parser.add_argument(
+ "-i",
+ action="store_true",
+ default=False,
+ help="apply edits to files instead of displaying a diff",
+ )
+ parser.add_argument(
+ "-p",
+ metavar="NUM",
+ default=0,
+ help="strip the smallest prefix containing P slashes",
+ )
+ parser.add_argument(
+ "-regex",
+ metavar="PATTERN",
+ default=None,
+ help="custom pattern selecting file paths to reformat "
+ "(case sensitive, overrides -iregex)",
+ )
+ parser.add_argument(
+ "-iregex",
+ metavar="PATTERN",
+ default=r".*\.(?:cpp|cc|c\+\+|cxx|cppm|ccm|cxxm|c\+\+m|c|cl|h|hh|hpp"
+ r"|hxx|m|mm|inc|js|ts|proto|protodevel|java|cs|json|s?vh?)",
+ help="custom pattern selecting file paths to reformat "
+ "(case insensitive, overridden by -regex)",
+ )
+ parser.add_argument(
+ "-sort-includes",
+ action="store_true",
+ default=False,
+ help="let clang-format sort include blocks",
+ )
+ parser.add_argument(
+ "-v",
+ "--verbose",
+ action="store_true",
+ help="be more verbose, ineffective without -i",
+ )
+ parser.add_argument(
+ "-style",
+ help="formatting style to apply (LLVM, GNU, Google, Chromium, "
+ "Microsoft, Mozilla, WebKit)",
+ )
+ parser.add_argument(
+ "-fallback-style",
+ help="The name of the predefined style used as a"
+ "fallback in case clang-format is invoked with"
+ "-style=file, but can not find the .clang-format"
+ "file to use.",
+ )
+ parser.add_argument(
+ "-binary",
+ default="clang-format",
+ help="location of binary to use for clang-format",
+ )
+ args = parser.parse_args()
+
+ # Extract changed lines for each file.
+ filename = None
+ lines_by_file = {}
+ for line in sys.stdin:
+ match = re.search(r"^\+\+\+\ (.*?/){%s}(\S*)" % args.p, line)
+ if match:
+ filename = match.group(2)
+ if filename is None:
+ continue
+
+ if args.regex is not None:
+ if not re.match("^%s$" % args.regex, filename):
+ continue
+ else:
+ if not re.match("^%s$" % args.iregex, filename, re.IGNORECASE):
+ continue
+
+ match = re.search(r"^@@.*\+(\d+)(?:,(\d+))?", line)
+ if match:
+ start_line = int(match.group(1))
+ line_count = 1
+ if match.group(2):
+ line_count = int(match.group(2))
+ # The input is something like
+ #
+ # @@ -1, +0,0 @@
+ #
+ # which means no lines were added.
+ if line_count == 0:
+ continue
+ # Also format lines range if line_count is 0 in case of deleting
+ # surrounding statements.
+ end_line = start_line
+ if line_count != 0:
+ end_line += line_count - 1
+ lines_by_file.setdefault(filename, []).extend(
+ ["-lines", str(start_line) + ":" + str(end_line)]
+ )
+
+ # Reformat files containing changes in place.
+ for filename, lines in lines_by_file.items():
+ if args.i and args.verbose:
+ print("Formatting {}".format(filename))
+ command = [args.binary, filename]
+ if args.i:
+ command.append("-i")
+ if args.sort_includes:
+ command.append("-sort-includes")
+ command.extend(lines)
+ if args.style:
+ command.extend(["-style", args.style])
+ if args.fallback_style:
+ command.extend(["-fallback-style", args.fallback_style])
+
+ try:
+ p = subprocess.Popen(
+ command,
+ stdout=subprocess.PIPE,
+ stderr=None,
+ stdin=subprocess.PIPE,
+ universal_newlines=True,
+ )
+ except OSError as e:
+ # Give the user more context when clang-format isn't
+ # found/isn't executable, etc.
+ raise RuntimeError(
+ 'Failed to run "%s" - %s"' % (" ".join(command), e.strerror)
+ )
+
+ stdout, stderr = p.communicate()
+ if p.returncode != 0:
+ sys.exit(p.returncode)
+
+ if not args.i:
+ with open(filename, encoding="utf8") as f:
+ code = f.readlines()
+ formatted_code = StringIO(stdout).readlines()
+ diff = difflib.unified_diff(
+ code,
+ formatted_code,
+ filename,
+ filename,
+ "(before formatting)",
+ "(after formatting)",
+ )
+ diff_string = "".join(diff)
+ if len(diff_string) > 0:
+ sys.stdout.write(diff_string)
+ sys.exit(1)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/contrib/devtools/headerssync-params.py b/contrib/devtools/headerssync-params.py
new file mode 100644
index 0000000000..0198f5db99
--- /dev/null
+++ b/contrib/devtools/headerssync-params.py
@@ -0,0 +1,357 @@
+#!/usr/bin/env python3
+# Copyright (c) 2022 Pieter Wuille
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+"""Script to find the optimal parameters for the headerssync module through simulation."""
+
+from math import log, exp, sqrt
+from datetime import datetime, timedelta
+import random
+
+# Parameters:
+
+# Aim for still working fine at some point in the future. [datetime]
+TIME = datetime(2026, 10, 5)
+
+# Expected block interval. [timedelta]
+BLOCK_INTERVAL = timedelta(seconds=600)
+
+# The number of headers corresponding to the minchainwork parameter. [headers]
+MINCHAINWORK_HEADERS = 804000
+
+# Combined processing bandwidth from all attackers to one victim. [bit/s]
+# 6 Gbit/s is approximately the speed at which a single thread of a Ryzen 5950X CPU thread can hash
+# headers. In practice, the victim's network bandwidth and network processing overheads probably
+# impose a far lower number, but it's a useful upper bound.
+ATTACK_BANDWIDTH = 6000000000
+
+# How much additional permanent memory usage are attackers (jointly) allowed to cause in the victim,
+# expressed as fraction of the normal memory usage due to mainchain growth, for the duration the
+# attack is sustained. [unitless]
+# 0.2 means that attackers, while they keep up the attack, can cause permanent memory usage due to
+# headers storage to grow at 1.2 header per BLOCK_INTERVAL.
+ATTACK_FRACTION = 0.2
+
+# When this is set, the mapping from period size to memory usage (at optimal buffer size for that
+# period) is assumed to be convex. This greatly speeds up the computation, and does not appear
+# to influence the outcome. Set to False for a stronger guarantee to get the optimal result.
+ASSUME_CONVEX = True
+
+# Explanation:
+#
+# The headerssync module implements a DoS protection against low-difficulty header spam which does
+# not rely on checkpoints. In short it works as follows:
+#
+# - (initial) header synchronization is split into two phases:
+# - A commitment phase, in which headers are downloaded from the peer, and a very compact
+# commitment to them is remembered in per-peer memory. The commitment phase ends when the
+# received chain's combined work reaches a predetermined threshold.
+# - A redownload phase, during which the headers are downloaded a second time from the same peer,
+# and compared against the commitment constructed in the first phase. If there is a match, the
+# redownloaded headers are fed to validation and accepted into permanent storage.
+#
+# This separation guarantees that no headers are accepted into permanent storage without
+# requiring the peer to first prove the chain actually has sufficient work.
+#
+# - To actually implement this commitment mechanism, the following approach is used:
+# - Keep a *1 bit* commitment (constructed using a salted hash function), for every block whose
+# height is a multiple of {period} plus an offset value. If RANDOMIZE_OFFSET, the offset,
+# like the salt, is chosen randomly when the synchronization starts and kept fixed afterwards.
+# - When redownloading, headers are fed through a per-peer queue that holds {bufsize} headers,
+# before passing them to validation. All the headers in this queue are verified against the
+# commitment bits created in the first phase before any header is released from it. This means
+# {bufsize/period} bits are checked "on top of" each header before actually processing it,
+# which results in a commitment structure with roughly {bufsize/period} bits of security, as
+# once a header is modified, due to the prevhash inclusion, all future headers necessarily
+# change as well.
+#
+# The question is what these {period} and {bufsize} parameters need to be set to. This program
+# exhaustively tests a range of values to find the optimal choice, taking into account:
+#
+# - Minimizing the (maximum of) two scenarios that trigger per-peer memory usage:
+#
+# - When downloading a (likely honest) chain that reaches the chainwork threshold after {n}
+# blocks, and then redownloads them, we will consume per-peer memory that is sufficient to
+# store {n/period} commitment bits and {bufsize} headers. We only consider attackers without
+# sufficient hashpower (as otherwise they are from a PoW perspective not attackers), which
+# means {n} is restricted to the honest chain's length before reaching minchainwork.
+#
+# - When downloading a (likely false) chain of {n} headers that never reaches the chainwork
+# threshold, we will consume per-peer memory that is sufficient to store {n/period}
+# commitment bits. Such a chain may be very long, by exploiting the timewarp bug to avoid
+# ramping up difficulty. There is however an absolute limit on how long such a chain can be: 6
+# blocks per second since genesis, due to the increasing MTP consensus rule.
+#
+# - Not gratuitously preventing synchronizing any valid chain, however difficult such a chain may
+# be to construct. In particular, the above scenario with an enormous timewarp-expoiting chain
+# cannot simply be ignored, as it is legal that the honest main chain is like that. We however
+# do not bother minimizing the memory usage in that case (because a billion-header long honest
+# chain will inevitably use far larger amounts of memory than designed for).
+#
+# - Keep the rate at which attackers can get low-difficulty headers accepted to the block index
+# negligible. Specifically, the possibility exists for an attacker to send the honest main
+# chain's headers during the commitment phase, but then start deviating at an attacker-chosen
+# point by sending novel low-difficulty headers instead. Depending on how high we set the
+# {bufsize/period} ratio, we can make the probability that such a header makes it in
+# arbitrarily small, but at the cost of higher memory during the redownload phase. It turns out,
+# some rate of memory usage growth is expected anyway due to chain growth, so permitting the
+# attacker to increase that rate by a small factor isn't concerning. The attacker may start
+# somewhat later than genesis, as long as the difficulty doesn't get too high. This reduces
+# the attacker bandwidth required at the cost of higher PoW needed for constructing the
+# alternate chain. This trade-off is ignored here, as it results in at most a small constant
+# factor in attack rate.
+
+
+# System properties:
+
+# Headers in the redownload buffer are stored without prevhash. [bits]
+COMPACT_HEADER_SIZE = 48 * 8
+
+# How many bits a header uses in P2P protocol. [bits]
+NET_HEADER_SIZE = 81 * 8
+
+# How many headers are sent at once. [headers]
+HEADER_BATCH_COUNT = 2000
+
+# Whether or not the offset of which blocks heights get checksummed is randomized.
+RANDOMIZE_OFFSET = True
+
+# Timestamp of the genesis block
+GENESIS_TIME = datetime(2009, 1, 3)
+
+# Derived values:
+
+# What rate of headers worth of RAM attackers are allowed to cause in the victim. [headers/s]
+LIMIT_HEADERRATE = ATTACK_FRACTION / BLOCK_INTERVAL.total_seconds()
+
+# How many headers can attackers (jointly) send a victim per second. [headers/s]
+NET_HEADERRATE = ATTACK_BANDWIDTH / NET_HEADER_SIZE
+
+# What fraction of headers sent by attackers can at most be accepted by a victim [unitless]
+LIMIT_FRACTION = LIMIT_HEADERRATE / NET_HEADERRATE
+
+# How many headers we permit attackers to cause being accepted per attack. [headers/attack]
+ATTACK_HEADERS = LIMIT_FRACTION * MINCHAINWORK_HEADERS
+
+
+def find_max_headers(when):
+ """Compute the maximum number of headers a valid Bitcoin chain can have at given time."""
+ # When exploiting the timewarp attack, this can be up to 6 per second since genesis.
+ return 6 * ((when - GENESIS_TIME) // timedelta(seconds=1))
+
+
+def lambert_w(value):
+ """Solve the equation x*exp(x)=value (x > 0, value > 0)."""
+ # Initial approximation.
+ approx = max(log(value), 0.0)
+ for _ in range(10):
+ # Newton-Rhapson iteration steps.
+ approx += (value * exp(-approx) - approx) / (approx + 1.0)
+ return approx
+
+
+def attack_rate(period, bufsize, limit=None):
+ """Compute maximal accepted headers per attack in (period, bufsize) configuration.
+
+ If limit is provided, the computation is stopped early when the result is known to exceed the
+ value in limit.
+ """
+
+ max_rate = None
+ max_honest = None
+ # Let the current batch 0 being received be the first one in which the attacker starts lying.
+ # They will only ever start doing so right after a commitment block, but where that is can be
+ # in a number of places. Let honest be the number of honest headers in this current batch,
+ # preceding the forged ones.
+ for honest in range(HEADER_BATCH_COUNT):
+ # The number of headers the attack under consideration will on average get accepted.
+ # This is the number being computed.
+ rate = 0
+
+ # Iterate over the possible alignments of commitments w.r.t. the first batch. In case
+ # the alignments are randomized, try all values. If not, the attacker can know/choose
+ # the alignment, and will always start forging right after a commitment.
+ if RANDOMIZE_OFFSET:
+ align_choices = list(range(period))
+ else:
+ align_choices = [(honest - 1) % period]
+ # Now loop over those possible alignment values, computing the average attack rate
+ # over them by dividing each contribution by len(align_choices).
+ for align in align_choices:
+ # These state variables capture the situation after receiving the first batch.
+ # - The number of headers received after the last commitment for an honest block:
+ after_good_commit = HEADER_BATCH_COUNT - honest + ((honest - align - 1) % period)
+ # - The number of forged headers in the redownload buffer:
+ forged_in_buf = HEADER_BATCH_COUNT - honest
+
+ # Now iterate over the next batches of headers received, adding contributions to the
+ # rate variable.
+ while True:
+ # Process the first HEADER_BATCH_COUNT headers in the buffer:
+ accept_forged_headers = max(forged_in_buf - bufsize, 0)
+ forged_in_buf -= accept_forged_headers
+ if accept_forged_headers:
+ # The probability the attack has not been detected yet at this point:
+ prob = 0.5 ** (after_good_commit // period)
+ # Update attack rate, divided by align_choices to average over the alignments.
+ rate += accept_forged_headers * prob / len(align_choices)
+ # If this means we exceed limit, bail out early (performance optimization).
+ if limit is not None and rate >= limit:
+ return rate, None
+ # If the maximal term being added is negligible compared to rate, stop
+ # iterating.
+ if HEADER_BATCH_COUNT * prob < 1.0e-16 * rate * len(align_choices):
+ break
+ # Update state from a new incoming batch (which is all forged)
+ after_good_commit += HEADER_BATCH_COUNT
+ forged_in_buf += HEADER_BATCH_COUNT
+
+ if max_rate is None or rate > max_rate:
+ max_rate = rate
+ max_honest = honest
+
+ return max_rate, max_honest
+
+
+def memory_usage(period, bufsize, when):
+ """How much memory (max,mainchain,timewarp) does the (period,bufsize) configuration need?"""
+
+ # Per-peer memory usage for a timewarp chain that never meets minchainwork
+ mem_timewarp = find_max_headers(when) // period
+ # Per-peer memory usage for being fed the main chain
+ mem_mainchain = (MINCHAINWORK_HEADERS // period) + bufsize * COMPACT_HEADER_SIZE
+ # Maximum per-peer memory usage
+ max_mem = max(mem_timewarp, mem_mainchain)
+
+ return max_mem, mem_mainchain, mem_timewarp
+
+def find_bufsize(period, attack_headers, when, max_mem=None, min_bufsize=1):
+ """Determine how big bufsize needs to be given a specific period length.
+
+ Given a period, find the smallest value of bufsize such that the attack rate against the
+ (period, bufsize) configuration is below attack_headers. If max_mem is provided, and no
+ such bufsize exists that needs less than max_mem bits of memory, None is returned.
+ min_bufsize is the minimal result to be considered."""
+
+ if max_mem is None:
+ succ_buf = min_bufsize - 1
+ fail_buf = min_bufsize
+ # First double iteratively until an upper bound for failure is found.
+ while True:
+ if attack_rate(period, fail_buf, attack_headers)[0] < attack_headers:
+ break
+ succ_buf, fail_buf = fail_buf, 3 * fail_buf - 2 * succ_buf
+ else:
+ # If a long low-work header chain exists that exceeds max_mem already, give up.
+ if find_max_headers(when) // period > max_mem:
+ return None
+ # Otherwise, verify that the maximal buffer size that permits a mainchain sync with less
+ # than max_mem memory is sufficient to get the attack rate below attack_headers. If not,
+ # also give up.
+ max_buf = (max_mem - (MINCHAINWORK_HEADERS // period)) // COMPACT_HEADER_SIZE
+ if max_buf < min_bufsize:
+ return None
+ if attack_rate(period, max_buf, attack_headers)[0] >= attack_headers:
+ return None
+ # If it is sufficient, that's an upper bound to start our search.
+ succ_buf = min_bufsize - 1
+ fail_buf = max_buf
+
+ # Then perform a bisection search to narrow it down.
+ while fail_buf > succ_buf + 1:
+ try_buf = (succ_buf + fail_buf) // 2
+ if attack_rate(period, try_buf, attack_headers)[0] >= attack_headers:
+ succ_buf = try_buf
+ else:
+ fail_buf = try_buf
+ return fail_buf
+
+
+def optimize(when):
+ """Find the best (period, bufsize) configuration."""
+
+ # When period*bufsize = memory_scale, the per-peer memory for a mainchain sync and a maximally
+ # long low-difficulty header sync are equal.
+ memory_scale = (find_max_headers(when) - MINCHAINWORK_HEADERS) / COMPACT_HEADER_SIZE
+ # Compute approximation for {bufsize/period}, using a formula for a simplified problem.
+ approx_ratio = lambert_w(log(4) * memory_scale / ATTACK_HEADERS**2) / log(4)
+ # Use those for a first attempt.
+ print("Searching configurations:")
+ period = int(sqrt(memory_scale / approx_ratio) + 0.5)
+ bufsize = find_bufsize(period, ATTACK_HEADERS, when)
+ mem = memory_usage(period, bufsize, when)
+ best = (period, bufsize, mem)
+ maps = [(period, bufsize), (MINCHAINWORK_HEADERS + 1, None)]
+ print(f"- Initial: period={period}, buffer={bufsize}, mem={mem[0] / 8192:.3f} KiB")
+
+ # Consider all period values between 1 and MINCHAINWORK_HEADERS, except the one just tried.
+ periods = [iv for iv in range(1, MINCHAINWORK_HEADERS + 1) if iv != period]
+ # Iterate, picking a random element from periods, computing its corresponding bufsize, and
+ # then using the result to shrink the period.
+ while True:
+ # Remove all periods whose memory usage for low-work long chain sync exceed the best
+ # memory usage we've found so far.
+ periods = [p for p in periods if find_max_headers(when) // p < best[2][0]]
+ # Stop if there is nothing left to try.
+ if len(periods) == 0:
+ break
+ # Pick a random remaining option for period size, and compute corresponding bufsize.
+ period = periods.pop(random.randrange(len(periods)))
+ # The buffer size (at a given attack level) cannot shrink as the period grows. Find the
+ # largest period smaller than the selected one we know the buffer size for, and use that
+ # as a lower bound to find_bufsize.
+ min_bufsize = max([(p, b) for p, b in maps if p < period] + [(0,0)])[1]
+ bufsize = find_bufsize(period, ATTACK_HEADERS, when, best[2][0], min_bufsize)
+ if bufsize is not None:
+ # We found a (period, bufsize) configuration with better memory usage than our best
+ # so far. Remember it for future lower bounds.
+ maps.append((period, bufsize))
+ mem = memory_usage(period, bufsize, when)
+ assert mem[0] <= best[2][0]
+ if ASSUME_CONVEX:
+ # Remove all periods that are on the other side of the former best as the new
+ # best.
+ periods = [p for p in periods if (p < best[0]) == (period < best[0])]
+ best = (period, bufsize, mem)
+ print(f"- New best: period={period}, buffer={bufsize}, mem={mem[0] / 8192:.3f} KiB")
+ else:
+ # The (period, bufsize) configuration we found is worse than what we already had.
+ if ASSUME_CONVEX:
+ # Remove all periods that are on the other side of the tried configuration as the
+ # best one.
+ periods = [p for p in periods if (p < period) == (best[0] < period)]
+
+ # Return the result.
+ period, bufsize, _ = best
+ return period, bufsize
+
+
+def analyze(when):
+ """Find the best configuration and print it out."""
+
+ period, bufsize = optimize(when)
+ # Compute accurate statistics for the best found configuration.
+ _, mem_mainchain, mem_timewarp = memory_usage(period, bufsize, when)
+ headers_per_attack, _ = attack_rate(period, bufsize)
+ attack_volume = NET_HEADER_SIZE * MINCHAINWORK_HEADERS
+ # And report them.
+ print()
+ print("Optimal configuration:")
+ print()
+ print("//! Store one header commitment per HEADER_COMMITMENT_PERIOD blocks.")
+ print(f"constexpr size_t HEADER_COMMITMENT_PERIOD{{{period}}};")
+ print()
+ print("//! Only feed headers to validation once this many headers on top have been")
+ print("//! received and validated against commitments.")
+ print(f"constexpr size_t REDOWNLOAD_BUFFER_SIZE{{{bufsize}}};"
+ f" // {bufsize}/{period} = ~{bufsize/period:.1f} commitments")
+ print()
+ print("Properties:")
+ print(f"- Per-peer memory for mainchain sync: {mem_mainchain / 8192:.3f} KiB")
+ print(f"- Per-peer memory for timewarp attack: {mem_timewarp / 8192:.3f} KiB")
+ print(f"- Attack rate: {1/headers_per_attack:.1f} attacks for 1 header of memory growth")
+ print(f" (where each attack costs {attack_volume / 8388608:.3f} MiB bandwidth)")
+
+
+analyze(TIME)
diff --git a/contrib/devtools/iwyu/bitcoin.core.imp b/contrib/devtools/iwyu/bitcoin.core.imp
index 919ffab102..befc949f18 100644
--- a/contrib/devtools/iwyu/bitcoin.core.imp
+++ b/contrib/devtools/iwyu/bitcoin.core.imp
@@ -1,7 +1,4 @@
# Fixups / upstreamed changes
[
- { include: [ "<bits/termios-c_lflag.h>", private, "<termios.h>", public ] },
- { include: [ "<bits/termios-struct.h>", private, "<termios.h>", public ] },
- { include: [ "<bits/termios-tcflow.h>", private, "<termios.h>", public ] },
{ include: [ "<bits/chrono.h>", private, "<chrono>", public ] },
]
diff --git a/contrib/devtools/security-check.py b/contrib/devtools/security-check.py
index 6cd022ef17..f57e9abfec 100755
--- a/contrib/devtools/security-check.py
+++ b/contrib/devtools/security-check.py
@@ -8,9 +8,8 @@ Exit status will be 0 if successful, and the program will be silent.
Otherwise the exit status will be 1 and it will log which executables failed which checks.
'''
import sys
-from typing import List
-import lief #type:ignore
+import lief
def check_ELF_RELRO(binary) -> bool:
'''
@@ -113,7 +112,7 @@ def check_ELF_control_flow(binary) -> bool:
main = binary.get_function_address('main')
content = binary.get_content_from_virtual_address(main, 4, lief.Binary.VA_TYPES.AUTO)
- if content == [243, 15, 30, 250]: # endbr64
+ if content.tolist() == [243, 15, 30, 250]: # endbr64
return True
return False
@@ -142,7 +141,7 @@ def check_PE_control_flow(binary) -> bool:
content = binary.get_content_from_virtual_address(virtual_address, 4, lief.Binary.VA_TYPES.VA)
- if content == [243, 15, 30, 250]: # endbr64
+ if content.tolist() == [243, 15, 30, 250]: # endbr64
return True
return False
@@ -158,12 +157,11 @@ def check_MACHO_NOUNDEFS(binary) -> bool:
'''
return binary.header.has(lief.MachO.HEADER_FLAGS.NOUNDEFS)
-def check_MACHO_LAZY_BINDINGS(binary) -> bool:
+def check_MACHO_FIXUP_CHAINS(binary) -> bool:
'''
- Check for no lazy bindings.
- We don't use or check for MH_BINDATLOAD. See #18295.
+ Check for use of chained fixups.
'''
- return binary.dyld_info.lazy_bind == (0,0)
+ return binary.has_dyld_chained_fixups
def check_MACHO_Canary(binary) -> bool:
'''
@@ -190,7 +188,17 @@ def check_MACHO_control_flow(binary) -> bool:
'''
content = binary.get_content_from_virtual_address(binary.entrypoint, 4, lief.Binary.VA_TYPES.AUTO)
- if content == [243, 15, 30, 250]: # endbr64
+ if content.tolist() == [243, 15, 30, 250]: # endbr64
+ return True
+ return False
+
+def check_MACHO_branch_protection(binary) -> bool:
+ '''
+ Check for branch protection instrumentation
+ '''
+ content = binary.get_content_from_virtual_address(binary.entrypoint, 4, lief.Binary.VA_TYPES.AUTO)
+
+ if content.tolist() == [95, 36, 3, 213]: # bti
return True
return False
@@ -214,8 +222,8 @@ BASE_PE = [
BASE_MACHO = [
('NOUNDEFS', check_MACHO_NOUNDEFS),
- ('LAZY_BINDINGS', check_MACHO_LAZY_BINDINGS),
('Canary', check_MACHO_Canary),
+ ('FIXUP_CHAINS', check_MACHO_FIXUP_CHAINS),
]
CHECKS = {
@@ -233,7 +241,7 @@ CHECKS = {
lief.ARCHITECTURES.X86: BASE_MACHO + [('PIE', check_PIE),
('NX', check_NX),
('CONTROL_FLOW', check_MACHO_control_flow)],
- lief.ARCHITECTURES.ARM64: BASE_MACHO,
+ lief.ARCHITECTURES.ARM64: BASE_MACHO + [('BRANCH_PROTECTION', check_MACHO_branch_protection)],
}
}
@@ -256,7 +264,7 @@ if __name__ == '__main__':
retval = 1
continue
- failed: List[str] = []
+ failed: list[str] = []
for (name, func) in CHECKS[etype][arch]:
if not func(binary):
failed.append(name)
diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py
index f26236dd59..b3e73bb2b9 100755
--- a/contrib/devtools/symbol-check.py
+++ b/contrib/devtools/symbol-check.py
@@ -11,9 +11,8 @@ Example usage:
find ../path/to/binaries -type f -executable | xargs python3 contrib/devtools/symbol-check.py
'''
import sys
-from typing import List, Dict
-import lief #type:ignore
+import lief
# Debian 10 (Buster) EOL: 2024. https://wiki.debian.org/LTS
#
@@ -33,7 +32,7 @@ import lief #type:ignore
# See https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html for more info.
MAX_VERSIONS = {
-'GCC': (4,8,0),
+'GCC': (4,3,0),
'GLIBC': {
lief.ELF.ARCH.x86_64: (2,27),
lief.ELF.ARCH.ARM: (2,27),
@@ -53,7 +52,7 @@ IGNORE_EXPORTS = {
# Expected linker-loader names can be found here:
# https://sourceware.org/glibc/wiki/ABIList?action=recall&rev=16
-ELF_INTERPRETER_NAMES: Dict[lief.ELF.ARCH, Dict[lief.ENDIANNESS, str]] = {
+ELF_INTERPRETER_NAMES: dict[lief.ELF.ARCH, dict[lief.ENDIANNESS, str]] = {
lief.ELF.ARCH.x86_64: {
lief.ENDIANNESS.LITTLE: "/lib64/ld-linux-x86-64.so.2",
},
@@ -72,6 +71,25 @@ ELF_INTERPRETER_NAMES: Dict[lief.ELF.ARCH, Dict[lief.ENDIANNESS, str]] = {
},
}
+ELF_ABIS: dict[lief.ELF.ARCH, dict[lief.ENDIANNESS, list[int]]] = {
+ lief.ELF.ARCH.x86_64: {
+ lief.ENDIANNESS.LITTLE: [3,2,0],
+ },
+ lief.ELF.ARCH.ARM: {
+ lief.ENDIANNESS.LITTLE: [3,2,0],
+ },
+ lief.ELF.ARCH.AARCH64: {
+ lief.ENDIANNESS.LITTLE: [3,7,0],
+ },
+ lief.ELF.ARCH.PPC64: {
+ lief.ENDIANNESS.LITTLE: [3,10,0],
+ lief.ENDIANNESS.BIG: [3,2,0],
+ },
+ lief.ELF.ARCH.RISCV: {
+ lief.ENDIANNESS.LITTLE: [4,15,0],
+ },
+}
+
# Allowed NEEDED libraries
ELF_ALLOWED_LIBRARIES = {
# bitcoind and bitcoin-qt
@@ -79,7 +97,6 @@ ELF_ALLOWED_LIBRARIES = {
'libc.so.6', # C library
'libpthread.so.0', # threading
'libm.so.6', # math library
-'librt.so.1', # real-time (clock)
'libatomic.so.1',
'ld-linux-x86-64.so.2', # 64-bit dynamic linker
'ld-linux.so.2', # 32-bit dynamic linker
@@ -139,21 +156,21 @@ PE_ALLOWED_LIBRARIES = {
'KERNEL32.dll', # win32 base APIs
'msvcrt.dll', # C standard library for MSVC
'SHELL32.dll', # shell API
-'USER32.dll', # user interface
'WS2_32.dll', # sockets
# bitcoin-qt only
'dwmapi.dll', # desktop window manager
'GDI32.dll', # graphics device interface
'IMM32.dll', # input method editor
-'NETAPI32.dll',
+'NETAPI32.dll', # network management
'ole32.dll', # component object model
'OLEAUT32.dll', # OLE Automation API
'SHLWAPI.dll', # light weight shell API
-'USERENV.dll',
-'UxTheme.dll',
+'USER32.dll', # user interface
+'USERENV.dll', # user management
+'UxTheme.dll', # visual style
'VERSION.dll', # version checking
'WINMM.dll', # WinMM audio API
-'WTSAPI32.dll',
+'WTSAPI32.dll', # Remote Desktop
}
def check_version(max_versions, version, arch) -> bool:
@@ -213,12 +230,17 @@ def check_MACHO_libraries(binary) -> bool:
return ok
def check_MACHO_min_os(binary) -> bool:
- if binary.build_version.minos == [10,15,0]:
+ if binary.build_version.minos == [11,0,0]:
return True
return False
def check_MACHO_sdk(binary) -> bool:
- if binary.build_version.sdk == [11, 0, 0]:
+ if binary.build_version.sdk == [14, 0, 0]:
+ return True
+ return False
+
+def check_MACHO_ld64(binary) -> bool:
+ if binary.build_version.tools[0].version == [711, 0, 0]:
return True
return False
@@ -242,17 +264,25 @@ def check_ELF_interpreter(binary) -> bool:
return binary.concrete.interpreter == expected_interpreter
+def check_ELF_ABI(binary) -> bool:
+ expected_abi = ELF_ABIS[binary.header.machine_type][binary.abstract.header.endianness]
+ note = binary.concrete.get(lief.ELF.NOTE_TYPES.ABI_TAG)
+ assert note.details.abi == lief.ELF.NOTE_ABIS.LINUX
+ return note.details.version == expected_abi
+
CHECKS = {
lief.EXE_FORMATS.ELF: [
('IMPORTED_SYMBOLS', check_imported_symbols),
('EXPORTED_SYMBOLS', check_exported_symbols),
('LIBRARY_DEPENDENCIES', check_ELF_libraries),
('INTERPRETER_NAME', check_ELF_interpreter),
+ ('ABI', check_ELF_ABI),
],
lief.EXE_FORMATS.MACHO: [
('DYNAMIC_LIBRARIES', check_MACHO_libraries),
('MIN_OS', check_MACHO_min_os),
('SDK', check_MACHO_sdk),
+ ('LD64', check_MACHO_ld64),
],
lief.EXE_FORMATS.PE: [
('DYNAMIC_LIBRARIES', check_PE_libraries),
@@ -271,7 +301,7 @@ if __name__ == '__main__':
retval = 1
continue
- failed: List[str] = []
+ failed: list[str] = []
for (name, func) in CHECKS[etype]:
if not func(binary):
failed.append(name)
diff --git a/contrib/devtools/test-security-check.py b/contrib/devtools/test-security-check.py
index 54718fd7a1..48823c7e45 100755
--- a/contrib/devtools/test-security-check.py
+++ b/contrib/devtools/test-security-check.py
@@ -5,10 +5,9 @@
'''
Test script for security-check.py
'''
-import lief #type:ignore
+import lief
import os
import subprocess
-from typing import List
import unittest
from utils import determine_wellknown_cmd
@@ -28,13 +27,13 @@ def clean_files(source, executable):
os.remove(source)
os.remove(executable)
-def call_security_check(cc, source, executable, options):
+def call_security_check(cc: str, source: str, executable: str, options) -> tuple:
# This should behave the same as AC_TRY_LINK, so arrange well-known flags
# in the same order as autoconf would.
#
# See the definitions for ac_link in autoconf's lib/autoconf/c.m4 file for
# reference.
- env_flags: List[str] = []
+ env_flags: list[str] = []
for var in ['CFLAGS', 'CPPFLAGS', 'LDFLAGS']:
env_flags += filter(None, os.environ.get(var, '').split(' '))
@@ -119,29 +118,31 @@ class TestSecurityChecks(unittest.TestCase):
arch = get_arch(cc, source, executable)
if arch == lief.ARCHITECTURES.X86:
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fno-stack-protector']),
- (1, executable+': failed NOUNDEFS LAZY_BINDINGS Canary PIE NX CONTROL_FLOW'))
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fstack-protector-all']),
- (1, executable+': failed NOUNDEFS LAZY_BINDINGS PIE NX CONTROL_FLOW'))
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-fstack-protector-all']),
- (1, executable+': failed NOUNDEFS LAZY_BINDINGS PIE CONTROL_FLOW'))
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-fstack-protector-all']),
- (1, executable+': failed LAZY_BINDINGS PIE CONTROL_FLOW'))
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-bind_at_load','-fstack-protector-all']),
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fno-stack-protector', '-Wl,-no_fixup_chains']),
+ (1, executable+': failed NOUNDEFS Canary FIXUP_CHAINS PIE NX CONTROL_FLOW'))
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fno-stack-protector', '-Wl,-fixup_chains']),
+ (1, executable+': failed NOUNDEFS Canary PIE NX CONTROL_FLOW'))
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fstack-protector-all', '-Wl,-fixup_chains']),
+ (1, executable+': failed NOUNDEFS PIE NX CONTROL_FLOW'))
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-fstack-protector-all', '-Wl,-fixup_chains']),
+ (1, executable+': failed NOUNDEFS PIE CONTROL_FLOW'))
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-fstack-protector-all', '-Wl,-fixup_chains']),
(1, executable+': failed PIE CONTROL_FLOW'))
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-bind_at_load','-fstack-protector-all', '-fcf-protection=full']),
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-fstack-protector-all', '-Wl,-fixup_chains']),
+ (1, executable+': failed PIE CONTROL_FLOW'))
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-fstack-protector-all', '-fcf-protection=full', '-Wl,-fixup_chains']),
(1, executable+': failed PIE'))
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-pie','-Wl,-bind_at_load','-fstack-protector-all', '-fcf-protection=full']),
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-pie','-fstack-protector-all', '-fcf-protection=full', '-Wl,-fixup_chains']),
(0, ''))
else:
# arm64 darwin doesn't support non-PIE binaries, control flow or executable stacks
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-flat_namespace','-fno-stack-protector']),
- (1, executable+': failed NOUNDEFS LAZY_BINDINGS Canary'))
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-flat_namespace','-fstack-protector-all']),
- (1, executable+': failed NOUNDEFS LAZY_BINDINGS'))
- self.assertEqual(call_security_check(cc, source, executable, ['-fstack-protector-all']),
- (1, executable+': failed LAZY_BINDINGS'))
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-bind_at_load','-fstack-protector-all']),
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-flat_namespace','-fno-stack-protector', '-Wl,-no_fixup_chains']),
+ (1, executable+': failed NOUNDEFS Canary FIXUP_CHAINS BRANCH_PROTECTION'))
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-flat_namespace','-fno-stack-protector', '-Wl,-fixup_chains', '-mbranch-protection=bti']),
+ (1, executable+': failed NOUNDEFS Canary'))
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-flat_namespace','-fstack-protector-all', '-Wl,-fixup_chains', '-mbranch-protection=bti']),
+ (1, executable+': failed NOUNDEFS'))
+ self.assertEqual(call_security_check(cc, source, executable, ['-fstack-protector-all', '-Wl,-fixup_chains', '-mbranch-protection=bti']),
(0, ''))
diff --git a/contrib/devtools/test-symbol-check.py b/contrib/devtools/test-symbol-check.py
index e304880140..0140decb25 100755
--- a/contrib/devtools/test-symbol-check.py
+++ b/contrib/devtools/test-symbol-check.py
@@ -7,18 +7,17 @@ Test script for symbol-check.py
'''
import os
import subprocess
-from typing import List
import unittest
from utils import determine_wellknown_cmd
-def call_symbol_check(cc: List[str], source, executable, options):
+def call_symbol_check(cc: list[str], source, executable, options):
# This should behave the same as AC_TRY_LINK, so arrange well-known flags
# in the same order as autoconf would.
#
# See the definitions for ac_link in autoconf's lib/autoconf/c.m4 file for
# reference.
- env_flags: List[str] = []
+ env_flags: list[str] = []
for var in ['CFLAGS', 'CPPFLAGS', 'LDFLAGS']:
env_flags += filter(None, os.environ.get(var, '').split(' '))
@@ -28,7 +27,7 @@ def call_symbol_check(cc: List[str], source, executable, options):
os.remove(executable)
return (p.returncode, p.stdout.rstrip())
-def get_machine(cc: List[str]):
+def get_machine(cc: list[str]):
p = subprocess.run([*cc,'-dumpmachine'], stdout=subprocess.PIPE, text=True)
return p.stdout.rstrip()
@@ -121,7 +120,7 @@ class TestSymbolChecks(unittest.TestCase):
}
''')
- self.assertEqual(call_symbol_check(cc, source, executable, ['-Wl,-platform_version','-Wl,macos', '-Wl,10.15', '-Wl,11.4']),
+ self.assertEqual(call_symbol_check(cc, source, executable, ['-Wl,-platform_version','-Wl,macos', '-Wl,11.0', '-Wl,11.4']),
(1, f'{executable}: failed SDK'))
def test_PE(self):
diff --git a/contrib/devtools/test_deterministic_coverage.sh b/contrib/devtools/test_deterministic_coverage.sh
index 8501c72f04..23c260b529 100755
--- a/contrib/devtools/test_deterministic_coverage.sh
+++ b/contrib/devtools/test_deterministic_coverage.sh
@@ -17,21 +17,21 @@ NON_DETERMINISTIC_TESTS=(
"blockfilter_index_tests/blockfilter_index_initial_sync" # src/checkqueue.h: In CCheckQueue::Loop(): while (queue.empty()) { ... }
"coinselector_tests/knapsack_solver_test" # coinselector_tests.cpp: if (equal_sets(setCoinsRet, setCoinsRet2))
"fs_tests/fsbridge_fstream" # deterministic test failure?
- "miner_tests/CreateNewBlock_validity" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
+ "miner_tests/CreateNewBlock_validity" # validation.cpp: if (signals.CallbacksPending() > 10)
"scheduler_tests/manythreads" # scheduler.cpp: CScheduler::serviceQueue()
"scheduler_tests/singlethreadedscheduler_ordered" # scheduler.cpp: CScheduler::serviceQueue()
- "txvalidationcache_tests/checkinputs_test" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
- "txvalidationcache_tests/tx_mempool_block_doublespend" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
- "txindex_tests/txindex_initial_sync" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
- "txvalidation_tests/tx_mempool_reject_coinbase" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
- "validation_block_tests/processnewblock_signals_ordering" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
- "wallet_tests/coin_mark_dirty_immature_credit" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
- "wallet_tests/dummy_input_size_test" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
- "wallet_tests/importmulti_rescan" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
- "wallet_tests/importwallet_rescan" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
- "wallet_tests/ListCoins" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
- "wallet_tests/scan_for_wallet_transactions" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
- "wallet_tests/wallet_disableprivkeys" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
+ "txvalidationcache_tests/checkinputs_test" # validation.cpp: if (signals.CallbacksPending() > 10)
+ "txvalidationcache_tests/tx_mempool_block_doublespend" # validation.cpp: if (signals.CallbacksPending() > 10)
+ "txindex_tests/txindex_initial_sync" # validation.cpp: if (signals.CallbacksPending() > 10)
+ "txvalidation_tests/tx_mempool_reject_coinbase" # validation.cpp: if (signals.CallbacksPending() > 10)
+ "validation_block_tests/processnewblock_signals_ordering" # validation.cpp: if (signals.CallbacksPending() > 10)
+ "wallet_tests/coin_mark_dirty_immature_credit" # validation.cpp: if (signals.CallbacksPending() > 10)
+ "wallet_tests/dummy_input_size_test" # validation.cpp: if (signals.CallbacksPending() > 10)
+ "wallet_tests/importmulti_rescan" # validation.cpp: if (signals.CallbacksPending() > 10)
+ "wallet_tests/importwallet_rescan" # validation.cpp: if (signals.CallbacksPending() > 10)
+ "wallet_tests/ListCoins" # validation.cpp: if (signals.CallbacksPending() > 10)
+ "wallet_tests/scan_for_wallet_transactions" # validation.cpp: if (signals.CallbacksPending() > 10)
+ "wallet_tests/wallet_disableprivkeys" # validation.cpp: if (signals.CallbacksPending() > 10)
)
TEST_BITCOIN_BINARY="src/test/test_bitcoin"
diff --git a/contrib/devtools/test_utxo_snapshots.sh b/contrib/devtools/test_utxo_snapshots.sh
new file mode 100755
index 0000000000..d7c019f4a6
--- /dev/null
+++ b/contrib/devtools/test_utxo_snapshots.sh
@@ -0,0 +1,209 @@
+#!/usr/bin/env bash
+# Demonstrate the creation and usage of UTXO snapshots.
+#
+# A server node starts up, IBDs up to a certain height, then generates a UTXO
+# snapshot at that point.
+#
+# The server then downloads more blocks (to create a diff from the snapshot).
+#
+# We bring a client up, load the UTXO snapshot, and we show the client sync to
+# the "network tip" and then start a background validation of the snapshot it
+# loaded. We see the background validation chainstate removed after validation
+# completes.
+#
+# The shellcheck rule SC2086 (quoted variables) disablements are necessary
+# since this rule needs to be violated in order to get bitcoind to pick up on
+# $EARLY_IBD_FLAGS for the script to work.
+
+export LC_ALL=C
+set -e
+
+BASE_HEIGHT=${1:-30000}
+INCREMENTAL_HEIGHT=20000
+FINAL_HEIGHT=$((BASE_HEIGHT + INCREMENTAL_HEIGHT))
+
+SERVER_DATADIR="$(pwd)/utxodemo-data-server-$BASE_HEIGHT"
+CLIENT_DATADIR="$(pwd)/utxodemo-data-client-$BASE_HEIGHT"
+UTXO_DAT_FILE="$(pwd)/utxo.$BASE_HEIGHT.dat"
+
+# Chosen to try to not interfere with any running bitcoind processes.
+SERVER_PORT=8633
+SERVER_RPC_PORT=8632
+
+CLIENT_PORT=8733
+CLIENT_RPC_PORT=8732
+
+SERVER_PORTS="-port=${SERVER_PORT} -rpcport=${SERVER_RPC_PORT}"
+CLIENT_PORTS="-port=${CLIENT_PORT} -rpcport=${CLIENT_RPC_PORT}"
+
+# Ensure the client exercises all indexes to test that snapshot use works
+# properly with indexes.
+ALL_INDEXES="-txindex -coinstatsindex -blockfilterindex=1"
+
+if ! command -v jq >/dev/null ; then
+ echo "This script requires jq to parse JSON RPC output. Please install it."
+ echo "(e.g. sudo apt install jq)"
+ exit 1
+fi
+
+DUMP_OUTPUT="dumptxoutset-output-$BASE_HEIGHT.json"
+
+finish() {
+ echo
+ echo "Killing server and client PIDs ($SERVER_PID, $CLIENT_PID) and cleaning up datadirs"
+ echo
+ rm -f "$UTXO_DAT_FILE" "$DUMP_OUTPUT"
+ rm -rf "$SERVER_DATADIR" "$CLIENT_DATADIR"
+ kill -9 "$SERVER_PID" "$CLIENT_PID"
+}
+
+trap finish EXIT
+
+# Need to specify these to trick client into accepting server as a peer
+# it can IBD from, otherwise the default values prevent IBD from the server node.
+EARLY_IBD_FLAGS="-maxtipage=9223372036854775207 -minimumchainwork=0x00"
+
+server_rpc() {
+ ./src/bitcoin-cli -rpcport=$SERVER_RPC_PORT -datadir="$SERVER_DATADIR" "$@"
+}
+client_rpc() {
+ ./src/bitcoin-cli -rpcport=$CLIENT_RPC_PORT -datadir="$CLIENT_DATADIR" "$@"
+}
+server_sleep_til_boot() {
+ while ! server_rpc ping >/dev/null 2>&1; do sleep 0.1; done
+}
+client_sleep_til_boot() {
+ while ! client_rpc ping >/dev/null 2>&1; do sleep 0.1; done
+}
+server_sleep_til_shutdown() {
+ while server_rpc ping >/dev/null 2>&1; do sleep 0.1; done
+}
+
+mkdir -p "$SERVER_DATADIR" "$CLIENT_DATADIR"
+
+echo "Hi, welcome to the assumeutxo demo/test"
+echo
+echo "We're going to"
+echo
+echo " - start up a 'server' node, sync it via mainnet IBD to height ${BASE_HEIGHT}"
+echo " - create a UTXO snapshot at that height"
+echo " - IBD ${INCREMENTAL_HEIGHT} more blocks on top of that"
+echo
+echo "then we'll demonstrate assumeutxo by "
+echo
+echo " - starting another node (the 'client') and loading the snapshot in"
+echo " * first you'll have to modify the code slightly (chainparams) and recompile"
+echo " * don't worry, we'll make it easy"
+echo " - observing the client sync ${INCREMENTAL_HEIGHT} blocks on top of the snapshot from the server"
+echo " - observing the client validate the snapshot chain via background IBD"
+echo
+read -p "Press [enter] to continue" _
+
+echo
+echo "-- Starting the demo. You might want to run the two following commands in"
+echo " separate terminal windows:"
+echo
+echo " watch -n0.1 tail -n 30 $SERVER_DATADIR/debug.log"
+echo " watch -n0.1 tail -n 30 $CLIENT_DATADIR/debug.log"
+echo
+read -p "Press [enter] to continue" _
+
+echo
+echo "-- IBDing the blocks (height=$BASE_HEIGHT) required to the server node..."
+# shellcheck disable=SC2086
+./src/bitcoind -logthreadnames=1 $SERVER_PORTS \
+ -datadir="$SERVER_DATADIR" $EARLY_IBD_FLAGS -stopatheight="$BASE_HEIGHT" >/dev/null
+
+echo
+echo "-- Creating snapshot at ~ height $BASE_HEIGHT ($UTXO_DAT_FILE)..."
+server_sleep_til_shutdown # wait for stopatheight to be hit
+# shellcheck disable=SC2086
+./src/bitcoind -logthreadnames=1 $SERVER_PORTS \
+ -datadir="$SERVER_DATADIR" $EARLY_IBD_FLAGS -connect=0 -listen=0 >/dev/null &
+SERVER_PID="$!"
+
+server_sleep_til_boot
+server_rpc dumptxoutset "$UTXO_DAT_FILE" > "$DUMP_OUTPUT"
+cat "$DUMP_OUTPUT"
+kill -9 "$SERVER_PID"
+
+RPC_BASE_HEIGHT=$(jq -r .base_height < "$DUMP_OUTPUT")
+RPC_AU=$(jq -r .txoutset_hash < "$DUMP_OUTPUT")
+RPC_NCHAINTX=$(jq -r .nchaintx < "$DUMP_OUTPUT")
+RPC_BLOCKHASH=$(jq -r .base_hash < "$DUMP_OUTPUT")
+
+server_sleep_til_shutdown
+
+echo
+echo "-- Now: add the following to CMainParams::m_assumeutxo_data"
+echo " in src/kernel/chainparams.cpp, and recompile:"
+echo
+echo " {${RPC_BASE_HEIGHT}, AssumeutxoHash{uint256S(\"0x${RPC_AU}\")}, ${RPC_NCHAINTX}, uint256S(\"0x${RPC_BLOCKHASH}\")},"
+echo
+echo
+echo "-- IBDing more blocks to the server node (height=$FINAL_HEIGHT) so there is a diff between snapshot and tip..."
+# shellcheck disable=SC2086
+./src/bitcoind $SERVER_PORTS -logthreadnames=1 -datadir="$SERVER_DATADIR" \
+ $EARLY_IBD_FLAGS -stopatheight="$FINAL_HEIGHT" >/dev/null
+
+echo
+echo "-- Starting the server node to provide blocks to the client node..."
+# shellcheck disable=SC2086
+./src/bitcoind $SERVER_PORTS -logthreadnames=1 -debug=net -datadir="$SERVER_DATADIR" \
+ $EARLY_IBD_FLAGS -connect=0 -listen=1 >/dev/null &
+SERVER_PID="$!"
+server_sleep_til_boot
+
+echo
+echo "-- Okay, what you're about to see is the client starting up and activating the snapshot."
+echo " I'm going to display the top 14 log lines from the client on top of an RPC called"
+echo " getchainstates, which is like getblockchaininfo but for both the snapshot and "
+echo " background validation chainstates."
+echo
+echo " You're going to first see the snapshot chainstate sync to the server's tip, then"
+echo " the background IBD chain kicks in to validate up to the base of the snapshot."
+echo
+echo " Once validation of the snapshot is done, you should see log lines indicating"
+echo " that we've deleted the background validation chainstate."
+echo
+echo " Once everything completes, exit the watch command with CTRL+C."
+echo
+read -p "When you're ready for all this, hit [enter]" _
+
+echo
+echo "-- Starting the client node to get headers from the server, then load the snapshot..."
+# shellcheck disable=SC2086
+./src/bitcoind $CLIENT_PORTS $ALL_INDEXES -logthreadnames=1 -datadir="$CLIENT_DATADIR" \
+ -connect=0 -addnode=127.0.0.1:$SERVER_PORT -debug=net $EARLY_IBD_FLAGS >/dev/null &
+CLIENT_PID="$!"
+client_sleep_til_boot
+
+echo
+echo "-- Initial state of the client:"
+client_rpc getchainstates
+
+echo
+echo "-- Loading UTXO snapshot into client. Calling RPC in a loop..."
+while ! client_rpc loadtxoutset "$UTXO_DAT_FILE" ; do sleep 10; done
+
+watch -n 0.3 "( tail -n 14 $CLIENT_DATADIR/debug.log ; echo ; ./src/bitcoin-cli -rpcport=$CLIENT_RPC_PORT -datadir=$CLIENT_DATADIR getchainstates) | cat"
+
+echo
+echo "-- Okay, now I'm going to restart the client to make sure that the snapshot chain reloads "
+echo " as the main chain properly..."
+echo
+echo " Press CTRL+C after you're satisfied to exit the demo"
+echo
+read -p "Press [enter] to continue"
+
+client_sleep_til_boot
+# shellcheck disable=SC2086
+./src/bitcoind $CLIENT_PORTS $ALL_INDEXES -logthreadnames=1 -datadir="$CLIENT_DATADIR" -connect=0 \
+ -addnode=127.0.0.1:$SERVER_PORT "$EARLY_IBD_FLAGS" >/dev/null &
+CLIENT_PID="$!"
+client_sleep_til_boot
+
+watch -n 0.3 "( tail -n 14 $CLIENT_DATADIR/debug.log ; echo ; ./src/bitcoin-cli -rpcport=$CLIENT_RPC_PORT -datadir=$CLIENT_DATADIR getchainstates) | cat"
+
+echo
+echo "-- Done!"
diff --git a/contrib/devtools/utils.py b/contrib/devtools/utils.py
index 68ad1c3aba..8b4c67c6c0 100755
--- a/contrib/devtools/utils.py
+++ b/contrib/devtools/utils.py
@@ -8,10 +8,9 @@ Common utility functions
import shutil
import sys
import os
-from typing import List
-def determine_wellknown_cmd(envvar, progname) -> List[str]:
+def determine_wellknown_cmd(envvar, progname) -> list[str]:
maybe_env = os.getenv(envvar)
maybe_which = shutil.which(progname)
if maybe_env:
diff --git a/contrib/devtools/utxo_snapshot.sh b/contrib/devtools/utxo_snapshot.sh
index dee25ff67b..fbb8591965 100755
--- a/contrib/devtools/utxo_snapshot.sh
+++ b/contrib/devtools/utxo_snapshot.sh
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
#
-# Copyright (c) 2019 The Bitcoin Core developers
+# Copyright (c) 2019-2023 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
@@ -8,6 +8,8 @@ export LC_ALL=C
set -ueo pipefail
+NETWORK_DISABLED=false
+
if (( $# < 3 )); then
echo 'Usage: utxo_snapshot.sh <generate-at-height> <snapshot-out-path> <bitcoin-cli-call ...>'
echo
@@ -26,19 +28,67 @@ OUTPUT_PATH="${1}"; shift;
# Most of the calls we make take a while to run, so pad with a lengthy timeout.
BITCOIN_CLI_CALL="${*} -rpcclienttimeout=9999999"
+# Check if the node is pruned and get the pruned block height
+PRUNED=$( ${BITCOIN_CLI_CALL} getblockchaininfo | awk '/pruneheight/ {print $2}' | tr -d ',' )
+
+if (( GENERATE_AT_HEIGHT < PRUNED )); then
+ echo "Error: The requested snapshot height (${GENERATE_AT_HEIGHT}) should be greater than the pruned block height (${PRUNED})."
+ exit 1
+fi
+
+# Early exit if file at OUTPUT_PATH already exists
+if [[ -e "$OUTPUT_PATH" ]]; then
+ (>&2 echo "Error: $OUTPUT_PATH already exists or is not a valid path.")
+ exit 1
+fi
+
+# Validate that the path is correct
+if [[ "${OUTPUT_PATH}" != "-" && ! -d "$(dirname "${OUTPUT_PATH}")" ]]; then
+ (>&2 echo "Error: The directory $(dirname "${OUTPUT_PATH}") does not exist.")
+ exit 1
+fi
+
+function cleanup {
+ (>&2 echo "Restoring chain to original height; this may take a while")
+ ${BITCOIN_CLI_CALL} reconsiderblock "${PIVOT_BLOCKHASH}"
+
+ if $NETWORK_DISABLED; then
+ (>&2 echo "Restoring network activity")
+ ${BITCOIN_CLI_CALL} setnetworkactive true
+ fi
+}
+
+function early_exit {
+ (>&2 echo "Exiting due to Ctrl-C")
+ cleanup
+ exit 1
+}
+
+# Prompt the user to disable network activity
+read -p "Do you want to disable network activity (setnetworkactive false) before running invalidateblock? (Y/n): " -r
+if [[ "$REPLY" =~ ^[Yy]*$ || -z "$REPLY" ]]; then
+ # User input is "Y", "y", or Enter key, proceed with the action
+ NETWORK_DISABLED=true
+ (>&2 echo "Disabling network activity")
+ ${BITCOIN_CLI_CALL} setnetworkactive false
+else
+ (>&2 echo "Network activity remains enabled")
+fi
+
# Block we'll invalidate/reconsider to rewind/fast-forward the chain.
PIVOT_BLOCKHASH=$($BITCOIN_CLI_CALL getblockhash $(( GENERATE_AT_HEIGHT + 1 )) )
+# Trap for normal exit and Ctrl-C
+trap cleanup EXIT
+trap early_exit INT
+
(>&2 echo "Rewinding chain back to height ${GENERATE_AT_HEIGHT} (by invalidating ${PIVOT_BLOCKHASH}); this may take a while")
${BITCOIN_CLI_CALL} invalidateblock "${PIVOT_BLOCKHASH}"
if [[ "${OUTPUT_PATH}" = "-" ]]; then
(>&2 echo "Generating txoutset info...")
- ${BITCOIN_CLI_CALL} gettxoutsetinfo | grep hash_serialized_2 | sed 's/^.*: "\(.\+\)\+",/\1/g'
+ ${BITCOIN_CLI_CALL} gettxoutsetinfo | grep hash_serialized_3 | sed 's/^.*: "\(.\+\)\+",/\1/g'
else
(>&2 echo "Generating UTXO snapshot...")
${BITCOIN_CLI_CALL} dumptxoutset "${OUTPUT_PATH}"
fi
-
-(>&2 echo "Restoring chain to original height; this may take a while")
-${BITCOIN_CLI_CALL} reconsiderblock "${PIVOT_BLOCKHASH}"
diff --git a/contrib/guix/INSTALL.md b/contrib/guix/INSTALL.md
index bbd88e58f3..35ea83e585 100644
--- a/contrib/guix/INSTALL.md
+++ b/contrib/guix/INSTALL.md
@@ -62,9 +62,6 @@ so you should log out and log back in.
Please refer to fanquake's instructions
[here](https://github.com/fanquake/core-review/tree/master/guix).
-Note that the `Dockerfile` is largely equivalent to running through the binary
-tarball installation steps.
-
## Option 4: Using a distribution-maintained package
Note that this section is based on the distro packaging situation at the time of
@@ -74,25 +71,15 @@ https://repology.org/project/guix/versions
### Debian / Ubuntu
-Guix v1.2.0 is available as a distribution package starting in [Debian
-11](https://packages.debian.org/bullseye/guix) and [Ubuntu
-21.04](https://packages.ubuntu.com/search?keywords=guix).
-
-Note that if you intend on using Guix without using any substitutes (more
-details [here][security-model]), v1.2.0 has a known problem when building GnuTLS
-from source. Solutions and workarounds are documented
-[here](#gnutls-test-suite-fail-status-request-revoked).
-
+Guix is available as a distribution package in [Debian
+](https://packages.debian.org/search?keywords=guix) and [Ubuntu
+](https://packages.ubuntu.com/search?keywords=guix).
To install:
```sh
sudo apt install guix
```
-For up-to-date information on Debian and Ubuntu's release history:
-- [Debian release history](https://www.debian.org/releases/)
-- [Ubuntu release history](https://ubuntu.com/about/release-cycle)
-
### Arch Linux
Guix is available in the AUR as
@@ -167,80 +154,41 @@ For reference, the graphic below outlines Guix v1.3.0's dependency graph:
![bootstrap map](https://user-images.githubusercontent.com/6399679/125064185-a9a59880-e0b0-11eb-82c1-9b8e5dc9950d.png)
-#### Consider /tmp on tmpfs
-
-If you use an NVME (SSD) drive, you may encounter [cryptic build errors](#coreutils-fail-teststail-2inotify-dir-recreate). Mounting a [tmpfs at /tmp](https://ubuntu.com/blog/data-driven-analysis-tmp-on-tmpfs) should prevent this and may improve performance as a bonus.
-
-#### Guile
-
-##### Choosing a Guile version and sticking to it
-
-One of the first things you need to decide is which Guile version you want to
-use: Guile v2.2 or Guile v3.0. Unlike the python2 to python3 transition, Guile
-v2.2 and Guile v3.0 are largely compatible, as evidenced by the fact that most
-Guile packages and even [Guix
-itself](https://guix.gnu.org/en/blog/2020/guile-3-and-guix/) support running on
-both.
-
-What is important here is that you **choose one**, and you **remain consistent**
-with your choice throughout **all Guile-related packages**, no matter if they
-are installed via the distribution's package manager or installed from source.
-This is because the files for Guile packages are installed to directories which
-are separated based on the Guile version.
-
-###### Example: Checking that Ubuntu's `guile-git` is compatible with your chosen Guile version
-
-On Ubuntu Focal:
+If you do not care about building each dependency from source, and Guix is
+already packaged for your distribution, you can easily install only the build
+dependencies of Guix. For example, to enable deb-src and install the Guix build
+dependencies on Ubuntu/Debian:
```sh
-$ apt show guile-git
-Package: guile-git
-...
-Depends: guile-2.2, guile-bytestructures, libgit2-dev
-...
+sed -i 's|# deb-src|deb-src|g' /etc/apt/sources.list
+apt update
+apt-get build-dep -y guix
```
-As you can see, the package `guile-git` depends on `guile-2.2`, meaning that it
-was likely built for Guile v2.2. This means that if you decided to use Guile
-v3.0 on Ubuntu Focal, you would need to build guile-git from source instead of
-using the distribution package.
+If this succeeded, you can likely skip to section
+["Building and Installing Guix itself"](#building-and-installing-guix-itself).
-On Ubuntu Hirsute:
-
-```sh
-$ apt show guile-git
-Package: guile-git
-...
-Depends: guile-3.0 | guile-2.2, guile-bytestructures (>= 1.0.7-3~), libgit2-dev (>= 1.0)
-...
-```
-
-In this case, `guile-git` depends on either `guile-3.0` or `guile-2.2`, meaning
-that it would work no matter what Guile version you decided to use.
+#### Guile
###### Corner case: Multiple versions of Guile on one system
-It is recommended to only install one version of Guile, so that build systems do
+It is recommended to only install the required version of Guile, so that build systems do
not get confused about which Guile to use.
-However, if you insist on having both Guile v2.2 and Guile v3.0 installed on
-your system, then you need to **consistently** specify one of
-`GUILE_EFFECTIVE_VERSION=3.0` or `GUILE_EFFECTIVE_VERSION=2.2` to all
+However, if you insist on having more versions of Guile installed on
+your system, then you need to **consistently** specify
+`GUILE_EFFECTIVE_VERSION=3.0` to all
`./configure` invocations for Guix and its dependencies.
##### Installing Guile
-Guile is most likely already packaged for your distribution, so after you have
-[chosen a Guile version](#choosing-a-guile-version-and-sticking-to-it), install
-it via your distribution's package manager.
-
If your distribution splits packages into `-dev`-suffixed and
non-`-dev`-suffixed sub-packages (as is the case for Debian-derived
distributions), please make sure to install both. For example, to install Guile
-v2.2 on Debian/Ubuntu:
+v3.0 on Debian/Ubuntu:
```sh
-apt install guile-2.2 guile-2.2-dev
+apt install guile-3.0 guile-3.0-dev
```
#### Mixing distribution packages and source-built packages
@@ -258,16 +206,16 @@ source-built packages, you will need to augment the `GUILE_LOAD_PATH` and
`GUILE_LOAD_COMPILED_PATH` environment variables so that Guile will look
under the right prefix and find your source-built packages.
-For example, if you are using Guile v2.2, and have Guile packages in the
+For example, if you are using Guile v3.0, and have Guile packages in the
`/usr/local` prefix, either add the following lines to your `.profile` or
`.bash_profile` so that the environment variable is properly set for all future
shell logins, or paste the lines into a POSIX-style shell to temporarily modify
the environment variables of your current shell session.
```sh
-# Help Guile v2.2.x find packages in /usr/local
-export GUILE_LOAD_PATH="/usr/local/share/guile/site/2.2${GUILE_LOAD_PATH:+:}$GUILE_LOAD_PATH"
-export GUILE_LOAD_COMPILED_PATH="/usr/local/lib/guile/2.2/site-ccache${GUILE_LOAD_COMPILED_PATH:+:}$GUILE_COMPILED_LOAD_PATH"
+# Help Guile v3.0.x find packages in /usr/local
+export GUILE_LOAD_PATH="/usr/local/share/guile/site/3.0${GUILE_LOAD_PATH:+:}$GUILE_LOAD_PATH"
+export GUILE_LOAD_COMPILED_PATH="/usr/local/lib/guile/3.0/site-ccache${GUILE_LOAD_COMPILED_PATH:+:}$GUILE_COMPILED_LOAD_PATH"
```
Note that these environment variables are used to check for packages during
@@ -352,7 +300,7 @@ Relevant for:
- Those installing `guile-git` from their distribution where `guile-git` is
built against `libgit2 < 1.1`
-As of v0.4.0, `guile-git` claims to only require `libgit2 >= 0.28.0`, however,
+As of v0.5.2, `guile-git` claims to only require `libgit2 >= 0.28.0`, however,
it actually requires `libgit2 >= 1.1`, otherwise, it will be confused by a
reference of `origin/keyring`: instead of interpreting the reference as "the
'keyring' branch of the 'origin' remote", the reference is interpreted as "the
@@ -366,20 +314,6 @@ Should you be in this situation, you need to build both `libgit2 v1.1.x` and
Source: https://logs.guix.gnu.org/guix/2020-11-12.log#232527
-##### `{scheme,guile}-bytestructures` v1.0.8 and v1.0.9 are broken for Guile v2.2
-
-Relevant for:
-- Those building `{scheme,guile}-bytestructures` from source against Guile v2.2
-
-Commit
-[707eea3](https://github.com/TaylanUB/scheme-bytestructures/commit/707eea3a85e1e375e86702229ebf73d496377669)
-introduced a regression for Guile v2.2 and was first included in v1.0.8, this
-was later corrected in commit
-[ec9a721](https://github.com/TaylanUB/scheme-bytestructures/commit/ec9a721957c17bcda13148f8faa5f06934431ff7)
-and included in v1.1.0.
-
-TL;DR If you decided to use Guile v2.2, do not use `{scheme,guile}-bytestructures` v1.0.8 or v1.0.9.
-
### Building and Installing Guix itself
Start by cloning Guix:
@@ -389,10 +323,8 @@ git clone https://git.savannah.gnu.org/git/guix.git
cd guix
```
-You will likely want to build the latest release, however, if the latest release
-when you're reading this is still 1.3.0 then you may want to use 998eda30 instead
-to avoid the issues described in [#25099](
-https://github.com/bitcoin/bitcoin/pull/25099).
+You will likely want to build the latest release.
+At the time of writing (November 2023), the latest release was `v1.4.0`.
```
git branch -a -l 'origin/version-*' # check for the latest release
@@ -578,7 +510,7 @@ sudo --login guix pull --commit=<particular-commit>
```
`guix pull` is quite a long process (especially if you're using
-`--no-substitute`). If you encounter build problems, please refer to the
+`--no-substitutes`). If you encounter build problems, please refer to the
[troubleshooting section](#troubleshooting).
Note that running a bare `guix pull` with no commit or branch specified will
@@ -616,7 +548,7 @@ systemctl enable guix-daemon
systemctl start guix-daemon
```
-Remember to set `--no-substitute` in `$libdir/systemd/system/guix-daemon.service` and other customizations if you used them for `guix-daemon-original.service`.
+Remember to set `--no-substitutes` in `$libdir/systemd/system/guix-daemon.service` and other customizations if you used them for `guix-daemon-original.service`.
##### If you installed Guix via the Debian/Ubuntu distribution packages
@@ -726,26 +658,18 @@ $ bzcat /var/log/guix/drvs/../...-foo-3.6.12.drv.bz2 | less
times, it may be `/tmp/...drv-1` or `/tmp/...drv-2`. Always consult the build
failure output for the most accurate, up-to-date information.
-### openssl-1.1.1l and openssl-1.1.1n
-
-OpenSSL includes tests that will fail once some certificate has expired. A workaround
-is to change your system clock:
-
-```sh
-sudo timedatectl set-ntp no
-sudo date --set "28 may 2022 15:00:00"
-sudo --login guix build --cores=1 /gnu/store/g9alz81w4q03ncm542487xd001s6akd4-openssl-1.1.1l.drv
-sudo --login guix build --cores=1 /gnu/store/mw6ax0gk33gh082anrdrxp2flrbskxv6-openssl-1.1.1n.drv
-sudo timedatectl set-ntp yes
-```
-
### python(-minimal): [Errno 84] Invalid or incomplete multibyte or wide character
This error occurs when your `$TMPDIR` (default: /tmp) exists on a filesystem
which rejects characters not present in the UTF-8 character code set. An example
is ZFS with the utf8only=on option set.
-More information: https://bugs.python.org/issue37584
+More information: https://github.com/python/cpython/issues/81765
+
+### openssl-1.1.1l and openssl-1.1.1n
+
+OpenSSL includes tests that will fail once some certificate has expired.
+The workarounds from the GnuTLS section immediately below can be used.
### GnuTLS: test-suite FAIL: status-request-revoked
@@ -781,13 +705,41 @@ authorized.
This workaround was described [here](https://issues.guix.gnu.org/44559#5).
Basically:
-1. Turn off networking
2. Turn off NTP
3. Set system time to 2020-10-01
4. guix build --no-substitutes /gnu/store/vhphki5sg9xkdhh2pbc8gi6vhpfzryf0-gnutls-3.6.12.drv
5. Set system time back to accurate current time
6. Turn NTP back on
-7. Turn networking back on
+
+For example,
+
+```sh
+sudo timedatectl set-ntp no
+sudo date --set "01 oct 2020 15:00:00"
+guix build /gnu/store/vhphki5sg9xkdhh2pbc8gi6vhpfzryf0-gnutls-3.6.12.drv
+sudo timedatectl set-ntp yes
+```
+
+#### Workaround 3: Disable the tests in the Guix source code for this single derivation
+
+If all of the above workarounds fail, you can also disable the `tests` phase of
+the derivation via the `arguments` option, as described in the official
+[`package`
+reference](https://guix.gnu.org/manual/en/html_node/package-Reference.html).
+
+For example, to disable the openssl-1.1 check phase:
+
+```diff
+diff --git a/gnu/packages/tls.scm b/gnu/packages/tls.scm
+index f1e844b..1077c4b 100644
+--- a/gnu/packages/tls.scm
++++ b/gnu/packages/tls.scm
+@@ -494,4 +494,5 @@ (define-public openssl-1.1
+ (arguments
+ `(#:parallel-tests? #f
++ #:tests? #f
+ #:test-target "test"
+```
### coreutils: FAIL: tests/tail-2/inotify-dir-recreate
@@ -796,7 +748,7 @@ The inotify-dir-create test fails on "remote" filesystems such as overlayfs
as non-remote.
A relatively easy workaround to this is to make sure that a somewhat traditional
-filesystem is mounted at `/tmp` (where `guix-daemon` performs its builds), see [/tmp on tmpfs](#consider-tmp-on-tmpfs). For
+filesystem is mounted at `/tmp` (where `guix-daemon` performs its builds). For
Docker users, this might mean [using a volume][docker/volumes], [binding
mounting][docker/bind-mnt] from host, or (for those with enough RAM and swap)
[mounting a tmpfs][docker/tmpfs] using the `--tmpfs` flag.
diff --git a/contrib/guix/README.md b/contrib/guix/README.md
index c0feb486ff..6fb647f8a9 100644
--- a/contrib/guix/README.md
+++ b/contrib/guix/README.md
@@ -11,7 +11,7 @@ We achieve bootstrappability by using Guix as a functional package manager.
# Requirements
-Conservatively, you will need an x86_64 machine with:
+Conservatively, you will need:
- 16GB of free disk space on the partition that /gnu/store will reside in
- 8GB of free disk space **per platform triple** you're planning on building
@@ -259,7 +259,7 @@ details.
Override the number of jobs to run simultaneously, you might want to do so on
a memory-limited machine. This may be passed to:
- - `guix` build commands as in `guix environment --cores="$JOBS"`
+ - `guix` build commands as in `guix shell --cores="$JOBS"`
- `make` as in `make --jobs="$JOBS"`
- `xargs` as in `xargs -P"$JOBS"`
@@ -301,7 +301,7 @@ details.
* _**ADDITIONAL_GUIX_ENVIRONMENT_FLAGS**_
- Additional flags to be passed to the invocation of `guix environment` inside
+ Additional flags to be passed to the invocation of `guix shell` inside
`guix time-machine`.
# Choosing your security model
diff --git a/contrib/guix/guix-build b/contrib/guix/guix-build
index 74b24b9612..870938cb52 100755
--- a/contrib/guix/guix-build
+++ b/contrib/guix/guix-build
@@ -74,7 +74,8 @@ mkdir -p "$VERSION_BASE"
################
# Default to building for all supported HOSTs (overridable by environment)
-export HOSTS="${HOSTS:-x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu powerpc64-linux-gnu powerpc64le-linux-gnu
+# powerpc64le-linux-gnu currently disabled due non-determinism issues across build arches.
+export HOSTS="${HOSTS:-x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu powerpc64-linux-gnu
x86_64-w64-mingw32
x86_64-apple-darwin arm64-apple-darwin}"
@@ -365,7 +366,7 @@ EOF
# Run the build script 'contrib/guix/libexec/build.sh' in the build
# container specified by 'contrib/guix/manifest.scm'.
#
- # Explanation of `guix environment` flags:
+ # Explanation of `guix shell` flags:
#
# --container run command within an isolated container
#
@@ -428,7 +429,7 @@ EOF
# more information.
#
# shellcheck disable=SC2086,SC2031
- time-machine environment --manifest="${PWD}/contrib/guix/manifest.scm" \
+ time-machine shell --manifest="${PWD}/contrib/guix/manifest.scm" \
--container \
--pure \
--no-cwd \
diff --git a/contrib/guix/guix-codesign b/contrib/guix/guix-codesign
index 3279d431aa..4694209e00 100755
--- a/contrib/guix/guix-codesign
+++ b/contrib/guix/guix-codesign
@@ -286,7 +286,7 @@ EOF
# Run the build script 'contrib/guix/libexec/build.sh' in the build
# container specified by 'contrib/guix/manifest.scm'.
#
- # Explanation of `guix environment` flags:
+ # Explanation of `guix shell` flags:
#
# --container run command within an isolated container
#
@@ -343,7 +343,7 @@ EOF
# more information.
#
# shellcheck disable=SC2086,SC2031
- time-machine environment --manifest="${PWD}/contrib/guix/manifest.scm" \
+ time-machine shell --manifest="${PWD}/contrib/guix/manifest.scm" \
--container \
--pure \
--no-cwd \
diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh
index e0bd15493f..1e9b682f3f 100755
--- a/contrib/guix/libexec/build.sh
+++ b/contrib/guix/libexec/build.sh
@@ -8,7 +8,7 @@ export TZ=UTC
# Although Guix _does_ set umask when building its own packages (in our case,
# this is all packages in manifest.scm), it does not set it for `guix
-# environment`. It does make sense for at least `guix environment --container`
+# shell`. It does make sense for at least `guix shell --container`
# to set umask, so if that change gets merged upstream and we bump the
# time-machine to a commit which includes the aforementioned change, we can
# remove this line.
@@ -52,7 +52,8 @@ BASEPREFIX="${PWD}/depends"
store_path() {
grep --extended-regexp "/[^-]{32}-${1}-[^-]+${2:+-${2}}" "${GUIX_ENVIRONMENT}/manifest" \
| head --lines=1 \
- | sed --expression='s|^[[:space:]]*"||' \
+ | sed --expression='s|\x29*$||' \
+ --expression='s|^[[:space:]]*"||' \
--expression='s|"[[:space:]]*$||'
}
@@ -60,7 +61,6 @@ store_path() {
# Set environment variables to point the NATIVE toolchain to the right
# includes/libs
NATIVE_GCC="$(store_path gcc-toolchain)"
-NATIVE_GCC_STATIC="$(store_path gcc-toolchain static)"
unset LIBRARY_PATH
unset CPATH
@@ -69,12 +69,20 @@ unset CPLUS_INCLUDE_PATH
unset OBJC_INCLUDE_PATH
unset OBJCPLUS_INCLUDE_PATH
-export LIBRARY_PATH="${NATIVE_GCC}/lib:${NATIVE_GCC_STATIC}/lib"
export C_INCLUDE_PATH="${NATIVE_GCC}/include"
export CPLUS_INCLUDE_PATH="${NATIVE_GCC}/include/c++:${NATIVE_GCC}/include"
export OBJC_INCLUDE_PATH="${NATIVE_GCC}/include"
export OBJCPLUS_INCLUDE_PATH="${NATIVE_GCC}/include/c++:${NATIVE_GCC}/include"
+case "$HOST" in
+ *darwin*) export LIBRARY_PATH="${NATIVE_GCC}/lib" ;;
+ *mingw*) export LIBRARY_PATH="${NATIVE_GCC}/lib" ;;
+ *)
+ NATIVE_GCC_STATIC="$(store_path gcc-toolchain static)"
+ export LIBRARY_PATH="${NATIVE_GCC}/lib:${NATIVE_GCC_STATIC}/lib"
+ ;;
+esac
+
# Set environment variables to point the CROSS toolchain to the right
# includes/libs for $HOST
case "$HOST" in
@@ -299,11 +307,9 @@ mkdir -p "$DISTSRC"
case "$HOST" in
*darwin*)
- make osx_volname ${V:+V=1}
make deploydir ${V:+V=1}
mkdir -p "unsigned-app-${HOST}"
cp --target-directory="unsigned-app-${HOST}" \
- osx_volname \
contrib/macdeploy/detached-sig-create.sh
mv --target-directory="unsigned-app-${HOST}" dist
(
@@ -314,32 +320,22 @@ mkdir -p "$DISTSRC"
| gzip -9n > "${OUTDIR}/${DISTNAME}-${HOST}-unsigned.tar.gz" \
|| ( rm -f "${OUTDIR}/${DISTNAME}-${HOST}-unsigned.tar.gz" && exit 1 )
)
- make deploy ${V:+V=1} OSX_DMG="${OUTDIR}/${DISTNAME}-${HOST}-unsigned.dmg"
+ make deploy ${V:+V=1} OSX_ZIP="${OUTDIR}/${DISTNAME}-${HOST}-unsigned.zip"
;;
esac
(
cd installed
- case "$HOST" in
- *mingw*)
- mv --target-directory="$DISTNAME"/lib/ "$DISTNAME"/bin/*.dll
- ;;
- esac
-
# Prune libtool and object archives
find . -name "lib*.la" -delete
find . -name "lib*.a" -delete
- # Prune pkg-config files
- rm -rf "${DISTNAME}/lib/pkgconfig"
-
case "$HOST" in
*darwin*) ;;
*)
- # Split binaries and libraries from their debug symbols
+ # Split binaries from their debug symbols
{
find "${DISTNAME}/bin" -type f -executable -print0
- find "${DISTNAME}/lib" -type f -print0
} | xargs -0 -P"$JOBS" -I{} "${DISTSRC}/contrib/devtools/split-debug.sh" {} {} {}.dbg
;;
esac
diff --git a/contrib/guix/libexec/codesign.sh b/contrib/guix/libexec/codesign.sh
index 6ffa0f07b2..b56d2a2309 100755
--- a/contrib/guix/libexec/codesign.sh
+++ b/contrib/guix/libexec/codesign.sh
@@ -8,7 +8,7 @@ export TZ=UTC
# Although Guix _does_ set umask when building its own packages (in our case,
# this is all packages in manifest.scm), it does not set it for `guix
-# environment`. It does make sense for at least `guix environment --container`
+# shell`. It does make sense for at least `guix shell --container`
# to set umask, so if that change gets merged upstream and we bump the
# time-machine to a commit which includes the aforementioned change, we can
# remove this line.
@@ -85,11 +85,12 @@ mkdir -p "$DISTSRC"
# Apply detached codesignatures to dist/ (in-place)
signapple apply dist/Bitcoin-Qt.app codesignatures/osx/dist
- # Make a DMG from dist/
- xorrisofs -D -l -V "$(< osx_volname)" -no-pad -r -dir-mode 0755 \
- -o "${OUTDIR}/${DISTNAME}-${HOST}.dmg" \
- dist \
- -- -volume_date all_file_dates ="$SOURCE_DATE_EPOCH"
+ # Make a .zip from dist/
+ cd dist/
+ find . -print0 \
+ | xargs -0r touch --no-dereference --date="@${SOURCE_DATE_EPOCH}"
+ find . | sort \
+ | zip -X@ "${OUTDIR}/${DISTNAME}-${HOST}.zip"
;;
*)
exit 1
diff --git a/contrib/guix/libexec/prelude.bash b/contrib/guix/libexec/prelude.bash
index 3eb8fc02da..ce6a9562b4 100644
--- a/contrib/guix/libexec/prelude.bash
+++ b/contrib/guix/libexec/prelude.bash
@@ -51,7 +51,7 @@ fi
time-machine() {
# shellcheck disable=SC2086
guix time-machine --url=https://git.savannah.gnu.org/git/guix.git \
- --commit=998eda3067c7d21e0d9bb3310d2f5a14b8f1c681 \
+ --commit=dc4842797bfdc5f9f3f5f725bf189c2b68bd6b5a \
--cores="$JOBS" \
--keep-failed \
--fallback \
diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm
index d83ff08713..8f13c642d3 100644
--- a/contrib/guix/manifest.scm
+++ b/contrib/guix/manifest.scm
@@ -1,44 +1,35 @@
-(use-modules (gnu)
- (gnu packages)
+(use-modules (gnu packages)
(gnu packages autotools)
- (gnu packages base)
- (gnu packages bash)
+ ((gnu packages bash) #:select (bash-minimal))
(gnu packages bison)
- (gnu packages certs)
- (gnu packages cdrom)
- (gnu packages check)
- (gnu packages cmake)
+ ((gnu packages certs) #:select (nss-certs))
+ ((gnu packages cmake) #:select (cmake-minimal))
(gnu packages commencement)
(gnu packages compression)
(gnu packages cross-base)
- (gnu packages curl)
(gnu packages file)
(gnu packages gawk)
(gnu packages gcc)
- (gnu packages gnome)
- (gnu packages installers)
- (gnu packages linux)
+ ((gnu packages installers) #:select (nsis-x86_64))
+ ((gnu packages linux) #:select (linux-libre-headers-6.1 util-linux))
(gnu packages llvm)
(gnu packages mingw)
(gnu packages moreutils)
(gnu packages pkg-config)
- (gnu packages python)
- (gnu packages python-crypto)
- (gnu packages python-web)
- (gnu packages shells)
- (gnu packages tls)
- (gnu packages version-control)
+ ((gnu packages python) #:select (python-minimal))
+ ((gnu packages python-build) #:select (python-tomli))
+ ((gnu packages python-crypto) #:select (python-asn1crypto))
+ ((gnu packages tls) #:select (openssl))
+ ((gnu packages version-control) #:select (git-minimal))
(guix build-system cmake)
(guix build-system gnu)
(guix build-system python)
(guix build-system trivial)
- (guix download)
(guix gexp)
(guix git-download)
((guix licenses) #:prefix license:)
(guix packages)
- (guix profiles)
- (guix utils))
+ ((guix utils) #:select (substitute-keyword-arguments)))
(define-syntax-rule (search-our-patches file-name ...)
"Return the list of absolute file names corresponding to each
@@ -47,41 +38,7 @@ FILE-NAME found in ./patches relative to the current file."
((%patch-path (list (string-append (dirname (current-filename)) "/patches"))))
(list (search-patch file-name) ...)))
-(define (make-ssp-fixed-gcc xgcc)
- "Given a XGCC package, return a modified package that uses the SSP function
-from glibc instead of from libssp.so. Our `symbol-check' script will complain if
-we link against libssp.so, and thus will ensure that this works properly.
-
-Taken from:
-http://www.linuxfromscratch.org/hlfs/view/development/chapter05/gcc-pass1.html"
- (package
- (inherit xgcc)
- (arguments
- (substitute-keyword-arguments (package-arguments xgcc)
- ((#:make-flags flags)
- `(cons "gcc_cv_libc_provides_ssp=yes" ,flags))))))
-
-(define (make-gcc-rpath-link xgcc)
- "Given a XGCC package, return a modified package that replace each instance of
--rpath in the default system spec that's inserted by Guix with -rpath-link"
- (package
- (inherit xgcc)
- (arguments
- (substitute-keyword-arguments (package-arguments xgcc)
- ((#:phases phases)
- `(modify-phases ,phases
- (add-after 'pre-configure 'replace-rpath-with-rpath-link
- (lambda _
- (substitute* (cons "gcc/config/rs6000/sysv4.h"
- (find-files "gcc/config"
- "^gnu-user.*\\.h$"))
- (("-rpath=") "-rpath-link="))
- #t))))))))
-
-(define building-on (string-append (list-ref (string-split (%current-system) #\-) 0) "-guix-linux-gnu"))
-
-(define (explicit-cross-configure package)
- (package-with-extra-configure-variable package "--build" building-on))
+(define building-on (string-append "--build=" (list-ref (string-split (%current-system) #\-) 0) "-guix-linux-gnu"))
(define (make-cross-toolchain target
base-gcc-for-libc
@@ -92,28 +49,28 @@ http://www.linuxfromscratch.org/hlfs/view/development/chapter05/gcc-pass1.html"
(let* ((xbinutils (cross-binutils target))
;; 1. Build a cross-compiling gcc without targeting any libc, derived
;; from BASE-GCC-FOR-LIBC
- (xgcc-sans-libc (explicit-cross-configure (cross-gcc target
- #:xgcc base-gcc-for-libc
- #:xbinutils xbinutils)))
+ (xgcc-sans-libc (cross-gcc target
+ #:xgcc base-gcc-for-libc
+ #:xbinutils xbinutils))
;; 2. Build cross-compiled kernel headers with XGCC-SANS-LIBC, derived
;; from BASE-KERNEL-HEADERS
(xkernel (cross-kernel-headers target
- base-kernel-headers
- xgcc-sans-libc
- xbinutils))
+ #:linux-headers base-kernel-headers
+ #:xgcc xgcc-sans-libc
+ #:xbinutils xbinutils))
;; 3. Build a cross-compiled libc with XGCC-SANS-LIBC and XKERNEL,
;; derived from BASE-LIBC
- (xlibc (explicit-cross-configure (cross-libc target
- base-libc
- xgcc-sans-libc
- xbinutils
- xkernel)))
+ (xlibc (cross-libc target
+ #:libc base-libc
+ #:xgcc xgcc-sans-libc
+ #:xbinutils xbinutils
+ #:xheaders xkernel))
;; 4. Build a cross-compiling gcc targeting XLIBC, derived from
;; BASE-GCC
- (xgcc (explicit-cross-configure (cross-gcc target
- #:xgcc base-gcc
- #:xbinutils xbinutils
- #:libc xlibc))))
+ (xgcc (cross-gcc target
+ #:xgcc base-gcc
+ #:xbinutils xbinutils
+ #:libc xlibc)))
;; Define a meta-package that propagates the resulting XBINUTILS, XLIBC, and
;; XGCC
(package
@@ -123,35 +80,26 @@ http://www.linuxfromscratch.org/hlfs/view/development/chapter05/gcc-pass1.html"
(build-system trivial-build-system)
(arguments '(#:builder (begin (mkdir %output) #t)))
(propagated-inputs
- `(("binutils" ,xbinutils)
- ("libc" ,xlibc)
- ("libc:static" ,xlibc "static")
- ("gcc" ,xgcc)
- ("gcc-lib" ,xgcc "lib")))
+ (list xbinutils
+ xlibc
+ xgcc
+ `(,xlibc "static")
+ `(,xgcc "lib")))
(synopsis (string-append "Complete GCC tool chain for " target))
(description (string-append "This package provides a complete GCC tool
chain for " target " development."))
(home-page (package-home-page xgcc))
(license (package-license xgcc)))))
-(define base-gcc gcc-10)
-(define base-linux-kernel-headers linux-libre-headers-5.15)
-
-;; https://gcc.gnu.org/install/configure.html
-(define (hardened-gcc gcc)
- (package-with-extra-configure-variable (
- package-with-extra-configure-variable (
- package-with-extra-configure-variable gcc
- "--enable-initfini-array" "yes")
- "--enable-default-ssp" "yes")
- "--enable-default-pie" "yes"))
+(define base-gcc gcc-12)
+(define base-linux-kernel-headers linux-libre-headers-6.1)
(define* (make-bitcoin-cross-toolchain target
#:key
- (base-gcc-for-libc base-gcc)
+ (base-gcc-for-libc linux-base-gcc)
(base-kernel-headers base-linux-kernel-headers)
- (base-libc (hardened-glibc glibc-2.27))
- (base-gcc (make-gcc-rpath-link (hardened-gcc base-gcc))))
+ (base-libc glibc-2.27)
+ (base-gcc linux-base-gcc))
"Convenience wrapper around MAKE-CROSS-TOOLCHAIN with default values
desirable for building Bitcoin Core release binaries."
(make-cross-toolchain target
@@ -160,26 +108,22 @@ desirable for building Bitcoin Core release binaries."
base-libc
base-gcc))
-(define (make-gcc-with-pthreads gcc)
- (package-with-extra-configure-variable
- (package-with-extra-patches gcc
- (search-our-patches "gcc-10-remap-guix-store.patch"))
- "--enable-threads" "posix"))
+(define (gcc-mingw-patches gcc)
+ (package-with-extra-patches gcc
+ (search-our-patches "gcc-remap-guix-store.patch")))
-(define (make-mingw-w64-cross-gcc cross-gcc)
- (package-with-extra-patches cross-gcc
- (search-our-patches "vmov-alignment.patch"
- "gcc-broken-longjmp.patch")))
+(define (binutils-mingw-patches binutils)
+ (package-with-extra-patches binutils
+ (search-our-patches "binutils-unaligned-default.patch")))
(define (make-mingw-pthreads-cross-toolchain target)
"Create a cross-compilation toolchain package for TARGET"
- (let* ((xbinutils (cross-binutils target))
+ (let* ((xbinutils (binutils-mingw-patches (cross-binutils target)))
(pthreads-xlibc mingw-w64-x86_64-winpthreads)
- (pthreads-xgcc (make-gcc-with-pthreads
- (cross-gcc target
- #:xgcc (make-ssp-fixed-gcc (make-mingw-w64-cross-gcc base-gcc))
+ (pthreads-xgcc (cross-gcc target
+ #:xgcc (gcc-mingw-patches mingw-w64-base-gcc)
#:xbinutils xbinutils
- #:libc pthreads-xlibc))))
+ #:libc pthreads-xlibc)))
;; Define a meta-package that propagates the resulting XBINUTILS, XLIBC, and
;; XGCC
(package
@@ -189,53 +133,54 @@ desirable for building Bitcoin Core release binaries."
(build-system trivial-build-system)
(arguments '(#:builder (begin (mkdir %output) #t)))
(propagated-inputs
- `(("binutils" ,xbinutils)
- ("libc" ,pthreads-xlibc)
- ("gcc" ,pthreads-xgcc)
- ("gcc-lib" ,pthreads-xgcc "lib")))
+ (list xbinutils
+ pthreads-xlibc
+ pthreads-xgcc
+ `(,pthreads-xgcc "lib")))
(synopsis (string-append "Complete GCC tool chain for " target))
(description (string-append "This package provides a complete GCC tool
chain for " target " development."))
(home-page (package-home-page pthreads-xgcc))
(license (package-license pthreads-xgcc)))))
-(define (make-nsis-for-gcc-10 base-nsis)
- (package-with-extra-patches base-nsis
- (search-our-patches "nsis-gcc-10-memmove.patch"
- "nsis-disable-installer-reloc.patch")))
-
-(define (fix-ppc64-nx-default lief)
- (package-with-extra-patches lief
- (search-our-patches "lief-fix-ppc64-nx-default.patch")))
-
-;; Our python-lief package can be removed once we are using
-;; guix 83bfdb409787cb2737e68b093a319b247b7858e6 or later.
-;; Note we currently use cmake-minimal.
+;; While LIEF is packaged in Guix, we maintain our own package,
+;; to simplify building, and more easily apply updates.
+;; Moreover, the Guix's package uses cmake, which caused build
+;; failure; see https://github.com/bitcoin/bitcoin/pull/27296.
(define-public python-lief
(package
(name "python-lief")
- (version "0.12.3")
+ (version "0.13.2")
(source (origin
(method git-fetch)
(uri (git-reference
(url "https://github.com/lief-project/LIEF")
(commit version)))
(file-name (git-file-name name version))
+ (modules '((guix build utils)))
+ (snippet
+ '(begin
+ ;; Configure build for Python bindings.
+ (substitute* "api/python/config-default.toml"
+ (("(ninja = )true" all m)
+ (string-append m "false"))
+ (("(parallel-jobs = )0" all m)
+ (string-append m (number->string (parallel-job-count)))))))
(sha256
(base32
- "11i6hqmcjh56y554kqhl61698n9v66j2qk1c1g63mv2w07h2z661"))))
+ "0y48x358ppig5xp97ahcphfipx7cg9chldj2q5zrmn610fmi4zll"))))
(build-system python-build-system)
- (native-inputs (list cmake-minimal))
+ (native-inputs (list cmake-minimal python-tomli))
(arguments
(list
#:tests? #f ;needs network
#:phases #~(modify-phases %standard-phases
+ (add-before 'build 'change-directory
+ (lambda _
+ (chdir "api/python")))
(replace 'build
(lambda _
- (invoke
- "python" "setup.py" "--sdk" "build"
- (string-append
- "-j" (number->string (parallel-job-count)))))))))
+ (invoke "python" "setup.py" "build"))))))
(home-page "https://github.com/lief-project/LIEF")
(synopsis "Library to instrument executable formats")
(description
@@ -248,18 +193,15 @@ and abstract ELF, PE and MachO formats.")
(name "osslsigncode")
(version "2.5")
(source (origin
- (method url-fetch)
- (uri (string-append "https://github.com/mtrojnar/"
- name "/archive/" version ".tar.gz"))
+ (method git-fetch)
+ (uri (git-reference
+ (url "https://github.com/mtrojnar/osslsigncode")
+ (commit version)))
(sha256
(base32
- "03by9706gg0an6dn48pljx38vcb76ziv11bgm8ilwsf293x2k4hv"))))
+ "1j47vwq4caxfv0xw68kw5yh00qcpbd56d7rq6c483ma3y7s96yyz"))))
(build-system cmake-build-system)
- (inputs
- `(("openssl", openssl)))
- (arguments
- '(#:configure-flags
- (list "-DCMAKE_DISABLE_FIND_PACKAGE_CURL=TRUE")))
+ (inputs (list openssl))
(home-page "https://github.com/mtrojnar/osslsigncode")
(synopsis "Authenticode signing and timestamping tool")
(description "osslsigncode is a small tool that implements part of the
@@ -295,7 +237,7 @@ thus should be able to compile on most platforms where these exist.")
(define-public python-oscrypto
(package
(name "python-oscrypto")
- (version "1.2.1")
+ (version "1.3.0")
(source
(origin
(method git-fetch)
@@ -305,7 +247,7 @@ thus should be able to compile on most platforms where these exist.")
(file-name (git-file-name name version))
(sha256
(base32
- "1d4d8s4z340qhvb3g5m5v3436y3a71yc26wk4749q64m09kxqc3l"))
+ "1v5wkmzcyiqy39db8j2dvkdrv2nlsc48556h73x4dzjwd6kg4q0a"))
(patches (search-our-patches "oscrypto-hard-code-openssl.patch"))))
(build-system python-build-system)
(native-search-paths
@@ -316,8 +258,7 @@ thus should be able to compile on most platforms where these exist.")
(files '("etc/ssl/certs/ca-certificates.crt")))))
(propagated-inputs
- `(("python-asn1crypto" ,python-asn1crypto)
- ("openssl" ,openssl)))
+ (list python-asn1crypto openssl))
(arguments
`(#:phases
(modify-phases %standard-phases
@@ -355,7 +296,7 @@ thus should be able to compile on most platforms where these exist.")
(package (inherit python-oscrypto)
(name "python-oscryptotests")
(propagated-inputs
- `(("python-oscrypto" ,python-oscrypto)))
+ (list python-oscrypto))
(arguments
`(#:tests? #f
#:phases
@@ -382,9 +323,9 @@ thus should be able to compile on most platforms where these exist.")
"1qw2k7xis53179lpqdqyylbcmp76lj7sagp883wmxg5i7chhc96k"))))
(build-system python-build-system)
(propagated-inputs
- `(("python-asn1crypto" ,python-asn1crypto)
- ("python-oscrypto" ,python-oscrypto)
- ("python-oscryptotests", python-oscryptotests))) ;; certvalidator tests import oscryptotests
+ (list python-asn1crypto
+ python-oscrypto
+ python-oscryptotests)) ;; certvalidator tests import oscryptotests
(arguments
`(#:phases
(modify-phases %standard-phases
@@ -432,79 +373,8 @@ certificates or paths. Supports various options, including: validation at a
specific moment in time, whitelisting and revocation checks.")
(license license:expat))))
-(define-public python-altgraph
- (package
- (name "python-altgraph")
- (version "0.17")
- (source
- (origin
- (method git-fetch)
- (uri (git-reference
- (url "https://github.com/ronaldoussoren/altgraph")
- (commit (string-append "v" version))))
- (file-name (git-file-name name version))
- (sha256
- (base32
- "09sm4srvvkw458pn48ga9q7ykr4xlz7q8gh1h9w7nxpf001qgpwb"))))
- (build-system python-build-system)
- (home-page "https://github.com/ronaldoussoren/altgraph")
- (synopsis "Python graph (network) package")
- (description "altgraph is a fork of graphlib: a graph (network) package for
-constructing graphs, BFS and DFS traversals, topological sort, shortest paths,
-etc. with graphviz output.")
- (license license:expat)))
-
-
-(define-public python-macholib
- (package
- (name "python-macholib")
- (version "1.14")
- (source
- (origin
- (method git-fetch)
- (uri (git-reference
- (url "https://github.com/ronaldoussoren/macholib")
- (commit (string-append "v" version))))
- (file-name (git-file-name name version))
- (sha256
- (base32
- "0aislnnfsza9wl4f0vp45ivzlc0pzhp9d4r08700slrypn5flg42"))))
- (build-system python-build-system)
- (propagated-inputs
- `(("python-altgraph" ,python-altgraph)))
- (arguments
- '(#:phases
- (modify-phases %standard-phases
- (add-after 'unpack 'disable-broken-tests
- (lambda _
- ;; This test is broken as there is no keyboard interrupt.
- (substitute* "macholib_tests/test_command_line.py"
- (("^(.*)class TestCmdLine" line indent)
- (string-append indent
- "@unittest.skip(\"Disabled by Guix\")\n"
- line)))
- (substitute* "macholib_tests/test_dyld.py"
- (("^(.*)def test_\\S+_find" line indent)
- (string-append indent
- "@unittest.skip(\"Disabled by Guix\")\n"
- line))
- (("^(.*)def testBasic" line indent)
- (string-append indent
- "@unittest.skip(\"Disabled by Guix\")\n"
- line))
- )
- #t)))))
- (home-page "https://github.com/ronaldoussoren/macholib")
- (synopsis "Python library for analyzing and editing Mach-O headers")
- (description "macholib is a Macho-O header analyzer and editor. It's
-typically used as a dependency analysis tool, and also to rewrite dylib
-references in Mach-O headers to be @executable_path relative. Though this tool
-targets a platform specific file format, it is pure python code that is platform
-and endian independent.")
- (license license:expat)))
-
(define-public python-signapple
- (let ((commit "8a945a2e7583be2665cf3a6a89d665b70ecd1ab6"))
+ (let ((commit "62155712e7417aba07565c9780a80e452823ae6a"))
(package
(name "python-signapple")
(version (git-version "0.1" "1" commit))
@@ -517,15 +387,13 @@ and endian independent.")
(file-name (git-file-name name commit))
(sha256
(base32
- "0fr1hangvfyiwflca6jg5g8zvg3jc9qr7vd2c12ff89pznf38dlg"))))
+ "1nm6rm4h4m7kbq729si4cm8rzild62mk4ni8xr5zja7l33fhv3gb"))))
(build-system python-build-system)
(propagated-inputs
- `(("python-asn1crypto" ,python-asn1crypto)
- ("python-oscrypto" ,python-oscrypto)
- ("python-certvalidator" ,python-certvalidator)
- ("python-elfesteem" ,python-elfesteem)
- ("python-requests" ,python-requests)
- ("python-macholib" ,python-macholib)))
+ (list python-asn1crypto
+ python-oscrypto
+ python-certvalidator
+ python-elfesteem))
;; There are no tests, but attempting to run python setup.py test leads to
;; problems, just disable the test
(arguments '(#:tests? #f))
@@ -535,16 +403,42 @@ and endian independent.")
inspecting signatures in Mach-O binaries.")
(license license:expat))))
-;; https://www.gnu.org/software/libc/manual/html_node/Configuring-and-compiling.html
-;; We don't use --disable-werror directly, as that would be passed through to bash,
-;; and cause it's build to fail.
-(define (hardened-glibc glibc)
- (package-with-extra-configure-variable (
- package-with-extra-configure-variable (
- package-with-extra-configure-variable glibc
- "enable_werror" "no")
- "--enable-stack-protector" "all")
- "--enable-bind-now" "yes"))
+(define-public mingw-w64-base-gcc
+ (package
+ (inherit base-gcc)
+ (arguments
+ (substitute-keyword-arguments (package-arguments base-gcc)
+ ((#:configure-flags flags)
+ `(append ,flags
+ ;; https://gcc.gnu.org/install/configure.html
+ (list "--enable-threads=posix",
+ "--enable-default-ssp=yes",
+ building-on)))))))
+
+(define-public linux-base-gcc
+ (package
+ (inherit base-gcc)
+ (arguments
+ (substitute-keyword-arguments (package-arguments base-gcc)
+ ((#:configure-flags flags)
+ `(append ,flags
+ ;; https://gcc.gnu.org/install/configure.html
+ (list "--enable-initfini-array=yes",
+ "--enable-default-ssp=yes",
+ "--enable-default-pie=yes",
+ "--enable-standard-branch-protection=yes",
+ building-on)))
+ ((#:phases phases)
+ `(modify-phases ,phases
+ ;; Given a XGCC package, return a modified package that replace each instance of
+ ;; -rpath in the default system spec that's inserted by Guix with -rpath-link
+ (add-after 'pre-configure 'replace-rpath-with-rpath-link
+ (lambda _
+ (substitute* (cons "gcc/config/rs6000/sysv4.h"
+ (find-files "gcc/config"
+ "^gnu-user.*\\.h$"))
+ (("-rpath=") "-rpath-link="))
+ #t))))))))
(define-public glibc-2.27
(package
@@ -559,11 +453,32 @@ inspecting signatures in Mach-O binaries.")
(sha256
(base32
"0azpb9cvnbv25zg8019rqz48h8i2257ngyjg566dlnp74ivrs9vq"))
- (patches (search-our-patches "glibc-ldd-x86_64.patch"
- "glibc-versioned-locpath.patch"
- "glibc-2.27-riscv64-Use-__has_include-to-include-asm-syscalls.h.patch"
+ (patches (search-our-patches "glibc-2.27-riscv64-Use-__has_include-to-include-asm-syscalls.h.patch"
"glibc-2.27-fcommon.patch"
- "glibc-2.27-guix-prefix.patch"))))))
+ "glibc-2.27-guix-prefix.patch"
+ "glibc-2.27-no-librt.patch"
+ "glibc-2.27-powerpc-ldbrx.patch"))))
+ (arguments
+ (substitute-keyword-arguments (package-arguments glibc)
+ ((#:configure-flags flags)
+ `(append ,flags
+ ;; https://www.gnu.org/software/libc/manual/html_node/Configuring-and-compiling.html
+ (list "--enable-stack-protector=all",
+ "--enable-bind-now",
+ "--disable-werror",
+ building-on)))
+ ((#:phases phases)
+ `(modify-phases ,phases
+ (add-before 'configure 'set-etc-rpc-installation-directory
+ (lambda* (#:key outputs #:allow-other-keys)
+ ;; Install the rpc data base file under `$out/etc/rpc'.
+ ;; Otherwise build will fail with "Permission denied."
+ (let ((out (assoc-ref outputs "out")))
+ (substitute* "sunrpc/Makefile"
+ (("^\\$\\(inst_sysconfdir\\)/rpc(.*)$" _ suffix)
+ (string-append out "/etc/rpc" suffix "\n"))
+ (("^install-others =.*$")
+ (string-append "install-others = " out "/etc/rpc\n"))))))))))))
(packages->manifest
(append
@@ -588,31 +503,38 @@ inspecting signatures in Mach-O binaries.")
gzip
xz
;; Build tools
+ cmake-minimal
gnu-make
- libtool-2.4.7
+ libtool
autoconf-2.71
automake
pkg-config
bison
- ;; Native GCC 10 toolchain
- gcc-toolchain-10
- (list gcc-toolchain-10 "static")
;; Scripting
- python-minimal ;; (3.9)
+ python-minimal ;; (3.10)
;; Git
git-minimal
;; Tests
- (fix-ppc64-nx-default python-lief))
+ python-lief)
(let ((target (getenv "HOST")))
(cond ((string-suffix? "-mingw32" target)
- ;; Windows
- (list zip
+ (list ;; Native GCC 12 toolchain
+ gcc-toolchain-12
+ zip
(make-mingw-pthreads-cross-toolchain "x86_64-w64-mingw32")
- (make-nsis-for-gcc-10 nsis-x86_64)
+ nsis-x86_64
nss-certs
osslsigncode))
((string-contains target "-linux-")
- (list (make-bitcoin-cross-toolchain target)))
+ (list ;; Native GCC 12 toolchain
+ gcc-toolchain-12
+ (list gcc-toolchain-12 "static")
+ (make-bitcoin-cross-toolchain target)))
((string-contains target "darwin")
- (list clang-toolchain-10 binutils cmake-minimal xorriso python-signapple))
+ (list ;; Native GCC 11 toolchain
+ gcc-toolchain-11
+ binutils
+ clang-toolchain-17
+ python-signapple
+ zip))
(else '())))))
diff --git a/contrib/guix/patches/binutils-unaligned-default.patch b/contrib/guix/patches/binutils-unaligned-default.patch
new file mode 100644
index 0000000000..d1bc71aee1
--- /dev/null
+++ b/contrib/guix/patches/binutils-unaligned-default.patch
@@ -0,0 +1,22 @@
+commit 6537181f59ed186a341db621812a6bc35e22eaf6
+Author: fanquake <fanquake@gmail.com>
+Date: Wed Apr 10 12:15:52 2024 +0200
+
+ build: turn on -muse-unaligned-vector-move by default
+
+ This allows us to avoid (more invasively) patching GCC, to avoid
+ unaligned instruction use.
+
+diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
+index e0632681477..14a9653abdf 100644
+--- a/gas/config/tc-i386.c
++++ b/gas/config/tc-i386.c
+@@ -801,7 +801,7 @@ static unsigned int no_cond_jump_promotion = 0;
+ static unsigned int sse2avx;
+
+ /* Encode aligned vector move as unaligned vector move. */
+-static unsigned int use_unaligned_vector_move;
++static unsigned int use_unaligned_vector_move = 1;
+
+ /* Encode scalar AVX instructions with specific vector length. */
+ static enum
diff --git a/contrib/guix/patches/gcc-broken-longjmp.patch b/contrib/guix/patches/gcc-broken-longjmp.patch
deleted file mode 100644
index 1cfc0918b0..0000000000
--- a/contrib/guix/patches/gcc-broken-longjmp.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-commit eb5698897c52702498938592d7f76e67d126451f
-Author: Eric Botcazou <ebotcazou@adacore.com>
-Date: Wed May 5 22:48:51 2021 +0200
-
- Fix PR target/100402
-
- This is a regression for 64-bit Windows present from mainline down to the 9
- branch and introduced by the fix for PR target/99234. Again SEH, but with
- a twist related to the way MinGW implements setjmp/longjmp, which turns out
- to be piggybacked on SEH with recent versions of MinGW, i.e. the longjmp
- performs a bona-fide unwinding of the stack, because it calls RtlUnwindEx
- with the second argument initially passed to setjmp, which is the result of
- __builtin_frame_address (0) in the MinGW header file:
-
- define setjmp(BUF) _setjmp((BUF), __builtin_frame_address (0))
-
- This means that we directly expose the frame pointer to the SEH machinery
- here (unlike with regular exception handling where we use an intermediate
- CFA) and thus that we cannot do whatever we want with it. The old code
- would leave it unaligned, i.e. not multiple of 16, whereas the new code
- aligns it, but this breaks for some reason; at least it appears that a
- .seh_setframe directive with 0 as second argument always works, so the
- fix aligns it this way.
-
- gcc/
- PR target/100402
- * config/i386/i386.c (ix86_compute_frame_layout): For a SEH target,
- always return the establisher frame for __builtin_frame_address (0).
- gcc/testsuite/
- * gcc.c-torture/execute/20210505-1.c: New test.
-
-diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
-index 2f838840e96..06ad1b2274e 100644
---- a/gcc/config/i386/i386.c
-+++ b/gcc/config/i386/i386.c
-@@ -6356,12 +6356,29 @@ ix86_compute_frame_layout (void)
- area, see the SEH code in config/i386/winnt.c for the rationale. */
- frame->hard_frame_pointer_offset = frame->sse_reg_save_offset;
-
-- /* If we can leave the frame pointer where it is, do so. Also, return
-+ /* If we can leave the frame pointer where it is, do so; however return
- the establisher frame for __builtin_frame_address (0) or else if the
-- frame overflows the SEH maximum frame size. */
-+ frame overflows the SEH maximum frame size.
-+
-+ Note that the value returned by __builtin_frame_address (0) is quite
-+ constrained, because setjmp is piggybacked on the SEH machinery with
-+ recent versions of MinGW:
-+
-+ # elif defined(__SEH__)
-+ # if defined(__aarch64__) || defined(_ARM64_)
-+ # define setjmp(BUF) _setjmp((BUF), __builtin_sponentry())
-+ # elif (__MINGW_GCC_VERSION < 40702)
-+ # define setjmp(BUF) _setjmp((BUF), mingw_getsp())
-+ # else
-+ # define setjmp(BUF) _setjmp((BUF), __builtin_frame_address (0))
-+ # endif
-+
-+ and the second argument passed to _setjmp, if not null, is forwarded
-+ to the TargetFrame parameter of RtlUnwindEx by longjmp (after it has
-+ built an ExceptionRecord on the fly describing the setjmp buffer). */
- const HOST_WIDE_INT diff
- = frame->stack_pointer_offset - frame->hard_frame_pointer_offset;
-- if (diff <= 255)
-+ if (diff <= 255 && !crtl->accesses_prior_frames)
- {
- /* The resulting diff will be a multiple of 16 lower than 255,
- i.e. at most 240 as required by the unwind data structure. */
diff --git a/contrib/guix/patches/gcc-10-remap-guix-store.patch b/contrib/guix/patches/gcc-remap-guix-store.patch
index a47ef7a2df..a47ef7a2df 100644
--- a/contrib/guix/patches/gcc-10-remap-guix-store.patch
+++ b/contrib/guix/patches/gcc-remap-guix-store.patch
diff --git a/contrib/guix/patches/glibc-2.27-fcommon.patch b/contrib/guix/patches/glibc-2.27-fcommon.patch
index f3baacab98..f8d14837fc 100644
--- a/contrib/guix/patches/glibc-2.27-fcommon.patch
+++ b/contrib/guix/patches/glibc-2.27-fcommon.patch
@@ -5,7 +5,7 @@ Date: Fri May 6 11:03:04 2022 +0100
build: use -fcommon to retain legacy behaviour with GCC 10
GCC 10 started using -fno-common by default, which causes issues with
- the powerpc builds using gibc 2.24. A patch was commited to glibc to fix
+ the powerpc builds using gibc 2.27. A patch was committed to glibc to fix
the issue, 18363b4f010da9ba459b13310b113ac0647c2fcc but is non-trvial
to backport, and was broken in at least one way, see the followup in
commit 7650321ce037302bfc2f026aa19e0213b8d02fe6.
@@ -17,6 +17,8 @@ Date: Fri May 6 11:03:04 2022 +0100
https://sourceware.org/git/?p=glibc.git;a=commit;h=18363b4f010da9ba459b13310b113ac0647c2fcc
https://sourceware.org/git/?p=glibc.git;a=commit;h=7650321ce037302bfc2f026aa19e0213b8d02fe6
+ This patch can be dropped when we are building with glibc 2.31+.
+
diff --git a/Makeconfig b/Makeconfig
index 86a71e5802..aa2166be60 100644
--- a/Makeconfig
diff --git a/contrib/guix/patches/glibc-2.27-guix-prefix.patch b/contrib/guix/patches/glibc-2.27-guix-prefix.patch
index 6648bc6c05..dc515907ff 100644
--- a/contrib/guix/patches/glibc-2.27-guix-prefix.patch
+++ b/contrib/guix/patches/glibc-2.27-guix-prefix.patch
@@ -5,7 +5,7 @@ In order to be reproducible regardless of the architecture used to build
the package, map all guix store prefixes to something fixed, e.g. /usr.
We might be able to drop this in favour of using --with-nonshared-cflags
-when we being using newer versions of glibc.
+when we begin using newer versions of glibc.
--- a/Makeconfig
+++ b/Makeconfig
diff --git a/contrib/guix/patches/glibc-2.27-no-librt.patch b/contrib/guix/patches/glibc-2.27-no-librt.patch
new file mode 100644
index 0000000000..4f2092ba7e
--- /dev/null
+++ b/contrib/guix/patches/glibc-2.27-no-librt.patch
@@ -0,0 +1,53 @@
+This patch can be dropped when we are building with glibc 2.30+.
+
+commit 6e41ef56c9baab719a02f1377b1e7ce7bff61e73
+Author: Florian Weimer <fweimer@redhat.com>
+Date: Fri Feb 8 10:21:56 2019 +0100
+
+ rt: Turn forwards from librt to libc into compat symbols [BZ #24194]
+
+ As the result of commit 6e6249d0b461b952d0f544792372663feb6d792a
+ ("BZ#14743: Move clock_* symbols from librt to libc."), in glibc 2.17,
+ clock_gettime, clock_getres, clock_settime, clock_getcpuclockid,
+ clock_nanosleep were added to libc, and the file rt/clock-compat.c
+ was added with forwarders to the actual implementations in libc.
+ These forwarders were wrapped in
+
+ #if SHLIB_COMPAT (librt, GLIBC_2_2, GLIBC_2_17)
+
+ so that they are not present for newer architectures (such as
+ powerpc64le) with a 2.17 or later ABI baseline. But the forwarders
+ were not marked as compatibility symbols. As a result, on older
+ architectures, historic configure checks such as
+
+ AC_CHECK_LIB(rt, clock_gettime)
+
+ still cause linking against librt, even though this is completely
+ unnecessary. It also creates a needless porting hazard because
+ architectures behave differently when it comes to symbol availability.
+
+ Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+diff --git a/rt/clock-compat.c b/rt/clock-compat.c
+index f816973c05..11e71aa890 100644
+--- a/rt/clock-compat.c
++++ b/rt/clock-compat.c
+@@ -30,14 +30,16 @@
+ #if HAVE_IFUNC
+ # undef INIT_ARCH
+ # define INIT_ARCH()
+-# define COMPAT_REDIRECT(name, proto, arglist) libc_ifunc (name, &__##name)
++# define COMPAT_REDIRECT(name, proto, arglist) libc_ifunc (name, &__##name) \
++ compat_symbol (librt, name, name, GLIBC_2_2);
+ #else
+ # define COMPAT_REDIRECT(name, proto, arglist) \
+ int \
+ name proto \
+ { \
+ return __##name arglist; \
+- }
++ } \
++ compat_symbol (librt, name, name, GLIBC_2_2);
+ #endif
+
+ COMPAT_REDIRECT (clock_getres,
diff --git a/contrib/guix/patches/glibc-2.27-powerpc-ldbrx.patch b/contrib/guix/patches/glibc-2.27-powerpc-ldbrx.patch
new file mode 100644
index 0000000000..26716054c8
--- /dev/null
+++ b/contrib/guix/patches/glibc-2.27-powerpc-ldbrx.patch
@@ -0,0 +1,245 @@
+From 50b0b3c9ff71ffd7ebbd74ae46844c3566478123 Mon Sep 17 00:00:00 2001
+From: "Gabriel F. T. Gomes" <gabrielftg@linux.ibm.com>
+Date: Mon, 27 May 2019 15:21:22 -0300
+Subject: [PATCH] powerpc: Fix build failures with current GCC
+
+Since GCC commit 271500 (svn), also known as the following commit on the
+git mirror:
+
+commit e154242724b084380e3221df7c08fcdbd8460674
+Author: amodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>
+Date: Wed May 22 04:34:26 2019 +0000
+
+ [RS6000] Don't pass -many to the assembler
+
+glibc builds are failing when an assembly implementation does not
+declare the correct '.machine' directive, or when no such directive is
+declared at all. For example, when a POWER6 instruction is used, but
+'.machine power6' is not declared, the assembler will fail with an error
+similar to the following:
+
+ ../sysdeps/powerpc/powerpc64/power8/strcmp.S: Assembler messages:
+ 24 ../sysdeps/powerpc/powerpc64/power8/strcmp.S:55: Error: unrecognized opcode: `cmpb'
+
+This patch adds '.machine powerN' directives where none existed, as well
+as it updates '.machine power7' directives on POWER8 files, because the
+minimum binutils version required to build glibc (binutils 2.25) now
+provides this machine version. It also adds '-many' to the assembler
+command used to build tst-set_ppr.c.
+
+Tested for powerpc, powerpc64, and powerpc64le, as well as with
+build-many-glibcs.py for powerpc targets.
+
+Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
+---
+ sysdeps/powerpc/Makefile | 5 +++
+ sysdeps/powerpc/powerpc64/power4/memcmp.S | 7 ++++
+ sysdeps/powerpc/powerpc64/power7/strncmp.S | 1 +
+ .../powerpc/powerpc64/power8/fpu/s_llround.S | 1 +
+ sysdeps/powerpc/powerpc64/power8/strcasecmp.S | 36 ++++++-------------
+ sysdeps/powerpc/powerpc64/power8/strcasestr.S | 14 ++------
+ sysdeps/powerpc/powerpc64/power8/strcmp.S | 1 +
+ 7 files changed, 28 insertions(+), 37 deletions(-)
+
+diff --git a/sysdeps/powerpc/Makefile b/sysdeps/powerpc/Makefile
+index 6aa683b03f..23126147df 100644
+--- a/sysdeps/powerpc/Makefile
++++ b/sysdeps/powerpc/Makefile
+@@ -45,6 +45,11 @@ ifeq ($(subdir),misc)
+ sysdep_headers += sys/platform/ppc.h
+ tests += test-gettimebase
+ tests += tst-set_ppr
++
++# This test is expected to run and exit with EXIT_UNSUPPORTED on
++# processors that do not implement the Power ISA 2.06 or greater.
++# But the test makes use of instructions from Power ISA 2.06 and 2.07.
++CFLAGS-tst-set_ppr.c += -Wa,-many
+ endif
+
+ ifneq (,$(filter %le,$(config-machine)))
+diff --git a/sysdeps/powerpc/powerpc64/power4/memcmp.S b/sysdeps/powerpc/powerpc64/power4/memcmp.S
+index e5319f101f..38dcf4c9a1 100644
+--- a/sysdeps/powerpc/powerpc64/power4/memcmp.S
++++ b/sysdeps/powerpc/powerpc64/power4/memcmp.S
+@@ -26,7 +26,14 @@
+ # define MEMCMP memcmp
+ #endif
+
++#ifndef __LITTLE_ENDIAN__
+ .machine power4
++#else
++/* Little endian is only available since POWER8, so it's safe to
++ specify .machine as power8 (or older), even though this is a POWER4
++ file. Since the little-endian code uses 'ldbrx', power7 is enough. */
++ .machine power7
++#endif
+ ENTRY_TOCLESS (MEMCMP, 4)
+ CALL_MCOUNT 3
+
+diff --git a/sysdeps/powerpc/powerpc64/power7/strncmp.S b/sysdeps/powerpc/powerpc64/power7/strncmp.S
+index 0c7429d19f..10f898c5a3 100644
+--- a/sysdeps/powerpc/powerpc64/power7/strncmp.S
++++ b/sysdeps/powerpc/powerpc64/power7/strncmp.S
+@@ -28,6 +28,7 @@
+ const char *s2 [r4],
+ size_t size [r5]) */
+
++ .machine power7
+ ENTRY_TOCLESS (STRNCMP, 5)
+ CALL_MCOUNT 3
+
+diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S
+index a22fc63bb3..84c76ba0f9 100644
+--- a/sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S
++++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S
+@@ -26,6 +26,7 @@
+
+ /* long long [r3] llround (float x [fp1]) */
+
++ .machine power8
+ ENTRY_TOCLESS (__llround)
+ CALL_MCOUNT 0
+ frin fp1,fp1 /* Round to nearest +-0.5. */
+diff --git a/sysdeps/powerpc/powerpc64/power8/strcasecmp.S b/sysdeps/powerpc/powerpc64/power8/strcasecmp.S
+index 3a2efe2a64..eeacd40c7f 100644
+--- a/sysdeps/powerpc/powerpc64/power8/strcasecmp.S
++++ b/sysdeps/powerpc/powerpc64/power8/strcasecmp.S
+@@ -91,21 +91,7 @@
+ 3: \
+ TOLOWER()
+
+-#ifdef _ARCH_PWR8
+-# define VCLZD_V8_v7 vclzd v8, v7;
+-# define MFVRD_R3_V1 mfvrd r3, v1;
+-# define VSUBUDM_V9_V8 vsubudm v9, v9, v8;
+-# define VPOPCNTD_V8_V8 vpopcntd v8, v8;
+-# define VADDUQM_V7_V8 vadduqm v9, v7, v8;
+-#else
+-# define VCLZD_V8_v7 .long 0x11003fc2
+-# define MFVRD_R3_V1 .long 0x7c230067
+-# define VSUBUDM_V9_V8 .long 0x112944c0
+-# define VPOPCNTD_V8_V8 .long 0x110047c3
+-# define VADDUQM_V7_V8 .long 0x11274100
+-#endif
+-
+- .machine power7
++ .machine power8
+
+ ENTRY (__STRCASECMP)
+ #ifdef USE_AS_STRNCASECMP
+@@ -265,15 +251,15 @@ L(different):
+ #ifdef __LITTLE_ENDIAN__
+ /* Count trailing zero. */
+ vspltisb v8, -1
+- VADDUQM_V7_V8
++ vadduqm v9, v7, v8
+ vandc v8, v9, v7
+- VPOPCNTD_V8_V8
++ vpopcntd v8, v8
+ vspltb v6, v8, 15
+ vcmpequb. v6, v6, v1
+ blt cr6, L(shift8)
+ #else
+ /* Count leading zero. */
+- VCLZD_V8_v7
++ vclzd v8, v7
+ vspltb v6, v8, 7
+ vcmpequb. v6, v6, v1
+ blt cr6, L(shift8)
+@@ -291,7 +277,7 @@ L(skipsum):
+ /* Merge and move to GPR. */
+ vmrglb v6, v6, v7
+ vslo v1, v6, v1
+- MFVRD_R3_V1
++ mfvrd r3, v1
+ /* Place the characters that are different in first position. */
+ sldi rSTR2, rRTN, 56
+ srdi rSTR2, rSTR2, 56
+@@ -301,7 +287,7 @@ L(skipsum):
+ vslo v6, v5, v8
+ vslo v7, v4, v8
+ vmrghb v1, v6, v7
+- MFVRD_R3_V1
++ mfvrd r3, v1
+ srdi rSTR2, rRTN, 48
+ sldi rSTR2, rSTR2, 56
+ srdi rSTR2, rSTR2, 56
+@@ -320,15 +306,15 @@ L(null_found):
+ #ifdef __LITTLE_ENDIAN__
+ /* Count trailing zero. */
+ vspltisb v8, -1
+- VADDUQM_V7_V8
++ vadduqm v9, v7, v8
+ vandc v8, v9, v7
+- VPOPCNTD_V8_V8
++ vpopcntd v8, v8
+ vspltb v6, v8, 15
+ vcmpequb. v6, v6, v10
+ blt cr6, L(shift_8)
+ #else
+ /* Count leading zero. */
+- VCLZD_V8_v7
++ vclzd v8, v7
+ vspltb v6, v8, 7
+ vcmpequb. v6, v6, v10
+ blt cr6, L(shift_8)
+@@ -343,10 +329,10 @@ L(skipsum1):
+ vspltisb v10, 7
+ vslb v10, v10, v10
+ vsldoi v9, v0, v10, 1
+- VSUBUDM_V9_V8
++ vsubudm v9, v9, v8
+ vspltisb v8, 8
+ vsldoi v8, v0, v8, 1
+- VSUBUDM_V9_V8
++ vsubudm v9, v9, v8
+ /* Shift and remove junk after null character. */
+ #ifdef __LITTLE_ENDIAN__
+ vslo v5, v5, v9
+diff --git a/sysdeps/powerpc/powerpc64/power8/strcasestr.S b/sysdeps/powerpc/powerpc64/power8/strcasestr.S
+index 9fc24c29f9..e10f06fd86 100644
+--- a/sysdeps/powerpc/powerpc64/power8/strcasestr.S
++++ b/sysdeps/powerpc/powerpc64/power8/strcasestr.S
+@@ -73,18 +73,8 @@
+ vor reg, v8, reg; \
+ vcmpequb. v6, reg, v4;
+
+-/* TODO: change these to the actual instructions when the minimum required
+- binutils allows it. */
+-#ifdef _ARCH_PWR8
+-#define VCLZD_V8_v7 vclzd v8, v7;
+-#else
+-#define VCLZD_V8_v7 .long 0x11003fc2
+-#endif
+-
+ #define FRAMESIZE (FRAME_MIN_SIZE+48)
+-/* TODO: change this to .machine power8 when the minimum required binutils
+- allows it. */
+- .machine power7
++ .machine power8
+ ENTRY (STRCASESTR, 4)
+ CALL_MCOUNT 2
+ mflr r0 /* Load link register LR to r0. */
+@@ -291,7 +281,7 @@ L(nullchk1):
+ vcmpequb. v6, v0, v7
+ /* Shift r3 by 16 bytes and proceed. */
+ blt cr6, L(shift16)
+- VCLZD_V8_v7
++ vclzd v8, v7
+ #ifdef __LITTLE_ENDIAN__
+ vspltb v6, v8, 15
+ #else
+diff --git a/sysdeps/powerpc/powerpc64/power8/strcmp.S b/sysdeps/powerpc/powerpc64/power8/strcmp.S
+index 15e7351d1b..d592266d1d 100644
+--- a/sysdeps/powerpc/powerpc64/power8/strcmp.S
++++ b/sysdeps/powerpc/powerpc64/power8/strcmp.S
+@@ -31,6 +31,7 @@
+ 64K as default, the page cross handling assumes minimum page size of
+ 4k. */
+
++ .machine power8
+ ENTRY_TOCLESS (STRCMP, 4)
+ li r0,0
+
+--
+2.41.0
diff --git a/contrib/guix/patches/glibc-2.27-riscv64-Use-__has_include-to-include-asm-syscalls.h.patch b/contrib/guix/patches/glibc-2.27-riscv64-Use-__has_include-to-include-asm-syscalls.h.patch
index c0f8495c41..ab8ae9c023 100644
--- a/contrib/guix/patches/glibc-2.27-riscv64-Use-__has_include-to-include-asm-syscalls.h.patch
+++ b/contrib/guix/patches/glibc-2.27-riscv64-Use-__has_include-to-include-asm-syscalls.h.patch
@@ -4,6 +4,8 @@ See also: http://lists.busybox.net/pipermail/buildroot/2020-July/590376.html.
https://sourceware.org/git/?p=glibc.git;a=commit;h=0b9c84906f653978fb8768c7ebd0ee14a47e662e
+This patch can be dropped when we are building with glibc 2.28+.
+
From 562c52cc81a4e456a62e6455feb32732049e9070 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Mon, 31 Dec 2018 09:26:42 -0800
diff --git a/contrib/guix/patches/glibc-ldd-x86_64.patch b/contrib/guix/patches/glibc-ldd-x86_64.patch
deleted file mode 100644
index a23b095caa..0000000000
--- a/contrib/guix/patches/glibc-ldd-x86_64.patch
+++ /dev/null
@@ -1,10 +0,0 @@
-By default, 'RTDLLIST' in 'ldd' refers to 'lib64/ld-linux-x86-64.so', whereas
-it's in 'lib/' for us. This patch fixes that.
-
---- a/sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed
-+++ b/sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed
-@@ -1,3 +1,3 @@
- /LD_TRACE_LOADED_OBJECTS=1/a\
- add_env="$add_env LD_LIBRARY_VERSION=\\$verify_out"
--s_^\(RTLDLIST=\)\(.*lib\)\(\|64\|x32\)\(/[^/]*\)\(-x86-64\|-x32\)\(\.so\.[0-9.]*\)[ ]*$_\1"\2\4\6 \264\4-x86-64\6 \2x32\4-x32\6"_
-+s_^\(RTLDLIST=\)\(.*lib\)\(\|64\|x32\)\(/[^/]*\)\(-x86-64\|-x32\)\(\.so\.[0-9.]*\)[ ]*$_\1"\2\4\6 \2\4-x86-64\6 \2x32\4-x32\6"_
diff --git a/contrib/guix/patches/glibc-versioned-locpath.patch b/contrib/guix/patches/glibc-versioned-locpath.patch
deleted file mode 100644
index bc7652127f..0000000000
--- a/contrib/guix/patches/glibc-versioned-locpath.patch
+++ /dev/null
@@ -1,240 +0,0 @@
-The format of locale data can be incompatible between libc versions, and
-loading incompatible data can lead to 'setlocale' returning EINVAL at best
-or triggering an assertion failure at worst. See
-https://lists.gnu.org/archive/html/guix-devel/2015-09/msg00717.html
-for background information.
-
-To address that, this patch changes libc to honor a new 'GUIX_LOCPATH'
-variable, and to look for locale data in version-specific sub-directories of
-that variable. So, if GUIX_LOCPATH=/foo:/bar, locale data is searched for in
-/foo/X.Y and /bar/X.Y, where X.Y is the libc version number.
-
-That way, a single 'GUIX_LOCPATH' setting can work even if different libc
-versions coexist on the system.
-
---- a/locale/newlocale.c
-+++ b/locale/newlocale.c
-@@ -30,6 +30,7 @@
- /* Lock for protecting global data. */
- __libc_rwlock_define (extern , __libc_setlocale_lock attribute_hidden)
-
-+extern error_t compute_locale_search_path (char **, size_t *);
-
- /* Use this when we come along an error. */
- #define ERROR_RETURN \
-@@ -48,7 +49,6 @@ __newlocale (int category_mask, const char *locale, __locale_t base)
- __locale_t result_ptr;
- char *locale_path;
- size_t locale_path_len;
-- const char *locpath_var;
- int cnt;
- size_t names_len;
-
-@@ -102,17 +102,8 @@ __newlocale (int category_mask, const char *locale, __locale_t base)
- locale_path = NULL;
- locale_path_len = 0;
-
-- locpath_var = getenv ("LOCPATH");
-- if (locpath_var != NULL && locpath_var[0] != '\0')
-- {
-- if (__argz_create_sep (locpath_var, ':',
-- &locale_path, &locale_path_len) != 0)
-- return NULL;
--
-- if (__argz_add_sep (&locale_path, &locale_path_len,
-- _nl_default_locale_path, ':') != 0)
-- return NULL;
-- }
-+ if (compute_locale_search_path (&locale_path, &locale_path_len) != 0)
-+ return NULL;
-
- /* Get the names for the locales we are interested in. We either
- allow a composite name or a single name. */
-diff --git a/locale/setlocale.c b/locale/setlocale.c
-index ead030d..0c0e314 100644
---- a/locale/setlocale.c
-+++ b/locale/setlocale.c
-@@ -215,12 +215,65 @@ setdata (int category, struct __locale_data *data)
- }
- }
-
-+/* Return in *LOCALE_PATH and *LOCALE_PATH_LEN the locale data search path as
-+ a colon-separated list. Return ENOMEN on error, zero otherwise. */
-+error_t
-+compute_locale_search_path (char **locale_path, size_t *locale_path_len)
-+{
-+ char* guix_locpath_var = getenv ("GUIX_LOCPATH");
-+ char *locpath_var = getenv ("LOCPATH");
-+
-+ if (guix_locpath_var != NULL && guix_locpath_var[0] != '\0')
-+ {
-+ /* Entries in 'GUIX_LOCPATH' take precedence over 'LOCPATH'. These
-+ entries are systematically prefixed with "/X.Y" where "X.Y" is the
-+ libc version. */
-+ if (__argz_create_sep (guix_locpath_var, ':',
-+ locale_path, locale_path_len) != 0
-+ || __argz_suffix_entries (locale_path, locale_path_len,
-+ "/" VERSION) != 0)
-+ goto bail_out;
-+ }
-+
-+ if (locpath_var != NULL && locpath_var[0] != '\0')
-+ {
-+ char *reg_locale_path = NULL;
-+ size_t reg_locale_path_len = 0;
-+
-+ if (__argz_create_sep (locpath_var, ':',
-+ &reg_locale_path, &reg_locale_path_len) != 0)
-+ goto bail_out;
-+
-+ if (__argz_append (locale_path, locale_path_len,
-+ reg_locale_path, reg_locale_path_len) != 0)
-+ goto bail_out;
-+
-+ free (reg_locale_path);
-+ }
-+
-+ if (*locale_path != NULL)
-+ {
-+ /* Append the system default locale directory. */
-+ if (__argz_add_sep (locale_path, locale_path_len,
-+ _nl_default_locale_path, ':') != 0)
-+ goto bail_out;
-+ }
-+
-+ return 0;
-+
-+ bail_out:
-+ free (*locale_path);
-+ *locale_path = NULL;
-+ *locale_path_len = 0;
-+
-+ return ENOMEM;
-+}
-+
- char *
- setlocale (int category, const char *locale)
- {
- char *locale_path;
- size_t locale_path_len;
-- const char *locpath_var;
- char *composite;
-
- /* Sanity check for CATEGORY argument. */
-@@ -251,17 +304,10 @@ setlocale (int category, const char *locale)
- locale_path = NULL;
- locale_path_len = 0;
-
-- locpath_var = getenv ("LOCPATH");
-- if (locpath_var != NULL && locpath_var[0] != '\0')
-+ if (compute_locale_search_path (&locale_path, &locale_path_len) != 0)
- {
-- if (__argz_create_sep (locpath_var, ':',
-- &locale_path, &locale_path_len) != 0
-- || __argz_add_sep (&locale_path, &locale_path_len,
-- _nl_default_locale_path, ':') != 0)
-- {
-- __libc_rwlock_unlock (__libc_setlocale_lock);
-- return NULL;
-- }
-+ __libc_rwlock_unlock (__libc_setlocale_lock);
-+ return NULL;
- }
-
- if (category == LC_ALL)
-diff --git a/string/Makefile b/string/Makefile
-index 8424a61..f925503 100644
---- a/string/Makefile
-+++ b/string/Makefile
-@@ -38,7 +38,7 @@ routines := strcat strchr strcmp strcoll strcpy strcspn \
- swab strfry memfrob memmem rawmemchr strchrnul \
- $(addprefix argz-,append count create ctsep next \
- delete extract insert stringify \
-- addsep replace) \
-+ addsep replace suffix) \
- envz basename \
- strcoll_l strxfrm_l string-inlines memrchr \
- xpg-strerror strerror_l
-diff --git a/string/argz-suffix.c b/string/argz-suffix.c
-new file mode 100644
-index 0000000..505b0f2
---- /dev/null
-+++ b/string/argz-suffix.c
-@@ -0,0 +1,56 @@
-+/* Copyright (C) 2015 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ludovic Courtès <ludo@gnu.org>.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, see
-+ <http://www.gnu.org/licenses/>. */
-+
-+#include <argz.h>
-+#include <errno.h>
-+#include <stdlib.h>
-+#include <string.h>
-+
-+
-+error_t
-+__argz_suffix_entries (char **argz, size_t *argz_len, const char *suffix)
-+
-+{
-+ size_t suffix_len = strlen (suffix);
-+ size_t count = __argz_count (*argz, *argz_len);
-+ size_t new_argz_len = *argz_len + count * suffix_len;
-+ char *new_argz = malloc (new_argz_len);
-+
-+ if (new_argz)
-+ {
-+ char *p = new_argz, *entry;
-+
-+ for (entry = *argz;
-+ entry != NULL;
-+ entry = argz_next (*argz, *argz_len, entry))
-+ {
-+ p = stpcpy (p, entry);
-+ p = stpcpy (p, suffix);
-+ p++;
-+ }
-+
-+ free (*argz);
-+ *argz = new_argz;
-+ *argz_len = new_argz_len;
-+
-+ return 0;
-+ }
-+ else
-+ return ENOMEM;
-+}
-+weak_alias (__argz_suffix_entries, argz_suffix_entries)
-diff --git a/string/argz.h b/string/argz.h
-index bb62a31..d276a35 100644
---- a/string/argz.h
-+++ b/string/argz.h
-@@ -134,6 +134,16 @@ extern error_t argz_replace (char **__restrict __argz,
- const char *__restrict __str,
- const char *__restrict __with,
- unsigned int *__restrict __replace_count);
-+
-+/* Suffix each entry of ARGZ & ARGZ_LEN with SUFFIX. Return 0 on success,
-+ and ENOMEN if memory cannot be allocated. */
-+extern error_t __argz_suffix_entries (char **__restrict __argz,
-+ size_t *__restrict __argz_len,
-+ const char *__restrict __suffix);
-+extern error_t argz_suffix_entries (char **__restrict __argz,
-+ size_t *__restrict __argz_len,
-+ const char *__restrict __suffix);
-+
-
- /* Returns the next entry in ARGZ & ARGZ_LEN after ENTRY, or NULL if there
- are no more. If entry is NULL, then the first entry is returned. This
diff --git a/contrib/guix/patches/lief-fix-ppc64-nx-default.patch b/contrib/guix/patches/lief-fix-ppc64-nx-default.patch
deleted file mode 100644
index 101bc1ddc0..0000000000
--- a/contrib/guix/patches/lief-fix-ppc64-nx-default.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-Correct default for Binary::has_nx on ppc64
-
-From the Linux kernel source:
-
- * This is the default if a program doesn't have a PT_GNU_STACK
- * program header entry. The PPC64 ELF ABI has a non executable stack
- * stack by default, so in the absence of a PT_GNU_STACK program header
- * we turn execute permission off.
-
-This patch can be dropped the next time we update LIEF.
-
-diff --git a/src/ELF/Binary.cpp b/src/ELF/Binary.cpp
-index a90be1ab..fd2d9764 100644
---- a/src/ELF/Binary.cpp
-+++ b/src/ELF/Binary.cpp
-@@ -1084,7 +1084,12 @@ bool Binary::has_nx() const {
- return segment->type() == SEGMENT_TYPES::PT_GNU_STACK;
- });
- if (it_stack == std::end(segments_)) {
-- return false;
-+ if (header().machine_type() == ARCH::EM_PPC64) {
-+ // The PPC64 ELF ABI has a non-executable stack by default.
-+ return true;
-+ } else {
-+ return false;
-+ }
- }
-
- return !(*it_stack)->has(ELF_SEGMENT_FLAGS::PF_X);
diff --git a/contrib/guix/patches/nsis-disable-installer-reloc.patch b/contrib/guix/patches/nsis-disable-installer-reloc.patch
deleted file mode 100644
index 4914527e56..0000000000
--- a/contrib/guix/patches/nsis-disable-installer-reloc.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-Patch NSIS so that it's installer stubs, produced at NSIS build time,
-do not contain .reloc sections, which will exist by default when using
-binutils/ld 2.36+.
-
-This ultimately fixes an issue when running the installer with the
-"Force randomization for images (Mandatory ASLR)" setting active.
-
-This patch has not yet been sent upstream, because it's not clear if this
-is the best fix, for the underlying issue, which seems to be that makensis
-doesn't account for .reloc sections when it builds installers.
-
-The existence of a reloc section shouldn't be a problem, and, if anything,
-is actually a requirement for working ASLR. All other Windows binaries we
-produce contain them, and function correctly when under the same
-"Force randomization for images (Mandatory ASLR)" setting.
-
-See:
-https://github.com/bitcoin/bitcoin/issues/25726
-https://sourceforge.net/p/nsis/bugs/1131/
-
---- a/SCons/Config/gnu
-+++ b/SCons/Config/gnu
-@@ -102,6 +102,7 @@ stub_env.Append(LINKFLAGS = ['-mwindows']) # build windows executables
- stub_env.Append(LINKFLAGS = ['$NODEFLIBS_FLAG']) # no standard libraries
- stub_env.Append(LINKFLAGS = ['$ALIGN_FLAG']) # 512 bytes align
- stub_env.Append(LINKFLAGS = ['$MAP_FLAG']) # generate map file
-+stub_env.Append(LINKFLAGS = ['-Wl,--disable-reloc-section'])
-
- conf = FlagsConfigure(stub_env)
- conf.CheckCompileFlag('-fno-tree-loop-distribute-patterns') # GCC 10: Don't generate msvcrt!memmove calls (bug #1248)
diff --git a/contrib/guix/patches/nsis-gcc-10-memmove.patch b/contrib/guix/patches/nsis-gcc-10-memmove.patch
deleted file mode 100644
index a1aadfd4f3..0000000000
--- a/contrib/guix/patches/nsis-gcc-10-memmove.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-commit f6df41524e703dc471e283e566a48e05a735b7f2
-Author: Anders <anders_k@users.sourceforge.net>
-Date: Sat Jun 27 23:18:45 2020 +0000
-
- Don't let GCC 10 generate memmove calls (bug #1248)
-
- git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@7189 212acab6-be3b-0410-9dea-997c60f758d6
-
-diff --git a/SCons/Config/gnu b/SCons/Config/gnu
-index bfcb362d..21fa446b 100644
---- a/SCons/Config/gnu
-+++ b/SCons/Config/gnu
-@@ -103,6 +103,10 @@ stub_env.Append(LINKFLAGS = ['$NODEFLIBS_FLAG']) # no standard libraries
- stub_env.Append(LINKFLAGS = ['$ALIGN_FLAG']) # 512 bytes align
- stub_env.Append(LINKFLAGS = ['$MAP_FLAG']) # generate map file
-
-+conf = FlagsConfigure(stub_env)
-+conf.CheckCompileFlag('-fno-tree-loop-distribute-patterns') # GCC 10: Don't generate msvcrt!memmove calls (bug #1248)
-+conf.Finish()
-+
- stub_uenv = stub_env.Clone()
- stub_uenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
-
diff --git a/contrib/guix/patches/vmov-alignment.patch b/contrib/guix/patches/vmov-alignment.patch
deleted file mode 100644
index 072f76eafd..0000000000
--- a/contrib/guix/patches/vmov-alignment.patch
+++ /dev/null
@@ -1,267 +0,0 @@
-Description: Use unaligned VMOV instructions
-Author: Stephen Kitt <skitt@debian.org>
-Bug-Debian: https://bugs.debian.org/939559
-
-Based on a patch originally by Claude Heiland-Allen <claude@mathr.co.uk>
-
---- a/gcc/config/i386/sse.md
-+++ b/gcc/config/i386/sse.md
-@@ -1058,17 +1058,11 @@
- {
- if (FLOAT_MODE_P (GET_MODE_INNER (<MODE>mode)))
- {
-- if (misaligned_operand (operands[1], <MODE>mode))
-- return "vmovu<ssemodesuffix>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}";
-- else
-- return "vmova<ssemodesuffix>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}";
-+ return "vmovu<ssemodesuffix>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}";
- }
- else
- {
-- if (misaligned_operand (operands[1], <MODE>mode))
-- return "vmovdqu<ssescalarsize>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}";
-- else
-- return "vmovdqa<ssescalarsize>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}";
-+ return "vmovdqu<ssescalarsize>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}";
- }
- }
- [(set_attr "type" "ssemov")
-@@ -1184,17 +1178,11 @@
- {
- if (FLOAT_MODE_P (GET_MODE_INNER (<MODE>mode)))
- {
-- if (misaligned_operand (operands[0], <MODE>mode))
-- return "vmovu<ssemodesuffix>\t{%1, %0%{%2%}|%0%{%2%}, %1}";
-- else
-- return "vmova<ssemodesuffix>\t{%1, %0%{%2%}|%0%{%2%}, %1}";
-+ return "vmovu<ssemodesuffix>\t{%1, %0%{%2%}|%0%{%2%}, %1}";
- }
- else
- {
-- if (misaligned_operand (operands[0], <MODE>mode))
-- return "vmovdqu<ssescalarsize>\t{%1, %0%{%2%}|%0%{%2%}, %1}";
-- else
-- return "vmovdqa<ssescalarsize>\t{%1, %0%{%2%}|%0%{%2%}, %1}";
-+ return "vmovdqu<ssescalarsize>\t{%1, %0%{%2%}|%0%{%2%}, %1}";
- }
- }
- [(set_attr "type" "ssemov")
-@@ -7806,7 +7794,7 @@
- "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "@
- %vmovlps\t{%1, %0|%q0, %1}
-- %vmovaps\t{%1, %0|%0, %1}
-+ %vmovups\t{%1, %0|%0, %1}
- %vmovlps\t{%1, %d0|%d0, %q1}"
- [(set_attr "type" "ssemov")
- (set_attr "prefix" "maybe_vex")
-@@ -13997,29 +13985,15 @@
- switch (<MODE>mode)
- {
- case E_V8DFmode:
-- if (misaligned_operand (operands[2], <ssequartermode>mode))
-- return "vmovupd\t{%2, %x0|%x0, %2}";
-- else
-- return "vmovapd\t{%2, %x0|%x0, %2}";
-+ return "vmovupd\t{%2, %x0|%x0, %2}";
- case E_V16SFmode:
-- if (misaligned_operand (operands[2], <ssequartermode>mode))
-- return "vmovups\t{%2, %x0|%x0, %2}";
-- else
-- return "vmovaps\t{%2, %x0|%x0, %2}";
-+ return "vmovups\t{%2, %x0|%x0, %2}";
- case E_V8DImode:
-- if (misaligned_operand (operands[2], <ssequartermode>mode))
-- return which_alternative == 2 ? "vmovdqu64\t{%2, %x0|%x0, %2}"
-+ return which_alternative == 2 ? "vmovdqu64\t{%2, %x0|%x0, %2}"
- : "vmovdqu\t{%2, %x0|%x0, %2}";
-- else
-- return which_alternative == 2 ? "vmovdqa64\t{%2, %x0|%x0, %2}"
-- : "vmovdqa\t{%2, %x0|%x0, %2}";
- case E_V16SImode:
-- if (misaligned_operand (operands[2], <ssequartermode>mode))
-- return which_alternative == 2 ? "vmovdqu32\t{%2, %x0|%x0, %2}"
-+ return which_alternative == 2 ? "vmovdqu32\t{%2, %x0|%x0, %2}"
- : "vmovdqu\t{%2, %x0|%x0, %2}";
-- else
-- return which_alternative == 2 ? "vmovdqa32\t{%2, %x0|%x0, %2}"
-- : "vmovdqa\t{%2, %x0|%x0, %2}";
- default:
- gcc_unreachable ();
- }
-@@ -21225,63 +21199,27 @@
- switch (get_attr_mode (insn))
- {
- case MODE_V16SF:
-- if (misaligned_operand (operands[1], <ssehalfvecmode>mode))
-- return "vmovups\t{%1, %t0|%t0, %1}";
-- else
-- return "vmovaps\t{%1, %t0|%t0, %1}";
-+ return "vmovups\t{%1, %t0|%t0, %1}";
- case MODE_V8DF:
-- if (misaligned_operand (operands[1], <ssehalfvecmode>mode))
-- return "vmovupd\t{%1, %t0|%t0, %1}";
-- else
-- return "vmovapd\t{%1, %t0|%t0, %1}";
-+ return "vmovupd\t{%1, %t0|%t0, %1}";
- case MODE_V8SF:
-- if (misaligned_operand (operands[1], <ssehalfvecmode>mode))
-- return "vmovups\t{%1, %x0|%x0, %1}";
-- else
-- return "vmovaps\t{%1, %x0|%x0, %1}";
-+ return "vmovups\t{%1, %x0|%x0, %1}";
- case MODE_V4DF:
-- if (misaligned_operand (operands[1], <ssehalfvecmode>mode))
-- return "vmovupd\t{%1, %x0|%x0, %1}";
-- else
-- return "vmovapd\t{%1, %x0|%x0, %1}";
-+ return "vmovupd\t{%1, %x0|%x0, %1}";
- case MODE_XI:
-- if (misaligned_operand (operands[1], <ssehalfvecmode>mode))
-- {
-- if (which_alternative == 2)
-- return "vmovdqu\t{%1, %t0|%t0, %1}";
-- else if (GET_MODE_SIZE (<ssescalarmode>mode) == 8)
-- return "vmovdqu64\t{%1, %t0|%t0, %1}";
-- else
-- return "vmovdqu32\t{%1, %t0|%t0, %1}";
-- }
-+ if (which_alternative == 2)
-+ return "vmovdqu\t{%1, %t0|%t0, %1}";
-+ else if (GET_MODE_SIZE (<ssescalarmode>mode) == 8)
-+ return "vmovdqu64\t{%1, %t0|%t0, %1}";
- else
-- {
-- if (which_alternative == 2)
-- return "vmovdqa\t{%1, %t0|%t0, %1}";
-- else if (GET_MODE_SIZE (<ssescalarmode>mode) == 8)
-- return "vmovdqa64\t{%1, %t0|%t0, %1}";
-- else
-- return "vmovdqa32\t{%1, %t0|%t0, %1}";
-- }
-+ return "vmovdqu32\t{%1, %t0|%t0, %1}";
- case MODE_OI:
-- if (misaligned_operand (operands[1], <ssehalfvecmode>mode))
-- {
-- if (which_alternative == 2)
-- return "vmovdqu\t{%1, %x0|%x0, %1}";
-- else if (GET_MODE_SIZE (<ssescalarmode>mode) == 8)
-- return "vmovdqu64\t{%1, %x0|%x0, %1}";
-- else
-- return "vmovdqu32\t{%1, %x0|%x0, %1}";
-- }
-+ if (which_alternative == 2)
-+ return "vmovdqu\t{%1, %x0|%x0, %1}";
-+ else if (GET_MODE_SIZE (<ssescalarmode>mode) == 8)
-+ return "vmovdqu64\t{%1, %x0|%x0, %1}";
- else
-- {
-- if (which_alternative == 2)
-- return "vmovdqa\t{%1, %x0|%x0, %1}";
-- else if (GET_MODE_SIZE (<ssescalarmode>mode) == 8)
-- return "vmovdqa64\t{%1, %x0|%x0, %1}";
-- else
-- return "vmovdqa32\t{%1, %x0|%x0, %1}";
-- }
-+ return "vmovdqu32\t{%1, %x0|%x0, %1}";
- default:
- gcc_unreachable ();
- }
---- a/gcc/config/i386/i386.c
-+++ b/gcc/config/i386/i386.c
-@@ -4981,13 +4981,13 @@
- switch (type)
- {
- case opcode_int:
-- opcode = misaligned_p ? "vmovdqu32" : "vmovdqa32";
-+ opcode = "vmovdqu32";
- break;
- case opcode_float:
-- opcode = misaligned_p ? "vmovups" : "vmovaps";
-+ opcode = "vmovups";
- break;
- case opcode_double:
-- opcode = misaligned_p ? "vmovupd" : "vmovapd";
-+ opcode = "vmovupd";
- break;
- }
- }
-@@ -4996,16 +4996,16 @@
- switch (scalar_mode)
- {
- case E_SFmode:
-- opcode = misaligned_p ? "%vmovups" : "%vmovaps";
-+ opcode = "%vmovups";
- break;
- case E_DFmode:
-- opcode = misaligned_p ? "%vmovupd" : "%vmovapd";
-+ opcode = "%vmovupd";
- break;
- case E_TFmode:
- if (evex_reg_p)
-- opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
-+ opcode = "vmovdqu64";
- else
-- opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
-+ opcode = "%vmovdqu";
- break;
- default:
- gcc_unreachable ();
-@@ -5017,48 +5017,32 @@
- {
- case E_QImode:
- if (evex_reg_p)
-- opcode = (misaligned_p
-- ? (TARGET_AVX512BW
-- ? "vmovdqu8"
-- : "vmovdqu64")
-- : "vmovdqa64");
-+ opcode = TARGET_AVX512BW ? "vmovdqu8" : "vmovdqu64";
- else
-- opcode = (misaligned_p
-- ? (TARGET_AVX512BW
-- ? "vmovdqu8"
-- : "%vmovdqu")
-- : "%vmovdqa");
-+ opcode = TARGET_AVX512BW ? "vmovdqu8" : "%vmovdqu";
- break;
- case E_HImode:
- if (evex_reg_p)
-- opcode = (misaligned_p
-- ? (TARGET_AVX512BW
-- ? "vmovdqu16"
-- : "vmovdqu64")
-- : "vmovdqa64");
-+ opcode = TARGET_AVX512BW ? "vmovdqu16" : "vmovdqu64";
- else
-- opcode = (misaligned_p
-- ? (TARGET_AVX512BW
-- ? "vmovdqu16"
-- : "%vmovdqu")
-- : "%vmovdqa");
-+ opcode = TARGET_AVX512BW ? "vmovdqu16" : "%vmovdqu";
- break;
- case E_SImode:
- if (evex_reg_p)
-- opcode = misaligned_p ? "vmovdqu32" : "vmovdqa32";
-+ opcode = "vmovdqu32";
- else
-- opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
-+ opcode = "%vmovdqu";
- break;
- case E_DImode:
- case E_TImode:
- case E_OImode:
- if (evex_reg_p)
-- opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
-+ opcode = "vmovdqu64";
- else
-- opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
-+ opcode = "%vmovdqu";
- break;
- case E_XImode:
-- opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
-+ opcode = "vmovdqu64";
- break;
- default:
- gcc_unreachable ();
diff --git a/contrib/init/bitcoind.service b/contrib/init/bitcoind.service
index 93de353bb4..87da17f955 100644
--- a/contrib/init/bitcoind.service
+++ b/contrib/init/bitcoind.service
@@ -18,10 +18,11 @@ After=network-online.target
Wants=network-online.target
[Service]
-ExecStart=/usr/bin/bitcoind -daemonwait \
- -pid=/run/bitcoind/bitcoind.pid \
+ExecStart=/usr/bin/bitcoind -pid=/run/bitcoind/bitcoind.pid \
-conf=/etc/bitcoin/bitcoin.conf \
- -datadir=/var/lib/bitcoind
+ -datadir=/var/lib/bitcoind \
+ -startupnotify='systemd-notify --ready' \
+ -shutdownnotify='systemd-notify --stopping'
# Make sure the config directory is readable by the service user
PermissionsStartOnly=true
@@ -30,8 +31,10 @@ ExecStartPre=/bin/chgrp bitcoin /etc/bitcoin
# Process management
####################
-Type=forking
+Type=notify
+NotifyAccess=all
PIDFile=/run/bitcoind/bitcoind.pid
+
Restart=on-failure
TimeoutStartSec=infinity
TimeoutStopSec=600
diff --git a/contrib/macdeploy/README.md b/contrib/macdeploy/README.md
index 599a0bfa6c..ea599df3d8 100644
--- a/contrib/macdeploy/README.md
+++ b/contrib/macdeploy/README.md
@@ -6,7 +6,7 @@ The `macdeployqtplus` script should not be run manually. Instead, after building
make deploy
```
-When complete, it will have produced `Bitcoin-Core.dmg`.
+When complete, it will have produced `Bitcoin-Core.zip`.
## SDK Extraction
@@ -14,56 +14,50 @@ When complete, it will have produced `Bitcoin-Core.dmg`.
A free Apple Developer Account is required to proceed.
-Our current macOS SDK
-(`Xcode-12.2-12B45b-extracted-SDK-with-libcxx-headers.tar.gz`)
-can be extracted from
-[Xcode_12.2.xip](https://download.developer.apple.com/Developer_Tools/Xcode_12.2/Xcode_12.2.xip).
+Our macOS SDK can be extracted from
+[Xcode_15.xip](https://download.developer.apple.com/Developer_Tools/Xcode_15/Xcode_15.xip).
Alternatively, after logging in to your account go to 'Downloads', then 'More'
-and search for [`Xcode 12.2`](https://developer.apple.com/download/all/?q=Xcode%2012.2).
+and search for [`Xcode 15`](https://developer.apple.com/download/all/?q=Xcode%2015).
An Apple ID and cookies enabled for the hostname are needed to download this.
-The `sha256sum` of the downloaded XIP archive should be `28d352f8c14a43d9b8a082ac6338dc173cb153f964c6e8fb6ba389e5be528bd0`.
+The `sha256sum` of the downloaded XIP archive should be `4daaed2ef2253c9661779fa40bfff50655dc7ec45801aba5a39653e7bcdde48e`.
-After Xcode version 7.x, Apple started shipping the `Xcode.app` in a `.xip`
-archive. This makes the SDK less-trivial to extract on non-macOS machines. One
-approach (tested on Debian Buster) is outlined below:
+To extract the `.xip` on Linux:
```bash
# Install/clone tools needed for extracting Xcode.app
apt install cpio
git clone https://github.com/bitcoin-core/apple-sdk-tools.git
-# Unpack Xcode_12.2.xip and place the resulting Xcode.app in your current
+# Unpack the .xip and place the resulting Xcode.app in your current
# working directory
-python3 apple-sdk-tools/extract_xcode.py -f Xcode_12.2.xip | cpio -d -i
+python3 apple-sdk-tools/extract_xcode.py -f Xcode_15.xip | cpio -d -i
```
-On macOS the process is more straightforward:
+On macOS:
```bash
-xip -x Xcode_12.2.xip
+xip -x Xcode_15.xip
```
-### Step 2: Generating `Xcode-12.2-12B45b-extracted-SDK-with-libcxx-headers.tar.gz` from `Xcode.app`
+### Step 2: Generating the SDK tarball from `Xcode.app`
-To generate `Xcode-12.2-12B45b-extracted-SDK-with-libcxx-headers.tar.gz`, run
-the script [`gen-sdk`](./gen-sdk) with the path to `Xcode.app` (extracted in the
-previous stage) as the first argument.
+To generate the SDK, run the script [`gen-sdk`](./gen-sdk) with the
+path to `Xcode.app` (extracted in the previous stage) as the first argument.
```bash
-# Generate a Xcode-12.2-12B45b-extracted-SDK-with-libcxx-headers.tar.gz from
-# the supplied Xcode.app
./contrib/macdeploy/gen-sdk '/path/to/Xcode.app'
```
-The `sha256sum` of the generated TAR.GZ archive should be `df75d30ecafc429e905134333aeae56ac65fac67cb4182622398fd717df77619`.
+The generated archive should be: `Xcode-15.0-15A240d-extracted-SDK-with-libcxx-headers.tar.gz`.
+The `sha256sum` should be `c0c2e7bb92c1fee0c4e9f3a485e4530786732d6c6dd9e9f418c282aa6892f55d`.
-## Deterministic macOS DMG Notes
+## Deterministic macOS App Notes
-Working macOS DMGs are created in Linux by combining a recent `clang`, the Apple
-`binutils` (`ld`, `ar`, etc) and DMG authoring tools.
+macOS Applications are created in Linux by combining a recent `clang` and the Apple
+`binutils` (`ld`, `ar`, etc).
Apple uses `clang` extensively for development and has upstreamed the necessary
functionality so that a vanilla clang can take advantage. It supports the use of `-F`,
@@ -93,20 +87,15 @@ created using these tools. The build process has been designed to avoid includin
SDK's files in Guix's outputs. All interim tarballs are fully deterministic and may be freely
redistributed.
-[`xorrisofs`](https://www.gnu.org/software/xorriso/) is used to create the DMG.
-
-A background image is added to DMG files by inserting a `.DS_Store` during creation.
-
As of OS X 10.9 Mavericks, using an Apple-blessed key to sign binaries is a requirement in
order to satisfy the new Gatekeeper requirements. Because this private key cannot be
shared, we'll have to be a bit creative in order for the build process to remain somewhat
deterministic. Here's how it works:
-- Builders use Guix to create an unsigned release. This outputs an unsigned DMG which
+- Builders use Guix to create an unsigned release. This outputs an unsigned ZIP which
users may choose to bless and run. It also outputs an unsigned app structure in the form
- of a tarball, which also contains all of the tools that have been previously (deterministically)
- built in order to create a final DMG.
+ of a tarball.
- The Apple keyholder uses this unsigned app to create a detached signature, using the
script that is also included there. Detached signatures are available from this [repository](https://github.com/bitcoin-core/bitcoin-detached-sigs).
- Builders feed the unsigned app + detached signature back into Guix. It uses the
- pre-built tools to recombine the pieces into a deterministic DMG.
+ pre-built tools to recombine the pieces into a deterministic ZIP.
diff --git a/contrib/macdeploy/background.tiff b/contrib/macdeploy/background.tiff
deleted file mode 100644
index 1fb088c837..0000000000
--- a/contrib/macdeploy/background.tiff
+++ /dev/null
Binary files differ
diff --git a/contrib/macdeploy/detached-sig-create.sh b/contrib/macdeploy/detached-sig-create.sh
index 626381cf43..097a7c35ee 100755
--- a/contrib/macdeploy/detached-sig-create.sh
+++ b/contrib/macdeploy/detached-sig-create.sh
@@ -24,7 +24,7 @@ fi
rm -rf ${TEMPDIR}
mkdir -p ${TEMPDIR}
-${SIGNAPPLE} sign -f --detach "${TEMPDIR}/${OUTROOT}" "$@" "${BUNDLE}"
+${SIGNAPPLE} sign -f --detach "${TEMPDIR}/${OUTROOT}" "$@" "${BUNDLE}" --hardened-runtime
tar -C "${TEMPDIR}" -czf "${OUT}" .
rm -rf "${TEMPDIR}"
diff --git a/contrib/macdeploy/gen-sdk b/contrib/macdeploy/gen-sdk
index 6efaaccb8e..b73f5cba14 100755
--- a/contrib/macdeploy/gen-sdk
+++ b/contrib/macdeploy/gen-sdk
@@ -62,9 +62,6 @@ def run():
out_name = "Xcode-{xcode_version}-{xcode_build_id}-extracted-SDK-with-libcxx-headers".format(xcode_version=xcode_version, xcode_build_id=xcode_build_id)
- xcode_libcxx_dir = xcode_app.joinpath("Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1")
- assert xcode_libcxx_dir.is_dir()
-
if args.out_sdktgz:
out_sdktgz_path = pathlib.Path(args.out_sdktgz_path)
else:
@@ -72,7 +69,7 @@ def run():
out_sdktgz_path = pathlib.Path("./{}.tar.gz".format(out_name))
def tarfp_add_with_base_change(tarfp, dir_to_add, alt_base_dir):
- """Add all files in dir_to_add to tarfp, but prepent MEMBERPREFIX to the files'
+ """Add all files in dir_to_add to tarfp, but prepent alt_base_dir to the files'
names
e.g. if the only file under /root/bazdir is /root/bazdir/qux, invoking:
@@ -107,8 +104,6 @@ def run():
with tarfile.open(mode="w", fileobj=gzf, format=tarfile.GNU_FORMAT) as tarfp:
print("Adding MacOSX SDK {} files...".format(sdk_version))
tarfp_add_with_base_change(tarfp, sdk_dir, out_name)
- print("Adding libc++ headers...")
- tarfp_add_with_base_change(tarfp, xcode_libcxx_dir, "{}/usr/include/c++/v1".format(out_name))
print("Done! Find the resulting gzipped tarball at:")
print(out_sdktgz_path.resolve())
diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus
index f8677ba7b8..4b1d72650d 100755
--- a/contrib/macdeploy/macdeployqtplus
+++ b/contrib/macdeploy/macdeployqtplus
@@ -18,11 +18,9 @@
import sys, re, os, platform, shutil, stat, subprocess, os.path
from argparse import ArgumentParser
-from ds_store import DSStore
-from mac_alias import Alias
from pathlib import Path
from subprocess import PIPE, run
-from typing import List, Optional
+from typing import Optional
# This is ported from the original macdeployqt with modifications
@@ -183,7 +181,7 @@ class DeploymentInfo(object):
return True
return False
-def getFrameworks(binaryPath: str, verbose: int) -> List[FrameworkInfo]:
+def getFrameworks(binaryPath: str, verbose: int) -> list[FrameworkInfo]:
if verbose:
print(f"Inspecting with otool: {binaryPath}")
otoolbin=os.getenv("OTOOL", "otool")
@@ -287,7 +285,7 @@ def copyFramework(framework: FrameworkInfo, path: str, verbose: int) -> Optional
return toPath
-def deployFrameworks(frameworks: List[FrameworkInfo], bundlePath: str, binaryPath: str, strip: bool, verbose: int, deploymentInfo: Optional[DeploymentInfo] = None) -> DeploymentInfo:
+def deployFrameworks(frameworks: list[FrameworkInfo], bundlePath: str, binaryPath: str, strip: bool, verbose: int, deploymentInfo: Optional[DeploymentInfo] = None) -> DeploymentInfo:
if deploymentInfo is None:
deploymentInfo = DeploymentInfo()
@@ -385,7 +383,7 @@ def deployPlugins(appBundleInfo: ApplicationBundleInfo, deploymentInfo: Deployme
ap = ArgumentParser(description="""Improved version of macdeployqt.
-Outputs a ready-to-deploy app in a folder "dist" and optionally wraps it in a .dmg file.
+Outputs a ready-to-deploy app in a folder "dist" and optionally wraps it in a .zip file.
Note, that the "dist" folder will be deleted before deploying on each run.
Optionally, Qt translation files (.qm) can be added to the bundle.""")
@@ -395,8 +393,8 @@ ap.add_argument("appname", nargs=1, metavar="appname", help="name of the app bei
ap.add_argument("-verbose", nargs="?", const=True, help="Output additional debugging information")
ap.add_argument("-no-plugins", dest="plugins", action="store_false", default=True, help="skip plugin deployment")
ap.add_argument("-no-strip", dest="strip", action="store_false", default=True, help="don't run 'strip' on the binaries")
-ap.add_argument("-dmg", nargs="?", const="", metavar="basename", help="create a .dmg disk image")
ap.add_argument("-translations-dir", nargs=1, metavar="path", default=None, help="Path to Qt's translations. Base translations will automatically be added to the bundle's resources.")
+ap.add_argument("-zip", nargs="?", const="", metavar="zip", help="create a .zip containing the app bundle")
config = ap.parse_args()
@@ -417,12 +415,9 @@ if os.path.exists("dist"):
print("+ Removing existing dist folder +")
shutil.rmtree("dist")
-if os.path.exists(appname + ".dmg"):
- print("+ Removing existing DMG +")
- os.unlink(appname + ".dmg")
-
-if os.path.exists(appname + ".temp.dmg"):
- os.unlink(appname + ".temp.dmg")
+if os.path.exists(appname + ".zip"):
+ print("+ Removing existing .zip +")
+ os.unlink(appname + ".zip")
# ------------------------------------------------
@@ -497,99 +492,13 @@ with open(os.path.join(applicationBundle.resourcesPath, "qt.conf"), "wb") as f:
# ------------------------------------------------
-print("+ Generating .DS_Store +")
-
-output_file = os.path.join("dist", ".DS_Store")
-
-ds = DSStore.open(output_file, 'w+')
-
-ds['.']['bwsp'] = {
- 'WindowBounds': '{{300, 280}, {500, 343}}',
- 'PreviewPaneVisibility': False,
-}
-
-icvp = {
- 'gridOffsetX': 0.0,
- 'textSize': 12.0,
- 'viewOptionsVersion': 1,
- 'backgroundImageAlias': b'\x00\x00\x00\x00\x02\x1e\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\x94\\\xb0H+\x00\x05\x00\x00\x00\x98\x0fbackground.tiff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x99\xd19\xb0\xf8\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\r\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b.background\x00\x00\x10\x00\x08\x00\x00\xd1\x94\\\xb0\x00\x00\x00\x11\x00\x08\x00\x00\xd19\xb0\xf8\x00\x00\x00\x01\x00\x04\x00\x00\x00\x98\x00\x0e\x00 \x00\x0f\x00b\x00a\x00c\x00k\x00g\x00r\x00o\x00u\x00n\x00d\x00.\x00t\x00i\x00f\x00f\x00\x0f\x00\x02\x00\x00\x00\x12\x00\x1c/.background/background.tiff\x00\x14\x01\x06\x00\x00\x00\x00\x01\x06\x00\x02\x00\x00\x0cMacintosh HD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xce\x97\xab\xc3H+\x00\x00\x01\x88[\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02u\xab\x8d\xd1\x94\\\xb0devrddsk\xff\xff\xff\xff\x00\x00\t \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07bitcoin\x00\x00\x10\x00\x08\x00\x00\xce\x97\xab\xc3\x00\x00\x00\x11\x00\x08\x00\x00\xd1\x94\\\xb0\x00\x00\x00\x01\x00\x14\x01\x88[\x88\x00\x16\xa9\t\x00\x08\xfaR\x00\x08\xfaQ\x00\x02d\x8e\x00\x0e\x00\x02\x00\x00\x00\x0f\x00\x1a\x00\x0c\x00M\x00a\x00c\x00i\x00n\x00t\x00o\x00s\x00h\x00 \x00H\x00D\x00\x13\x00\x01/\x00\x00\x15\x00\x02\x00\x14\xff\xff\x00\x00\xff\xff\x00\x00',
- 'backgroundColorBlue': 1.0,
- 'iconSize': 96.0,
- 'backgroundColorGreen': 1.0,
- 'arrangeBy': 'none',
- 'showIconPreview': True,
- 'gridSpacing': 100.0,
- 'gridOffsetY': 0.0,
- 'showItemInfo': False,
- 'labelOnBottom': True,
- 'backgroundType': 2,
- 'backgroundColorRed': 1.0
-}
-alias = Alias().from_bytes(icvp['backgroundImageAlias'])
-alias.volume.name = appname
-alias.volume.posix_path = '/Volumes/' + appname
-icvp['backgroundImageAlias'] = alias.to_bytes()
-ds['.']['icvp'] = icvp
-
-ds['.']['vSrn'] = ('long', 1)
-
-ds['Applications']['Iloc'] = (370, 156)
-ds['Bitcoin-Qt.app']['Iloc'] = (128, 156)
-
-ds.flush()
-ds.close()
-
-# ------------------------------------------------
-
if platform.system() == "Darwin":
subprocess.check_call(f"codesign --deep --force --sign - {target}", shell=True)
-print("+ Installing background.tiff +")
-
-bg_path = os.path.join('dist', '.background', 'background.tiff')
-os.mkdir(os.path.dirname(bg_path))
-
-tiff_path = os.path.join('contrib', 'macdeploy', 'background.tiff')
-shutil.copy2(tiff_path, bg_path)
-
-# ------------------------------------------------
-
-print("+ Generating symlink for /Applications +")
-
-os.symlink("/Applications", os.path.join('dist', "Applications"))
-
# ------------------------------------------------
-if config.dmg is not None:
-
- print("+ Preparing .dmg disk image +")
-
- if verbose:
- print("Determining size of \"dist\"...")
- size = 0
- for path, dirs, files in os.walk("dist"):
- for file in files:
- size += os.path.getsize(os.path.join(path, file))
- size += int(size * 0.15)
-
- if verbose:
- print("Creating temp image for modification...")
-
- tempname: str = appname + ".temp.dmg"
-
- run(["hdiutil", "create", tempname, "-srcfolder", "dist", "-format", "UDRW", "-size", str(size), "-volname", appname], check=True, text=True)
-
- if verbose:
- print("Attaching temp image...")
- output = run(["hdiutil", "attach", tempname, "-readwrite"], check=True, text=True, stdout=PIPE).stdout
-
- print("+ Finalizing .dmg disk image +")
-
- run(["hdiutil", "detach", f"/Volumes/{appname}"], text=True)
-
- run(["hdiutil", "convert", tempname, "-format", "UDZO", "-o", appname, "-imagekey", "zlib-level=9"], check=True, text=True)
-
- os.unlink(tempname)
+if config.zip is not None:
+ shutil.make_archive('{}'.format(appname), format='zip', root_dir='dist', base_dir='Bitcoin-Qt.app')
# ------------------------------------------------
diff --git a/contrib/message-capture/message-capture-parser.py b/contrib/message-capture/message-capture-parser.py
index d6ddc1c149..0f409717d4 100755
--- a/contrib/message-capture/message-capture-parser.py
+++ b/contrib/message-capture/message-capture-parser.py
@@ -11,7 +11,7 @@ import sys
from io import BytesIO
import json
from pathlib import Path
-from typing import Any, List, Optional
+from typing import Any, Optional
sys.path.append(os.path.join(os.path.dirname(__file__), '../../test/functional'))
@@ -92,7 +92,7 @@ def to_jsonable(obj: Any) -> Any:
return obj
-def process_file(path: str, messages: List[Any], recv: bool, progress_bar: Optional[ProgressBar]) -> None:
+def process_file(path: str, messages: list[Any], recv: bool, progress_bar: Optional[ProgressBar]) -> None:
with open(path, 'rb') as f_in:
if progress_bar:
bytes_read = 0
@@ -188,7 +188,7 @@ def main():
output = Path.cwd() / Path(args.output) if args.output else False
use_progress_bar = (not args.no_progress_bar) and sys.stdout.isatty()
- messages = [] # type: List[Any]
+ messages = [] # type: list[Any]
if use_progress_bar:
total_size = sum(capture.stat().st_size for capture in capturepaths)
progress_bar = ProgressBar(total_size)
diff --git a/contrib/seeds/README.md b/contrib/seeds/README.md
index b0bbe96493..ad1ac4a64d 100644
--- a/contrib/seeds/README.md
+++ b/contrib/seeds/README.md
@@ -4,15 +4,17 @@ Utility to generate the seeds.txt list that is compiled into the client
(see [src/chainparamsseeds.h](/src/chainparamsseeds.h) and other utilities in [contrib/seeds](/contrib/seeds)).
Be sure to update `PATTERN_AGENT` in `makeseeds.py` to include the current version,
-and remove old versions as necessary (at a minimum when GetDesirableServiceFlags
+and remove old versions as necessary (at a minimum when SeedsServiceFlags()
changes its default return value, as those are the services which seeds are added
to addrman with).
The seeds compiled into the release are created from sipa's DNS seed and AS map
data. Run the following commands from the `/contrib/seeds` directory:
- curl https://bitcoin.sipa.be/seeds.txt.gz | gzip -dc > seeds_main.txt
- curl https://bitcoin.sipa.be/asmap-filled.dat > asmap-filled.dat
- python3 makeseeds.py -a asmap-filled.dat -s seeds_main.txt > nodes_main.txt
- cat nodes_main_manual.txt >> nodes_main.txt
- python3 generate-seeds.py . > ../../src/chainparamsseeds.h
+```
+curl https://bitcoin.sipa.be/seeds.txt.gz | gzip -dc > seeds_main.txt
+curl https://bitcoin.sipa.be/asmap-filled.dat > asmap-filled.dat
+python3 makeseeds.py -a asmap-filled.dat -s seeds_main.txt > nodes_main.txt
+cat nodes_main_manual.txt >> nodes_main.txt
+python3 generate-seeds.py . > ../../src/chainparamsseeds.h
+```
diff --git a/contrib/seeds/asmap.py b/contrib/seeds/asmap.py
index e28e5cf532..214805b5a5 100644
--- a/contrib/seeds/asmap.py
+++ b/contrib/seeds/asmap.py
@@ -10,11 +10,12 @@ import copy
import ipaddress
import random
import unittest
+from collections.abc import Callable, Iterable
from enum import Enum
from functools import total_ordering
-from typing import Callable, Dict, Iterable, List, Optional, Tuple, Union, overload
+from typing import Optional, Union, overload
-def net_to_prefix(net: Union[ipaddress.IPv4Network,ipaddress.IPv6Network]) -> List[bool]:
+def net_to_prefix(net: Union[ipaddress.IPv4Network,ipaddress.IPv6Network]) -> list[bool]:
"""
Convert an IPv4 or IPv6 network to a prefix represented as a list of bits.
@@ -32,7 +33,7 @@ def net_to_prefix(net: Union[ipaddress.IPv4Network,ipaddress.IPv6Network]) -> Li
assert (netrange & ((1 << (128 - num_bits)) - 1)) == 0
return [((netrange >> (127 - i)) & 1) != 0 for i in range(num_bits)]
-def prefix_to_net(prefix: List[bool]) -> Union[ipaddress.IPv4Network,ipaddress.IPv6Network]:
+def prefix_to_net(prefix: list[bool]) -> Union[ipaddress.IPv4Network,ipaddress.IPv6Network]:
"""The reverse operation of net_to_prefix."""
# Convert to number
netrange = sum(b << (127 - i) for i, b in enumerate(prefix))
@@ -47,10 +48,10 @@ def prefix_to_net(prefix: List[bool]) -> Union[ipaddress.IPv4Network,ipaddress.I
return ipaddress.IPv6Network((netrange, num_bits), True)
# Shortcut for (prefix, ASN) entries.
-ASNEntry = Tuple[List[bool], int]
+ASNEntry = tuple[list[bool], int]
# Shortcut for (prefix, old ASN, new ASN) entries.
-ASNDiff = Tuple[List[bool], int, int]
+ASNDiff = tuple[list[bool], int, int]
class _VarLenCoder:
"""
@@ -75,7 +76,7 @@ class _VarLenCoder:
other classes start one past the last element of the class before it.
"""
- def __init__(self, minval: int, clsbits: List[int]):
+ def __init__(self, minval: int, clsbits: list[int]):
"""Construct a new _VarLenCoder."""
self._minval = minval
self._clsbits = clsbits
@@ -85,7 +86,7 @@ class _VarLenCoder:
"""Check whether value val is in the range this coder supports."""
return self._minval <= val <= self._maxval
- def encode(self, val: int, ret: List[int]) -> None:
+ def encode(self, val: int, ret: list[int]) -> None:
"""Append encoding of val onto integer list ret."""
assert self._minval <= val <= self._maxval
@@ -120,7 +121,7 @@ class _VarLenCoder:
break
return ret + bits
- def decode(self, stream, bitpos) -> Tuple[int,int]:
+ def decode(self, stream, bitpos) -> tuple[int,int]:
"""Decode a number starting at bitpos in stream, returning value and new bitpos."""
val = self._minval
bits = 0
@@ -281,11 +282,11 @@ class ASMap:
- mappings, represented by new trie nodes.
"""
- def update(self, prefix: List[bool], asn: int) -> None:
+ def update(self, prefix: list[bool], asn: int) -> None:
"""Update this ASMap object to map prefix to the specified asn."""
assert asn == 0 or _CODER_ASN.can_encode(asn)
- def recurse(node: List, offset: int) -> None:
+ def recurse(node: list, offset: int) -> None:
if offset == len(prefix):
# Reached the end of prefix; overwrite this node.
node.clear()
@@ -306,7 +307,7 @@ class ASMap:
node.append(oldasn)
recurse(self._trie, 0)
- def update_multi(self, entries: List[Tuple[List[bool], int]]) -> None:
+ def update_multi(self, entries: list[tuple[list[bool], int]]) -> None:
"""Apply multiple update operations, where longer prefixes take precedence."""
entries.sort(key=lambda entry: len(entry[0]))
for prefix, asn in entries:
@@ -314,7 +315,7 @@ class ASMap:
def _set_trie(self, trie) -> None:
"""Set trie directly. Internal use only."""
- def recurse(node: List) -> None:
+ def recurse(node: list) -> None:
if len(node) < 2:
return
recurse(node[0])
@@ -342,7 +343,7 @@ class ASMap:
for prefix, asn in sorted(entries, key=entry_key):
self.update(prefix, asn)
- def lookup(self, prefix: List[bool]) -> Optional[int]:
+ def lookup(self, prefix: list[bool]) -> Optional[int]:
"""Look up a prefix. Returns ASN, or 0 if unassigned, or None if indeterminate."""
node = self._trie
for bit in prefix:
@@ -353,11 +354,11 @@ class ASMap:
return node[0]
return None
- def _to_entries_flat(self, fill: bool = False) -> List[ASNEntry]:
+ def _to_entries_flat(self, fill: bool = False) -> list[ASNEntry]:
"""Convert an ASMap object to a list of non-overlapping (prefix, asn) objects."""
- prefix : List[bool] = []
+ prefix : list[bool] = []
- def recurse(node: List) -> List[ASNEntry]:
+ def recurse(node: list) -> list[ASNEntry]:
ret = []
if len(node) == 1:
if node[0] > 0:
@@ -375,24 +376,24 @@ class ASMap:
return ret
return recurse(self._trie)
- def _to_entries_minimal(self, fill: bool = False) -> List[ASNEntry]:
+ def _to_entries_minimal(self, fill: bool = False) -> list[ASNEntry]:
"""Convert a trie to a minimal list of ASNEntry objects, exploiting overlap."""
- prefix : List[bool] = []
+ prefix : list[bool] = []
- def recurse(node: List) -> (Tuple[Dict[Optional[int], List[ASNEntry]], bool]):
+ def recurse(node: list) -> (tuple[dict[Optional[int], list[ASNEntry]], bool]):
if len(node) == 1 and node[0] == 0:
return {None if fill else 0: []}, True
if len(node) == 1:
return {node[0]: [], None: [(list(prefix), node[0])]}, False
- ret: Dict[Optional[int], List[ASNEntry]] = {}
+ ret: dict[Optional[int], list[ASNEntry]] = {}
prefix.append(False)
left, lhole = recurse(node[0])
prefix[-1] = True
right, rhole = recurse(node[1])
prefix.pop()
hole = not fill and (lhole or rhole)
- def candidate(ctx: Optional[int], res0: Optional[List[ASNEntry]],
- res1: Optional[List[ASNEntry]]):
+ def candidate(ctx: Optional[int], res0: Optional[list[ASNEntry]],
+ res1: Optional[list[ASNEntry]]):
if res0 is not None and res1 is not None:
if ctx not in ret or len(res0) + len(res1) < len(ret[ctx]):
ret[ctx] = res0 + res1
@@ -417,7 +418,7 @@ class ASMap:
"""Convert this ASMap object to a string containing Python code constructing it."""
return f"ASMap({self._trie})"
- def to_entries(self, overlapping: bool = True, fill: bool = False) -> List[ASNEntry]:
+ def to_entries(self, overlapping: bool = True, fill: bool = False) -> list[ASNEntry]:
"""
Convert the mappings in this ASMap object to a list of ASNEntry objects.
@@ -448,7 +449,7 @@ class ASMap:
assert max_asn >= 1 or unassigned_prob == 1
assert _CODER_ASN.can_encode(max_asn)
assert 0.0 <= unassigned_prob <= 1.0
- trie: List = []
+ trie: list = []
leaves = [trie]
ret = ASMap()
for i in range(1, num_leaves):
@@ -472,12 +473,12 @@ class ASMap:
def _to_binnode(self, fill: bool = False) -> _BinNode:
"""Convert a trie to a _BinNode object."""
- def recurse(node: List) -> Tuple[Dict[Optional[int], _BinNode], bool]:
+ def recurse(node: list) -> tuple[dict[Optional[int], _BinNode], bool]:
if len(node) == 1 and node[0] == 0:
return {(None if fill else 0): _BinNode.make_end()}, True
if len(node) == 1:
return {None: _BinNode.make_leaf(node[0]), node[0]: _BinNode.make_end()}, False
- ret: Dict[Optional[int], _BinNode] = {}
+ ret: dict[Optional[int], _BinNode] = {}
left, lhole = recurse(node[0])
right, rhole = recurse(node[1])
hole = (lhole or rhole) and not fill
@@ -507,7 +508,7 @@ class ASMap:
@staticmethod
def _from_binnode(binnode: _BinNode) -> "ASMap":
"""Construct an ASMap object from a _BinNode. Internal use only."""
- def recurse(node: _BinNode, default: int) -> List:
+ def recurse(node: _BinNode, default: int) -> list:
if node.ins == _Instruction.RETURN:
return [node.arg1]
if node.ins == _Instruction.JUMP:
@@ -542,7 +543,7 @@ class ASMap:
Returns:
A bytes object with the encoding of this ASMap object.
"""
- bits: List[int] = []
+ bits: list[int] = []
def recurse(node: _BinNode) -> None:
_CODER_INS.encode(node.ins.value, bits)
@@ -582,11 +583,11 @@ class ASMap:
def from_binary(bindata: bytes) -> Optional["ASMap"]:
"""Decode an ASMap object from the provided binary encoding."""
- bits: List[int] = []
+ bits: list[int] = []
for byte in bindata:
bits.extend((byte >> i) & 1 for i in range(8))
- def recurse(bitpos: int) -> Tuple[_BinNode, int]:
+ def recurse(bitpos: int) -> tuple[_BinNode, int]:
insval, bitpos = _CODER_INS.decode(bits, bitpos)
ins = _Instruction(insval)
if ins == _Instruction.RETURN:
@@ -632,7 +633,7 @@ class ASMap:
def extends(self, req: "ASMap") -> bool:
"""Determine whether this matches req for all subranges where req is assigned."""
- def recurse(actual: List, require: List) -> bool:
+ def recurse(actual: list, require: list) -> bool:
if len(require) == 1 and require[0] == 0:
return True
if len(require) == 1:
@@ -646,20 +647,20 @@ class ASMap:
#pylint: disable=protected-access
return recurse(self._trie, req._trie)
- def diff(self, other: "ASMap") -> List[ASNDiff]:
+ def diff(self, other: "ASMap") -> list[ASNDiff]:
"""Compute the diff from self to other."""
- prefix: List[bool] = []
- ret: List[ASNDiff] = []
+ prefix: list[bool] = []
+ ret: list[ASNDiff] = []
- def recurse(old_node: List, new_node: List):
+ def recurse(old_node: list, new_node: list):
if len(old_node) == 1 and len(new_node) == 1:
if old_node[0] != new_node[0]:
ret.append((list(prefix), old_node[0], new_node[0]))
else:
- old_left: List = old_node if len(old_node) == 1 else old_node[0]
- old_right: List = old_node if len(old_node) == 1 else old_node[1]
- new_left: List = new_node if len(new_node) == 1 else new_node[0]
- new_right: List = new_node if len(new_node) == 1 else new_node[1]
+ old_left: list = old_node if len(old_node) == 1 else old_node[0]
+ old_right: list = old_node if len(old_node) == 1 else old_node[1]
+ new_left: list = new_node if len(new_node) == 1 else new_node[0]
+ new_right: list = new_node if len(new_node) == 1 else new_node[1]
prefix.append(False)
recurse(old_left, new_left)
prefix[-1] = True
@@ -760,7 +761,7 @@ class TestASMap(unittest.TestCase):
# It starts off being equal to asmap.
patched = copy.copy(asmap)
# Keep a list of patches performed.
- patches: List[ASNEntry] = []
+ patches: list[ASNEntry] = []
# Initially there cannot be any difference.
self.assertEqual(asmap.diff(patched), [])
# Make 5 patches, each building on top of the previous ones.
diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py
index a6f435af0d..e921757802 100755
--- a/contrib/seeds/generate-seeds.py
+++ b/contrib/seeds/generate-seeds.py
@@ -3,7 +3,7 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
'''
-Script to generate list of seed nodes for chainparams.cpp.
+Script to generate list of seed nodes for kernel/chainparams.cpp.
This script expects two text files in the directory that is passed as an
argument:
diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py
index 23d38ee48d..79bb178b21 100755
--- a/contrib/seeds/makeseeds.py
+++ b/contrib/seeds/makeseeds.py
@@ -11,7 +11,7 @@ import collections
import ipaddress
import re
import sys
-from typing import List, Dict, Union
+from typing import Union
from asmap import ASMap, net_to_prefix
@@ -27,6 +27,7 @@ MIN_BLOCKS = 730000
PATTERN_IPV4 = re.compile(r"^((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})):(\d+)$")
PATTERN_IPV6 = re.compile(r"^\[([0-9a-z:]+)\]:(\d+)$")
PATTERN_ONION = re.compile(r"^([a-z2-7]{56}\.onion):(\d+)$")
+PATTERN_I2P = re.compile(r"^([a-z2-7]{52}\.b32.i2p):(\d+)$")
PATTERN_AGENT = re.compile(
r"^/Satoshi:("
r"0.14.(0|1|2|3|99)|"
@@ -37,19 +38,27 @@ PATTERN_AGENT = re.compile(
r"0.19.(0|1|2|99)|"
r"0.20.(0|1|2|99)|"
r"0.21.(0|1|2|99)|"
- r"22.(0|99)|"
- r"23.(0|99)|"
- r"24.99"
+ r"22.(0|1|99)|"
+ r"23.(0|1|99)|"
+ r"24.(0|1|99)|"
+ r"25.(0|1|99)|"
+ r"26.(0|99)|"
r")")
def parseline(line: str) -> Union[dict, None]:
""" Parses a line from `seeds_main.txt` into a dictionary of details for that line.
or `None`, if the line could not be parsed.
"""
+ if line.startswith('#'):
+ # Ignore line that starts with comment
+ return None
sline = line.split()
if len(sline) < 11:
# line too short to be valid, skip it.
return None
+ # Skip bad results.
+ if int(sline[1]) == 0:
+ return None
m = PATTERN_IPV4.match(sline[0])
sortkey = None
ip = None
@@ -58,7 +67,13 @@ def parseline(line: str) -> Union[dict, None]:
if m is None:
m = PATTERN_ONION.match(sline[0])
if m is None:
- return None
+ m = PATTERN_I2P.match(sline[0])
+ if m is None:
+ return None
+ else:
+ net = 'i2p'
+ ipstr = sortkey = m.group(1)
+ port = int(m.group(2))
else:
net = 'onion'
ipstr = sortkey = m.group(1)
@@ -83,9 +98,6 @@ def parseline(line: str) -> Union[dict, None]:
sortkey = ip
ipstr = m.group(1)
port = int(m.group(6))
- # Skip bad results.
- if sline[1] == 0:
- return None
# Extract uptime %.
uptime30 = float(sline[7][:-1])
# Extract Unix timestamp of last success.
@@ -113,14 +125,14 @@ def parseline(line: str) -> Union[dict, None]:
'sortkey': sortkey,
}
-def dedup(ips: List[Dict]) -> List[Dict]:
+def dedup(ips: list[dict]) -> list[dict]:
""" Remove duplicates from `ips` where multiple ips share address and port. """
d = {}
for ip in ips:
d[ip['ip'],ip['port']] = ip
return list(d.values())
-def filtermultiport(ips: List[Dict]) -> List[Dict]:
+def filtermultiport(ips: list[dict]) -> list[dict]:
""" Filter out hosts with more nodes per IP"""
hist = collections.defaultdict(list)
for ip in ips:
@@ -128,7 +140,7 @@ def filtermultiport(ips: List[Dict]) -> List[Dict]:
return [value[0] for (key,value) in list(hist.items()) if len(value)==1]
# Based on Greg Maxwell's seed_filter.py
-def filterbyasn(asmap: ASMap, ips: List[Dict], max_per_asn: Dict, max_per_net: int) -> List[Dict]:
+def filterbyasn(asmap: ASMap, ips: list[dict], max_per_asn: dict, max_per_net: int) -> list[dict]:
""" Prunes `ips` by
(a) trimming ips to have at most `max_per_net` ips from each net (e.g. ipv4, ipv6); and
(b) trimming ips to have at most `max_per_asn` ips from each asn in each net.
@@ -136,11 +148,12 @@ def filterbyasn(asmap: ASMap, ips: List[Dict], max_per_asn: Dict, max_per_net: i
# Sift out ips by type
ips_ipv46 = [ip for ip in ips if ip['net'] in ['ipv4', 'ipv6']]
ips_onion = [ip for ip in ips if ip['net'] == 'onion']
+ ips_i2p = [ip for ip in ips if ip['net'] == 'i2p']
# Filter IPv46 by ASN, and limit to max_per_net per network
result = []
- net_count: Dict[str, int] = collections.defaultdict(int)
- asn_count: Dict[int, int] = collections.defaultdict(int)
+ net_count: dict[str, int] = collections.defaultdict(int)
+ asn_count: dict[int, int] = collections.defaultdict(int)
for i, ip in enumerate(ips_ipv46):
if net_count[ip['net']] == max_per_net:
@@ -159,16 +172,17 @@ def filterbyasn(asmap: ASMap, ips: List[Dict], max_per_asn: Dict, max_per_net: i
# Add back Onions (up to max_per_net)
result.extend(ips_onion[0:max_per_net])
+ result.extend(ips_i2p[0:max_per_net])
return result
-def ip_stats(ips: List[Dict]) -> str:
+def ip_stats(ips: list[dict]) -> str:
""" Format and return pretty string from `ips`. """
- hist: Dict[str, int] = collections.defaultdict(int)
+ hist: dict[str, int] = collections.defaultdict(int)
for ip in ips:
if ip is not None:
hist[ip['net']] += 1
- return f"{hist['ipv4']:6d} {hist['ipv6']:6d} {hist['onion']:6d}"
+ return f"{hist['ipv4']:6d} {hist['ipv6']:6d} {hist['onion']:6d} {hist['i2p']:6d}"
def parse_args():
argparser = argparse.ArgumentParser(description='Generate a list of bitcoin node seed ip addresses.')
@@ -190,7 +204,7 @@ def main():
ips = [parseline(line) for line in lines]
print('Done.', file=sys.stderr)
- print('\x1b[7m IPv4 IPv6 Onion Pass \x1b[0m', file=sys.stderr)
+ print('\x1b[7m IPv4 IPv6 Onion I2P Pass \x1b[0m', file=sys.stderr)
print(f'{ip_stats(ips):s} Initial', file=sys.stderr)
# Skip entries with invalid address.
ips = [ip for ip in ips if ip is not None]
@@ -204,11 +218,12 @@ def main():
# Require service bit 1.
ips = [ip for ip in ips if (ip['service'] & 1) == 1]
print(f'{ip_stats(ips):s} Require service bit 1', file=sys.stderr)
- # Require at least 50% 30-day uptime for clearnet, 10% for onion.
+ # Require at least 50% 30-day uptime for clearnet, 10% for onion and i2p.
req_uptime = {
'ipv4': 50,
'ipv6': 50,
'onion': 10,
+ 'i2p' : 10,
}
ips = [ip for ip in ips if ip['uptime'] > req_uptime[ip['net']]]
print(f'{ip_stats(ips):s} Require minimum uptime', file=sys.stderr)
diff --git a/contrib/seeds/nodes_main.txt b/contrib/seeds/nodes_main.txt
index f8572b26c7..be7607c0f7 100644
--- a/contrib/seeds/nodes_main.txt
+++ b/contrib/seeds/nodes_main.txt
@@ -1,540 +1,534 @@
-2.3.25.181:8333 # AS3215
-2.152.78.124:8333 # AS12430
-5.39.74.166:8333 # AS16276
-5.45.79.81:18332 # AS50673
-5.53.16.128:8333 # AS50923
-5.95.186.78:8333 # AS30722
+1.253.159.19:8333 # AS9318
+2.152.74.211:8333 # AS12430
+5.2.23.226:8333 # AS21472
5.128.87.126:8333 # AS31200
-5.133.65.82:8333 # AS15440
-5.146.20.229:8333 # AS3209
-5.180.41.119:8333 # AS18978
+5.157.103.202:8333 # AS35612
5.188.62.18:8333 # AS34665
-5.199.173.66:8333 # AS16125
-5.255.97.25:8333 # AS60404
-5.255.103.180:8333 # AS60404
+5.253.18.218:8333 # AS58073
+5.255.109.160:8333 # AS60404
+8.129.184.255:8333 # AS37963
8.209.70.77:8333 # AS45102
-8.209.105.138:8333 # AS45102
-18.162.208.153:48332 # AS16509
-23.175.0.200:8333 # AS395502
+8.210.18.56:8333 # AS45102
+12.34.98.148:8333 # AS7018
+18.27.79.17:8333 # AS3
+23.93.170.118:8333 # AS46375
+23.154.136.144:8333 # AS54002
+23.175.0.212:8333 # AS395502
23.175.0.222:8333 # AS395502
-23.233.107.21:8333 # AS5645
-23.236.25.169:8333 # AS30029
-24.35.68.229:8333 # AS11404
24.84.164.50:8333 # AS6327
-24.116.153.115:8333 # AS11492
-24.184.0.146:8333 # AS6128
-27.33.160.196:8333 # AS7545
+24.86.90.127:8333 # AS6327
+24.101.126.194:8333 # AS27364
+24.183.75.154:8333 # AS20115
27.124.108.19:8333 # AS58511
27.148.206.140:8333 # AS4134
-31.17.64.192:8333 # AS204028
-31.18.114.135:8333 # AS204028
+31.25.98.16:8333 # AS48635
31.41.23.249:8333 # AS31287
-31.42.176.138:8333 # AS43641
31.47.202.112:8333 # AS34385
-34.65.45.157:8333 # AS15169
+31.156.128.248:8333 # AS30722
+31.164.160.162:8333 # AS6730
+31.201.190.134:8333 # AS50266
+31.208.34.61:8333 # AS29518
+34.78.14.25:8333 # AS15169
34.80.134.68:8333 # AS15169
-34.126.115.35:8333 # AS396982
-37.1.204.231:8333 # AS50673
-37.120.155.34:8333 # AS9009
-37.143.118.174:8333 # AS48926
-37.193.227.16:8333 # AS31200
+35.137.133.225:8333 # AS7843
+35.193.192.48:8333 # AS396982
+35.194.39.250:8333 # AS396982
+37.15.60.144:8333 # AS12479
+37.60.228.251:8333 # AS31214
+37.60.229.117:8333 # AS31214
+37.110.132.94:8333 # AS42610
+37.120.179.29:8333 # AS47147
+37.139.102.73:8333 # AS35816
+37.157.192.94:8333 # AS197019
37.220.135.151:8333 # AS41206
-37.235.146.236:8333 # AS41268
-38.124.126.42:8333 # AS11550
-38.141.134.140:8333 # AS174
-38.145.151.150:8333 # AS40545
-40.115.137.28:8333 # AS8075
-41.72.154.66:8333 # AS37153
-41.79.70.146:8333 # AS37349
-42.193.55.135:8333 # AS45090
+38.9.81.160:8333 # AS16904
+38.21.221.252:8333 # AS40545
+38.54.14.89:8333 # AS138915
+38.91.106.111:8333 # AS63023
+38.102.85.36:8333 # AS174
+42.2.162.218:8333 # AS4760
+43.129.75.20:8333 # AS132203
+43.159.61.16:8333 # AS132203
43.225.62.107:8333 # AS63953
-45.43.97.103:8333 # AS26827
-45.85.48.58:8333 # AS208016
-45.126.26.229:8333 # AS45763
-45.134.142.40:8333 # AS60068
-45.154.252.162:8333 # AS13335
-46.13.216.169:8333 # AS6855
-46.23.87.218:8333 # AS51088
-46.40.127.164:8333 # AS43205
-46.48.126.58:8333 # AS12668
-46.59.13.35:8333 # AS8473
-46.72.238.17:8333 # AS12714
-46.128.141.184:8333 # AS16097
-46.146.248.89:8333 # AS9049
-46.165.221.209:9333 # AS28753
+43.245.196.214:8333 # AS63916
+45.13.7.221:8333 # AS60377
+45.44.213.123:8333 # AS54198
+45.48.75.224:8333 # AS20001
+45.79.76.12:8333 # AS63949
+45.94.209.127:8333 # AS13789
+45.130.23.57:8333 # AS3214
+45.132.118.25:8333 # AS208451
+45.144.249.207:8333 # AS203936
+45.145.40.43:8333 # AS63213
+45.155.169.30:8333 # AS62000
+46.17.99.13:8333 # AS57043
+46.17.99.26:8333 # AS57043
+46.21.250.25:8333 # AS24875
+46.28.204.161:8333 # AS197988
+46.128.199.26:8333 # AS16097
+46.164.59.139:8333 # AS21283
46.166.142.2:8333 # AS43350
-46.175.178.3:8333 # AS28725
-47.36.144.51:8333 # AS20115
-47.180.49.158:8333 # AS5650
-49.228.131.133:2210 # AS133481
-50.2.13.164:8333 # AS62904
-50.35.71.51:8333 # AS20055
+46.172.233.241:8333 # AS6752
+46.252.5.112:8333 # AS206774
+47.28.85.71:8333 # AS20115
+47.176.248.250:8333 # AS5650
+47.198.60.180:8333 # AS5650
+50.27.22.141:8333 # AS19108
+50.39.170.149:8333 # AS20055
50.53.250.162:8333 # AS20055
-51.68.36.57:8333 # AS16276
-51.138.4.135:30001 # AS8075
51.154.62.103:8333 # AS15796
51.158.150.155:8333 # AS12876
-54.176.63.16:8333 # AS16509
-58.158.0.86:8333 # AS2519
-59.138.115.137:8333 # AS2516
+51.174.206.76:8333 # AS29695
+54.217.136.122:8333 # AS16509
+54.253.15.33:8333 # AS16509
+57.128.96.115:8333 # AS8220
+57.128.148.169:8333 # AS8220
+58.6.46.171:8333 # AS7545
+58.96.77.114:8333 # AS10143
+58.96.123.120:8333 # AS38195
+58.168.253.35:8333 # AS1221
59.167.191.60:8333 # AS4739
60.205.205.119:8333 # AS37963
-60.234.122.245:8333 # AS9790
-60.240.210.155:8333 # AS7545
-61.239.91.250:8333 # AS9269
-62.74.143.11:8333 # AS3329
-62.138.162.12:8333 # AS20773
-62.169.74.233:8333 # AS2860
+60.212.189.151:8333 # AS4837
+61.74.99.193:8333 # AS4766
+62.24.76.122:8333 # AS16019
+62.106.70.249:8333 # AS8100
+62.168.65.42:8333 # AS5578
62.171.129.32:8333 # AS51167
-62.209.198.65:8333 # AS6855
-63.247.147.166:8333 # AS30221
-64.98.76.62:8333 # AS32133
-66.29.129.218:8333 # AS22612
-66.96.235.28:8333 # AS63859
-66.130.120.52:8333 # AS5769
-66.198.209.243:8333 # AS33152
-66.208.64.128:8333 # AS10352
-66.225.231.148:8333 # AS23352
-67.55.3.200:8333 # AS33139
-67.58.232.107:8333 # AS14051
-67.211.92.2:8333 # AS11711
-67.223.119.122:8333 # AS22612
-68.48.131.251:8333 # AS7922
-68.181.4.12:8333 # AS47
-69.14.185.9:8333 # AS12083
-69.54.29.193:8333 # AS12282
-69.59.18.22:8333 # AS397444
-69.131.101.176:8333 # AS4181
-69.165.205.142:8833 # AS5645
-69.228.219.124:8333 # AS7018
-70.59.123.25:8333 # AS209
-70.62.13.150:8333 # AS7843
-70.66.248.170:8333 # AS6327
-70.112.153.229:8333 # AS7843
-70.160.240.132:8333 # AS22773
-70.190.177.204:8333 # AS22773
-71.28.189.239:8333 # AS398465
-71.234.125.198:8333 # AS1351
-72.74.123.179:8333 # AS701
-72.253.236.217:8333 # AS36149
-73.219.254.120:8333 # AS1351
-74.91.115.229:8333 # AS14586
+62.245.75.70:8333 # AS16019
+62.248.8.167:8333 # AS16010
+64.23.150.211:8333 # AS3064
+64.98.119.136:8333 # AS32133
+65.24.75.34:8333 # AS7843
+65.175.185.101:8333 # AS11776
+66.45.141.46:8333 # AS11232
+66.58.163.185:8333 # AS8047
+66.85.133.182:8333 # AS12189
+66.206.22.26:8333 # AS29802
+67.40.102.33:8333 # AS209
+67.43.210.62:8333 # AS394883
+67.82.136.177:8333 # AS6128
+67.193.87.50:8333 # AS7992
+67.210.228.203:8333 # AS7819
+67.211.211.118:8333 # AS19318
+67.231.246.58:8333 # AS40244
+68.6.84.222:8333 # AS22773
+68.48.136.216:8333 # AS7922
+68.69.170.92:8333 # AS6315
+69.4.94.226:8333 # AS36352
+69.8.175.201:8333 # AS21766
+69.57.160.49:8333 # AS22612
+69.112.103.124:8333 # AS6128
+69.196.152.33:8333 # AS5645
+71.19.148.180:8333 # AS6939
+73.227.153.213:8333 # AS1351
+74.50.81.93:8333 # AS19318
+74.101.205.214:8333 # AS701
74.118.137.119:8333 # AS20326
-74.195.166.100:8333 # AS19108
+74.213.175.108:8333 # AS21949
+74.213.251.239:8333 # AS14978
74.220.255.190:8333 # AS23175
-76.67.211.110:8333 # AS577
-76.169.163.14:8333 # AS20001
-77.32.121.162:8333 # AS35612
-77.53.135.74:8333 # AS45011
-77.70.16.245:8333 # AS8717
-77.85.204.149:8333 # AS8866
-77.107.38.239:8333 # AS62183
-77.120.26.102:8333 # AS25229
+77.20.48.144:8333 # AS3209
+77.21.149.160:8333 # AS204028
+77.37.240.209:8333 # AS42610
+77.43.14.68:8333 # AS5396
+77.111.57.109:8333 # AS3212
77.162.190.90:8333 # AS1136
-78.20.227.249:8333 # AS6848
-78.21.167.8:8333 # AS6848
+77.173.132.140:8333 # AS1136
+77.202.10.220:8333 # AS15557
78.27.139.13:8333 # AS6723
-78.90.91.220:8333 # AS8717
-78.108.108.25:8333 # AS8251
-78.108.108.38:8333 # AS8251
-79.77.182.183:8333 # AS13285
-79.98.159.7:11333 # AS44065
-79.189.211.201:8333 # AS5617
-80.55.225.158:8333 # AS5617
-80.83.186.35:8333 # AS33891
-80.88.172.227:64264 # AS31263
-80.209.87.103:9333 # AS31027
+78.31.71.190:8333 # AS24961
+78.35.147.203:8333 # AS8422
+78.42.144.24:8333 # AS51185
+78.43.153.185:8333 # AS51185
+78.56.89.146:8333 # AS8764
+78.70.208.53:8333 # AS3301
+79.109.120.38:8333 # AS12430
+79.116.56.89:8333 # AS57269
+79.124.7.253:8333 # AS203380
+79.136.250.162:8333 # AS9049
+80.83.186.25:8333 # AS33891
+80.98.75.248:8333 # AS21334
80.229.28.60:8333 # AS2856
-81.7.16.182:8333 # AS35366
+80.244.26.192:8333 # AS35432
+81.4.110.168:8333 # AS198203
81.7.17.202:8333 # AS35366
81.19.10.2:8333 # AS24641
-81.88.221.190:8333 # AS39709
+81.83.214.134:8333 # AS6848
+81.170.142.100:8333 # AS8473
81.171.22.143:8333 # AS60781
-81.224.44.164:8333 # AS3301
-81.224.160.81:8333 # AS3301
-82.1.68.54:8333 # AS5089
-82.21.164.47:8333 # AS5089
-82.64.116.5:8333 # AS12322
+81.242.239.139:8333 # AS5432
82.66.10.11:8333 # AS12322
+82.66.204.177:8333 # AS12322
82.96.96.40:8333 # AS29686
-82.116.50.101:8333 # AS30936
-82.129.68.62:8333 # AS48945
-82.136.99.122:8333 # AS8821
-82.154.24.209:8333 # AS8657
-82.197.215.125:8333 # AS25596
-83.128.132.91:8333 # AS15435
-83.137.41.10:8333 # AS31394
-83.208.6.211:8333 # AS5610
+82.149.225.249:8333 # AS29551
+82.155.148.211:8333 # AS8657
+82.181.218.133:8333 # AS16086
+83.99.247.25:8333 # AS24651
+83.136.232.21:8333 # AS29182
+83.192.226.66:8333 # AS3215
83.208.193.242:8333 # AS5610
-83.222.138.85:8333 # AS31736
-83.240.124.68:8333 # AS31246
-83.243.191.199:8333 # AS41164
-84.9.5.211:8333 # AS5378
-84.28.57.90:8333 # AS6830
-84.38.3.249:8333 # AS196691
+83.240.118.196:8333 # AS31246
+84.7.219.130:8333 # AS15557
+84.52.64.82:8333 # AS25408
+84.64.99.78:8333 # AS5378
84.112.60.16:8333 # AS8412
-84.215.56.119:8333 # AS41164
-84.226.243.175:8333 # AS6730
-84.245.14.73:8333 # AS25596
-84.252.157.90:18333 # AS200590
-84.255.244.61:8333 # AS34779
-85.23.24.123:8333 # AS16086
-85.52.185.29:8666 # AS12479
-85.58.120.201:8333 # AS12479
-85.93.96.18:8333 # AS29208
-85.165.8.197:8333 # AS2119
+84.113.129.195:8333 # AS8412
+84.211.187.211:8333 # AS41164
+84.217.134.213:8333 # AS2119
+84.247.128.15:8333 # AS49788
+84.247.132.27:8333 # AS29286
+84.247.173.117:8333 # AS29286
+84.247.179.51:8333 # AS49788
+84.255.245.194:8333 # AS34779
+85.145.79.26:8333 # AS50266
85.173.165.66:8333 # AS12389
-85.184.143.105:8333 # AS39642
-85.191.74.103:8333 # AS39642
-85.194.238.134:8333 # AS47605
-85.195.54.110:8333 # AS35706
-85.195.196.142:8333 # AS13030
-85.208.69.11:8333 # AS25091
-85.208.69.21:8333 # AS25091
-85.208.71.36:8333 # AS42275
-85.208.71.39:8333 # AS42275
+85.195.196.86:8333 # AS13030
85.214.118.71:8333 # AS6724
-85.214.161.252:8333 # AS6724
-85.216.32.73:8333 # AS51185
-85.254.98.221:8333 # AS13194
-86.58.11.152:8333 # AS3212
-86.95.8.249:8333 # AS1136
-86.100.26.188:8333 # AS39007
-86.106.143.143:55373 # AS9009
-86.124.145.184:8333 # AS8708
-86.133.251.239:8901 # AS2856
+86.22.20.13:8333 # AS5089
+86.45.238.115:8333 # AS5466
+86.182.223.189:8333 # AS2856
+86.215.168.115:8333 # AS3215
87.79.94.221:8333 # AS8422
-87.120.8.5:20008 # AS34224
-87.125.157.220:8333 # AS12430
-88.9.76.133:8333 # AS3352
-88.90.184.68:8333 # AS2119
-88.151.101.14:5000 # AS41075
-88.151.101.253:5000 # AS41075
-88.198.92.47:8333 # AS24940
-88.208.115.70:8333 # AS29208
-88.210.15.24:8333 # AS212702
-88.212.45.166:8333 # AS42841
-89.102.206.238:8333 # AS16019
-89.103.111.34:8333 # AS16019
-89.114.143.113:8333 # AS12353
-89.134.62.74:8333 # AS21334
-89.152.8.231:8333 # AS2860
-89.161.26.78:8333 # AS39375
-89.207.131.19:8333 # AS49544
-89.248.193.229:8333 # AS49505
-90.3.48.62:8333 # AS3215
-90.146.121.97:8333 # AS12605
-90.146.130.214:8333 # AS12605
-90.196.169.58:8333 # AS5607
-90.250.9.1:8333 # AS5378
-91.93.194.154:8333 # AS34984
-91.126.40.109:8333 # AS35699
-91.204.99.178:8333 # AS20485
+87.90.94.120:8333 # AS5410
+87.92.171.53:8333 # AS16086
+87.236.195.198:8333 # AS35592
+87.236.199.197:8333 # AS35592
+88.6.31.66:8333 # AS3352
+88.9.73.252:8333 # AS3352
+88.84.223.30:8333 # AS21453
+88.146.114.173:8333 # AS29208
+89.35.142.177:8333 # AS34977
+89.44.41.142:8333 # AS56478
+89.116.25.234:8333 # AS398465
+89.117.58.113:8333 # AS1239
+89.117.172.121:8333 # AS3320
+89.165.232.242:8333 # AS48161
+89.190.142.56:8333 # AS38919
+89.216.91.120:8333 # AS31042
+89.247.224.28:8333 # AS8881
+90.146.207.67:8333 # AS12605
+90.156.26.148:8333 # AS12741
+90.163.172.78:8333 # AS12479
+90.192.118.202:8333 # AS5607
+90.208.159.11:8333 # AS5607
+90.247.70.31:8333 # AS5378
+91.86.25.207:8333 # AS47377
+91.123.182.164:8333 # AS51648
+91.123.183.219:8333 # AS51792
+91.134.145.202:8333 # AS16276
+91.135.0.187:8333 # AS12496
+91.152.122.36:8333 # AS6667
+91.184.174.191:8333 # AS9063
91.204.149.5:8333 # AS42765
91.206.17.195:8333 # AS13259
91.209.51.131:8333 # AS48239
91.215.91.254:8333 # AS48078
-92.91.27.60:8333 # AS15557
-92.221.20.232:8333 # AS29695
-92.255.85.31:8333 # AS9002
-93.4.101.37:8333 # AS15557
-93.46.81.5:8333 # AS12874
+91.231.182.53:8333 # AS44103
+91.236.251.137:8333 # AS57944
+91.236.251.139:8333 # AS57944
+91.237.88.218:8333 # AS56813
+92.27.150.46:8333 # AS13285
+92.27.150.47:8333 # AS13285
+92.42.110.219:8333 # AS1273
+92.43.187.34:8333 # AS8359
+92.206.105.31:8333 # AS20880
+92.233.2.59:8333 # AS5089
+92.240.181.45:8333 # AS16246
+93.51.13.120:8333 # AS12874
93.57.81.162:8333 # AS12874
-93.73.39.196:8333 # AS25229
-93.90.82.226:8333 # AS47626
-93.95.88.13:8333 # AS35434
+93.71.19.130:8333 # AS30722
+93.81.254.159:8333 # AS8402
+93.90.82.227:8333 # AS47626
+93.100.35.189:8333 # AS35807
+93.103.13.1:8333 # AS34779
93.123.180.164:8333 # AS35539
-93.189.145.169:8333 # AS12555
-94.17.185.107:8333 # AS12709
-94.75.198.120:8333 # AS60781
-94.114.196.169:8333 # AS3209
-94.142.213.250:55544 # AS5524
-94.154.159.99:8333 # AS62240
-94.158.246.183:8333 # AS39798
-94.239.145.32:8333 # AS5410
-95.31.12.22:8333 # AS8402
-95.31.196.15:8333 # AS3216
-95.110.133.223:8333 # AS31034
+93.177.188.74:8333 # AS16010
+93.188.102.53:8333 # AS43989
+94.19.7.55:8333 # AS35807
+94.63.75.74:8333 # AS12353
+94.72.141.61:8333 # AS57344
+94.72.143.47:8333 # AS203380
+94.105.53.124:8333 # AS47377
+94.181.46.106:8333 # AS9049
+94.231.253.18:8333 # AS35224
+95.42.140.142:8333 # AS8866
+95.82.130.223:8333 # AS31246
+95.88.61.176:8333 # AS204028
+95.105.172.171:8333 # AS15962
95.110.234.93:8333 # AS31034
-95.161.12.45:8333 # AS39598
+95.164.182.44:8333 # AS29632
95.191.130.100:8333 # AS12389
-95.208.158.161:8333 # AS51185
-95.213.145.218:8333 # AS49505
-95.214.53.154:8333 # AS201814
-95.214.53.160:8333 # AS201814
-96.44.156.199:8333 # AS8100
-97.75.145.12:8333 # AS22709
-102.132.192.141:8333 # AS37680
-103.14.245.250:8333 # AS24482
-103.85.38.205:8333 # AS134090
-103.88.92.78:8332 # AS17547
-103.99.168.100:8333 # AS6939
-103.99.168.140:8333 # AS6939
+96.3.53.254:8333 # AS11232
+97.75.144.9:8333 # AS22709
+98.17.95.93:8333 # AS398465
+98.128.230.186:8333 # AS8473
+98.163.242.149:8333 # AS22773
+98.229.126.23:8333 # AS1351
+99.233.20.215:8333 # AS812
+99.246.87.2:8333 # AS812
+101.51.138.194:8333 # AS38040
+102.130.113.94:8333 # AS328364
103.99.170.210:8333 # AS54415
103.99.170.220:8333 # AS54415
-103.100.44.70:8333 # AS10143
-103.178.236.27:8333 # AS49981
-103.209.12.144:8333 # AS58511
-104.59.147.15:8333 # AS7018
-104.129.171.121:8333 # AS174
-104.200.65.234:8333 # AS23033
-104.238.220.199:8333 # AS23470
+103.156.165.171:8333 # AS63859
+103.219.169.49:8333 # AS13335
+104.171.202.244:8333 # AS30496
+104.225.220.33:8333 # AS29802
104.244.73.6:8333 # AS53667
-106.71.119.230:8333 # AS4804
-107.173.166.43:8333 # AS23352
-108.161.22.78:8333 # AS54154
-108.174.63.234:8333 # AS36352
+104.244.79.131:8333 # AS53667
+108.49.65.132:8333 # AS701
+109.86.60.33:8333 # AS13188
+109.91.141.145:8333 # AS3209
109.99.63.159:8333 # AS9050
-109.105.40.247:8333 # AS12570
-109.107.185.130:8333 # AS48282
-109.110.239.4:8333 # AS35432
-109.173.41.43:8333 # AS42610
-109.236.90.117:8333 # AS49981
-109.248.206.13:8333 # AS203493
-109.255.106.206:8333 # AS6830
-111.90.140.23:8333 # AS45839
+109.120.194.136:8333 # AS34569
+109.196.124.182:8333 # AS196883
+109.201.168.32:8333 # AS41750
+109.224.84.149:8333 # AS197197
111.90.140.46:8333 # AS45839
-111.90.159.246:8333 # AS34309
-112.118.188.50:8333 # AS4760
-115.47.141.250:8885 # AS4134
+112.139.10.25:8333 # AS10010
+114.34.130.206:8333 # AS3462
116.58.171.67:8333 # AS2514
-118.92.107.108:8333 # AS9500
+116.86.195.192:8333 # AS4657
+119.31.179.202:8333 # AS17408
119.42.55.203:8333 # AS133159
-120.79.71.72:8333 # AS37963
+120.226.39.100:8333 # AS9808
+120.226.39.103:8333 # AS9808
+121.6.69.73:8333 # AS9506
121.99.240.87:8333 # AS9790
+122.148.147.136:8333 # AS4826
+122.199.40.21:8333 # AS38195
123.60.213.192:8333 # AS55990
-124.156.158.100:8333 # AS132203
-124.222.123.238:8333 # AS45090
-125.178.6.116:8333 # AS3786
+123.202.193.121:8333 # AS9269
+124.170.182.194:8333 # AS7545
+124.197.54.113:8333 # AS9790
+125.168.110.28:8333 # AS4826
+125.227.178.68:8333 # AS3462
128.0.190.26:8333 # AS30764
-128.65.194.136:8333 # AS29222
-129.13.189.212:8333 # AS34878
-129.126.172.115:8333 # AS17547
-129.146.52.174:8333 # AS31898
-130.44.168.202:8333 # AS6079
-131.161.80.166:8333 # AS263694
-131.188.40.191:8333 # AS680
-134.195.185.52:8333 # AS13536
-135.134.238.47:8333 # AS4181
-135.180.218.58:8333 # AS46375
+129.13.189.215:8333 # AS34878
+130.44.176.111:8333 # AS6079
+130.204.161.3:8333 # AS8717
+131.153.232.139:8333 # AS12189
+131.188.40.47:8333 # AS680
+134.65.193.149:8333 # AS19037
+135.19.41.208:8333 # AS5769
+135.19.253.101:8333 # AS5769
+135.23.204.98:8333 # AS5645
135.181.215.237:8333 # AS24940
-136.29.109.180:8333 # AS19165
-136.32.238.6:8333 # AS16591
-136.56.170.96:8333 # AS16591
-137.25.38.108:8333 # AS20115
+136.55.46.15:8333 # AS16591
+136.62.58.224:8333 # AS16591
+136.175.8.175:8333 # AS14315
+136.244.19.126:8333 # AS397412
137.226.34.46:8333 # AS680
-138.207.211.106:8333 # AS11776
-139.130.41.82:8333 # AS1221
-139.153.255.107:8333 # AS786
-140.190.12.129:8333 # AS14828
+138.59.20.209:8333 # AS28201
+139.59.70.163:8333 # AS14061
+140.238.220.99:8333 # AS31898
+141.193.68.11:8333 # AS396998
142.54.181.218:8333 # AS32097
-143.177.229.149:8333 # AS50266
-143.178.64.10:8333 # AS50266
-144.24.245.183:8333 # AS31898
-144.126.130.178:8333 # AS40021
-146.4.124.129:8333 # AS3303
+142.115.140.2:8333 # AS577
+142.188.125.200:8333 # AS577
+143.110.252.124:8333 # AS14061
+144.24.236.64:8333 # AS31898
+144.137.29.181:8333 # AS1221
146.71.69.103:8333 # AS7782
-146.83.56.69:8333 # AS23140
-147.194.177.165:8333 # AS15128
-149.90.214.78:8333 # AS12353
-149.102.157.156:8333 # AS13768
-151.248.156.55:8333 # AS8821
-151.252.193.245:8333 # AS29582
-153.92.93.114:8333 # AS41998
-154.211.6.2:8333 # AS140224
-156.17.103.2:8088 # AS8970
-156.146.177.221:8333 # AS1448
-157.131.143.173:8333 # AS46375
-158.58.188.37:8333 # AS57497
-158.248.39.239:8333 # AS29695
-159.89.230.128:8333 # AS14061
-159.196.3.239:8333 # AS4764
-159.224.189.250:8333 # AS13188
-160.72.51.154:8333 # AS46887
-161.29.236.55:8333 # AS4826
-161.97.119.166:8333 # AS51167
-161.246.11.230:8333 # AS9486
-162.62.18.226:8333 # AS132203
-162.250.123.179:8333 # AS19318
-162.250.191.222:8333 # AS26832
-162.254.118.20:8333 # AS6130
-163.172.81.70:8333 # AS12876
-164.90.47.8:8333 # AS53449
-165.228.174.117:8333 # AS1221
-166.70.145.151:8333 # AS6315
-168.91.238.8:8333 # AS11039
-170.253.11.25:8333 # AS15704
-171.103.170.115:8333 # AS7470
-172.93.166.135:8333 # AS22653
-172.103.217.236:8333 # AS25668
+149.28.159.141:8333 # AS20473
+149.143.32.26:8333 # AS15435
+149.202.79.199:8333 # AS16276
+149.248.1.254:8333 # AS20473
+151.248.221.197:8333 # AS8821
+152.44.137.83:8333 # AS11404
+152.230.180.115:8333 # AS14259
+154.26.137.105:8333 # AS174
+154.92.111.100:8333 # AS141356
+157.131.20.174:8333 # AS46375
+158.129.140.201:8333 # AS5479
+158.181.114.196:8333 # AS8821
+158.220.85.82:8333 # AS8556
+158.220.121.93:8333 # AS8556
+159.2.191.175:8333 # AS855
+159.224.238.145:8333 # AS13188
+161.97.167.10:8333 # AS51167
+162.213.119.12:8333 # AS2711
+162.226.61.8:8333 # AS7018
+162.254.171.209:8333 # AS17210
+163.114.159.205:8333 # AS15830
+163.172.84.134:8333 # AS12876
+165.255.241.184:8333 # AS327693
+167.179.147.155:8333 # AS4764
+169.150.206.206:8333 # AS60068
+170.17.151.235:8333 # AS3303
+170.254.147.116:8333 # AS265398
+172.92.102.115:8333 # AS11404
172.105.21.216:8333 # AS63949
-172.112.153.95:8333 # AS20001
-173.3.218.91:8333 # AS6128
+172.219.229.252:8333 # AS852
+172.251.101.27:8333 # AS20001
173.12.119.133:8333 # AS7922
-173.34.127.181:8333 # AS812
-173.76.123.173:8333 # AS701
-173.176.198.68:8333 # AS5769
-173.208.152.218:8333 # AS32097
+173.19.176.228:8333 # AS30036
+173.181.35.50:8333 # AS395570
+173.212.98.0:8333 # AS11260
173.241.227.243:8333 # AS19009
-173.246.27.7:8333 # AS1403
-173.255.240.205:8333 # AS63949
-174.30.47.15:8333 # AS209
-174.114.250.86:8333 # AS812
-174.138.35.229:8333 # AS14061
-174.142.191.136:8333 # AS32613
-176.10.143.190:8333 # AS8473
+173.246.31.114:8333 # AS1403
+174.20.57.30:8333 # AS209
+175.27.247.104:8333 # AS45090
+175.136.174.174:8333 # AS4788
+176.9.17.121:8333 # AS24940
+176.37.82.83:8333 # AS39608
176.74.136.237:8333 # AS35613
176.118.220.29:8333 # AS60042
-176.126.116.7:8333 # AS20473
-176.126.167.10:8333 # AS8449
-176.212.185.153:8333 # AS9049
-176.235.209.186:8333 # AS34984
-177.81.236.117:8333 # AS28573
-177.89.205.70:8333 # AS28220
-178.48.168.12:8333 # AS21334
-178.124.162.209:8333 # AS6697
+176.138.233.166:8333 # AS5410
+177.32.50.167:8333 # AS28573
+178.21.118.178:8333 # AS49544
+178.41.11.254:8333 # AS6855
+178.79.83.147:8333 # AS3212
+178.88.189.254:8333 # AS9198
+178.154.222.104:8333 # AS200350
178.159.98.133:8333 # AS202390
-178.196.89.209:8333 # AS3303
-178.236.137.63:8333 # AS44843
-178.252.123.24:8333 # AS42893
-179.43.170.186:8333 # AS51852
-180.150.46.187:8333 # AS4764
-181.117.128.140:8333 # AS19037
-184.19.19.16:8333 # AS5650
-185.21.217.48:8333 # AS200052
+178.198.23.120:8333 # AS3303
+178.250.232.111:8333 # AS31197
+182.229.145.161:8333 # AS3786
+183.88.223.208:8333 # AS45758
+183.129.178.205:8333 # AS4134
185.25.48.184:8333 # AS61272
+185.26.99.171:8333 # AS44066
185.31.136.246:8333 # AS47605
185.52.93.45:8333 # AS39449
-185.64.116.15:8333 # AS31736
-185.68.249.91:8333 # AS51184
-185.98.54.20:8333 # AS39572
+185.69.53.153:8333 # AS62282
+185.84.224.116:8333 # AS8816
185.107.83.55:8333 # AS43350
-185.140.253.169:8333 # AS200735
-185.148.145.74:8333 # AS44901
+185.116.94.239:8333 # AS39184
+185.140.209.159:8333 # AS44901
+185.148.3.227:8333 # AS47605
+185.152.138.74:8333 # AS6697
+185.153.196.14:8333 # AS15836
+185.153.196.162:8333 # AS15836
+185.156.37.30:8333 # AS202605
+185.156.154.129:8333 # AS41897
+185.158.113.172:8333 # AS28917
185.165.170.19:8333 # AS3223
-185.167.113.59:8333 # AS207054
-185.185.26.141:8111 # AS201206
-185.197.163.136:8333 # AS60144
+185.190.24.72:8333 # AS9002
+185.199.209.52:8333 # AS49666
+185.203.41.148:8333 # AS9009
185.209.12.76:8333 # AS212323
-185.209.70.17:8333 # AS204568
-185.227.156.226:8333 # AS209846
+185.210.125.33:8333 # AS205671
185.233.189.210:8333 # AS61303
-185.239.221.5:8333 # AS61282
-185.244.100.106:8333 # AS2586
+185.250.36.66:8333 # AS1239
185.254.97.164:8333 # AS44486
-186.33.167.11:8333 # AS1299
-186.176.98.37:8333 # AS262197
-186.249.217.25:8333 # AS7195
-186.250.95.132:8333 # AS262967
-188.32.14.31:8334 # AS42610
+186.235.86.249:8333 # AS263097
+188.27.79.235:8333 # AS8708
188.35.167.14:8333 # AS34123
-188.68.45.143:8333 # AS47147
-188.117.200.212:8333 # AS25447
-188.138.88.14:8333 # AS20773
-188.151.237.158:8333 # AS1257
-188.154.236.49:8333 # AS6730
-189.123.177.128:8333 # AS4230
-190.123.27.11:8333 # AS52468
-190.145.127.254:8333 # AS14080
-192.69.53.77:8333 # AS11142
+188.68.53.44:8333 # AS47147
+188.119.67.137:8333 # AS9002
+188.127.243.41:8333 # AS56694
+188.138.112.60:8333 # AS20773
+188.142.199.17:8333 # AS21334
+188.155.72.160:8333 # AS6730
+188.214.129.52:8333 # AS16125
+188.214.129.139:8333 # AS16125
+188.215.62.122:8333 # AS203600
+188.237.167.51:8333 # AS8926
+188.246.224.12:8333 # AS49505
+189.6.221.37:8333 # AS28573
+190.2.146.90:8333 # AS49981
+190.17.18.190:8333 # AS7303
+190.210.98.253:8333 # AS16814
+192.3.11.24:8333 # AS36352
+192.69.53.18:8333 # AS11142
192.146.137.44:8333 # AS25376
-192.222.24.54:8333 # AS22646
-192.222.147.141:8333 # AS1403
-193.32.127.162:60969 # AS39351
-193.111.198.187:8111 # AS24961
+193.22.128.12:8333 # AS39647
+193.39.142.89:8333 # AS60781
+193.46.74.252:8333 # AS395003
+193.46.74.254:8333 # AS395003
+193.95.249.3:8333 # AS5603
+193.149.176.200:8333 # AS40676
+193.151.155.122:8333 # AS49666
+193.187.90.122:8333 # AS3399
193.196.37.62:8333 # AS34878
-194.13.80.185:15430 # AS47147
-194.147.113.201:8333 # AS21232
+194.35.184.95:8333 # AS9063
194.165.30.20:8333 # AS35162
-194.191.239.98:8333 # AS1836
-195.56.63.4:8333 # AS5483
-195.56.63.10:8333 # AS5483
-195.123.239.185:8333 # AS64010
+194.191.232.153:8333 # AS1836
+195.32.108.164:8333 # AS3269
+195.56.63.11:8333 # AS5483
+195.56.63.12:8333 # AS5483
+195.123.217.63:8333 # AS21100
+195.128.248.153:8333 # AS25229
195.140.226.154:8333 # AS35614
-198.1.231.6:8333 # AS30236
-198.148.112.27:8333 # AS35916
-199.126.234.237:8333 # AS395570
-199.193.174.173:8333 # AS7992
-199.247.7.208:8333 # AS20473
-200.122.181.46:8333 # AS3790
-201.191.6.103:8333 # AS11830
-201.212.36.209:8333 # AS7303
-201.221.234.200:8333 # AS27928
-202.108.211.135:8333 # AS4837
-202.169.17.178:8333 # AS137549
-202.177.24.140:8333 # AS7479
-203.130.48.117:8885 # AS54994
-203.132.94.196:8333 # AS38195
-205.178.41.124:8333 # AS11039
-206.72.201.228:8333 # AS19318
+195.160.222.81:8333 # AS31148
+195.206.105.7:8333 # AS9009
+199.36.253.252:8333 # AS16713
+199.58.100.115:8333 # AS25961
+202.90.242.93:8333 # AS4764
+202.112.238.128:8333 # AS4538
+202.186.38.99:8333 # AS9930
+203.12.0.167:8333 # AS134697
+203.12.10.224:8333 # AS134697
+203.210.193.21:8333 # AS45899
+204.228.142.211:8333 # AS6315
+205.178.182.133:8333 # AS396998
+206.55.178.157:8333 # AS10242
206.192.203.0:8333 # AS7029
-206.223.153.52:8333 # AS19214
-207.134.216.145:8334 # AS395570
-207.188.154.50:8333 # AS15704
-207.229.46.80:8333 # AS852
+207.98.253.88:8333 # AS12083
+207.115.84.47:8333 # AS18530
207.255.193.47:8333 # AS11776
208.104.92.74:8333 # AS14615
-209.58.145.157:8333 # AS394380
-209.58.158.232:8335 # AS394380
-209.141.43.243:8333 # AS53667
-209.226.142.62:8333 # AS577
-209.237.127.227:8333 # AS1299
+209.38.244.87:8333 # AS2914
+209.204.29.18:8333 # AS395439
+209.205.204.218:8333 # AS55081
209.237.133.54:8333 # AS53859
-211.248.90.50:8333 # AS4766
-212.21.18.78:8333 # AS20485
-212.34.225.118:8333 # AS44395
-212.51.146.137:8333 # AS13030
-212.227.211.87:8333 # AS8560
-213.0.69.76:8333 # AS3352
-213.5.36.58:8333 # AS49974
-213.47.64.105:8333 # AS8412
-213.89.135.151:8333 # AS1257
+210.6.95.127:8333 # AS9269
+210.205.146.114:8333 # AS9318
+211.221.42.143:8333 # AS4766
+212.5.157.40:8333 # AS8866
+212.51.136.50:8333 # AS13030
+212.86.32.106:8333 # AS15366
+212.162.152.149:8333 # AS24875
+212.227.150.147:8333 # AS8560
+212.227.155.170:8333 # AS8560
+212.251.162.190:8333 # AS2119
+213.109.236.129:8333 # AS47702
213.141.154.201:8333 # AS12714
-213.159.198.45:8333 # AS8359
-213.184.244.24:8333 # AS60280
-213.214.66.182:8333 # AS43205
-213.226.123.76:8333 # AS49943
-216.146.251.8:8333 # AS54579
-216.186.238.14:8333 # AS12083
-217.5.150.114:8333 # AS3320
-217.15.178.11:8333 # AS25534
-217.24.239.109:8333 # AS9063
+213.193.83.251:8333 # AS6830
+213.193.83.252:8333 # AS6830
+213.202.225.122:8333 # AS24961
+216.83.150.142:8333 # AS5048
+216.186.236.98:8333 # AS12083
+216.232.33.24:8333 # AS395570
217.64.47.138:8333 # AS39324
-217.73.80.104:8333 # AS44291
-217.79.181.38:8333 # AS24961
+217.64.47.200:8333 # AS39324
+217.76.61.78:8333 # AS39597
217.92.55.246:8333 # AS3320
217.113.121.169:8333 # AS8416
-217.115.116.250:8333 # AS30900
217.155.244.170:8333 # AS13037
217.170.124.170:8333 # AS35401
-220.132.135.54:8333 # AS3462
-220.233.178.199:8333 # AS38195
-222.154.111.46:8333 # AS4648
-[2001:1620:510::2]:8333 # AS13030
-[2001:19f0:6001:39aa:5400:3ff:fef0:916]:8333 # AS20473
-[2001:19f0:8001:f71:5400:4ff:fe10:6a63]:8333 # AS20473
+217.173.236.25:8333 # AS8447
+217.180.192.116:8333 # AS30600
+217.180.221.162:8333 # AS30600
+218.43.123.236:8333 # AS4713
+219.77.79.128:8333 # AS4760
+223.18.222.210:8333 # AS9304
+223.167.75.165:8333 # AS4837
+[2001:1620:5566:100::62c]:8333 # AS13030
+[2001:1620:a21:0:da5e:d3ff:fee3:68a0]:8333 # AS13030
+[2001:19f0:4401:e8a:5400:4ff:fe8e:d398]:8333 # AS20473
[2001:1bc0:c1::2000]:8333 # AS29686
-[2001:1c02:11e:3500:df25:6321:8260:d9be]:8333 # AS6830
-[2001:41d0:1004:1b79::]:8339 # AS16276
-[2001:41d0:203:3739::]:8333 # AS16276
-[2001:41d0:203:aacc::]:8333 # AS16276
-[2001:41d0:203:bb0a::]:8333 # AS16276
-[2001:41d0:2:bf8f::]:8333 # AS16276
-[2001:41d0:303:6586::]:8333 # AS16276
-[2001:41d0:602:4493::]:8333 # AS16276
-[2001:41d0:8:b9d8::1]:8333 # AS16276
+[2001:4060:4419:8001::42]:8333 # AS6772
+[2001:41d0:203:8f46::]:8333 # AS16276
+[2001:41d0:30e:8e00::]:8333 # AS16276
+[2001:41d0:403:3d61::]:8333 # AS16276
+[2001:41d0:405:6e00::]:8333 # AS16276
+[2001:41d0:8:83cf:195b:b202:9271:cc5b]:8333 # AS16276
+[2001:41d0:8:ed7f::1]:8333 # AS16276
[2001:41d0:a:69a2::1]:8333 # AS16276
-[2001:41f0::62:6974:636f:696e]:8333 # AS6830
-[2001:44b8:256:5d11:216:3eff:fe39:d5d4]:8333 # AS4739
+[2001:41d0:a:6b4d::1]:8333 # AS16276
+[2001:470:1b55::]:8333 # AS6939
[2001:470:1b62::]:8333 # AS6939
-[2001:470:1f07:803:20c:29ff:fe2d:5879]:8333 # AS6939
-[2001:470:1f15:106:e2d5:5eff:fe42:7ae5]:8333 # AS6939
-[2001:470:1f15:c43::11]:8333 # AS6939
-[2001:470:26:472::b7c]:8333 # AS6939
+[2001:470:1f09:b14::11]:8333 # AS6939
+[2001:470:1f0a:89a::2]:8333 # AS6939
+[2001:470:1f1b:5a6:216:3eff:fe24:1162]:8333 # AS6939
[2001:470:75e9:1::10]:8333 # AS6939
-[2001:470:de5a::ec]:9333 # AS6939
-[2001:4ba0:babe:584::1]:8333 # AS24961
-[2001:4ba0:ffff:24::1]:8333 # AS24961
+[2001:470:88ff:2e::1]:8333 # AS6939
+[2001:470:8ca0:2:7646:a0ff:fe9b:e662]:8333 # AS6939
+[2001:470:a:c13::2]:8333 # AS6939
+[2001:470:c:1077::2]:8333 # AS6939
[2001:4dd0:3564:0:30b7:1d7b:6fec:4c5c]:8333 # AS8422
[2001:4dd0:3564:0:88e:b4ff:2ad0:699b]:8333 # AS8422
[2001:4dd0:3564:0:9c1c:cc31:9fe8:5505]:8333 # AS8422
@@ -544,314 +538,1211 @@
[2001:4dd0:3564:1:b977:bd71:4612:8e40]:8333 # AS8422
[2001:4dd0:af0e:3564::69:1]:8333 # AS8422
[2001:4dd0:af0e:3564::69:90]:8333 # AS8422
-[2001:4de8:b1b2:1:0:dead:beef:7]:8333 # AS29208
-[2001:638:a000:4140::ffff:191]:8333 # AS680
-[2001:678:acc:42::]:8333 # AS60404
+[2001:560:441f:1::4]:8333 # AS18530
+[2001:5a8:40c7:f500:7a0d:d50:255e:dbac]:8333 # AS46375
+[2001:638:a000:4140::ffff:47]:8333 # AS680
[2001:67c:26b4:ff00::44]:8333 # AS25376
-[2001:67c:2db8:6::36]:8333 # AS39798
-[2001:7c0:2310:0:f816:3eff:fe0d:4ab6]:8333 # AS34878
+[2001:67c:440:688:91:236:251:137]:8333 # AS57944
+[2001:67c:440:688:91:236:251:139]:8333 # AS57944
[2001:7c0:2310:0:f816:3eff:fe6c:4f58]:8333 # AS34878
-[2001:861:3246:a10::40]:8333 # AS5410
-[2001:b07:2e6:38d7:ba27:ebff:fe60:3dc1]:8333 # AS12874
+[2001:861:c62:2fd0:ca7f:54ff:fece:6d9]:8333 # AS5410
+[2001:871:23d:d5d1:5a47:caff:fe71:c8d]:8333 # AS8447
+[2001:910:109d:2c03:d217:c2ff:fe07:2cd9]:8333 # AS20766
[2001:b07:6461:7811:489:d2da:e07:1af7]:8333 # AS12874
-[2001:b07:ac9:442b:79d6:bbbe:b37c:a783]:8333 # AS12874
+[2001:b07:646b:8074:32e8:9243:a337:e60a]:8333 # AS12874
+[2001:bc8:1201:715:ca1f:66ff:fec9:5ff0]:8333 # AS12876
+[2001:bc8:1201:71a:2e59:e5ff:fe42:52f4]:8333 # AS12876
[2001:bc8:1600:0:208:a2ff:fe0c:8a2e]:8333 # AS12876
-[2001:bc8:323c:ff:a634:384f:1849:f4bc]:8333 # AS12876
-[2001:bc8:323c:ff:d217:c2ff:fe07:2cd9]:8333 # AS12876
-[2001:bc8:3bec:100::1]:8333 # AS12876
-[2002:2f5b:a5f9::2f5b:a5f9]:8885 # AS6939
-[2003:cb:8713:6102:aaa1:59ff:fe57:7779]:8333 # AS3320
-[2003:e0:370e:1400::5]:8333 # AS3320
-[2003:f6:3f10:6700:4c9f:7620:8324:d4a7]:8333 # AS3320
-[2400:2410:cea2:d00:41bc:c9ea:861b:51ee]:8333 # AS17676
-[2400:2411:a3e1:4900:2568:684b:e99:7120]:8333 # AS17676
-[2400:2411:a3e1:4900:2987:b88f:61e0:84fa]:8333 # AS17676
-[2400:3b00:20:c:bacb:29ff:feab:8886]:8333 # AS18229
+[2003:dc:2f4a:eb00:4ecc:6aff:fe25:c9a3]:8333 # AS3320
+[2003:f6:3f31:600:4c9f:7620:8324:d4a7]:8333 # AS3320
+[2400:6180:100:d0::848:5001]:8333 # AS14061
+[2400:6180:100:d0::940:4001]:8333 # AS14061
+[2400:6180:100:d0::953:8001]:8333 # AS14061
+[2400:6180:100:d0::a02:2001]:8333 # AS14061
+[2400:6180:100:d0::a0f:9001]:8333 # AS14061
+[2400:6180:100:d0::a3d:b001]:8333 # AS14061
+[2400:6180:100:d0::a3f:1001]:8333 # AS14061
+[2400:6180:100:d0::a49:a001]:8333 # AS14061
+[2400:6180:100:d0::a56:d001]:8333 # AS14061
+[2400:6180:100:d0::a56:e001]:8333 # AS14061
[2401:b140:1::100:210]:8333 # AS54415
[2401:b140:1::100:220]:8333 # AS54415
-[2401:b140::42:100]:8333 # AS6939
-[2401:b140::44:130]:8333 # AS6939
-[2401:d002:3902:700:d72c:5e22:4e95:389d]:8333 # AS38195
-[2404:4408:6752:c000::1999]:8333 # AS9790
-[2404:7a85:4161:2b00:49a1:427a:fac:3409]:8333 # AS2518
-[2405:9800:b972:ab58:c05:e938:267e:271]:8333 # AS45430
-[2406:da11:169:b03:32b5:f901:9f7c:3e4b]:8333 # AS16509
-[2406:da14:335:b601:ceb7:b4fc:a855:f3a5]:8333 # AS16509
-[2406:da1e:a4e:8a03:2aad:496b:768d:e497]:8333 # AS16509
-[2407:8800:bc61:2202:a0c6:107:502b:4e3b]:8333 # AS7545
-[2409:10:ca20:1df0:224:e8ff:fe1f:60d9]:8333 # AS55391
-[2600:1700:22f1:641f:e8:39c8:eb1d:a1eb]:8333 # AS7018
-[2600:1700:9c5d:ed0::38]:8333 # AS7018
-[2600:1700:9c5d:ed0:d0d6:1d9:5cc2:ab47]:8333 # AS7018
-[2600:1702:1ce0:4010::40]:8333 # AS7018
-[2600:1f14:40e:e301:d155:aa3a:77be:960e]:8333 # AS16509
-[2600:1f16:a08:b901:1afa:ef4e:4ce7:2ba4]:8333 # AS16509
-[2600:1f1c:2d3:2403:5bac:3fc6:6513:7a63]:8333 # AS16509
+[2402:e280:3d17:945:1889:d3c6:8e85:d3c4]:8333 # AS134674
+[2403:6200:8821:2fdf:3903:a2b1:9f:c897]:8333 # AS20473
+[2406:3400:216:8b00:211:32ff:feca:336b]:8333 # AS10143
+[2406:da14:335:b600:eb14:5fd:2072:3653]:8333 # AS16509
+[2406:da1c:50b:cd00:3cae:1728:ecfc:4334]:8333 # AS16509
+[2406:da1c:50b:cd03:36d6:13fa:eba8:6543]:8333 # AS16509
+[2406:da1e:a4e:8a03:d90a:fbb0:23d3:ccb4]:8333 # AS16509
+[2407:3640:2107:1278::1]:8333 # AS141995
+[2407:7000:9f71:2d00:1c5a:5292:5108:c734]:8333 # AS9500
+[2408:8207:2655:fae0::10b]:8333 # AS4837
+[2408:8207:5456:d8d0::5c6]:8333 # AS4837
+[2409:250:60a0:2600:a971:1cdd:3d5b:654d]:8333 # AS55392
+[240d:1a:4b1:e700:19:d9ef:7f3:8e75]:8333 # AS2527
+[2600:1700:3948:82f:ce04:d382:5226:4cac]:8333 # AS7018
+[2600:1f16:a08:b900:4bfe:2f81:ae31:5f5]:8333 # AS16509
+[2600:1f1c:2d3:2401:6989:b1fd:d2a6:fbc8]:8333 # AS16509
+[2600:1f1e:2fe:3601:63a8:ebf6:83e4:1932]:8333 # AS16509
[2600:2104:1003:c5ab:dc5e:90ff:fe18:1d08]:8333 # AS11404
-[2600:3c00::f03c:92ff:fe92:2745]:8333 # AS63949
-[2600:3c00::f03c:92ff:fecf:61b6]:8333 # AS63949
-[2600:3c00::f03c:93ff:feb3:1b6]:8333 # AS63949
-[2600:3c00:e002:2e32::1:14]:8333 # AS63949
-[2600:3c02::f03c:92ff:fe5d:9fb]:8333 # AS63949
-[2600:4040:2854:5e00:c6e9:84ff:fe46:ee8]:8666 # AS13786
-[2600:6c54:7100:1ad1:bddf:550e:91be:f9e1]:8333 # AS20115
-[2600:8805:2400:14e:12dd:b1ff:fef2:3013]:8333 # AS22773
-[2601:184:300:bde:3c29:8e94:1ba8:fde3]:8333 # AS7922
-[2601:18c:8080:300f:219:d1ff:fe75:dc2f]:8333 # AS7922
-[2601:18d:4600:43f1:20e7:b3ff:fecf:a99]:8333 # AS7922
-[2601:18d:8701:c290::3330]:8333 # AS7922
-[2601:246:4d7f:9e28:f321:36ca:7a71:c687]:8333 # AS7922
-[2601:640:c201:960d:86eb:f27d:66a2:f2c1]:8333 # AS7922
-[2602:241:75d1:2b90::7840]:8333 # AS46375
-[2602:ffb8::208:72:57:200]:8333 # AS2914
+[2600:3c00::f03c:91ff:fe4b:c52]:8333 # AS63949
+[2600:3c00:e002:2e32::1:c8]:8333 # AS63949
+[2600:3c02::f03c:94ff:fecc:c99c]:8333 # AS63949
+[2600:6c4e:a00:cd0:428d:5cff:fe58:4884]:8333 # AS20115
+[2600:6c54:7100:1ad1:c92e:36d:651:bd18]:8333 # AS20115
+[2601:184:300:156c:ba4c:30:9da:6c06]:8333 # AS7922
+[2601:185:8302:12f0:1ab2:2840:9de4:1550]:8333 # AS7922
+[2603:3003:11b:e100:20c:29ff:fe38:bbc0]:8333 # AS7922
[2603:3004:6a1:3800:851f:584d:7aba:affb]:8333 # AS7922
-[2603:3004:6a1:3800::4402]:8333 # AS7922
-[2603:3004:70d:1400:8532:2900:ce6f:acdf]:8333 # AS7922
-[2603:3004:745:900:f0d7:556a:a8c:ced5]:8333 # AS7922
-[2603:6080:c000:5d8a::104f]:8333 # AS7843
-[2603:8000:d100:8991:cc29:ccff:fe42:300c]:8333 # AS7843
+[2603:3024:18ee:8000:20e:c4ff:fed1:ef15]:8333 # AS7922
[2603:8080:1f07:6fdd:7de2:d969:78c9:b7ea]:8333 # AS7843
-[2603:8080:7300:531::13ea]:8333 # AS7843
-[2603:80a0:703:40f8::38]:8333 # AS7843
-[2604:180:f3::218]:8333 # AS3842
-[2604:3d08:0:5:d941:4b03:a093:131b]:8333 # AS6327
-[2604:7c00:120:4b::eb24]:8333 # AS174
-[2604:a00:21:3043:bf6a:535e:dfeb:5b7b]:8333 # AS19318
-[2604:a880:400:d0::1ce7:4001]:8333 # AS14061
-[2604:a880:400:d0::1d44:e001]:8333 # AS14061
-[2604:a880:400:d0::261f:6001]:8333 # AS14061
-[2604:a880:400:d1::7e2:e001]:8333 # AS14061
-[2604:a880:4:1d0::14:3000]:8333 # AS14061
-[2604:a880:4:1d0::e5:b000]:8333 # AS14061
+[2604:4080:1036:80b1:50e1:43ff:fe0e:9df5]:8333 # AS11404
[2605:6400:30:f220::]:8333 # AS53667
-[2605:6f80:0:7:fc1b:ccff:fe8a:d822]:8333 # AS53340
-[2605:a140:2076:8253::1]:8333 # AS40021
-[2605:a140:3007:1287::1]:8333 # AS40021
-[2605:ae00:203::203]:8333 # AS7819
+[2605:6400:30:fd6f::4]:8333 # AS53667
[2605:c000:2a0a:1::102]:8333 # AS7393
-[2607:1a00:1:d::11:7c4d]:8333 # AS22653
-[2607:5300:203:1214::]:8333 # AS16276
+[2606:6d00:100:5102:3d2:f06a:c2e8:a54]:8333 # AS1403
+[2607:5300:60:2e54::1]:8333 # AS16276
+[2607:5300:61:854::1]:8333 # AS16276
[2607:9280:b:73b:250:56ff:fe14:25b5]:8333 # AS395502
[2607:9280:b:73b:250:56ff:fe21:9c2f]:8333 # AS395502
[2607:9280:b:73b:250:56ff:fe21:bf32]:8333 # AS395502
[2607:9280:b:73b:250:56ff:fe33:4d1b]:8333 # AS395502
[2607:9280:b:73b:250:56ff:fe3d:401]:8333 # AS395502
-[2607:f2c0:e1c2:69:12c3:7bff:fe4d:9431]:8333 # AS5645
-[2607:f2c0:e1c2:69:ecb2:6e88:9f33:5057]:8333 # AS5645
-[2620:6:2003:105:2d8:61ff:fe0f:853]:8333 # AS25682
-[2620:6e:a000:1:42:42:42:42]:8333 # AS397444
-[2620:a6:2000:1::3:d570]:8333 # AS27566
-[2620:a6:2000:1::5:162a]:8333 # AS27566
-[2620:a6:2000:1::5:1631]:8333 # AS27566
-[2620:a6:2000:1::c:e634]:8333 # AS27566
-[2800:40:33:8ab:a0e7:b215:fc83:5c31]:8333 # AS16814
-[2800:bf0:149:f4b:f8df:8d7d:801b:e25e]:8333 # AS27947
-[2804:14c:198:80d5:7603:41d1:d3fc:e797]:8333 # AS28573
-[2804:14d:ae81:827b:99a8:1e3f:6db2:29db]:8333 # AS4230
-[2804:d57:5537:4800:3e7c:3fff:fe7b:80aa]:8333 # AS8167
+[2620:a6:2000:1:1:0:d:3015]:8333 # AS27566
+[2620:a6:2000:1:2:0:3:266c]:8333 # AS27566
+[2620:a6:2000:1:2:0:9:930b]:8333 # AS27566
+[2620:a6:2000:1:2:0:b:3011]:8333 # AS27566
+[2800:150:11d:2426:62b:b164:704a:6962]:8333 # AS22047
+[2800:300:8251:b50::d]:8333 # AS27651
+[2800:300:8251:b50:e92:64f5:22af:c31e]:8333 # AS27651
+[2800:40:15:6ad:48e8:2200:a882:e08e]:8333 # AS16814
+[2803:5180:4100:4000::2]:8333 # AS52468
+[2803:9800:9447:84bb:cab8:d2f5:388c:9a57]:8333 # AS19037
+[2804:14d:7e33:83b0:6e41:1ccc:cf20:aff9]:8333 # AS4230
+[2804:431:e038:cd01:aaa1:59ff:fe0d:44b8]:8333 # AS27699
+[2804:d57:450d:f00:a422:9828:b00e:91e9]:8333 # AS8167
+[2806:2f0:5020:d287:4dcd:6204:909b:4125]:8333 # AS17072
+[2a00:1298:8001::6542]:8333 # AS5578
[2a00:12e0:101:99:20c:29ff:fe29:d03f]:8333 # AS6798
-[2a00:1328:e101:c00::163]:8333 # AS31078
-[2a00:1398:4:2a03:215:5dff:fed6:1033]:8333 # AS34878
+[2a00:1398:4:2a03:3eec:efff:fe05:d93e]:8333 # AS34878
[2a00:1398:4:2a03::bc03]:8333 # AS34878
-[2a00:1630:10:1003:0:b19:b00b:babe]:8333 # AS49544
[2a00:1768:2001:27::ef6a]:8333 # AS43350
-[2a00:1828:a004:2::666]:8333 # AS34240
-[2a00:1c10:2:709::217]:22220 # AS50300
[2a00:1f40:5001:108:5d17:7703:b0f5:4133]:8333 # AS42864
[2a00:23c5:fe80:7301:d6ae:52ff:fed5:56a5]:8333 # AS2856
-[2a00:23c6:5c91:5808:c05a:4dff:fe65:9d69]:8333 # AS2856
-[2a00:6020:1bfa:d400:20c:29ff:fe61:4a4c]:8333 # AS60294
-[2a00:6020:b482:9200:491a:358c:d8f7:1da]:8333 # AS60294
+[2a00:23c6:5c8a:5c00:c05a:4dff:fe65:9d69]:8333 # AS2856
+[2a00:6020:4503:3700:5054:ff:fe90:640e]:8333 # AS60294
[2a00:6020:b489:2000:5054:ff:fefc:5ed8]:8333 # AS60294
-[2a00:7c80:0:25::e37a]:8333 # AS49981
-[2a00:7c80:0:71::8]:8333 # AS49981
[2a00:8a60:e012:a00::21]:8333 # AS680
-[2a00:ae40:240e:3200::3]:8333 # AS50923
-[2a00:bbe0:cc:0:62a4:4cff:fe23:7510]:8333 # AS47605
-[2a00:ca8:a1f:3025:f949:e442:c940:13e8]:8333 # AS30764
-[2a00:d4e0:2:d002:4467:31e0:6fa5:b3ef]:8333 # AS15600
-[2a00:ee2:1200:1900:8d3:d2ff:feb1:bc58]:8333 # AS5603
-[2a01:238:420f:9200:fa5a:1a4b:1e6a:fadf]:8333 # AS6724
-[2a01:238:4389:c400:3b26:d94e:38d5:44ef]:8333 # AS6724
-[2a01:490:16:301::2]:8333 # AS8251
-[2a01:4b00:807c:3100:cda1:c6a:2bad:2418]:8333 # AS56478
-[2a01:4f8:141:2254::2]:8333 # AS24940
-[2a01:4f8:173:230a::2]:8333 # AS24940
-[2a01:4f8:190:91c4::2]:8333 # AS24940
+[2a00:bbe0:0:221f::246]:8333 # AS47605
+[2a00:d520:9:9300:420b:544e:8019:6d3a]:8333 # AS15600
+[2a00:fd40:c:c::c]:8333 # AS3269
+[2a01:4f8:171:1f16::2]:8333 # AS24940
[2a01:4f8:200:7222::2]:8333 # AS24940
-[2a01:4f8:202:3e6::2]:8333 # AS24940
-[2a01:4f8:221:44d7::2]:8333 # AS24940
-[2a01:4f8:231:915::2]:8333 # AS24940
-[2a01:4f9:2a:1ce0::2]:8333 # AS24940
+[2a01:4f8:202:4205::2]:8333 # AS24940
+[2a01:4f8:242:2016::2]:8333 # AS24940
+[2a01:4f8:261:420c::2]:8333 # AS24940
+[2a01:4f8:272:4cd9::2]:8333 # AS24940
+[2a01:4f9:1a:a966::2]:8333 # AS24940
+[2a01:4f9:1a:af0d::2]:8333 # AS24940
[2a01:4f9:2b:29a::2]:8333 # AS24940
-[2a01:4f9:4a:31de::2]:8333 # AS24940
-[2a01:5200:6c:6162:7a61:746b:6f2e:736b]:8333 # AS6855
-[2a01:6380:fffe:73:10fb:d012:8581:b4d7]:8333 # AS25540
+[2a01:4f9:5a:44a5::2]:8333 # AS24940
[2a01:7a7:2:2804:ae1f:6bff:fe9d:6c94]:8333 # AS20773
-[2a01:7c8:aaac:89:5054:ff:feb7:f5cb]:8333 # AS20857
-[2a01:7c8:aac9:c9:5054:ff:fedf:ff95]:8333 # AS20857
-[2a01:7c8:d001:1c1:5054:ff:feee:3e1a]:8333 # AS20857
-[2a01:7c8:d009:2aa:5054:ff:fe1b:a196]:11520 # AS20857
-[2a01:7c8:fffa:50e:ddfe:c924:ca0a:cbab]:8333 # AS20857
-[2a01:7e00::f03c:93ff:fe59:66dc]:8333 # AS63949
-[2a01:7e01::f03c:93ff:fe3b:bb5b]:8333 # AS63949
+[2a01:8740:1:753::e5cb]:8333 # AS57344
+[2a01:8740:1:ff2e::9428]:8333 # AS57344
[2a01:8740:1:ffc5::8c6a]:8333 # AS57344
-[2a01:9f40:a000::100]:8333 # AS42908
-[2a01:cb00:d3d:7700:227:eff:fe28:c565]:8333 # AS3215
-[2a01:e0a:20:7350:919c:b1c3:8b83:adf9]:8333 # AS12322
+[2a01:cb00:790:f500:110b:b446:2260:7d2c]:8333 # AS3215
+[2a01:cb10:336:cb00:61ac:d15d:4ac0:2cbd]:8333 # AS3215
+[2a01:cb10:336:cb00:d237:45ff:fec5:2cd0]:8333 # AS3215
+[2a01:cb15:804c:8000:21e:6ff:fe51:2c32]:8333 # AS3215
+[2a01:e0a:185:55f0:a0ba:9eaf:9853:92b7]:8333 # AS12322
[2a01:e0a:301:7010:b87d:e14b:cea9:b998]:8333 # AS12322
-[2a01:e0a:48b:2d10:94f2:4d5c:ca5f:bf49]:8333 # AS12322
-[2a01:e0a:530:a0a0:f465:af5:be1b:9075]:8333 # AS12322
-[2a01:e0a:aa7:c8c0:9679:affa:b6e5:efc7]:8333 # AS12322
-[2a01:e11:100c:70:cbc8:9e31:4b77:1626]:8333 # AS12322
-[2a01:e34:ee78:3060:230:48ff:fe81:f1c6]:8333 # AS12322
-[2a02:1210:14a9:6700:a00:27ff:fe4e:82b6]:8333 # AS3303
-[2a02:1210:4639:f00:10a7:e965:509a:7a4a]:8333 # AS3303
+[2a01:e0a:3b3:1420:7ca0:3a9a:5cc3:b644]:8333 # AS12322
+[2a01:e0a:5:9390:bf35:4d41:8a2a:570]:8333 # AS12322
+[2a01:e0a:9e9:c240:8e3a:af64:4f0:8f79]:8333 # AS12322
+[2a01:e0a:b0f:37e0:a13f:e65:ac42:8e36]:8333 # AS12322
+[2a01:e0a:b5:7f50:c257:a55b:4846:97e1]:8333 # AS12322
+[2a01:e0a:bf6:8d70:20c:29ff:fe30:4fd2]:8333 # AS12322
+[2a01:e11:100c:70:39f3:e3c9:832f:37a]:8333 # AS12322
+[2a01:e34:ec1d:7100:8aae:ddff:fe02:4159]:8333 # AS12322
[2a02:1210:7c92:5100:211:32ff:feae:152d]:8333 # AS3303
-[2a02:1210:86bf:f100:3178:d700:d44d:6bb1]:8333 # AS3303
-[2a02:1210:9487:a200:edc1:93a4:945:9a92]:8333 # AS3303
-[2a02:168:420b:a::20]:8333 # AS13030
-[2a02:168:6328:0:4a21:bff:fe26:38c3]:8333 # AS13030
-[2a02:168:676e:0:e65f:1ff:fe09:3591]:8333 # AS13030
-[2a02:1748:f39f:5872:dead:beef:b1ac:c0fe]:8333 # AS51184
-[2a02:180:1:1::517:10b6]:8333 # AS35366
-[2a02:2168:a379:d100:96de:80ff:fea3:fd00]:8333 # AS42610
-[2a02:2780:9000:70::7]:8333 # AS35434
-[2a02:2780:9000:70::f]:8333 # AS35434
-[2a02:2780::e01a]:8333 # AS35434
-[2a02:2e02:3900:5400:a099:e1ff:feb6:d0e]:8333 # AS12479
-[2a02:2f05:660e:8b00::1]:8333 # AS48571
-[2a02:58:97:7d20::60]:8333 # AS25596
-[2a02:6d40:3073:c01:dea6:32ff:fe44:4b25]:8333 # AS42652
-[2a02:7a01::91:228:45:130]:8333 # AS16019
-[2a02:7b40:5928:89::1]:8333 # AS62282
-[2a02:7b40:c3b5:f583::1]:8333 # AS62282
-[2a02:8308:8087:aa00:9ea8:1b2:ef98:56bf]:8333 # AS16019
-[2a02:842a:1df:8a01:1e1b:dff:fe0b:236d]:8333 # AS15557
-[2a02:a44d:14d6:1:2c0:8ff:fe8f:b3b2]:8333 # AS1136
+[2a02:1210:86bf:f100:a9ac:d041:1f8e:6925]:8333 # AS3303
+[2a02:22a0:bbb3:dc10:50e1:57ff:fe70:9492]:8333 # AS1136
+[2a02:247a:215:3e00:1::1]:8333 # AS8560
+[2a02:2c60:f103:7c0:1a31:bfff:fecc:5d91]:8333 # AS9063
+[2a02:3102:4d5c:f000:dea6:32ff:febb:b9cb]:8333 # AS6805
+[2a02:3102:bc00:10e9:ca5:9dff:fea9:1cbb]:8333 # AS6805
+[2a02:390:9000:0:aaa1:59ff:fe43:b57b]:8333 # AS12496
+[2a02:768:f92b:db46:5e46:772b:71d:29b7]:8333 # AS44489
+[2a02:8070:f181:f600:bcb:2d1:d790:78ff]:8333 # AS51185
+[2a02:8071:6380:c500:7285:c2ff:feb5:a39c]:8333 # AS3209
+[2a02:8084:2021:73f3::66e6]:8333 # AS6830
+[2a02:8308:8188:5100:6d8b:4531:4331:eee2]:8333 # AS16019
+[2a02:8388:e302:7980:6f85:a0b3:4b4d:8b0f]:8333 # AS8412
+[2a02:8388:e5c3:4a80:201:2eff:fe82:b3cc]:8333 # AS8412
+[2a02:a31a:e03d:9400:3f18:2729:c86:d754]:8333 # AS6830
[2a02:a45a:94cd:f00d::1]:8333 # AS1136
-[2a02:a45f:3b9d:30::3]:8333 # AS1136
-[2a02:a467:7833:1:7285:c2ff:fe2c:21e9]:8333 # AS1136
-[2a02:aa14:2380:b300:4040:be88:8b01:d38]:8333 # AS6830
-[2a02:c206:2044:9826::1]:8333 # AS51167
-[2a02:c206:2082:1246::1]:8333 # AS51167
-[2a02:c206:3008:2368::1]:8333 # AS51167
-[2a02:c207:0:4971::1]:5332 # AS51167
-[2a02:c207:2014:4199::1]:8333 # AS51167
-[2a02:c207:2024:6115::1]:8333 # AS51167
-[2a02:c207:2026:6682::1]:8333 # AS51167
-[2a02:c207:3002:7468::1]:8333 # AS51167
-[2a02:e98:20:1504::1]:8333 # AS24641
-[2a03:4000:6:416c::43]:8333 # AS47147
-[2a03:4000:6:f814:548b:17ff:fe31:b64a]:8333 # AS47147
-[2a03:6000:870:0:46:23:87:218]:8333 # AS51088
-[2a03:94e0:ffff:185:243:218:0:19]:8333 # AS56655
-[2a03:b0c0:1:e0::397:6001]:8333 # AS14061
-[2a03:b0c0:2:f0::163:3001]:8333 # AS14061
-[2a03:b0c0:2:f0::18a:d001]:8333 # AS14061
-[2a03:b0c0:3:d0::f3e:2001]:8333 # AS14061
-[2a03:e2c0:1347::2]:8333 # AS50113
+[2a02:a465:80f4:1:f369:4ef5:aa12:7566]:8333 # AS1136
+[2a02:ab88:20b:ce00:223:24ff:fe56:6202]:8333 # AS21334
+[2a02:c206:2016:2394::1]:8333 # AS51167
+[2a02:c206:2162:5603::1]:8333 # AS51167
+[2a02:c206:2162:5605::1]:8333 # AS51167
+[2a02:c206:2162:5606::1]:8333 # AS51167
+[2a02:c206:2162:5856::1]:8333 # AS51167
+[2a02:c206:2162:7348::1]:8333 # AS51167
+[2a02:c206:2162:7352::1]:8333 # AS51167
+[2a02:c206:2162:8026::1]:8333 # AS51167
+[2a02:c207:2034:7358::1]:8333 # AS51167
+[2a02:c207:3006:3185::1]:8333 # AS51167
+[2a03:cfc0:8000:2a::9532:6507]:8333 # AS201814
+[2a03:cfc0:8000:2a::9532:6510]:8333 # AS201814
+[2a03:cfc0:8000:2a::9532:6511]:8333 # AS201814
+[2a03:cfc0:8000:2a::9532:6516]:8333 # AS201814
+[2a03:cfc0:8000:2a::9532:651d]:8333 # AS201814
+[2a03:cfc0:8000:2a::9532:6520]:8333 # AS201814
+[2a03:cfc0:8000:2a::9532:6522]:8333 # AS201814
+[2a03:cfc0:8000:2a::9532:6523]:8333 # AS201814
+[2a03:cfc0:8000:2a::9532:659a]:8333 # AS201814
+[2a03:cfc0:8000:2a::9532:659d]:8333 # AS201814
[2a03:ec0:0:928::701:701]:8333 # AS199669
-[2a04:52c0:103:c455::1]:8334 # AS60404
-[2a04:52c0:3007:200::2000]:8333 # AS60404
-[2a04:bc40:1dc3:8d::2:1001]:8333 # AS35277
-[2a05:1500:702:0:1c00:40ff:fe00:c]:8333 # AS48635
-[2a05:3580:d101:3700::]:8333 # AS20764
-[2a05:3580:db0b:1600:c489:76ed:313d:b33]:8333 # AS20764
-[2a05:d014:a55:4001:8127:afa7:daf9:d91b]:8333 # AS16509
+[2a04:ee41:86:50b6:fa75:a4ff:fe3c:243f]:8333 # AS15796
+[2a05:d012:42a:5703:4dc5:8116:787c:e016]:8333 # AS16509
[2a05:d014:a55:4001:f6ab:dd5e:4039:b46c]:8333 # AS16509
-[2a05:d014:a55:4003:6523:50a1:152:e88c]:8333 # AS16509
-[2a05:d01a:b7b:3c01:8bf7:ae14:afb3:33ae]:8333 # AS16509
-[2a05:f480:1800:697:5400:2ff:feb6:c36d]:8333 # AS20473
-[2a06:e040:7603:2918:c6ef:464e:9fe5:73ec]:8333 # AS198507
-[2a07:abc4::1:946]:8333 # AS62000
-[2a09:2681:102::210]:8333 # AS61282
-[2a0a:c801:1:7::183]:8333 # AS39798
-[2a0c:5a80:1210:a800:6af7:28ff:fee5:6b3a]:8333 # AS57269
-[2a0d:5600:24:a8e::a91e]:55373 # AS9009
-[2a0d:7c40:3000:b04::2]:8333 # AS54290
-[2a0d:8340:24::2]:8333 # AS50113
-[2a0f:df00:0:2010::162]:8333 # AS41281
-[2a10:3781:16b9:1:fe3f:dbff:fe04:2d4c]:8333 # AS206238
-[2a10:3781:84b:1:b123:6306:943a:f09b]:8333 # AS206238
-[2a10:d200:1:33:a6bf:1ff:fe6a:46a9]:8333 # AS212323
-[2c0f:f4c0:2202:20b0:261c:4ff:fe14:daa0]:8333 # AS327693
-[2c0f:f8f0:da51:0:70c3:eea9:9717:9579]:8333 # AS30844
-
-# manually updated 2022-08 for minimal torv3 bootstrap support
-5g72ppm3krkorsfopcm2bi7wlv4ohhs4u4mlseymasn7g7zhdcyjpfid.onion:8333
-b64xcbleqmwgq2u46bh4hegnlrzzvxntyzbmucn3zt7cssm7y4ubv3id.onion:8333
-fjdyxicpm4o42xmedlwl3uvk5gmqdfs5j37wir52327vncjzvtpfv7yd.onion:8333
-fpz6r5ppsakkwypjcglz6gcnwt7ytfhxskkfhzu62tnylcknh3eq6pad.onion:8333
-gxo5anvfnffnftfy5frkgvplq3rpga2ie3tcblo2vl754fvnhgorn5yd.onion:8333
-ifdu5qvbofrt4ekui2iyb3kbcyzcsglazhx2hn4wfskkrx2v24qxriid.onion:8333
-itz3oxsihs62muvknc237xabl5f6w6rfznfhbpayrslv2j2ubels47yd.onion:8333
-kpgvmscirrdqpekbqjsvw5teanhatztpp2gl6eee4zkowvwfxwenqaid.onion:8333
-m7cbpjolo662uel7rpaid46as2otcj44vvwg3gccodnvaeuwbm3anbyd.onion:8333
-mwmfluek4au6mxxpw6fy7sjhkm65bdfc7izc7lpz3trewfdghyrzsbid.onion:8333
-rp7k2go3s5lyj3fnj6zn62ktarlrsft2ohlsxkyd7v3e3idqyptvread.onion:8333
-
-# manually updated 2022-08 for minimal i2p bootstrap support
-255fhcp6ajvftnyo7bwz3an3t4a4brhopm3bamyh2iu5r3gnr2rq.b32.i2p:0
-27yrtht5b5bzom2w5ajb27najuqvuydtzb7bavlak25wkufec5mq.b32.i2p:0
-2el6enckmfyiwbfcwsygkwksovtynzsigmyv3bzyk7j7qqahooua.b32.i2p:0
-3gocb7wc4zvbmmebktet7gujccuux4ifk3kqilnxnj5wpdpqx2hq.b32.i2p:0
-3tns2oov4tnllntotazy6umzkq4fhkco3iu5rnkxtu3pbfzxda7q.b32.i2p:0
-4fcc23wt3hyjk3csfzcdyjz5pcwg5dzhdqgma6bch2qyiakcbboa.b32.i2p:0
-4osyqeknhx5qf3a73jeimexwclmt42cju6xdp7icja4ixxguu2hq.b32.i2p:0
-4umsi4nlmgyp4rckosg4vegd2ysljvid47zu7pqsollkaszcbpqq.b32.i2p:0
-52v6uo6crlrlhzphslyiqblirux6olgsaa45ixih7sq5np4jujaa.b32.i2p:0
-6j2ezegd3e2e2x3o3pox335f5vxfthrrigkdrbgfbdjchm5h4awa.b32.i2p:0
-6n36ljyr55szci5ygidmxqer64qr24f4qmnymnbvgehz7qinxnla.b32.i2p:0
-72yjs6mvlby3ky6mgpvvlemmwq5pfcznrzd34jkhclgrishqdxva.b32.i2p:0
-7r4ri53lby2i3xqbgpw3idvhzeku7ubhftlf72ldqkg5kde6dauq.b32.i2p:0
-a5qsnv3maw77mlmmzlcglu6twje6ttctd3fhpbfwcbpmewx6fczq.b32.i2p:0
-aovep2pco7v2k4rheofrgytbgk23eg22dczpsjqgqtxcqqvmxk6a.b32.i2p:0
-bddbsmkas3z6fakorbkfjhv77i4hv6rysyjsvrdjukxolfghc23q.b32.i2p:0
-bitcoi656nll5hu6u7ddzrmzysdtwtnzcnrjd4rfdqbeey7dmn5a.b32.i2p:0
-brifkruhlkgrj65hffybrjrjqcgdgqs2r7siizb5b2232nruik3a.b32.i2p:0
-c4gfnttsuwqomiygupdqqqyy5y5emnk5c73hrfvatri67prd7vyq.b32.i2p:0
-day3hgxyrtwjslt54sikevbhxxs4qzo7d6vi72ipmscqtq3qmijq.b32.i2p:0
-di2zq6fr3fegf2jdcd7hdwyql4umr462gonsns2nxz5qg5vz4bka.b32.i2p:0
-e55k6wu46rzp4pg5pk5npgbr3zz45bc3ihtzu2xcye5vwnzdy7pq.b32.i2p:0
-eciohu5nq7vsvwjjc52epskuk75d24iccgzmhbzrwonw6lx4gdva.b32.i2p:0
-ejlnngarmhqvune74ko7kk55xtgbz5i5ncs4vmnvjpy3l7y63xaa.b32.i2p:0
-g47cqoppu26pr4n2cfaioqx7lbdi7mea7yqhlrkdz3wjwxjxdh2a.b32.i2p:0
-h3r6bkn46qxftwja53pxiykntegfyfjqtnzbm6iv6r5mungmqgmq.b32.i2p:0
-hhfi4yqkg2twqiwezrfksftjjofbyx3ojkmlnfmcwntgnrjjhkya.b32.i2p:0
-hpiibrflqkbrcshfhmrtwfyeb7mds7a3obzwrgarejevddzamvsq.b32.i2p:0
-i4pyhsfdq4247dunel7paatdaq5gusi2hnybp2yf5wxwdnrgxaqq.b32.i2p:0
-iw6tgpmbdykffceku5da6nzf2bmz66fvp5fpcvemfu3df6aq6pga.b32.i2p:0
+[2a05:d018:a75:6c00:c05b:4d0a:3658:1030]:8333 # AS16509
+[2a07:9a07:3::2:1]:8333 # AS202605
+[2a07:d884::130e]:8333 # AS6762
+[2a0a:ef40:e44:9b01:2746:ca1e:6788:351c]:8333 # AS1273
+[2a0b:f4c0:c1:920e:b25a:daff:fe87:77b4]:8333 # AS205100
+[2a10:c941:100:24::2:1001]:8333 # AS141011
+[2a12:8e40:5668:f001::1]:8333 # AS34465
+[2a12:a302:1:a180::b5ca]:8333 # AS23959
+[2c0f:f4a8:b:b108:807d:b2d6:9146:38be]:8333 # AS37254
+[2c0f:f4a8:b:b108:c458:5c61:dcca:cb10]:8333 # AS37254
+iy7go4454pb4p2zmnkwrgsi6v6oqv53zxnmalz6rnfjemxftapfa.b32.i2p:0
+j225nrmndwviihpe7ib6mm5h723cg62wrb7vnwofopv472ue3zwa.b32.i2p:0
+j2m526lqsujvt6b6xl4ipzbjkvkuecrye3vkggwo6jadvzqu7f7q.b32.i2p:0
+j2pyenyhoppsjexenznxvgqrcs4buv4nssctowgpg6czdoo3nyiq.b32.i2p:0
+j3usxovx7ukl645u77jud2mpmrk7ryh5yaxno6rceu77hqlxkuta.b32.i2p:0
+j42dsnjlg4vv33tshgs5jyham6plf3suj2sn2k6ew4tmcz3fpaqq.b32.i2p:0
+j4tjrfxnwcmbhkixmqlnotginhfxgfdvjahr6yn7j7rkbdqngh4a.b32.i2p:0
+jb3iui7grnljdjmsz7qbustrl5vn3ip3upnkzbaegaiklric7cha.b32.i2p:0
+jbmqtghha7hscwbwpi7ps2dnghq2bvxjnfeb5glngnvgjmeackaq.b32.i2p:0
+jd43pc2l73ek6hk2tp6hiyada7ed7vshqo2fvxbga2daylcghfyq.b32.i2p:0
+jd63whebd5yuls7r34mi3lnnuuhqxxr4lns672tzliru4vk7hwrq.b32.i2p:0
+je6ju6ihybxm5wkw5daeqjet74lscvi4ls5wn5wf7kiaczfggafq.b32.i2p:0
+jeidstlwdlt63lju7cnj2mh4fofysjnc2wcvilphynprd7jw64ma.b32.i2p:0
+jeox5nruuoopedsfpuoi6kwewmhbbsnhf7kib2q6oafvchxvmnnq.b32.i2p:0
+jex3ykw2nmw7owhgbtio5flv7us624bxwp46nr7rhmteujrmtvvq.b32.i2p:0
+jfdh65i4nhpg4obnoe4aqi3vzvbi6fyzjj2ee7s3qm2gbcnllkvq.b32.i2p:0
+jh2qxkjqngj2m5tn2ecaidfqac4awgnmkgsajntoqs5qqyjtp5yq.b32.i2p:0
+jh7ev4a5zfzmeyekinhtbqfi6c7xhvc4msdpyi67j3sxl6r44ukq.b32.i2p:0
+jibaw7ynbnxueqsy7k7jyvoj6ldzbuckppfx5wozt7mftihy5vcq.b32.i2p:0
+jicc5kwy4tv4j2nn6gfbis7e6dxy2kdvet3zpxdbyp74h5gpnxuq.b32.i2p:0
+jimdydczt6e2lceezopnl4fgz7q2jeqqhlqaxrgen33ouxk57xiq.b32.i2p:0
+jjangl6h4py2pd2gwamhqlsymyuocmpioneinzf5bb5qvvdjzzqa.b32.i2p:0
+jk56z3febpco6rbkpzzv3jszf4px5uztmoxzkpss7mxnzqlpsdla.b32.i2p:0
jkfuajo4ayvo2rbv5qdj443q6adqmnormbhsf2f7rlp5t24xomda.b32.i2p:0
-jz3s4eurm5vzjresf4mwo7oni4bk36daolwxh4iqtewakylgkxmq.b32.i2p:0
+jkvey2vfdto2ucudi4jlgsbpmlls3uwmlkjonfhk5yminkwzwi2q.b32.i2p:0
+jl4vr5kac7njyltivn7ut5afyq5ipzc5woxl4523emodxixci3zq.b32.i2p:0
+jmebfluhrl6ad5pt4ipevf3g3a4trcu7axalpubpkir6zlwovm5q.b32.i2p:0
+jndr5i4qhxs6aa2bqvufrgttq6enavyghi54dqfuku2qnstdqa5a.b32.i2p:0
+jopiw2tup5h5xh2hwef4oflgskawbpfmswub2iosmqocejijd4fa.b32.i2p:0
+jrert3o2rhbkpquybwg7tq4bdvlxeh6lnlcr5ddexkuguvi2l2pq.b32.i2p:0
+jrobuecgmuuqmpdsbxwbqeldt2735cgcemngoasnbbkdz2ufdlmq.b32.i2p:0
+jrvg22xvbmjyrkqg7mr622zhnda3ijtua65cqngwrven7sf5zd7q.b32.i2p:0
+jsg4dsxvgjcqz3c2qgtwi4ip3l4n4hlxodbvgukwaipycwo26zua.b32.i2p:0
+jt35uwbl5wx7ponyxomksrjjs7zy5yymvtud3nmogt7ci7xxlm2q.b32.i2p:0
+jvaoh33cpczp626ldwr4azh4hb5cjmxlbz3dq3cxisdlzn7z25eq.b32.i2p:0
+jvlj7qyxcmolf76wneyvmdxrpiezsxkiimapwxbdbiw2phvlyjba.b32.i2p:0
+jwqlvqmfvodnrslde2idqt25qxiyvgqdlr2q4uod5s6lkmlempya.b32.i2p:0
+jxjc7oe24vxdepkfvl365qfwrxcad2f3j43fnfuchtvqqkqd2rzq.b32.i2p:0
+k4mch53m72zv7jdda3poa2zn7bi3jacqwfb45peealxbhysdozcq.b32.i2p:0
+k4pjt6m25dcxno3udek6rasooz5ztqnywa3f2owpvcjzvisg7nga.b32.i2p:0
+k5ars7hsrfubadroe5h7oypjnqwi6v2vxxy6rmns7zubf66aivbq.b32.i2p:0
+k6eeshsk4vf34b5gfnraz4p5qb6scv4kw6eiltebel5exw6keppq.b32.i2p:0
+k6gt64xby5igmln5hfcuzspt2tndimzrdvj65yo76h22g5yhlvja.b32.i2p:0
+k7kcnrqe3ybqu2w3fali7zext6na7o5o65rx6f5oqza2lonsry6a.b32.i2p:0
+kbawcieyelwwitrjow537zpmdkncwiq42rhjgayw5o7u562mk23a.b32.i2p:0
+kcqkothplemakipfpeajxmu4xsszpaxpprgtuv5tgfdaqejg2sqq.b32.i2p:0
+kdrcbr6wg2bj6oipsbeqy6bp3v7dqpth6cheviysmvo4bdta7fda.b32.i2p:0
+kehosmgk76fxnjywqjj6nqs4ohg4hsutljdzjo4sswhxlj5l5tca.b32.i2p:0
+khxruoaom7juockko2tbxqo3bnrjmoqjhdoady3yyr4qacz4somq.b32.i2p:0
+kjaa3zlp4sipfxikketgvlx4oxq5ok57ifxenbiewmsrew6lcw7q.b32.i2p:0
+kjvrzgckasb57yqhluvjblx2ngxstumfg6uufz5mc7zyetkjlr7a.b32.i2p:0
+kkihsh2faw2gxil6it4glol4u37ccruuzsusyikquzmkffj3wn6q.b32.i2p:0
+km3b5j6cqrcqewdpuveibptw5gguwktwan36jlow4xykpg2dgr6a.b32.i2p:0
+kppcor54kkge6cgq47nzevlfrhbxingcjfmk2emkrdaejpixkqdq.b32.i2p:0
+kskidltmbigp2etp4pdl67ke2qzjjw66wqairzr4wn2apq4o7bka.b32.i2p:0
+ksxxinje357zctkobwnxsy44ddivq7yp2n3n5gopk4okir2vghaa.b32.i2p:0
+ktua3j43ijxhhhfeljsp32kdiuic5nlnfnkx3ealy7ojva4vwkoq.b32.i2p:0
+kuzu73gzvlnog4cdtdk7edbusxr4pigknvwg2bjo6l46ugsgmrtq.b32.i2p:0
+kw3v6gq5semgt4gg6itum3qtaylanyof7wn6bnbngdeby4xixuoa.b32.i2p:0
+l364nudwoj63fe5nsjmniiun63e3ycdqrjyknbfixxtre5spx7ga.b32.i2p:0
+l3ach5wbdx3n5nq53sv6tagijrbse3nwa2gkqz5oj7aifyaizpcq.b32.i2p:0
+l5fita4r7niir3hxmu7mzcwrigxinkrn4oqeembdkgao7k2yztha.b32.i2p:0
+l5obkk7zzop3nztnt6ijugz4okqsyhhb5o6gkbqottgqzzzcgvla.b32.i2p:0
+lai3534z6zs2tukzixdagrciezum2bkyuask2srxjrn67yu4c57a.b32.i2p:0
+lbif3mgg2b2ir5dkz7u6iatdrui2h2a64vlmffcfgqnpjuvwzaxa.b32.i2p:0
+leu37bptuuu5377mi7cb5t2vsu4hesblyxl5zptnnk4vodhovwea.b32.i2p:0
+lfuvzzzceuik5u5pnd2i67amegel5ua2rrnncxkyyc7bhteq73aa.b32.i2p:0
+lgpojpoix7zd6dhpo5hdrnwm4ueyjvi7tbot4qsqybk3upuocnpa.b32.i2p:0
+lh7qjombcmiekvv6niz5eflr55cnd3oxx7nuus6vmehqfodr67za.b32.i2p:0
+lhupu3owhuc7qwvyfazgkbcmr7sjp5qqxps732vy52v67fsn5guq.b32.i2p:0
+li4vuovafxjrf54kvfg3mjrg2mebs6edpl5yrr2dohddvgmxjyvq.b32.i2p:0
liu75cvktv4icbctg72w7nxbk4eibt7wamizfdii4omz7gcke5vq.b32.i2p:0
-ljsquuu3y4xje6l32p32inn6r2y6ull6oocgup6jtjrohrqxbz6a.b32.i2p:0
+lmlf3yjyg4djrb7wtzmrb4fbkorqba7k4lvk7ax4omay4mbytupa.b32.i2p:0
+lpal67whroip3c2yj4fxbayj46d3tr5osyqog6el5n6ctktdnakq.b32.i2p:0
+lpektonr2uyiohuzi35shtj3oaa77rklmqsivuydxkcxkea2dwuq.b32.i2p:0
+lpffyejskwwap2go7ommmryex2autlkmcnnpk2tm6aitxcalwrha.b32.i2p:0
+lpqkgbek3ci3w4qobpeqepjor3bukz555rzlmghck4o7wwb7ajza.b32.i2p:0
+lprgmkc45te7skx7rffpz72ca5c3zdg3tabiksdboao5w4wceu5a.b32.i2p:0
+lqn32kgic4cincyqlybpwbywcrowcxmscfcm4mqt4fgp24qs3y3q.b32.i2p:0
lrah7acdsgopybg43shadwwiv6igezaw64i6jb5muqdg7dmhj3la.b32.i2p:0
+ls52j74gwtsrqhlgqcai2cjl2rcivfib7jzovc4454h6tq3i6k7q.b32.i2p:0
+ls5otp5mybmxqsaeaid7wlori2ukieehr644adjfwdxux7jxlvga.b32.i2p:0
+lttdnbluvybzbjq52t5vbdkk3pvzc6zyi2oji7yjdpcgtgz732bq.b32.i2p:0
+lunkwblewltvq4spt7j5u2nfpqyndvgepl7edkiru322mmtpy2lq.b32.i2p:0
+lvdbqavgdom5h5denwkmdwslfzxckf6eddwflelbog7tgo2m7usa.b32.i2p:0
+lwjrapkfexjyjqf2rrdr4ghhxmlr3jdygsonetgtheglvmru5x6q.b32.i2p:0
+lyg26sjkcx5ied5a4a7jdxmfeplfcnux3fux5rsxzkm5mgbbsllq.b32.i2p:0
+lyqmygrc6gujxa4xlnwqku3vtfkbrszdiirsagn6xd2yw4kvodrq.b32.i2p:0
lzuu6mjtu7vd55d2biphicihufipoa7vyym6xfnkmmlra3tiziia.b32.i2p:0
+m2k7ajij2wvgfpsbg32zuorbsjt72iye3ozz6dbyxtj57fx7xsqq.b32.i2p:0
+m3hlmj2gz2co5gu4ss3wj4b7ebeg2xbkrr65ogxvhn76uxna5qma.b32.i2p:0
+m4o2kndr75clxemwbq5m6vnok7eiqshf42wjjvag7dtwxtafxhra.b32.i2p:0
m6bpynxkv2ktwxkg6p2gyudjfhdupb6kuzabeqdnckkdkf4kxjla.b32.i2p:0
-m6v454xd6p3bt5swujgmveklsp7lzbkqlqqfc2p36cjlwv5dbucq.b32.i2p:0
-mlgeizrroynuhpxbzeosajt5u4ddcvynxfmcbm6kwjpaufilxigq.b32.i2p:0
-ofubxr2ir7u2guzjwyrvujicivzmvinwa36nuzlrg7tnsmebal7a.b32.i2p:0
-okfxeoh6itu4f5f43dhbzvkqwfrvm5c66lj6lvjj4q2b35i4pk4q.b32.i2p:0
+me6x2p4m6jw3cxi2xl4a37u4orzmv3xdopr5t2vgwjmauiuqrmzq.b32.i2p:0
+mf6tmlegp7uga66cdael5376uaz4qd3wacuh44yvepa3kbu4fk3a.b32.i2p:0
+mhgxec57s6h7eixgemsghlcuhmgh7m7p7phqd5kzmm4wovrp2pqq.b32.i2p:0
+mjpulaafdyuanouslfpjcsvumi4edtckfu3ffn3ipabkxj4sn35q.b32.i2p:0
+mlakhs4ixcqwvk4vo4ce3loa54wmdlfingk73jookrkbra6ppq4q.b32.i2p:0
+mnkqn3r4jmg6vrmlprabenndyft2z2jw6g4nsnolt434coiklmyq.b32.i2p:0
+mnrbc3qi4zuk2tzghmy55kplawncih6jkmt75qczfu27enu3gcea.b32.i2p:0
+mnrrefebq3yxr2avprp3ay7w42sx27ijv6stjljzpwohnfnkg26a.b32.i2p:0
+mo27t6wym666b3wfauhndqocbetdsssxksep6x4dcpuh5dxe76oa.b32.i2p:0
+mo6mp2tymma5l2swob6kqzzb25ccmgccfj5pic6omjkktv4wve2q.b32.i2p:0
+mpi7bivbr2pywsgasslw5we766m757os2667h3hqnhcftaszdv3a.b32.i2p:0
+mpqb3jdmdibarrflyiik5wj3ekitxpe2oqieztlax3uomxspgsvq.b32.i2p:0
+mqocuhx3qwcwfuuin42yuhtqgm76drlmfvzikf7urot75qw3ykpa.b32.i2p:0
+mrbhw6ow77bjqmb67rurbkcl4xs2ocj4pti6hnz4wcsg6bduwtya.b32.i2p:0
+mrypjr2fagjhg6z4ixr73f5npkeyoxsjamcdv5uc6oj5oi2ylsvq.b32.i2p:0
+msjl4a7mdp7x2bcllmbxurhfmtxvolykonz45psmh7j6pptfyy5a.b32.i2p:0
+mtlznxqya5nbuyorybzul4cpdlrnvlrhalx2eogwjce5j32js5wa.b32.i2p:0
+mv7b44duaxqpzbdztnrdvnj6ypsp7yhs4z3dc2q64jov6pritmja.b32.i2p:0
+mvs5a3s6rgfbvvgq44wzyd57vf5pr3jcthc5qdo75xgj4slsm7tq.b32.i2p:0
+mwcqoe2lu7u6ogwo77kr5sr4wx6pxnotkdeck3yyjfh4uklytj2a.b32.i2p:0
+mwevh5r5dkzddlo2ol6bojpdds3kno4xqoy6p6ulid3paamgrtla.b32.i2p:0
+mwyjzdrgtypbwjyulw4ifetejz6xusqstvzylztsphpg2r2zf7ua.b32.i2p:0
+my66tuvzfyy6kkbdeqvgfpk3xuoxerucxt73tw6wxv3ian2p2snq.b32.i2p:0
+n3f4ngbs2igvp3j27vsi7thguqxoyvbfenaqhgypuqdz5iovek2a.b32.i2p:0
+n3fa2yuf3i3opdktiwyxzhbpudcut73valxdrlre2xs2ooepddaa.b32.i2p:0
+n47e4gkf5xujcamnsarfuy7435hfsgs4zhndcxaw2evafn6r2rma.b32.i2p:0
+n4n7bivjb2mffgll2ulpwyb4m2oomv5roxtdj6bmlb4cgpf3wdja.b32.i2p:0
+n4zwusew5coibur4p2g436ktc3cyogz3sklztu6ruulag3je6ita.b32.i2p:0
+n7ykk3cxcqzcoeipo7ghzb62ko4d6bxzfgenzxistvg6fuclebva.b32.i2p:0
+nazasriqoa6qoxdlgzjwsggubxl6i4nge5q7om7nijaqi24ulgua.b32.i2p:0
+ncdjjthck6v6phz4laddyc7a7czoujys55melfcoptvl2h4izqlq.b32.i2p:0
+ndtoi53fz7e6ml6v6jn33675nwciw7mu5msn7afzbhebprusqg7a.b32.i2p:0
+ndunnsjyp6l4w3jebow4zgsfrdsy2lrapjgslb3tv7dg6oypfbwq.b32.i2p:0
+ndx23xqvt4qezezih4wlj7mqtwc4nzbvmgseq6fc6e2ddywrmkwq.b32.i2p:0
+nejmippeopyo75wd3gjrhca3fr5mo2g37owzwdezxmg7uhx6ygxa.b32.i2p:0
+nfsi3fenzrzoccj7bpzuvjbxnij7dmzuprg7ia4geuortoquja7q.b32.i2p:0
+ngn5elnvbm234yyun5kbjyr76oy5nhrvyckn33cqcbx25hw4lfoq.b32.i2p:0
+nhpbv2ravt6t5fhxyvuhrxyma37wph6dzuzpddlw3uoivzl6tx4a.b32.i2p:0
+ni4ns3ou7v6zh5qrawvkwnmshnrzcyc5zojkw647rrniplmurrba.b32.i2p:0
+nigrfbou3zt6wxegn5im4cyminjcjmbsqror7ntcr5i7yv6chwvq.b32.i2p:0
+nij7pzb6mhrra5glb3dyghjt55sngwrikzdlagmpsf7jn2onvoaa.b32.i2p:0
+nisd4was4gm3pkvuwjh3sbaoo35jtxop6y2d7ug4iol4cffkrk5q.b32.i2p:0
+niyz7v5fdhqqtlr4y3tcgdoeu3myntub4trzvgixlgjbmowccgja.b32.i2p:0
+nloq52novup3cawccvaakmbudooatwkw7dqltnr6q3j4qy7r6oia.b32.i2p:0
+nn7p4y7pun3m3txaqbkeptkxykzwrf75ru2zimadnewj7g3r4una.b32.i2p:0
+noj7le7kkj54umo6mdftagvvk327cuir7q75bnvuphrxa7kjujna.b32.i2p:0
+npcmehkhh4z2wtk3f5426izrytvqvyf6aa7hyx6hf6jdbxveqima.b32.i2p:0
+nrrg4p7tztllzthlkqzomqi3dejfcak7t63n7zzuomt5atzz5m4a.b32.i2p:0
+nt3ysas4wpjgkft5pohrfstm2vgj7t2vx34u32voy7rqon7dlbga.b32.i2p:0
+nu2ao72zway2ponkhrf322wyfrrn4mdmyp7n5q5xzmjhcge5odma.b32.i2p:0
+nufliiw3uav3tzdalit224yhbfpcjtgfrm5ic7ob6l3mmsay6cpa.b32.i2p:0
+numilh7hhhf6inzkzway3hzif4kiroqstxqbz7hzvoy2ctgpaqda.b32.i2p:0
+nuwphtuudfrswids22qjq63zgxh5wu7erafl36jyniuxhz75ikyq.b32.i2p:0
+nvmuuajhaw74g565l3a7dpezs4rkzm22ub5jhh6mdvzu43j4a6dq.b32.i2p:0
+nz4lq7pmswngaevv2uqyainqzutfxlkavxgde2w2slo2p6e2kcfq.b32.i2p:0
+o5ijpzor3en5xnndm3ntti7o4fxvv24t3veh4g7mahk7ogesb67a.b32.i2p:0
+o6b747qkpgu6gvsem7leylvmxsaaqby67pu55fmqn52dgazuvbxa.b32.i2p:0
+o6t4fr5ayfadzieutstgwcllvwxeuzjlxmzsmpj3hpkvefhzfaea.b32.i2p:0
+o6vbupdnpd5bwvcx7ivaecgyo7x5vdu5em4va6cmx5iwcf5tyaca.b32.i2p:0
+oaeqbkgpek4qnm3nly76x2tfrad2tun2xefliez7a3uxddeq4i4a.b32.i2p:0
+obf5kfk5n4nnsw7ez6ls6chqu4lz4wlck7utwvmjnlin4nzfnspq.b32.i2p:0
+oeydvkjoeqy3473wxkkbmoc6zz5m6zcmf6ov2hfkci54efsityua.b32.i2p:0
+of2gy2vblht57tn6yfczslnmp2xybdiazzta43y24w76tl6tu2xa.b32.i2p:0
+oggn6qbpmbag224gumagzgno53mgozb65tpzt5lezjbfbbiqky4q.b32.i2p:0
+ognn4mwwtmtjbrnq2kur7spcfohivxlrvz3sfamt3t46pk2e2ibq.b32.i2p:0
+ogqdcq2igslh3n5jn3utz2vpevttul366bt2246vilfnowuyvova.b32.i2p:0
+okjamsyd4wutvhfhsffejwk6ioru4mmvwagfssoy5hcocg2gj76a.b32.i2p:0
+om32whhwvcsbrf4g6uh5hupsl67oapccourkxyr7uf5zwaqxtxbq.b32.i2p:0
+ommky7qetuh45h4lk3raili27fnbhsgxv3zucinoaymnymo5735q.b32.i2p:0
+omngcjfwtiyqwbfqqggzbkttqgm3blywu43kpto2py2e4gp7fhra.b32.i2p:0
+opnpvz7mzfw6nypgmnn5zgtlzx7xuc4w7vat5bsr4mdtp77kz7eq.b32.i2p:0
+oqrl573nw6my2o5mup6uq6pm5immw3gnviahig5cceges4wfnyhq.b32.i2p:0
+orvshryqq24l24e4dvockx2ekj4hu42otqxsvyvy7tm7hhdjsz7a.b32.i2p:0
+oukeldqgovavh3npgb2by7w6hug575uae24z6uqfdl6flh7ma6rq.b32.i2p:0
+ovnk3wfbrkvvute6vkn5glhdtlxr6nyvebiflvr5l6ws6sorpa2q.b32.i2p:0
+owexluejb3eszx4p3b6zuxyggsxxtkxfgxoylkagfecs3bgfnpja.b32.i2p:0
oz2ia3flpm3du2tyusulrn7h7e2eo3juzkrmn34bvnrlcrugv7ia.b32.i2p:0
-qd6jlsevsexww3wefpqs7iglxb3f63y4e6ydulfzrvwflpicmdqa.b32.i2p:0
+oznpphdisfvlcjgkvny6ma62wy637nh4vtpxww47ifpmlqkjv3ba.b32.i2p:0
+p3au2w5jnkqugxnkukj4rusvynvz3oxawdf4ajzeyxvfvyzhmetq.b32.i2p:0
+p4tsqwvdpaitvlgaujfr2m2qbr36qiwusas5zkiut7w2wjcp3sqa.b32.i2p:0
+p6o3tzllswm2j4wah35niry4tcdu6lq5b67ehevcx45sae7pb6da.b32.i2p:0
+p7ifeij3vhds3diihx5qimucyzgck5omfkqxc4pkbbjtfu4hp6wq.b32.i2p:0
+pbag76x5yyo5d3wypvtohxmgbtdrjjb35ljnq4w5fpoguyt5mj6q.b32.i2p:0
+pbftrtdthbj5qcecraden3hdvwomqrgseec6ib5h24n2zcivdqaa.b32.i2p:0
+pc4d5v74tr4vz54pbr57ejga765ep6vwk5kox55gfobi5572apta.b32.i2p:0
+pcc6cnry4maul7zlbd32khalaavkcbw5hdjuk4zjwposaorjicca.b32.i2p:0
+pcdlqw2awppohbiued4rffgs6n3lv3thhon3r67jmx2652qx2khq.b32.i2p:0
+peteksofgwgndsdh6ovh2ydkrgpyqgttit4ususs4bzksvdqkbea.b32.i2p:0
+phendyytrqdr2vfsw3kil6yui5vb2p4v5xuddezg57wsdw5uyquq.b32.i2p:0
+plhoz53xhplmyuejnsg5bkfe24ow3pbldysoovuupu6qwb3nttca.b32.i2p:0
+pm4nukrzndd2lvd3shivpjrcbjlontmxhag2xzdf572snwbr3p6a.b32.i2p:0
+pn5cx32ljrvzj6x7hpgyff3rlftextqpp4zn3nkfufrrpnpuimzq.b32.i2p:0
+pnhspu3rloczdbzsysa2iftsgoiy3zgcd22jodmk7zdjanhiemla.b32.i2p:0
+ppe2jfsb2xrmgwugbq7agy44ucb6yq4qbufaf2sh76b4kwpa4jcq.b32.i2p:0
+ppez53yrs6lanyvyxuxblqxiuvhnqvvtafmwaid2kgp2dx2v5iaq.b32.i2p:0
+pqnqwxl7jsrok7vgpgcvlxwlkg6yckx33n3g4xf5lvuntwn63b6a.b32.i2p:0
+pri376r6uuwgnbnevki7c363h4ryfwjza7pcbfswqqxk6hnrkhja.b32.i2p:0
+pscw5yzaj5js2fn7gzrzoj6teonlsohlbnvdco65ubdefpnpwhpa.b32.i2p:0
+pt3mqmvkv7aleja7vattlysu6x7gjnbwqvwtu4skzabvkjztfi2q.b32.i2p:0
+pu6e2b5bz75qnmp2rox252aksllnitv2grnn7qfyzjkfio7w5h6a.b32.i2p:0
+punslpht6pysnlteht24rgvrkmzdd437lnpflojwakl5dy6mbema.b32.i2p:0
+pv6g7uin653rerdiivdgtoirjvokjowi4b3fwatszdlteyos3i2a.b32.i2p:0
+pvqyvn2lpvoeyhgcgunoqtetkrkp76iegyoii2af4crnlto6gb2q.b32.i2p:0
+pw42656k2vbwxmvrc2qbsz3jslvcxahln7rehsbia5jdio2knh3q.b32.i2p:0
+pxbyhv62tcdqqpl6pbp3og7ajzzcnbximv5kyt3hid3djd3uwkdq.b32.i2p:0
+pyf2csixjugwp6ad3bkry2ulkzj7inc747dsmpk7iebuidk4l3ra.b32.i2p:0
+pyole4gslrmenfcmd4ilqyzvsuyrjyffjbw7angentqjkkljitqq.b32.i2p:0
+q3ueujd332k5qjxdqkjtjlgkm3ktvdy7ats4c2ogcvokog4wm3vq.b32.i2p:0
+q4o7bf37e6afx7evwdyovsqptjwo6td3c6qtjh4rtdngp3trwi3a.b32.i2p:0
+q55g5g6s47hi7pcuomug3vrcd67vji7us2gqmfe7qn2nkq5vz52a.b32.i2p:0
+q6lzsezu4idxpdwro4x6svwz7j6h6gso6enidcxv7jhc2gbepuzq.b32.i2p:0
+q6o3eqnyg44uzjzqeudsankgdouylshkhdhl7b4bqxkbmdnm4iaq.b32.i2p:0
+q76g4lkosb2sxenh47eutqgwwzjyph52rirc635wkwnxsejrzdda.b32.i2p:0
+q7ntdwy6xueyvghbjamfrh62aqtuu3ikwg622em44pa3czomrdjq.b32.i2p:0
+qa77lz7dl64qwtj4fxxlz6otkuvv42dciggnmx62eobs2xqi3vlq.b32.i2p:0
+qaqvxmyvq2m4wombmtaz3our3qmp7eet3qle5flnrs3a5wgfhxba.b32.i2p:0
+qawed5ou5vb42ugi42goxr2s6cqzpyh3s5atkhvfvyhyc6anxyaa.b32.i2p:0
qddg7myylinn4tw6kdjmmp6fsyetkosnrbp2gsjx77tmkqyqv6ua.b32.i2p:0
-rizfinyses2r3or4iubs5wx66gdy6mpf73w7uobfacm2l5cral3q.b32.i2p:0
-s5hhjtmlg53bko3nwwskas7xgsmeqzy6thtsj5aa64djyrljgqaq.b32.i2p:0
-sedndhv5vpcgdmykyi5st4yqhdxl3hpdtglta4do435wupahhx6q.b32.i2p:0
-tsl4dlpu2id252b6crbdnblruct664se6f2iw35fuqwa3te7wcoq.b32.i2p:0
-tugq6wa2ls2bv27pr2iy3da3k5ow3fzefbcvjcr22uc7w5vmevja.b32.i2p:0
-usztavbib756k5vqggzgkyswoj6mttihjvp3c2pa642t2mb4pvsa.b32.i2p:0
+qelsaseevnmz2unpovh4nbpjpshjg45iudiaf5zbngealwwuxe2a.b32.i2p:0
+qfbughfr5hhgoomasyviwk3zin24uerpl6urz5smzxc2div5ixxa.b32.i2p:0
+qfl3i45ipgugo7ueswy3ynnbaet77xawiplvmm3kp4fj72qvzc6a.b32.i2p:0
+qhuk5zq5v7h5p7o62gsxgtqqo7va4i77o5vei6wttxqcgaw47h7a.b32.i2p:0
+qivuqkrr3pv3rul4wgx4o4zon5wegidt5auylv3bhebfuj6oqauq.b32.i2p:0
+qjdftbhcaghdslzxjqx3nmem4z5p5jt7e7ou5bdz5llnqlxshe5a.b32.i2p:0
+qk3iq3wr6emttdilvdqbv6vnqjshuzz6mylwyfo3z6vpjywvnfca.b32.i2p:0
+qkohzoxigef43ro7mf2bd76eyneuuj2vfyremufvufssksbvj3jq.b32.i2p:0
+qksthizqtfdjjxcrahqxkl3bev75k24blagrkoszxen45zelijpa.b32.i2p:0
+qlhklv3q3rrszbrkxw755lpdburxwcj5dkxwicas46flztlkdcja.b32.i2p:0
+qmtg5ukzxemsktsxw2brwmohehyehwlleky3kuzeqzy4ledcou3a.b32.i2p:0
+qndgqhj3cpbxrktu6r7ysaooccqzvselvn2tphu3plx2z5ouocgq.b32.i2p:0
+qnqojlthym7z4gwizcblhpd2thy7v4a6ifme57bzyl3nxzkj6ica.b32.i2p:0
+qorzdjceszf432obxa73tnwhqb7ltxrxlfkkqmw2flmfjhoyv36a.b32.i2p:0
+qp5ppgozzbkuingg22zgamf4ozpe2n5hjlu4i25r6pjqw2ngrhoq.b32.i2p:0
+qpddavnflr5tdmeypeu5lrjjwsgtdhz7hw5emxiyjkcp7m7xysca.b32.i2p:0
+qpo3u565rmgeioruszadbc4vmpgjyoh7qorv4lyefl7geewyyz7a.b32.i2p:0
+qqiakw24obfwz375gfb6muzaz7tr6ani3od6leoox7jwzrizyxkq.b32.i2p:0
+qqmxvujwi4ktgj2cuqmw4kiujkf7ukrkoe5ryy4bjb7tyleplsja.b32.i2p:0
+qrpz67rcwrbpcockid5ml24dtdhhhekty3xd66ekkyatpfjd2wka.b32.i2p:0
+quzkrgzb5pmn4465647ke5lsfbseqnorr6ljvfsxcagj7rzl7hcq.b32.i2p:0
+qv5e4jlcmmkdlmh5spkvv2wgj343vm4yoty2hofuzi4lornn3hzq.b32.i2p:0
+qwhvlprhk3ntswr5xntnc2hhgmvd3bbgzgkbombiibhrsj7k6gyq.b32.i2p:0
+qykavpjbecssape77mrxjxwxces2gbjd6gzewd6zys32uhmnnw3a.b32.i2p:0
+qyqwn5xs24h65rldrle5msyarmqof3lb33uz7sutauwdg5qiuhoq.b32.i2p:0
+r2p5kqr7xjo4ncz7l6ekdx2ge6su2j22j2tdsoxu4jw3u67z7poa.b32.i2p:0
+r4ukdj7c2k557k7qd6siauhhqucshwy2rrkm66twzyh4jiucimaq.b32.i2p:0
+r5d5jgscvs6ix5v646ohwa64vutu7umfeknrc2hrezdjtlr4lm6a.b32.i2p:0
+r6d4moarp22wnnsnmsxqt3s32gzyscaccackcazvimrep7sa26ma.b32.i2p:0
+r6hd3knqi2p6kaw7hybrcf2q5lcarulcczs3sgcuz4yc2saj3gya.b32.i2p:0
+r7bug6wbhevqqlbavouj3ggpa7e57sbd3oivkzqeyagrtxshmjpa.b32.i2p:0
+ra7ztq7oq7jcozpui7c4zv76gh7rjwhq5fkpxp7dvw7ritick66q.b32.i2p:0
+rb7tyjd6gi7evmt5mzvtboramqip43sh72zjxnwhj5k72zfi3g6a.b32.i2p:0
+rb7x26lmepfbcd7wtxu42pf4tdxbe5p5zsf3cwuukd4fs4zhxtba.b32.i2p:0
+rd2cw3iukuth2lwe44q7fipawrne2io6y3fyyv5xew6vd3hos2qa.b32.i2p:0
+refo4v727jmff6ylrpbkvd5emlfr2hamaeh7zho6oval5dmnwlta.b32.i2p:0
+refrtydbdslzcgcsmmph3435qigyajh4q2nvl756f5yojouln4yq.b32.i2p:0
+rfgsjhyvqbunef5b5r2emjuoxx2i7rcsl7gathy2n4gwjyyat6bq.b32.i2p:0
+rg677vpfzyhsckzzcvoyvqdbwtdkqig7lxv4unmxcz63vtr6tgza.b32.i2p:0
+rgbq36syjadm2ex2gftc6xztivckrqzcjszla3jacwfo5hqutzqa.b32.i2p:0
+rizuiypjfhukt3bqnetppoauovuaqq5e6jzgd7tgy24zrwa2ydxq.b32.i2p:0
+rkhb3463btvfozwta37itlkt37iyncpkzak2xhoe4kg7tqafqria.b32.i2p:0
+rl4b3r5h5xodo7kiw4nykd4rhoc4j37kxizzyb6ukgcomyc2qrya.b32.i2p:0
+rnsjgirap5lfhxpb2xczuawgoztb4ptgdwt5rcb2bz72vhtai2jq.b32.i2p:0
+rrm2pems425buhonptp7lbtbprmwwjhbftey4ujvk25nclx7rerq.b32.i2p:0
+rvjzxak3jvwwti7klfb64wrsmlfcs6ceiqhzbbmjynokn5tz3egq.b32.i2p:0
+rwgf2wj2x66xtnjx3dggxhkuy6gvihvur42tbkoej6bd7iukoqiq.b32.i2p:0
+rxatc4b7obgosvznpqrmyrl6ty2yixhi7rpbh45sopqwzglyimga.b32.i2p:0
+ry3iuaabf5ek73otfvchwrqryez3nsgq57bpmzkyzumqhfbhgtaq.b32.i2p:0
+rypsyqod2yq3zagcvvc2643vydtv4zm2ew5r3w5kjzyq2snvzv2a.b32.i2p:0
+s35hlnmumkgdsvj2gepnwro4wo2h7ts7ddjhhihqggywn7qcym2a.b32.i2p:0
+s3rbe5n7lyy6smerpkgr4ictzbvkciu7gxyj6zqw3xyw62rmivha.b32.i2p:0
+s43w4tsmzmddvu2cxugh2lx4o5mup3rkvjhm455u2qqpg4bqlhyq.b32.i2p:0
+s4qlly4iwzevejk4ex5zfqhb4t666o73mvdmy4gpu47tpb775nja.b32.i2p:0
+s5ls42vzfaqzgrjr6cvgkmgifei2rtvj7uzaljkpsmt62jwtmvxq.b32.i2p:0
+s6umfzwe27x7az2yjsgqftjzawoj5lrcrgxldkfwfq2qwobml2ma.b32.i2p:0
+s6vsdby2liaahn2fh7qvrehqfus7gaz3p3u3rpjtfjhm4ahvz46q.b32.i2p:0
+sa3k2xipbuwm62bb5n2mwaqyyjcvxzb53kmzinoojgnjpnqurzeq.b32.i2p:0
+sadnlzguaa4k6kvpiky27izp36er3i5h74l452povbnajqullpca.b32.i2p:0
+saj5uchj7dzmxjv3kdzalgtbqzw6wu4wzxxdiobc23m452ehk3zq.b32.i2p:0
+sbalp2doxyedtr52kj57va2rmbi5npspv4drk4vxnujag72gtpiq.b32.i2p:0
+sdxfzbgwxpf6hbik7k4bqm63wm4xld7qgo3hjlhknnehzxyyeu5a.b32.i2p:0
+sh5hww42vwlsl57cdropaeqmmwozinnr2tg6wq4prg5wrkusvxja.b32.i2p:0
+shpd3cifcjoebw6pskj4pfmrm7lwecrygjnje55heorhsxm2lnrq.b32.i2p:0
+si5x3fon3ew644friidc5o3syrf5v6kk4pxxjvhibev3odxk7nyq.b32.i2p:0
+sikkmrxv6wat265rpay2tk7jywyvlzkekpolmwyp2el5g7iihsvq.b32.i2p:0
+sjpqyf3rq7ojcalldlybvyyh5lqiq5j3ade5w6txe3473ybhk3sa.b32.i2p:0
+sk7aivked563g6g2ri2saggni7jqzxmucuqa6xkudcgjvpbjsyda.b32.i2p:0
+slbbsiq2pmouqht3hznafnowq7sxzlidmwghfch7iiq64rzdhwra.b32.i2p:0
+sle3cbbdom6rknc3drqtawctpy635ica5d5gerjjdahfymkok4ma.b32.i2p:0
+slnmute5o6h23ldim34wro4zh4qa2pchnskmdpek2nzc7u5oz7jq.b32.i2p:0
+snfinsblh4j4wsv2n5kmkfxbvqzcei2ryfyu4heqy6u73mosep6q.b32.i2p:0
+snsw3ewf7wjtwspiuj33h3vtxnybllurzcwm7u62iutf5phoitkq.b32.i2p:0
+sooo7ajo74ajo6m2yomcc6jcofdgkdoyjcbrpl3nyvvusr6fw7ta.b32.i2p:0
+sorobw22rerrhpx5t67joyqai3ou6xsvqxb7wdomtnwnqztm4sga.b32.i2p:0
+sotpvcqqzzmty6llimwlvknqsdcypn4wsnwk677kepzmy76w2gqa.b32.i2p:0
+spbb34lslk2tldwzr4ydi2culk7sxgl3imb2gg746xbxqqcj7vzq.b32.i2p:0
+spuaa2y6qsaywypklz7itcb5klesogef2x66m4flws2r574qjc5a.b32.i2p:0
+sqjjqyrhh45jpgfp66idiirgh5ck7f4s76ee2l5bli4obsotu7zq.b32.i2p:0
+sqjorsqambyienumg5qpw3foftkp44vpsd4lwklgbl4lag4mm6gq.b32.i2p:0
+sqr66feh2g3f6bknt2tnltmnhqdkzoq3jhdaatfusshrv6v2zhma.b32.i2p:0
+stltasmf4b54srrjb3mf7hjtjvmvvms26btxakccdtllgrm2qzgq.b32.i2p:0
+su7d4biurihkyr3qeea7makkxzikxr5zi4znvryh3bjespppfhxq.b32.i2p:0
+swmtaospvaup7me3dvzlw5xoeohhj4zn5q6agivif7kxtseweriq.b32.i2p:0
+syhxehvl6rublw6k5ysmzcsqrzdsnd7eqrbwalfkvhgfccpu2osq.b32.i2p:0
+sykjw3jnb7n6bo574wnpiaxhp2nm4gc6hc4jh4v6trsbpboysooa.b32.i2p:0
+syqxyl67b4hdo5u3jtkkzsabccvtjaerpushov7nrc2f42x67fja.b32.i2p:0
+t2e45js4dn4cfsyyevm26z5ltvmu6lftxziji4fm3v4v2t3ykaoa.b32.i2p:0
+t32qcc2tbjgqxrydr2txgm4ahhhae3zkkojmguehw5gsbtrdvxsa.b32.i2p:0
+t43qqzux7ik7kki2rxtillcgbxrznuhjac7wtqh52sqovk5ay3xq.b32.i2p:0
+t4notlid4bejwz2tzucpvednkeuskenpnu5sqcbdhh3lqouigqxa.b32.i2p:0
+t5cd7q36no6doxduuvk5psdx47zl7ousnckjgw7c6zr3o3ke7ffa.b32.i2p:0
+t7gbmefspnynaezmvx445fjapp24pjjf7wx3evpwlmolzyu3wi5q.b32.i2p:0
+tanmhvkoyd35kf6a2nhj5rmbwpt3shc6thypsle45my565womjya.b32.i2p:0
+tbqehmm3nuuf2spwsjobrc4hg6uxji4mdelivhywz4b7f5lv6rka.b32.i2p:0
+tbrjczwl76v7ob6hon36z6f35otpv5g467q33pgzyyakp525wwfq.b32.i2p:0
+tcx3ftsdl36ukysuuewydapdzuu4alewyg22squei2wda4a74tba.b32.i2p:0
+tetoqjagsf7fpejajiwm4rosqscy5huqbz5hcqgfuha5tdfnlrnq.b32.i2p:0
+tf4tozh5unsgyzpdsmrdcpbgekw2agu7tp5jvyclzcs5kjudwwpa.b32.i2p:0
+tfuvti7yonn5pjptzzvpshh23x4rqjvm2usolrbnlu42laj4mhyq.b32.i2p:0
+tg6goh3flzmcer5voft2nf3tudm7ikyez334zry66vqxmc4ieixa.b32.i2p:0
+tgt7rdhywtlwob47flp6ccq7prrbh4ipnwm3xszuykq7be2pksyq.b32.i2p:0
+th3dj5sqw75lga3tnffbsywajxafv7cvlb7sed6w7q3w3sxuqo6a.b32.i2p:0
+tj2upmck47iktfh4vncmyajnkbatqglqzy4coqef7wioor4hbsjq.b32.i2p:0
+tk63xbzug7def6esivofwq2h2c53ar3ot7hsezdq3amxqqaoyr5a.b32.i2p:0
+tkzuysa4lkad53cywbt6sgpcndvvvdkjeatpkwyfweorx7rfe3ba.b32.i2p:0
+tl3xkknuukvyinyhvt7saz3tvz24ptgyqtzy3igygyfapcf2o3lq.b32.i2p:0
+tl66bkfoqu6eameaqtlwrvfttyc6xj3s57za3hd7omnfnjg3i44a.b32.i2p:0
+tlfttkbshrcixu6i6syntl5xjsoh6mtgfpix54knahyeuhlju4ga.b32.i2p:0
+tmmjmcrwegjke5fzv2hha2wkis7l6xdaa7fkq24ge5rbvqpwxzpa.b32.i2p:0
+tobdew6554c76jhrulcd2ssgvef7dryini2xjxem2zushe37ycua.b32.i2p:0
+trucvlawpufrszky4zzhhxtddnhio4mnqawzc47n7kik6i444m2q.b32.i2p:0
+tsfr6zvcgsmw2ekaxqqtkdrnbib5uio7lgmrtmscrvwe2d46g7jq.b32.i2p:0
+tsrlbxayhihugr723z6rkyafglnhcyzi2zhojzsyfdjsqkkd53bq.b32.i2p:0
+tv3x4kddbu753tnlghgh3txogp26tlydt47rl5scx7eoxgnocf4a.b32.i2p:0
+tvbutrv73xhwqbtosmbp3cesdyc5bbtslay4gjsf7rzdx4ztgzaq.b32.i2p:0
+tvotv5p3emxxnti2bnvucbfy4to7gxptwvh4qznuhy62hghnju4a.b32.i2p:0
+txpr56jvbf3lmqgaozqdqzgckfpugzyd4cwplkjootvf3hk42ibq.b32.i2p:0
+tyfkhz6ggpi2rykez3v3j5f3evnjxfoau7ve7m2heaukrcqiui4a.b32.i2p:0
+tyvsuqy36cx2yvf7jhnkd5ojc52g6vxl2rw5qshqwpk63ptovdda.b32.i2p:0
+tz5txdipkxcnydzcsuqw47qxdvpob644u3cttlbrbfg3zp75vl7q.b32.i2p:0
+tzudbbctweb7rpnf2vswuw26j63ysqztsbt7lfpfj6xautueiklq.b32.i2p:0
+u2tnrysboqqwjn73awg4hfxtfjgbqab6vrdgyu43s672jdcanhca.b32.i2p:0
+u5ixxcd6slvzxouj532njusx7ec4wemrfwmg6gwltlnkruubi63q.b32.i2p:0
+u635477uxqs7z4uvwx224u6ojn3c3ewcb66f3j7qlbzqyrrevxja.b32.i2p:0
+u6wrw47yfjdzk6a7nc6c6scvfokwuqmvuhxehqvymrv7owiajxia.b32.i2p:0
+u7uklnwthbrynr3z2gc3yxfmi5yoemsugjbb4nm44x26f25vxp5q.b32.i2p:0
+u7ygn3heosxu6l2die34y7wteexfp6h2w5j3nhr424yoblysigyq.b32.i2p:0
+uags6hm646f2qsyqfhzjt2xlnjqbiopiodghywosdgz7bwtbggta.b32.i2p:0
+uc52rzz4xu5ikx6hl6r6sqxfmiyyxsffpcu5frrtepczidwjwuha.b32.i2p:0
+udfxh2r5yfu5z7ynzacur7p3g7ug35kfa33ghes2bazpdivxlhsq.b32.i2p:0
+udkwqdo5odg5npn52rueipghn5omhvojthzdmvcvuomgzglum7fa.b32.i2p:0
+udzbx5jyvrp4g3iujlca7jnlaaaa5m3e4jv4sbr7tvp6k6cdjc5q.b32.i2p:0
+ufgoaa6g746zzpphuvxuomuizkyfpz45chqta7skrywqq6cjbqna.b32.i2p:0
+ufittrlr4eautphuqzuotc7b3xx27n4xgy5afm4foc6nsv56q7ka.b32.i2p:0
+ugw5zbhs2pvsgxieklmc6z4z6d5cvyux4pctpf2udhjgxvajot2a.b32.i2p:0
+ujg6b4cyxhi5pf4puwvwupur3iddm23uibapigpwl4bstvlt4cva.b32.i2p:0
+undzufsjeb4qlf7y5llh56tji6zlhtshlsyht4yjdsa2k4ayx7vq.b32.i2p:0
+uobwophnzqq4yhpp54aisud5ojgrxq6pasmq4aq6qw7dhgjcoqpa.b32.i2p:0
+uodycjdscpurlego2nrs7ptoze26p6236t2r2tax5ubdgi6duqaa.b32.i2p:0
+uohuxnjd27cftarbf6kh4czmotwvstpon2sgs2vpffqkgmg7guxa.b32.i2p:0
+up2kudwqomqrwvfognnhz2mjwqvkgpknfyscp4ue5ioev3q4jd5q.b32.i2p:0
+upme7c64dwjgbt7w72yf5ydl3dyp25dtenrkq6z3aw6hbircqzsa.b32.i2p:0
+uppxodf6bz3qibvpzzvtedl5lk3h7fslrwmed2cmqvdpgtvqkv2q.b32.i2p:0
+urqlr3cei7pp2cruga4txxmmvel3bh7nsbqzqzpe7omvmbm4v75a.b32.i2p:0
+usgqijrwhtwgoekjcr26yqcgpncwpsescrr3eek35e3rhkrtptoa.b32.i2p:0
+uu47uxdqqtv2pqorbaxnhhfmcsxmknvpreambqqkosr45b44h5ia.b32.i2p:0
+uv44mjoqrj3m3gzz5wxlnszt5pvgk3iqlc3pmqfe6un6gxays2cq.b32.i2p:0
+uyshm6nokdjyq3l43224at2rigpa4zmiyybuufyq22t4l65ialmq.b32.i2p:0
+uysvdsh2bzicmdqqdl7ezuftxcywzapohbzl5ap5hyiinki354mq.b32.i2p:0
+uyy4dbfyx2i2x3goobc6uxj4nb7ktzsu72zlksypjfisgka3xnta.b32.i2p:0
+uzgfmsjcbjxitt6bed3p3gpdzviyop2rz3cxqyu64ec3z2r5imqa.b32.i2p:0
+vbzp4sjkgqwymn2z4ikbae7rv3clbo7vv4mwv4ft7tu7ubrmbeha.b32.i2p:0
+vcksnyuyw3i6hfviob5yzoynq7okxi677bw7224273fjhsk2kgra.b32.i2p:0
+vdpfoahxse7cjciw5l7ffbwzc6e4xdlf5ulvrk34mzm2gy4mhlwq.b32.i2p:0
+vdv2aitgqica4taqcmjexw5xfbrfbhvf5kuxwvfjf3yiki5a5cjq.b32.i2p:0
+vet6qwwa74jrqrjzcm7ylfprzwpnt3hlzjvkbnaoiv4o2zzkr3sq.b32.i2p:0
+veucihmd74nnumiunvruyjs6kpjs5sqw5dprldlzcf7i3h4igkda.b32.i2p:0
+vewdrismzwnlxlvni7slpq722wlwfami2elghudm2ofcjhpjcs6a.b32.i2p:0
+vf3l3f5unlwrfmr3fiphpomgslxgm6m4chg72itf45yfu3brmy2q.b32.i2p:0
+vfpzasrsrqh3llkudmas5fymwn2ohswqi3vakclgm6fn4nb6s5xq.b32.i2p:0
+vgkou4ysuxvhlxrwf5n2ihn4ffyvvedluun47l6dobi5ycziy3nq.b32.i2p:0
vgu6llqbyjphml25umd5ztvyxrxuplz2g74fzbx75g3kkaetoyiq.b32.i2p:0
-wjrul5jwwb4vqdmkkrjbmly7osj6amecdpsac5xvaoqrti4nb3ha.b32.i2p:0
+vj54d2pkdeqvcuj5ykeggr6jnhhnmq5q6qe7nttvb6yjetweadma.b32.i2p:0
+vlwovj6fxzvtsypnmslocootmphezr5txanyfz2gjhn5lanrn2fa.b32.i2p:0
+vmatpbu2vf5p76k2emzg2tjyqi6p6yj3cl4z32ncdhz37ubprkha.b32.i2p:0
+vmbyttxf6sw6ivdamftxung44mktqb4vphmm4lqzdqqpcmksterq.b32.i2p:0
+vmoogdd5lztt5wpzkwhd67uwnvpupye7ycsbz55jl25sueowcxxq.b32.i2p:0
+vn5rsr26rp7yxrqliq7vo4zb6aoichaybd3urvc5eedaspxjp3la.b32.i2p:0
+vnxjmzogakc2a4xn5w4qormiqt5khnjptnoaro74ehinrv4q3yga.b32.i2p:0
+voi5u3azhajnt7476tcikl5mactxcvtsbnrzixwkj62qhpaw5ujq.b32.i2p:0
+vpevx6tl6ma6mnlj42d4fke57en4v5r76yx6rcmhtvw47guo34uq.b32.i2p:0
+vpmkctqhkdqgkekt72srqm4sqaliug37uq2wp2ywady3p235cpaq.b32.i2p:0
+vptzpxba7oys3w2htjgh4uxogaedursdh2yz5k6e7yh4b3pokuna.b32.i2p:0
+vs67sj5crkcjo7m74tdunzefj6ahgrgohs6egj5jxmneszwaoo7a.b32.i2p:0
+vuqk76jvxfk55bkovqcmmkvycmndee7j3tuv7ezdb2slrfpjyvoa.b32.i2p:0
+vxokhkidetjp4tjrj7idojx45hguhnl2azvqnbulougvdkstf3ma.b32.i2p:0
+vxs2es6f7uw2uuneslb7ipvmg6kqh6ytpjezoj2ptwx7od4jqmxa.b32.i2p:0
+vziy2cbrbvliqpi27feak2hiewovxtlkqppsagtaxeib6nkonknq.b32.i2p:0
+vzqowkd4aoyekapcskylli77aj3e5fomixsjyiawnldzj6c5nxtq.b32.i2p:0
+w2a73mo4grdgwvkzdsh6nyutagd4bmywywacxviodw7xnof72aoa.b32.i2p:0
+w2mgaza75amrvfocl7wt6v7eimprlasuj3bi4xezdr2wyqhkxzwq.b32.i2p:0
+w2zi3xos4jaz3ft5yca2x5zf34esctpmzqlqpdrqntjmi2o3gfba.b32.i2p:0
+w3hyqnlueb4yv5lkzj3wlnrjp7fzpxnig6x6m3w5du2ptfjcm2jq.b32.i2p:0
+w4arykcvc7eckzuqr7kvs2njsjpknzb6vvsodpyzp6tvu27bzoka.b32.i2p:0
+w4k4gm3chiyskfzshilxjchpgtpx2xmc6euvkyzkyjvzvdbqroma.b32.i2p:0
+w55r4ykzu6qt6uhp33exqbqmlt357cts2u2zoi7hkuphqmv5iupa.b32.i2p:0
+w6jl2gubyscdpubizes5bp6s42cito4k27xwcjwh76rvuik2prha.b32.i2p:0
+wacfewi6ehmfxvftxqmracfh7se2t7ozl62u4hsuyd4c5xfzuajq.b32.i2p:0
+weidpvshind3dnblwtb4zpssazeenkf7a63favavkc4crhqdk76a.b32.i2p:0
+wgrbhqemtf7qu4c6acjicb7uyee6rlinafyysvxc2yocq4t2ilca.b32.i2p:0
+wjfukwyohljaxgv4woewdtpoxi3q6hnwcnefpgrtif2kqfrxslnq.b32.i2p:0
+wlepjf4lxs4e553rtpoys6kqp2ozcv4pqjwzoybawcl3zhrdvz2a.b32.i2p:0
+wmly6cz5j54w2g2gibnhlpvuhh3bky26cq3a5jy6dp2hg3hc34oq.b32.i2p:0
+wnp26nyphqfmq3udocgcwenpsgfwk4ssw53st4wvwt6mwf7wm35q.b32.i2p:0
+woanasilvwu3yfurvhvqj3lxd25bzj4fxwy3ef3qjbso3cozvyca.b32.i2p:0
+wpnewole7fofvwvrvkkgf45sgcverlodocu7fstm2axp5jfykraq.b32.i2p:0
+wrqu543ssub7kiwzfug4o7m6lc5ibmaamdc3o4uo6a7ntxiqzd4q.b32.i2p:0
+wsbf5tpo7ecsafusflyym72k6tbyclgvqav56qafvyc4j3spzdoq.b32.i2p:0
+wtfebbwmsxoywu6nw5cowlxqhtokxrxftve2zee6flvrpqg4j6ma.b32.i2p:0
+wtoh5v7xm3wx4rqutbyvqaixybwlprx5ua2yiv2gac3prria5emq.b32.i2p:0
+wuikfwkext6lbl6urhoysr2abcyff5lkm2ojr6mfenqq25nzlluq.b32.i2p:0
+wumjwpr45uhvtggq6jkzfda47e4iqk2onizw6vn5po3bd3uqcduq.b32.i2p:0
+wv335vkr73gsaza4t6foqypnovccubvwfsarkmw3xtc3t3sncmya.b32.i2p:0
wvktcp7hy4l6immhi5cxyz2dlsbhhvtcmskjemrnqehacnoap23q.b32.i2p:0
+wwbojywnrcf2mci7f3zgbomrukcm4d3nv6pttb3dohjpge2sz27a.b32.i2p:0
wwbw7nqr3ahkqv62cuqfwgtneekvvpnuc4i4f6yo7tpoqjswvcwa.b32.i2p:0
-xlqndzjoe5nr2nsxo6xwibh44ghyz4jfqevu62xykvemextpmjbq.b32.i2p:0
+wxfs2ccar4szd66dlmlijh3i3r4muehqjxjmabwbb46cq3gpbsoa.b32.i2p:0
+wy2udklgydh7iknnffbzvldoiwsct6dy3o7fjcsjcdjoq4b65vha.b32.i2p:0
+wzui6sc7667w7aabs6iebiex47o7cysxpryfdaltaklw2z2xgtuq.b32.i2p:0
+wzvki5234ffqhri26fqoxosqq3xengl23eoitkvip4mp7aipo3lq.b32.i2p:0
+x4cetuarbwiqphebitvgv4x4kzh6yhyyvu5c4yjlm4jsyl4bvs5q.b32.i2p:0
+x5qtgyzzgkovoko62l6n54p55xma5pbstbp6t6xc6hbugxz5ck2a.b32.i2p:0
+xasewpiqpzhyggxwsajmnkrppi2ozmapqv6673zuuymoueq67tla.b32.i2p:0
+xbetybs3nyeykskasolpatj4qrfnigz7a2bx7wcsyrniqd3usnaq.b32.i2p:0
+xd2byhr22rqkawocapbxedovmifyk77qrh6br4ctx7ny26hpmusq.b32.i2p:0
+xdoonpwnxhr7sjoyca3lkqsapmefd2puyar22ztocod4drjju6fq.b32.i2p:0
+xdq2g4tkaukzcu6mnvdukchinma7koi6c3noflpjabrzjrgeumfa.b32.i2p:0
+xegcohfrnnnuz3hdmb7r4e6pzxbmtg466n6mty2oz3tcoqutxj7q.b32.i2p:0
+xfyzfugo3qtfpq3s5zccbbqrxfkgy3ttlqhz6t6ovmtgrsuyce7q.b32.i2p:0
+xgbz5vpek6vaeej2zejxrjloqg2sqb67gim72qqpodqfq62rflvq.b32.i2p:0
+xgqzxudkvgbqwosaha7zb26jgza5wb7m66727rk4v2zj72xgg2ia.b32.i2p:0
+xgsk2huqghiftyznr6llr6ztepo523hiwqscxjpawcbme7xtjrta.b32.i2p:0
+xjebyiaydsbb76gqzetsmccgh67oeaxt3c4mkwmt7gjlfym266ea.b32.i2p:0
+xlfxusgnzpmatutaredcvx27zoiecno4tpxm52jicdvn4sr5dyya.b32.i2p:0
+xm55wnfhgmsy4wz24swjs2ziguheut6y72kht4ytwyfdmjsxslnq.b32.i2p:0
+xnb3pxtmai6ofbarycclwwueaarn4r3zt3zgkeepo4pgmswqvfcq.b32.i2p:0
+xnvsgbonlja7cmeokr2msvdelqlasbkwgqndqg7eakw43t3m465q.b32.i2p:0
+xpqubs4ftu7ym4xwrirlz2e36gvyjkil3chvq74bj4lf7djcrw4q.b32.i2p:0
+xrrx2rcpj3zefshtt7kamz3uflnwebpv2gkgd6vlrdazxgln57gq.b32.i2p:0
+xrwuqylcgkr2ovsf4pziosd27ywd7pfaohnreoyzm72qlnvoktrq.b32.i2p:0
+xtxh4wtmbjls76wxnehe57etubuqvsdiunwgve6kwjt4acwswnjq.b32.i2p:0
+xud4fgmeq4hl4cgsbjn3ubz2iyjguogskn7wreesvpsm3ib27kpa.b32.i2p:0
+xuivvnpcj2rhsxmkyyjzmyq6a7gwgusnqwdklgimamvkzu7rnnmq.b32.i2p:0
+xvpzaqftlfx2etqys733mndm7jr3l2j3if3wskfljzaow5s4rrfq.b32.i2p:0
+xvtvmaele7ns725mjaowsajpx4bgfecburyh6pqmdnn37cq7cs2q.b32.i2p:0
+xw6ble42juwkfrjetb3hmk2ep6jnyufhutoenyrou6ieoqiomw4q.b32.i2p:0
+xwlkpubkvsdsyaeylqfmxfk43juk6sz3hxnmwe4zencjq77aznea.b32.i2p:0
+xydzqrwggskdbmeqrhgt6alroglzbkcarzdlhabmvrszm5u6cfuq.b32.i2p:0
+xyhlemqmoeusqbbzr4oqph6kgmvm3a3lrbuanxkmyetwohxoynna.b32.i2p:0
+y365lf3vlh6vg4rs6trnjc4ia2xqplahk26y3tyqjly2q2vpfnqa.b32.i2p:0
+y3equ2tc6zsxqtndugsfzottuenfgxnl7eqgadmnzjkoigxvseka.b32.i2p:0
+y3occl5rqc2mz64esu5mqzoyfzlbxop7tttf2b3gyxjust57txfq.b32.i2p:0
+y45xhqkb43ncokfwhsmr4z6fwykuit6o3p2kbso3emv7stpiwwoq.b32.i2p:0
+y4njm6ftdn562q5thzd3fvb2f5mbi6bglmyupukcmcpt2tuo6slq.b32.i2p:0
+y5wr2bw3rt4rvw7hqqj7qtlf7vdds6zk6cs3mu3myyduasieqoka.b32.i2p:0
+ybjgylnhvk3fzyacxvyh6dwvrh7lk273qh5qws7uquvrhhwr6rka.b32.i2p:0
yc4xwin5ujenvcr6ynwkz7lnmmq3nmzxvfguele6ovqqpxgjvonq.b32.i2p:0
-zdoabsg7ugzothyawodjhq54nvlofa746rxfkxpnjzj6nukmha6a.b32.i2p:0
-zsxwyo6qcn3chqzwxnseusqgsnuw3maqnztkiypyfxtya4snkoka.b32.i2p:0
-zysrlpii5ftrzivfcyhdrwpeyyqddbrdefnfu5q6otk5gtugmh2a.b32.i2p:0
+yemrkyqmjzwwn2yast2ga6dcnsovnxwip2rjpid56grdg7itugpa.b32.i2p:0
+yfplj67xwcblbiu4ozddmzlmjl4ifa7bhkzzu6fu6jkoyqui6v6q.b32.i2p:0
+ygtc5m4mh3qhi7tct44gxqbenhkasp2y4ydjn5qua4l5vh35osdq.b32.i2p:0
+yj3v3ocgldnackxptsjmwasa4xzxj3it6rtuhmlpxvwlq5kmyytq.b32.i2p:0
+yk2srkdlbm7kebv53dx45ss7q2fjcy56m3gywqvw65eya7co7hgq.b32.i2p:0
+ykppjmwunzqzuuqc6qqsijomfzdgieeq2mkidapc4awrww2ninbq.b32.i2p:0
+ykv62rivlxurq2wkecagzs76tulfor765c237bsjn7jt4436kn2q.b32.i2p:0
+yllvqk2utimxjtoyzk7l24s4n5sqp5dbn5vwsbt3g3dd6h4dxseq.b32.i2p:0
+ylpyfcs24ij67dkl7ighyou4z2gpfhjlt2iellj2ad4ddrxci63a.b32.i2p:0
+ymo2cnldmstzqlsdhx7kurii7aaffrhpgafxlli3s47pzbfe5evq.b32.i2p:0
+yny6zqtb7qve7wwfctsozhzhbq4hyitlqco4uhc5q3rvjex77oaq.b32.i2p:0
+ynzhhxlieigtmj6l7f2dq54ypnsaf723au7o3uhnismlgnkmcqjq.b32.i2p:0
+yof4yvv4agwhfmicj5u2drem47nvfkihnp6bil7ocg65gydyzzcq.b32.i2p:0
+yojuyryq6vfoy2mftrdmybmq2hjefuzrwmpqqfvk2kd5hptgr3qa.b32.i2p:0
+ypbq5aleoqqoxto4tkxlmlxh2hrstjxzpgonj3lk7dzweahs3hhq.b32.i2p:0
+yql2k4zjl64dtybuculjgg4v4u6sje4smnyay3vslv7irrigzxka.b32.i2p:0
+ys36rtuedg44sahelbysqi2mbc2l3rcfdy33zdvhvfkx5uocacba.b32.i2p:0
+ys7np3pmfhiyq3z2rcoeylb7agfbyfuhhp7ky2uzvvuzswad6cia.b32.i2p:0
+yuqb55drzrhxfnvobycxqau47kibaaf4voamk3kxl77xbb42xkqa.b32.i2p:0
+ywfauauaekbrxgwaahcjzifemzdq26xsshw54sg4bpr5z74scwiq.b32.i2p:0
+ywpsgu6nlnf2l4sy44tit2av7hfzwwttbjvwbtsbtqur3awiax2a.b32.i2p:0
+z34pw5tlowwi3gpj3ycb2dptgyuq65bpj7w36xahslgikggo5eaa.b32.i2p:0
+z3j2xshl4tpbxaybcprhzq7cuz6urboqoxvvpnfriv4n2lq72jsq.b32.i2p:0
+z3pgyfiwfzcd2g7v4rs6el5tvc55y7a3tai4gcbpso6flaejckea.b32.i2p:0
+z6mlyrxcjddpcaoumxnw5peulnkvj56hgwqmnc5adoutp7piujaa.b32.i2p:0
+z6xsstyq4zynzvagwv3wr7htz4vxttrotzb5izefotlwqm7kjtua.b32.i2p:0
+z7cjxpy4taui2ka3ekfqtoumsb7pg2sok3wfey3m2roeuppcrzhq.b32.i2p:0
+z7cjzfmv6wadjguzaavu7pfsqhujbczspbf5sxxrqndeovu3lt3a.b32.i2p:0
+z7gkesbkbl27lpcpbnhgfofjz5fhnvljzfvyydu7ky3odzdqs4lq.b32.i2p:0
+zafd45c2hzd4w2t24qtjqqbqm3z4hayb6vadj6sd5oukjyij2ara.b32.i2p:0
+zbkqcqtiiw4nwsds5pjel6alr5i4hgiyqf5giwurdygfysacru2a.b32.i2p:0
+zbz722dh7rvu6ugdydmlmtgfyc7rnpeslae525c7mhr7rgsekjba.b32.i2p:0
+zcwgqw7hlw7437a7au6n6obljdb4arnshoibdqo6voree4xiznoq.b32.i2p:0
+zd4ns4zcyvgpwkioftiiftgj74n6mf4m4ieq6aedqaznmdi6rhdq.b32.i2p:0
+zgwseerxwqnid3zhculzuqbkhghthsbvsbnqowredostfqlvawsq.b32.i2p:0
+ziehuxdpyg5dvvnzedmcqxszdcflsrx6fqmgzb7odefqwqaxrs7q.b32.i2p:0
+zk2r7kzzigzu5kz67xnrbe56u5walngylcsk756bkmt66cmeeydq.b32.i2p:0
+zkbjgfp4ouockpsmpbdyli4ilo7f3lbfjsboay3nf47ymir2ldrq.b32.i2p:0
+zki6halesukhfel76pziutgica4zrp5qtbmlmgyqf6dnnomk7hja.b32.i2p:0
+zkij473aummp6rvwvi7wbr5iio6xu2uh4rophbhyot37uxhrygiq.b32.i2p:0
+zpvqqdrcnagad5ayutf7hkp6prtvrbmknhqdul3qweft7oa5ikzq.b32.i2p:0
+zqft7c6riv7aux62qwe5xfqki3dcb4urvbfy6m4wz7f46j2us3la.b32.i2p:0
+zqhoqgf3enj2pv74sjov6dthpr6jqafw5qqzzsvnfdqzycychxpq.b32.i2p:0
+zrrki54mn56fytizkfmhx7eubea37padxa3zliwq6gtknrsxv2aa.b32.i2p:0
+zsfpcnbk4g2bwxl7yy5ebrcvlxd5gpcxatewdrgpige7oqykunwq.b32.i2p:0
+zszq7enaxbz5p3f3idhfkkd2u2ygpeqwj3o6hkofffcmllnymwqa.b32.i2p:0
+ztr3c7qz6v4hrnegmkzjsr52wyi4u6ery4m74sk3m77oup2ws4ka.b32.i2p:0
+ztyxbjae7ucfyupxpy75jwpzdktg4gbvhl43nh2crwqrx2uhveda.b32.i2p:0
+zuamj63ad73jmnw7xnxrmjsbjg7vg23j46w3mpc2udpcgjfkcqcq.b32.i2p:0
+zvchlrjuzqdlx37fhibhnym4y6p56vtlymujjuzhh2cp34yqfrtq.b32.i2p:0
+zxsd3fqczh6ddgejc24nnmb3ww7nalieq3a7cs2mqiy6tmff3wia.b32.i2p:0
+zy2ywvyqds5bgdoo4tgbu3bwjp3ygyn3zfuby44jemc6xa6fbwta.b32.i2p:0
+zzre44vh766jgfordw2ehu2r6p44j23uyovgvm7iwuhp3g5iz4ca.b32.i2p:0
+ycdw2e4ufgfwhcqna4g3m2qsvaly23ozaexawcj3x4gtgcehgwujjgid.onion:8333
+ycfvedulkprd5bmivqejur5aptcs47daqtcvzotnnhfvwu3o6gcp5cyd.onion:8333
+yck6l5ffw6oszgtoc7et4fytvp3sqdf5awyky4tlpgem2n4y6icxqoqd.onion:8333
+ycnepnzktkhfysqijlgbjk5awivls3eiqb5kjudotjvnvlbe6ah2k5yd.onion:8333
+ycwrrabomoixkxggkxldyxkqoc7qqy2t5wxcsxjgodlvuydwch6dqoyd.onion:8333
+ycwwrwkqibvkftpc5kyqs6nf7hrzetrmqgwo4yae7bq5otvubkfsread.onion:8333
+ycxjdh4jr4vun447cdszcoge26pbdnqblfi2osmk5e4uqmrigw7y4byd.onion:8333
+yd2ami3rem3i24q2b76l4ujyq343ycrowrthwqycvpcsofgpwlxyryqd.onion:8333
+yd4nyusqking6tkcwmmopznlxhyfhk3gsw265alz7vpo6toqg3kwn6yd.onion:8333
+yd6b3wtmu6bz5km7hw645omyv65one627xech7f3vnlwkblsvqdtmiyd.onion:8333
+ydforbx54mnz7g5u2mu2ulkomvakdbwxoad6araknijb2i47gkfeh7qd.onion:8333
+ydiqekqpcf536w5uwsdclw5pt4n2fkz52fo4vwdducc5t5l4ghqaxnad.onion:8333
+ydl5kqr2auvie5mtjkm37hzkqh43pobibty4msfzkbu4junpg5gak6yd.onion:8333
+ydojumivjpins2lwgql5xaywbngrmw56nvmtalvfiy7sr42ksvr6apyd.onion:8333
+ydvbxdzs6w5wefifiqsqntpbd7tliofenqih5hlnz34546fvy4ab7iid.onion:8333
+yeat6ea4esvd4nimhg2rcb3ghpusoqzjb44alb3hhdj4d2nimn2vpoad.onion:8333
+yeficzguf443sojjdcmh7lzk7l6y43a6v2jbyk3x2w4n7xokjs4crnqd.onion:8333
+yefjaylovpdhbb5b5bhjx37digt5u62lmzyc54ygtabwdphm3zwd77id.onion:8333
+yeghpcuryadlbxzk6o3ujebmfuumkpoi32dr2ctfmql6vqn5wjioehqd.onion:8333
+yenw26f3i6kf5u2nad6xligxk5iyizjvl7msx3pzjcatiesogdef4zqd.onion:8333
+yeoadueo3ukf6s3fetywtbvgmpvrtkja5rlp7wcp4aich6tfhh35giyd.onion:8333
+yeqjrnnuf4fbgzik74qfhrohcymj7ccbze6ndky4pe673chfsjconfqd.onion:8333
+yernmfgru46g43vsijjv44n7m35tpoznnkd2p2wl3uqzkietukxqxoqd.onion:8333
+yettfzp2vanmkehwxeaugotqcsg3wsomcargvetk4nhwnebrpq7ah2qd.onion:8333
+yfgo33tiu6w3nrvnfyw2nmpcwtfozinctn57566y5l4hfcttuvgff7id.onion:8333
+yfmujam6pa75vm7p5q7gvgkocqzcwm7lgbnodwtmzfw7usy5dvlgqyqd.onion:8333
+yfpqwz4qogg2r5sdweggggz76pmhxtegnisz55urw3egvcq2e3amvkid.onion:8333
+yfpucmv4zspytubs5epnze4xc4joqny52s7ifjk3vu644axwkfyfurad.onion:8333
+yfq3sexjxzuww7tnwc7jj2ethiu5f5r65ewpy66os3ozhoeje7na4hyd.onion:8333
+yftuiua74fspnqanvait246qn6vmab4aoympjd3omppu46jkq777axid.onion:8333
+yfxz53gdbxu5hapg3e5kaa5pyxpbrpiql6j7sfe4i7fqj4blpqpufzyd.onion:8333
+yg5xbesziuiaigwyxjrn5c5hvj6fxef45edl7pir7risnr6un6esjtid.onion:8333
+yg75fc53cicbsarrpfv2s4crpkx6vdjub4va7cvbducwzhsf6qehx5id.onion:8333
+ygczn2llqhks3ohxvfck4ks45ekg4xr3loriyynnejw2jfmi7hjsfead.onion:8333
+ygdfwrg33s3qwiarwxbejalkirmqui3wjz7wfccprjry6bm5la65vhad.onion:8333
+ygh4hx4ugapidwxodkjr6vgl6vkaqvievk2eiie7v3ewuvjvg2mzp5id.onion:8333
+yglvvnb3dk2vh2wwgpcnvm6t4lgbdhnvpy4jfj3ee4ugb4xzvjrrcfqd.onion:8333
+ygospbn7dc5a6haqur4eoe2oj6jttjohs43rhl5m22ltruh4fz5isxyd.onion:8333
+ygowwz67kvvri2lcwknsc5xjdz7ffat5tqkm7fmxrrzfgvqnxoxkvgid.onion:8333
+ygwuwz5autfc4tqluyuoebghc7f6lgjykm6oprynh3h2vfp4xmhiapqd.onion:8333
+yh4edjvpbo55vsankh7e33u77ep7eah5h5gvfgu7t7mbb7kkmjvgirqd.onion:8333
+yh4uoyfzey53dnoj6zm3frihhgwpqfqkw36sjmqsvfnl3rqohs52wqid.onion:8333
+yh5us7dk25ttxkt6miers3bazlm3jiums5nwz6mzd4i6kn5oizjccuqd.onion:8333
+yhddybpp6lgu34i7uurdqg5jznfdajwr7co3twiqf7pgnj4yjgzbnpqd.onion:8333
+yhiswltkrs3upvkrygsuiou5i2njnyxk3gwtsmcr5yn4lfinzifbpkid.onion:8333
+yhjkylctf577degc7ufffvg3gsdxgnx64pdhzfujxjgfhbulmtc7yaad.onion:8333
+yhnzb5pmcbeiqs6bxm3xvzdy2dgblteiswvvtg6vhkum5gjjw7abjzqd.onion:8333
+yhqytulgwdtvozjhuyod2cufnkbh75mgyw43k6w63ah2fzulskfssyid.onion:8333
+yhtxfuf5zxqoqkuodfpmzsnnmtm354y5rtexqplt5l3fkzzksjkkzvyd.onion:8333
+yhvyxjfauptpsjrxrf3oxtv5zlju2gdpitwsabcmj5gdpjr6i4z4ulyd.onion:8333
+yhxcgpy2bwwhhpmgellyghjpkw7cfrjlq6trq2yl3632rxerwbmkvfyd.onion:8333
+yi2k4otmwujg7bi5iw7ewqntnxb26jyplx5xyk7bjvvaut2y2mhcgqid.onion:8333
+yi32omh7hh54oeot4i2ze2tif4l4cwdhzxxn4bzmtqrotfxrepttfead.onion:8333
+yi4gxqy63csutkea3zss2oryz4get22hcfginwcejy65g35ec5t4uzad.onion:8333
+yi4nvghovjd5bzcbhitvezh4uwg32n6r23et633odlacu4eamfym5mad.onion:8333
+yi5x6isngj7pivr5wt6i3drntlqsvbzijpdy254lbjdnihxmfy2cdgad.onion:8333
+yi6umkklbb6vr4j75buoss7kqkgcsdsx5fvgi57h7j5bzuleoe3ae4qd.onion:8333
+yibgffpo7dimyvjlbzfr3dnmnl2r5hbrpxbtcpksthsko6udsrk5uzqd.onion:8333
+yiiyiuwns45zhmkwi3wjumqhnyfkwkahbggd6hrxtnrxfqwn2vdx7pid.onion:8333
+yijdxmlgnfcwrb5zxvchjhgtc5357mecuopminujkono7bwjgqu4acyd.onion:8333
+yise75jksg27th74bxo3a6rcr3huvromhmuhnmy3n3ngcgfpagq445id.onion:8333
+yised7sf3xzsnlggeuioas2of4crrllkpz2gfbdy7c5cysa5sxi23lad.onion:8333
+yisvuvmqtn7wht6dndrqzsdl7vuspxwrmfwwu5o7wldnzn4mbzeb4yad.onion:8333
+yitceyo3wv2mk56omv6mon3n7dcfr7jiggdmzlmtikpoam2otiey64yd.onion:8333
+yiuesqqc73nn7kxadavmlwc7ymciszzk7bxs3bd4fwucaocme6qb7lyd.onion:8333
+yiz7d2lkgk2mftp6i5e2tqhotqkqjgxbdmzbnflwvsioyfydqrvll6qd.onion:8333
+yj3gs4nvumsfztawn7ku4cmner2zlmcn5kke33g4j2vywxsrqmbd7kyd.onion:8333
+yj3q4iustxfcq4bisbuw3jvqc7ph2ggld56mvyxqvgw2tmsinbwlnzyd.onion:8333
+yj666fxjddvz4xzkhtzhh53wvkiobvildczzxb3mixjipqqiqaz3bzid.onion:8333
+yjdhdurh6vqxuykgmuskpabjzjni3ehxxh3zq5redu5hqdmhdw5b5jyd.onion:8333
+yjkojvjsg6yhfj2ln2bpcrh2e6fr42ul3yzsebbz2kkytg7pf2zzjzid.onion:8333
+yjudzsswyvfqyeth2eghfvegxg6z6ubnx72kmqjljhdewrckw56lggyd.onion:8333
+yk2foofoifxgbrp5a45okwbelrsvycgqgw24xv56hmuqxlpmw6msndad.onion:8333
+yk4sercvyzvqxgbgn7srm6eeivlzoa3t4sz363aygcyciubcieihhxqd.onion:8333
+ykh3t44zjojpj76ouqeo662ljhyc2t6e3mike76iqpelcdztgaxuw5id.onion:8333
+ykkhln6x6hcmhyrx5rxaf3c5auh5k4plrpaisits63r33ecwkmtexhqd.onion:8333
+ykqehwl47hwypuhhuuxkpoexocldvllixqhplpsy6ym65vbjfa3yfbid.onion:8333
+yku2clwr3x3ndzfjdk3o4spoztoqy6ndatken5wopgapg7qkvypuqoid.onion:8333
+ykwrwuffwvaxlwivt3hlhyz2yo5xde7dw4x67ygc4xh2t6m4i5cftkid.onion:8333
+yl2preaby2yqyhmviyq46roapupmnijt2g3mzmvwtxptvybz7rbs32ad.onion:8333
+yl2stshaozpyqtut7m6ln47z2qhledknuwhij6kvxsuaai4nwy6fp7qd.onion:8333
+yl37nyh3vujz2fyrz3eoqoteixyiz3dj5rfnnmrglcgcswzbeqbjhiid.onion:8333
+yl3bo5zwwsg5dbhrrcjkvoyvwwxp3kbdgprhe6md52ob2lra7ynrbwid.onion:8333
+ylaoywooejvpfosewxmyxjhc2ahfepjbvuyjc4p7bymwirexlkdituid.onion:8333
+ylaprgwti4dsumx5xvlhul3esf3yi3ebyyubb2dwfgwe3zysv3e6nyad.onion:8333
+ylblnrd2jnfjtustl6yt6pix4mgqr5qqoevunmwk32e6fxq6uj3dchqd.onion:8333
+yldtx7o5y5jf2utrrtqf5yf56akol55wars2uwxuvjoubustrtmuqxid.onion:8333
+ylh3vliup6k27pt2thw4xgfguiziaosb5y3ovee4w6dzwcb6hc6czwqd.onion:8333
+ylsvnjqrcgatkzj5gfkwt6cz236z76yvgpeulggzml3xb7tnbsttjnad.onion:8333
+yluwecwlibf5dw2sup64dq4gs4cfdhtkfhoy5cszrvu75wljeqanr7ad.onion:8333
+ylyuglp5b2p65gmiofhe2irpxswlhecdecg7d27qhcwehegr2efmesyd.onion:8333
+ymgyodvztfs4nnijjnwiv6eadetxjm765iv3ryuyhsq4upnjwncpvsqd.onion:8333
+ymiw3d4klephwuwbkgdpllrs6hssb4svcg2um7sdm3hsnnksbnvj2vqd.onion:8333
+ymnypd7xmz2fka2r4yxvq2ibf7rvdyl6eemppo74rfehu2d2oqkclcqd.onion:8333
+ympp5jlakwfhj2bozw6w33qailkrqbroizxm3pdfxvjdbrkwtyx5iiqd.onion:8333
+ymrunm2vhoarw7rpo6jdmq4mev5hz63umljki65q2v327vmnw6wjyvad.onion:8333
+ymt2hdfgdxo2awvj2k4y5tbpvapj75j7v34tvvlrqy44lsvvdcnjx3qd.onion:8333
+ymuufa5br75liswfrb6pgm3hc6o67gnzhyg7vpfo2qsw3oyw7m7nsaqd.onion:8333
+ymxea74sswjyqvv7jsh74dnvimcsq4rnao5x5g7dfjnbfy67oj37l7id.onion:8333
+yn3avowdk5cox7qz34s3qiz2u5j2xg3irxckhzikfjv5ccjqrdiramid.onion:8333
+yna4zorq57ehghewlega7lb4zgx3t4lgv5k24orv7b4qcg27svymosid.onion:8333
+ync7fc7dz24s32kp6opdkbvohb74obme4jgo3rkkvjzywslxegist2id.onion:8333
+ynilvzuulga2tlv2hcic7ayc5qpd4nz7r7snsyejp4vxwnxlonf4gvid.onion:8333
+ynkv7njh6hj5xewxxy3gvtnu6ocyvu4tgrl3gnw5xxkdpfshalppqmyd.onion:8333
+ynqgzojvdwv2rui2rlechb22e5hwqipltusdnfkv7s65iz6fgrnybnyd.onion:8333
+yo4ykt7hngppavow7f2sz36ajl6w34bw6qrcfee6i3s6jkm6seove7ad.onion:8333
+yoat2b46hzeuhy7n57gjmfxgppei3xnzdxwsl2ipc5ny656j7zp6ovqd.onion:8333
+yobra7r3ketjuhr4g4cfdqumsez4om2eefvmgxrxq7wxnkouzmcemwid.onion:8333
+yogfxdco264tjbbeek22o26lznu2g2kwvs4lmft3ib3xelndagtf3uqd.onion:8333
+yomwxfciljad63gicbd5757og4lypcph5f5mqdou5kj5rowkyotaohid.onion:8333
+yon5gz4q7soici4i7jf2zaciusioym56jo2bat363tr3peoiurransqd.onion:8333
+yoobb72dyt62n5dpsu3aqpqa3lmfj6gfurno46o6vmqdbpwqw32ahjad.onion:8333
+yotcqynj24k2ckilo54hjhftjuvvwiacbzoraqc2kq5vtmsxloswddad.onion:8333
+yp3juo763dmi7ryhkv3kq2l262cllrru6ks5tlzcdlxdakmip3zosuyd.onion:8333
+yp47gud6fjsvjgu54oica4b3ij4zfreactcaon6fx7v7pfbxbrvqhtyd.onion:8333
+yp6klgnrvisq73qg4dk255h7un2k7pbk666jtzc22rxjs2en64ojauqd.onion:8333
+ypaazf2z3t5dqzudlygjjpyb2uvk63guovstzubsohbbeomometn7cad.onion:8333
+ypakyst4bbhh2juqd6r7xymqnrgwx3eajekpg6o5b4fazccy3mwovdqd.onion:8333
+ypkjkt4dnyqy6svecydigttwnsj5x643w6edk6qzhfo2hkxxu4ln6zad.onion:8333
+ypmikts3saaffj2uo5zmkbac5m7xnbblxkbhpw5xtxbamajqf36wgdad.onion:8333
+ypninar2hybv3jdovr7ax7teq6wpzvrw6n74csq7edos3hzumh2h27qd.onion:8333
+ypoinzgql3zo5d3strpmannbkdtndxkxlajwgcpaj4ngbc5mqrzzgpid.onion:8333
+ypp73pv2vcjfq23ltwhojuremxxfknwtgkxsvwe3widlaevyx34pepqd.onion:8333
+yq7s6pe7jzrzj5uxlorytwxd5bs4kljyvp27akdrpang765yd3sexwqd.onion:8333
+yqnal4phy7wz3lsoi23rziyb56bnbzvvypy2mg5ponzrk63qpyvle3qd.onion:8333
+yqoiqt3molj4ygq44zyme5gdbgee7catlf4ndjr4myiicduuwiev3fad.onion:8333
+yqvhbmvc45iy3drl7nceuhugdt2fevwx4x53zafio6h2626kflwtrcqd.onion:8333
+yrambbqlzkm6o5pkc5q563njvrkfallqobvscvpdik5owbdtnhbc5jad.onion:8333
+yrdtnt4lkpysyyrvryqhxw3k427gxwziosdtipf2dcifougwzomdfcqd.onion:8333
+yrlc4r3qfcr4x5wnciutrdvasrpahor3ui25lgdgkxbit3zwtmwfmxad.onion:8333
+yrmpasdjmb77ono4c6rjh24fj5gt7bbjx7nxurytkmxbww2gam6vodyd.onion:8333
+yrqolwaoxpa32cw2zegnaggmniuer66umflznja6dcp7udqpaoanqwqd.onion:8333
+yrwksigpx4foqlwnf6cxwtppx2z2msompig73dkcm34pwsmy5bwwg6yd.onion:8333
+yrybhm2es4siupjnyjffviemvqx24mqj5niwm2wf56spdqlwau44r4id.onion:8333
+yrzwl3rbfjx7eybyjvnjz2y7qmvpnkexkmylqpwsb7ivpg6ch42mmxyd.onion:8333
+ys2muyvcnpdadettzavleh7qrn7t6r7e2tobfp7yxftta7ez2i6rdxad.onion:8333
+yshp2g6b53ndeez34nxnk4bz6cqbzlfxqdggi7btqlwzxzuc7sweqcad.onion:8333
+ysq5rtpfzkz5gt2s62idbsd7secz3jepzlup6hqf5ttdutsdmwg2ryqd.onion:8333
+ysyx5eagwnqpfemz2nhwcxs2c3eueqk5f3jnyvyfqfno3pflcqfw6yqd.onion:8333
+yt2vub6llcegxuucu3iekjqfpmbyz4kreuxx4su2pqcetw7kbkbipzid.onion:8333
+yta7q7v5lkzt4zyp3m44cxcdtymxgmuqdntnagz6h3hwidmqoeavifid.onion:8333
+yti2ofsqg7k4zbln6aqx4zqaor2zpmlsebyljxlu7jczsjqtd4ctd5yd.onion:8333
+ytkkqeik77zjjwabsdlctuum37jr3r2rg6ckxudza7y7tialqr2wfeqd.onion:8333
+ytq4uowr6vwyjmrjvac7aimjjlzylfmhqhn3z4ecenm5dd6u2ccsijyd.onion:8333
+ytqhsolk7pqur5cu2faxruehvx72yiiwb33p4szdnzidjqksanps3nyd.onion:8333
+ytqzrm7fke3kqgh5b62taq7yyejgtd3yxwaifj2pimoqbfq4p7xi7sid.onion:8333
+ytrhvysmp4iq2qumdrpgp54q3ushkf53b6i4oxpddg4rmlk7hbayusqd.onion:8333
+ytyn2e3bkmgavrygpk5rzydfdmhpkercccqcaks3xtnbgq5qsyg4euyd.onion:8333
+ytz6ov6l5ofhjudlfi5k26lsg4v36p7xwciafy2sdau4cn6ozxgmefyd.onion:8333
+ytznm6jwapg5h3firimqb7ao2g7uihakg3gt6hcpfqkkgcyemklfufid.onion:8333
+yu6ilgxjfffdb3fq7srwwmz6ymp3fxberstpl6vdocmxbrrf5e3tw2qd.onion:8333
+yu7c5kjgmlci4arofpgq5d2qs5fvbw3zac52nampn2vc6vximc6qovqd.onion:8333
+yufe3o5x7spybs5tku64r6hzbrc46uq6izky6z3dyvba2ymblvehyiid.onion:8333
+yuhebtpb6urpsrr3g3vk7tcl5lp5dt7kcaj7zpgox5r4x6ptysxzvgqd.onion:8333
+yuqoihr4p76t2yupxuciurcpzsij5i32enjlsynqor25fhdvidx3djid.onion:8333
+yux32z6r5leyhbdrgdpti4sggxyoy336qb73ia6sk5egfli5qsvkxvyd.onion:8333
+yv2ezeqqfeoprti36q4fds3ckq43vdv7vktqfpn2npv6isnbxay47hid.onion:8333
+yv7ainbyxz6wejjhpjgzx6ghcomdwd3k7fclru4woooxcovyjwrp7dqd.onion:8333
+yv7llcydwvi2m4xpnulhgxcrje6vswtsasu5bbmgxuk3lgln37tdvbyd.onion:8333
+yvgzvmh4ngi36zvn7pe3bocsxj6pccafh7v6wmswkdobbxdzh3b56iyd.onion:8333
+yvhvl5bvjp5ljmooujmw74wdyqnhvwlm44766wwgq5thnzctyni6yeyd.onion:8333
+yvnppv3n3hwexlvugfviwv33ycavxdwnh24dps5vp3y7kw6kze36v3qd.onion:8333
+yvsokw66m7kqqqjxb4mntjvwhnpoovoec6rrpqtdze6fdvpbtvt4iyqd.onion:8333
+yvud2f6wb6puec4xq3a6yruax25jydqepowhz65uvlbvblsyi64skoid.onion:8333
+yvvodwqb3szlgkx4egcyq7qmhpyoqxdyxdnksxl6ppnmagnsu4noemqd.onion:8333
+yw7tqaujnglpjmjak5r7sxvjg4gqeubwetm5h54e7fbfn7yx7kgr4kyd.onion:8333
+ywbprsiodgtlc2qoubvot5qm22logutr2dbizmlond4dcifklaxqlcad.onion:8333
+ywkxlaydopi6ygjeggtv5znptkrldzsh7peg6wabkjmcu4k3hmbjivid.onion:8333
+ywmh5zcx3r2rd7zmkyx5kymgxk43lsamie52kbhayqwqyod5togs6aqd.onion:8333
+ywq6oxdfdvlict3cuasd3akvcl47iw6bxykrvkalemrcyqzyzclbf6id.onion:8333
+ywqkdkihpzr3hx6la2lzqsguoqbuwkn36qcrbkhvltd62zdrguprljad.onion:8333
+ywqp3kjwchkto24so4nn4ofq5m5c454btnkux5jxftkkqz66ducu3mad.onion:8333
+ywqygs72qzxbkjekezlhsnrsfnnvm66igkovfoh267ru7ho3qtxtalqd.onion:8333
+ywvpyur4ny6zhfxpsva4mh6cd4htw4q7ylx7tissnxehwg2bid5fumyd.onion:8333
+yx3nnyxy3h4ex22uqdjwephoprte34jelnkpr4ua3d23ks7qxjrqzoqd.onion:8333
+yxa2iu56fp4i4mxzdkmv7xxrluyxtkylqvexuceivx4fqxbjyzme76id.onion:8333
+yxgvp66ll3c6ko7w4hm7xvzofd3cb3ku3jjqc4wihapnyk3wxijafrid.onion:8333
+yxlaxiaatyfnrx3l2vhb4p6d347djzux75gcl2d33aydlwspo5w5wpad.onion:8333
+yxlwpmsjdbpldhi5hlzopision3iqbjzpvyaaeb4yst3z73qbgqy5fad.onion:8333
+yxnuslj7hslwmofh36a37stlm5jjnq46vvvyntf42uw3zuouot3sjaid.onion:8333
+yxq3bjwdrck3lflvwixj2fc2l7pzqnea5l7cucviamoc63a2xozk7iad.onion:8333
+yxreb5ajudnpt3b7z5hyizaj6ufgd46o334wtduuyaakboxwztgji2id.onion:8333
+yy3bnszld2tbbyd45f2j7btrbdz2p5zsuzie27liqr7xgkfh37rcojqd.onion:8333
+yy7rusheh2cq2xghpsdzlrx4gpejgfvsfhq6333d2jttcovhh5jo44ad.onion:8333
+yygxdcvyp6tn46umpmxlsgsi6crg2xjchuhi3okobofsx4dqgwucnnad.onion:8333
+yyo5s4r6wr6p7l5p5umlp7xgb47ugeptugscv4gvpsxvjlwymfpwruyd.onion:8333
+yyr2peqznujer3t63yyhlcasjndbhllvtxxkmcvr7p4yxpuzjrcylcid.onion:8333
+yywmc2hhk7t56e7jun62oidqft6jvtvvlylexihzgcrtkzxe5axsd7id.onion:8333
+yz3izxf6pdtr3ucbriuo4bpgjn2visad4vgocktexnpv3rfgar3kydid.onion:8333
+yz4l7aqcjf3lcdtdcuxoxljedrcrlo3lu6kths2bvjeoil4wqx3d46id.onion:8333
+yz5i6sldywr2mqzh5qmwoqfgsta5f67bgdhqogejjmpengl3llafdjyd.onion:8333
+yzakgornrhzzenpclo4ahyai5lxsg6mjq4zrwlhqt3ff4sblxi42jwad.onion:8333
+yzbka2sygb5eqgrgk2svqin5hl3dfknzfdn6wzwncexsejmrp5wgm4id.onion:8333
+yzh2ineefkzohck7vkwcfe62kvplsly5xn4dmm25fpxbjq2va34bu5id.onion:8333
+yzigosfexpco67cy3e32xehlpwor37fp52my5pwtr2xsnj3mxl7gfoid.onion:8333
+yzijb7pu6mrrdwb7sku2e3epfyrkhl7t2a723vaisqulr3roaxoy4xid.onion:8333
+yzlai35raddd2kdjnukns7u5t4m4ngi5dfrlq72e6lqf2hp5dzkuszqd.onion:8333
+yzo2vz4kuitm53zwynkm7ddfdw5escsp5fp7rgf6uspphe653mvdekqd.onion:8333
+yzqfzw7fgzzs63xpvsgznhnassxcadbfaxxaxbmkffvesgdxizhxkyyd.onion:8333
+yzrw7ukful7rhvlletmabm37wupkhsxwo2esqqotsoh6gxib57ss3tyd.onion:8333
+yzs2bdhwhxfgaozpcic4v66w7wwlxrr3v4xpgzer733qehcwewijipqd.onion:8333
+z23pfizxwpae2sbje722iesvd6rcxntazcaoefabzsudkc4xxmtbqoqd.onion:8333
+z2eky4p4ozlkrrmuq2jqcz6w2k22re6hxrm3um4ypcnmzmpsi4p6l2id.onion:8333
+z2eo4uckd3ymgtsjitag7yqukmjsjpwuf3d3npq4oskeatpkcinxkcad.onion:8333
+z2gnzha7ttijmle75dvqdzaeqz3xyxzjrrqbzribvwbomh74je4xeiad.onion:8333
+z2ihxne7lyodwglkwpvdmz3a6343msirrvjmaf2pytuo3jysabrkiiqd.onion:8333
+z2lhlshxak5owviqqzacj73ioftqmvq5idawmrgt4k347bwr6yubmqad.onion:8333
+z2njilhjl33youet5rbdfmncadpt7tohtconls3qhpvuqfkreoteqfyd.onion:8333
+z2nocd4haqt257cyr6festid7enoe72qpmu27cuvveoon4rcak4femad.onion:8333
+z2yjvxbv3rfpso4cjkxc4i72f55xb5fihthcdbvh6dp7ghxz2q2tabyd.onion:8333
+z33gr6fni32nkhfmkovcbvpuk7s2atoqfbuzdgz2jszh5ua7zdu6uvad.onion:8333
+z36427rantiy4ikleyihwfwh2ga3pyqqz7doezrzkyv52bi3mpcgt2yd.onion:8333
+z3asgzuzdvhrrejqjnkg5qfeynspuwzzrl3sr7seqxlwkiemnrpsrzyd.onion:8333
+z3hdtpvmnaz2izvnlopzmfgdb2synsomzgy62h7vlxvsn3yqhgufqjyd.onion:8333
+z3hgdhj7zxtih2gkjlnex6occtzw3tpd6f5eobwrntrhxtiww6ke43qd.onion:8333
+z3jl2izfxwfmqnbbrac3tustn4bngymj2tia2sn7nuyconbmjskedtyd.onion:8333
+z3m3a6wii62jc37c2fw7huca7mu4eywnssindvhn3hrh3t4y4kwj7dyd.onion:8333
+z3od23fobhkvypxarneq3fqsdsksjt3hmujnlaiwb65hdwa2n5xdjiyd.onion:8333
+z42np5zjd3thnd54h5n45ibynz5vb3flbgypt4me2c3bnvntn4rsgryd.onion:8333
+z4d7f4dvqutzvvqkmj35znzpyorroqg53jhbft34gyk2h34wzorv2rqd.onion:8333
+z4gvqymmj5jmg3dnao7k3vc245pzepqcrevzyh4s5xn5fcc6ape22sqd.onion:8333
+z4mmpbj7md2ljj2nzbk5b6stdromp2sxhysdexiq6kjqp2go2yfhlwyd.onion:8333
+z4pyvdupcieuqtzvhh47sbiahdyegvpgtwgfmlvfsrm4yj6g5mt6cgad.onion:8333
+z4qgvajgk3tr6aomi7zkpiilx5xb6tvavupvw42sgjf3bfqrgwk4tjyd.onion:8333
+z4rgrsudz3wjx7uykg2kmcadwixklibr5b4k5nulwrpxcjkasu6gnjqd.onion:8333
+z4s6g5bqdmo445vu2i6tcm54zjypfhl5uwnxqjq764bbu5h37gkp5gqd.onion:8333
+z4zr3v232rayjy7e4wuxxez2blz6p6apyv4souxjztqnv3mvaytb4nid.onion:8333
+z52bx6657mva3yjtrutjhxojkbwmrmndk3r3nptxc5xqz3nd62frfoqd.onion:8333
+z5ecnh7crpgo54nfll6qbwl4ybvfbq3izazsdu3pp6zqkam47nuux5ad.onion:8333
+z5v63i7lvhkfdqcex3ioeny62glxhptowtrfof54qbl545mlchkul5qd.onion:8333
+z62kddfut74o5njyehkdlj4caa6yg5orz5lznaccpbloqq2siiwbtayd.onion:8333
+z62r52qegmgv4otygobjdsubc6jffaei23he6n553akc4wnf5ryur4ad.onion:8333
+z63d77gd7artekfeamkqycni7tzrkvbc54fqr733veuoaqx45jwmytyd.onion:8333
+z63fpitzdw3ot62wtxtindh5334uatz2flxg6ronyy6jwx2ztjs4meqd.onion:8333
+z642d45aauehr2ycmv4ewv6zkwjlvlhwf5wlueuy5ynpu4qmffc7utyd.onion:8333
+z65lbxuvo5x36vuv5rgwgyoplqjzzciwvb2whvo3tlghzhp6zij6grad.onion:8333
+z6gr5c5yrp5seqsw73b2pkn3i4aqd5idmzgidjchjjm7f2hdgfkl4fad.onion:8333
+z6n3h75u5kkd5xkqfwbqasd2rekxams3jinrrqaj7p33qdxq7fdlmdqd.onion:8333
+z6n5kkyabl2huqtcp332n6xbo7kpilcw4b64govztw3swtzulgtxcjyd.onion:8333
+z6nq6lkmjoyjhqp5j3tg2gcjq4e3hgduo74unmtmnybd7a777hp4asad.onion:8333
+z6nuvxnjicev3v47o4vxjwakfz6g3jvyo3l4rds5qqfjptqie5re27qd.onion:8333
+z6okjxmclwc55pbwioqx5wyua7rjobcmbttpte525tlt2gexjcjtr4qd.onion:8333
+z6qmf32mld7uqjmx6hroqnkieerstp3vle3u3do6odxig3ubmv557qid.onion:8333
+z6s6t6bi4llpuod6rnakc344wn3h6ejpfejxrkjohjjy246shwfd34yd.onion:8333
+z6soa5spkni5ze6p2xg6lnehu3d7hnqn5ddiy34jtedwegf4syqnnaad.onion:8333
+z6t6fxwhgndvi36vra6d5duaryx2m75v6a5yoz3cqjlj53ko4wm7fhyd.onion:8333
+z6tmafvqwf2sd4rchnafg4urcug4xpkylwls2owruyifaduaeneyqkqd.onion:8333
+z6u4s3uz6bxke3tyibyccbg7uaxt4cb4dued3cu3pbjw6frqc5nil5yd.onion:8333
+z72rd3arkarr6eehucg7rrkjmvqnzdbjmppfk7zcvzd7jqrvisf7rpyd.onion:8333
+z745wkcll7vkkrx7zamibvbyqjtcp3y7wdz5kd33gijxfz54cxzg3mad.onion:8333
+z7eb2xkiigjdfay4ch4pubeqxb2jwyzdb5fo5owkbteyhefek76qoqyd.onion:8333
+z7f7lrvup632wkbzinvbkyyrhmguaf4fzt6zleiynk2vuvwdwt6ysnqd.onion:8333
+z7g3tx3nucmd5ozvs7wgq4i2riiufxlutv2usowr3p4lixfbx54fc3yd.onion:8333
+z7g4iekn3i7nliiowlt3ek7o6xlhi5tv2hofycacjqkpeoijghmiyxqd.onion:8333
+z7j2lcfj5b3isqznsb44ivi66lwmidcfspmvdrmhbfuyub2h3wbmnkid.onion:8333
+z7jbbwkyza6e37iqos6u7ln3nedom5i3dcnowdscr7wfj2xygre47aqd.onion:8333
+z7jtpaghm4na5po5p27fwbdh2aq3z4rkpwhhzemlrhsoefru2z5eyvyd.onion:8333
+z7m7rmzhol6swqnk6l4sadrjgxwnggt5zwgp2jx6tadca74o5puyuyid.onion:8333
+z7mcuih5vw5qob6o5qg27jhozuczpqx5lmzl2ghfxra53tov2h5xtmqd.onion:8333
+z7rxmrmvtsbgrrwwh4k37bpkk6dtu3aq7f5d442ys75nepy6r2q2xaad.onion:8333
+z7u326iowflnv6tvy6uiwwkusx4vat5gdaxwamcp6jd2we35ih6zplqd.onion:8333
+za6k2u2t22ohdrpqbirjhl75eadxcjvnqfkl4bzeygbnliqsc45gplyd.onion:8333
+zabx7shizdfchrfthsjcuyypqy473ni23ebi4aedow4bg5c4tl4cxbqd.onion:8333
+zac6qhbqbb5yo4rvcsmbilp33odkzfwrftwma4yo5hor4brj4d3ksiad.onion:8333
+zad5dkykkoelu5tdj7l7mr24pdf6eos4o7cbs5nvx6bcg5443eqwaiid.onion:8333
+zafdafmd2h6ue2pmuj25chhmkqad3jdcxwtaess2opxkrroopwdqfvyd.onion:8333
+zagkhagdzvkgpuo5znflvxcqxal5tweg3vsaoaonsvsl7r7orhlwshqd.onion:8333
+zahrvinucuxpxu56h6nkiiw7cvutxrua65l4jynvwkzt2bzmeuvdpuqd.onion:8333
+zalrhwuj5j47tntffl77xrdehzfwq7c7duhaq4jwnq5vdtdtajwiucad.onion:8333
+zaw7gnlyeqrlpgcmsp3e63anveudschhifaaezu3web3z6pjjdtvviqd.onion:8333
+zayfuym6j35mxprdsm2x7pvws2vyaoinsomdbgrqbe22rcc77j7jtnqd.onion:8333
+zb226sk3eljxccaswfgouu6mitu43sf2dan4feygrqnlvrot6z65oxad.onion:8333
+zb2qixzmsethowd6fqnwikvp3yeeeo3zvhgjmq2yb27tfslscgkp2zid.onion:8333
+zb62u4o5qzst7rzjaq6tafgzoybi2ncogcjp3sf7zbto7b2xmicwvyad.onion:8333
+zbci2c2pkku7hwg64ek4z4cbyn6o5bnzpzyriqwjckzgs34xmu62szid.onion:8333
+zbmhiorqlldelgniyhwogswpvrlcdjqxxcfm6vulenrpwiadvv37anad.onion:8333
+zbnovu66ikceaodzrkpwww4vop6iwvtebbeznngo2mtjkikwknqzgrid.onion:8333
+zbwbqxytihkvupc5zhezoh7oibfb7bopfcw6y4qbhh2kugnsw6zur4qd.onion:8333
+zbwpgu4z2lfuto566v6duz2qw5kkyvor37rpihk244bfjzqiuohdcyid.onion:8333
+zc2c56k7hcdux5wrlpixrx6lfutylfamr676tu2nr5z2vf5gwoyzrnid.onion:8333
+zc4l45jx3txlag7hduov4su5kl633sykaw7guioejg5pq2qyuescabqd.onion:8333
+zcc4wsaenndkzqdp4xsfzn6ilsdhwzpqiswumdc22dv5ejejec3o7qyd.onion:8333
+zcdv7z3vetrpeo7souyie7u3vyy6w43cuautaogldhs4n2fitytsihyd.onion:8333
+zcezifa7mmgv4voul4jf4wbqmr24djgrskwszktkt5hihywblltpahid.onion:8333
+zcif26i4yzp53k3uedswyrqkdmsmkflpmclmasdo6hat57pqjpm2omqd.onion:8333
+zcnl5vojc5aufydmssv4yxeotzeqpvyoxyae4kmoskty77j4dx4aykqd.onion:8333
+zctnwv5ln3yktcyqsbgie3qcee33x44b5quhjdq4zwjprl75r3snduid.onion:8333
+zcugrsfyxb3y5ucbdndifvt5ilp47a2233sv42ryf2cvzoncrgo2mrid.onion:8333
+zcw6xk4bfnl46fx3mkrmlnknbwnpssxsp7hlllj34fdrkutzts6yepyd.onion:8333
+zcyumipuaiotm5fhffmhit3ajzrgqihhibh73lvjo5hdt4aituudguyd.onion:8333
+zd2mgisets23i4mslxjl75froqjygtue4lnoq56qk3ohd4qcxpop7pqd.onion:8333
+zd3fxn7nwlj76qyjseubm4o2gs73jv2g22px6t24z7p5oeogqe3icyid.onion:8333
+zd7irysta3wti4efbjq3di2jfv237nhwotupj3rtufvvav4e5umtkfqd.onion:8333
+zd7uq75dlcseq546lmbqymh37cninokajwkixpvupillb7fgpqgbwjid.onion:8333
+zdi46azujxcjqa2wnvdecld3bdkps5erbodcvw2mn424gk2by5mterad.onion:8333
+zdm5zxotwdsma3jvij3jmlke5wmblwy7qa2kikfctlzltexx6l35u2id.onion:8333
+zdn24r3iovbxfkp5qx5ng7ribn4cqm4v5ers4olnbzugyp2gbhd56yid.onion:8333
+zdovdneke7oxtxdnee7f43vcu5mjzoa5m4bexpxgvopa5kaxyrcwa4qd.onion:8333
+zdovy6gcj6nrmxaygnjqf3ym5hbd3s7h3irznsbrjmgdywd2rkj2m6ad.onion:8333
+zdoyjklv576u3w4paxyjb4jmdhx2id7xoqkd7zn3sspodasmmazbbpqd.onion:8333
+zdqon7u5ofin5gy4rcmkixc7u42xypwklntwceohpektisokskrn5gad.onion:8333
+zdqxfzqxbaa654nsngnaqdz3jfsfe2u4hxs42covbct2dou7z7jpa7id.onion:8333
+zdtchifs5gqldijr7vzcgqqaftlcydhatm57owdwzrgudns5vpdcx3qd.onion:8333
+zdzkcrnoctqhn26hjbngpcl54nmvozbodf4gwf7anfxjrwhjxgurrdad.onion:8333
+zej7mizjlb26qecppzvgyswervt7ov6f4x6fwrot7obvab23xsv5jjid.onion:8333
+zejyatwyaptvvubp6b22cpow3an47bsrve63l6rerkldmuwwb37b74qd.onion:8333
+zepqddw4zaqqawkx7aqezpqwykxmxxeh2opnl3xnq2i6piazcvyb6qid.onion:8333
+zeso2dbskp3curnpgug5mjyvhs7i6rero3zbqo5n534wccstcok6ywad.onion:8333
+zexnlgnfxldyx6leiqvyhuimrfxznjfjoko2ek6rdtu4dvwkvztfysqd.onion:8333
+zf4cm7bgv4qollcjcj7kpx4qrtqzcsa3q7sds2jc3mxu45gvazlts3ad.onion:8333
+zf4k4efdpcwsfyobz444dgdfnsa6tdbd6aor7p2s6mpuol3ladssb6ad.onion:8333
+zf6nwlrrtd6q73svcimgfp54pinn46hbcriqnqqsitz3fbibzmkev3qd.onion:8333
+zf6tbmhchmzo46lmhx6vu3smjj3y4hjjrv4lnwpa3uq7bvtjcwapmqid.onion:8333
+zfhx5nerqkerm3jfoq4763vlmay4pifit5a6a6jtcjxpu7t4galhxwad.onion:8333
+zfo72va3rnioxbhh4kuth4epqwqque74aehlonvde3re6mvhz4uzgaqd.onion:8333
+zfomias3uj7w6sai3ty3coxhnb6voldudbeyldgyedxqo6kfc7rg7sqd.onion:8333
+zg2yslkwabguckkqanyxwbncrtozc2fjivsyesrcd27xxkowkbcwnxqd.onion:8333
+zg7obxhb4c4j3dgzg47zffbetclv2so4foyutdxizfnedhdkhjzo2cid.onion:8333
+zgaubbm4h7qckt4pgtp5zawrcf6aazby2zk7aeo5xsqpgwsc2yrlbiyd.onion:8333
+zgegpxbr7z34gupenib4tuwywyk4nlevo5dkfg3jt6c2jw23len76qad.onion:8333
+zgjrto32gianyp6i4gc73nlilodiqyo2s5dkr5ev73yq4qvcjxkwycad.onion:8333
+zgp3f3dmwbnr7257rouxkgddijr34keobzrtk5gkm2dgfbw2bylcwqyd.onion:8333
+zgrpshddeijmdp34xfyw2kz22la4jxgwce42pupjp3bo6xtchsorrxqd.onion:8333
+zgvklnnz2avqcnyiffw7t6umb3is4tfthnkzbhnyfr76sjtwu5u35pad.onion:8333
+zgwclfbi25s4ta5hfiwylboeitti64xzoan5aewuqimp5j55nye663qd.onion:8333
+zgxg4d4jifuihgozqblrt3kjkrh5zhbr4uyivtrzf2khnbtbe4z3qxad.onion:8333
+zhabxolberrktnga2eixvhe6vmaoxour3ktd6jgjq3emzkgthsmaq3ad.onion:8333
+zhapnpxpk3lmrfsmhluytttodeosmie7yabywa3aaxmtkreh2lmeemqd.onion:8333
+zhdd42th33pv6qnfi7v3w3gddy3tlgu6pjo2bhh5ezuytutxhivbtqqd.onion:8333
+zhea7pvhuzw4cte7pkd7u6lwjyiqczxi7wgvzhfovtjd7qwdc24pleqd.onion:8333
+zhgdvhnh5zymbwrmd2rfjncparbxfiyraqh4imk6kl3tkltgccl5cgqd.onion:8333
+zhhkv5u7pxuu36y7vzu6wlbjpd3wftxfuadsst3ifs3q23eydmako4yd.onion:8333
+zhhxxlz3wvdaj4scdetokkqgs2ndmdvyfwq4qwrn3l3hv2iftlgsucqd.onion:8333
+zhrzks7gkdvyef6s2aogxxuw7iqheixmrdzgkqotpvl5bjz4vq5tkkid.onion:8333
+zhwmsba7q6vn4yfi63p4tc3dobsarso4322ynl5ofggjbyiozefttcid.onion:8333
+zhzpumb4itgdxy53chqowtu43ru23ag3f37r77ydjs3t5o7bookfe3ad.onion:8333
+zi77cxawtknqkjiod4rhf7gsughbvv2z6e7mg5kax465uc4vtg4cwlid.onion:8333
+zike5s7xtcgp6frbjgzjhcz6gsvd3pghkl2jin3sdasrek3vy7l4ibqd.onion:8333
+zip37ysefmcbnyqvt4jiag6dj3h45ie7h56hmw7ktheotkuagippyiyd.onion:8333
+zipzgdr2m6gmjfucup7xpertovt746f57hrgb7lj6m4rxeniem6zdgad.onion:8333
+ziquiv5d3hditb2r2qmt7hn7knosdcokxe3khj3kgn253l6cynl62zyd.onion:8333
+ziyp62u4xfsuljn5ae4n7jea7wfd6vfutket2e73bzrhpstozs5364yd.onion:8333
+zj55khmgsehm24efh4nmye7oao3u3l4tjuk5edghey3mt2ippfste7yd.onion:8333
+zj7jf7o4b3qztdorj2stojv4us7lzqs37fbubqpqq2wu4dxi3cxpa3ad.onion:8333
+zjdf27w3vt4rpyb6usa3r5yi455svyaha4qtsfwvyrmf3hmz5hckbwad.onion:8333
+zjgnxih45rz3kalgxvhyebyavcnohmoa3bcnl5cwkmq5pmbyypavqcyd.onion:8333
+zjx5rmakdzormbwzl27w4xcucehwiat3dnncoqdiwesbmb7dg4fpmgad.onion:8333
+zjy7d5t6rxljc64pvta3hqi6yxzfsnixtbslafamoxiiw6ptcmv3kfyd.onion:8333
+zk3cgisxp3uxevuxmbzbmqyhvkhezspeydo2bmhu72b6mw2kl6v43fqd.onion:8333
+zkc2lid246a5jr2dpxtvmtu2tfiwt5dbry3xybu22b62vguco5a4qvid.onion:8333
+zkisbl3pv7dsz3szdawti4r7mhrhssqxf3uopi3vrib5dpt6u2u7ckyd.onion:8333
+zkjnuuenigzhs6d5y62jct4tira6fzijqx2k3yzsdsyulut6ywp5muid.onion:8333
+zkjoev53w4e547zot35onpmij4fiube4aomnysttqtv576zdr7wex4qd.onion:8333
+zkl2fsiisu3cyhhsua7qlr5afhyvmfh4qmapgubioyhoepqdb46jceqd.onion:8333
+zkl7x3u7365zj6opig53dxtty7ctw2ijidwa4lbdbhcv3wkld22bvxad.onion:8333
+zknqouk6z7g7h5y7rmycqb6sgzykylbbfpvf5efmzibww377iminltyd.onion:8333
+zkq4fgcc4bxksbsi74pjwjfby5tdwn26yhjnmewy2qy6a3l5p6bnaaad.onion:8333
+zkr66xkrvecgu6jkyan6nxvtefynf2mpsls5csvf6lt6ltqvoscw5yqd.onion:8333
+zkxe2fnm4tsmbu4bdge7i7j2cesfrq5oznfzobf4mwtejbhenp7ubxqd.onion:8333
+zkzj45moxjhjvrzqweh5g3iyucdb2qaqby7vdtmlqbvxmm5u337aglid.onion:8333
+zkzj4uhvvpav6ee7djkfj2uem6tyswi7idzupkozspbgr2kfvrk5biid.onion:8333
+zl27cum3gly7nfhwl7ulnob6pyichpxglnss4ffqv3terkquhf3dm7id.onion:8333
+zl3dx4nswje7l5p2fgvypve5wugfqtcru2ud55qo77tqdp2btm6kp3qd.onion:8333
+zl4gt6uafawn452rlqb4w2mujut5tjcnq4ahdr6ucdyeu2gtzlsk2jid.onion:8333
+zl5voqvgyf7deglpxamz6hpg4bierfngqsmmu72wpeut7toja47v6bid.onion:8333
+zliat4frxeuirx3nbijcljvgr5wembicg26fdpgda4pnps4oguaobmid.onion:8333
+zliy5o4uqgpqj2nbgyadqnlomnjtmdlwoxcuduwcfavzsguj4z4iwzqd.onion:8333
+zlkwqytpxbhkg4umwpqiynz6niefzqjbiwzryg2zpwwmvmw6pmssngqd.onion:8333
+zlpztcqey4osd3omtpsm7micrh6jrxuqzeeendpngk25iyfhleieekqd.onion:8333
+zlx2jkuv2iuzffo35hc264rnvoimzccvtlljdbmut4es76qe5pnvs6yd.onion:8333
+zlzhg5hipy7nc4ulsaprgro53f63mjj7je7m5xptgkksibgvbc6r2fyd.onion:8333
+zm2j2k2nl7pug2amadjkrcgs5omdnxctyl7b6kmlywsphcfl6c22gtad.onion:8333
+zmfmdmzlsyy7owe6vpgugvdq664vjhluqura3skjlm6fzpgqe6udm7ad.onion:8333
+zmfmmn72dg5jjkovy4jt56c6btg7pgp7wmeh547zlvavwmlbrbsl5yyd.onion:8333
+zmjncrrwtui476nyn6sqbp67bvgdhotllq33vzwygasumv6d2us64iad.onion:8333
+zmmtddrew2mjtghs7zjiyi2eelmyss7miyj2axzwfgnmvzthx7phevad.onion:8333
+zmn3jyv5a2rod2udnreygi6uan4zq5ul4mhewyfyrf7a3ury72bycuid.onion:8333
+zmqvv2cdxjj3vbclq7l6rfdmjegmixwkxsnzzd6qezwp32vxkr2cbiad.onion:8333
+zmt7psgtnnqxk6tibhvwkdfuhtgtjatz6bpoyyl4ptuv3u6ko2b5o5yd.onion:8333
+zmtd72b4nsa22ocez2hbjsxxrdfuxxyghg3zjtqjob5sgnjpustat4qd.onion:8333
+zmuuhwxhoa6h53jijpb6mczcvtxhw6zyjymm53dwzsbmkc3kkv5v64yd.onion:8333
+zmvriguathsanquofxml7kgcda4tkihm5qked7a6ntbqk7rmz7qadkad.onion:8333
+zmvritlexdmgatfqjlexl7wsx3lmf7y3qxe2kqeergb7ntkfu4nky5ad.onion:8333
+zmyavuyz774c2fo3eb55yokivpr7qfxdpjy2t5wpeygunhulck7yxzid.onion:8333
+zmzjx42yxlpepdgya34rvwb3wc2peggturiedmn4sfjltgy6gjtspsid.onion:8333
+zn3gjkpqkajav76kaem2espqt2bw6ggfvmn4u3gmkonds7pqd5heqkid.onion:8333
+zn3mj2tggwpbzzkvtsovkrbdshbsvac7n676hbi76r72de2b4gknpdyd.onion:8333
+zn5purhx3rnikkks5tx4scnjlhewwll3uzcs4pgde3qeqawof3jefhid.onion:8333
+znaiehv3qrtloxdi5rkbs4eqpmuveazuftob3sqzw3ta5pyakuwhx7qd.onion:8333
+znbv4cupk7rrdk4rqi6xncbouhscxnqdlbxtltp7564isfv5vtbyu7yd.onion:8333
+znc4xhwywjqejoioap3ssxvtsdilsc6i5o5s2rnp2ecmxqe6xe2nh5yd.onion:8333
+znea5ol7qgniizv3og2gfcbxw2wi4qhk7dfkdlt7bbxpy5aflljygbqd.onion:8333
+zngxgkdgkqpfyepa5cvxlaxvlyluzdryhzmviar4ojzaduxw37hhdmqd.onion:8333
+zni7kioacgsy5haqiftnexr74sv7rzvgy5o6lmz6dy26vvwg5lffioad.onion:8333
+znlvmmj4dvpju46kbb6mob4kufyf5a4qivyygmjj36kymbaa4nzi42ad.onion:8333
+znmgbi6qlwwwdlizjxsc6eujnfwgytufu6guo67b54av4y6inwgxllad.onion:8333
+znmwoazdkcffprail6h4p4opy7i4zqomhpdxe5l5nc6ejqagvt4i7yyd.onion:8333
+znt2jb6nivjgl47s2gdcgac3merqjfq5h2n6x6mbjegx6fumtl2ownid.onion:8333
+znvkqu376ienu62x5hprstn36jfqxospcnfhpc3kq5quwcd6436pzuid.onion:8333
+znwekshd4os5a2n222xrllgjuyvsw7hsb2y6br7pkwjatywk5lerbtid.onion:8333
+znxkxyd564sfftgjscsmi3a73jsazxwhsneix3bgto4suyjx356xewid.onion:8333
+zo4fczw4drgcbsumtgmigjkiso4miz34ltauajaawqmqoa6oxmzy4nad.onion:8333
+zo5jasvz5qo7pkgrgn4r45twdic4zake6zpjfemj6x2ioxcwvs7yzlid.onion:8333
+zobj27bempyxsigdvawc7foivyyuek73hemep7zf2tajof54353ok2yd.onion:8333
+zodjfmegrevmjbppq2t46iluruefbgh3b46tbrl2s5qkprvbetk3euyd.onion:8333
+zofseltpp23n2xb6fsmfgkwgqggwhrelxmt7zq7toazybgehbs7d5fad.onion:8333
+zohxazkomcr5ggqlj2edu23zs6xiay7wfsrxuetrn2k2s5gwhwhcngad.onion:8333
+zokmgys3gsgs5oivjcqp3xiki25iexezy33ekzuratdz3j5unqpxrzad.onion:8333
+zosjvclhqzwklml43hvsdmupglajj5lfdb5h5frgym7hsqo25rwrbdad.onion:8333
+zosk6fx2a3mxkfaeayziiuizq3y3j3azzp4ylwyh76wq2sqtaenuwdad.onion:8333
+zovm6wkattzmxc755cgqqd4sxugn3jaxw44izlm4yfpot2ucfeqnukqd.onion:8333
+zowc7rklhd6xhje724xomkftwimuihacwcnxkt7vhbjpvpkdahvlhxid.onion:8333
+zp3vpkpcfdx5lxvnuellqaf5qdvhu4luf4zqfx5xjo2dge7cqsxhsxyd.onion:8333
+zpgobpk2j2suauhuzfmh4iiz3y2zhj3xvb3g2t4a775t72stt3majryd.onion:8333
+zpgybnbaxfvzjeus7qna45zchxdkekjpk5webdkeqtxfwcglgogm2vad.onion:8333
+zphjbml3fqtbez63bjvd4s552yc2xebitadkpw2jon2qkbapbiltijyd.onion:8333
+zpnoo3qordv4xj5hjynkssu6wechvup6to7pamrgbi4ljmfugjyzwwad.onion:8333
+zppmhj76a6dyjch5qtubosxcyvtwjnb6zndsfywxci7dy3vc6lbfusyd.onion:8333
+zpq2nzcnlasmy3rmwtmaybav6t7xfrvorqqdwntnbgbxqujyy3dkwlid.onion:8333
+zpqvo25bxu4n2u3mh2pdzax7wmpsitd3qsszgw2ye3mpfdpjbg52kgid.onion:8333
+zpx2tq27yviwzbpc4nyjfqtlhigoa5k7cwl676nft7bkajo6jq224hid.onion:8333
+zqlwzzfzdoacgngtsnofmyqetag6o44f5r72opj733y434b7npnb4oyd.onion:8333
+zqq4g2eikcfgls64ffstsylfbqrfstm6n2otvrsbtvvjpqwgyqdnmbyd.onion:8333
+zqrj4fhhp4mq5eh5xptzcxjzpae37brkdn3voz32qsohl6noijygdkad.onion:8333
+zqrwah6dn3t5fuj7ohlyka27zzopduhxy4wyknfrtqpx4sykece65fqd.onion:8333
+zqtyvr7h277x5rxin6rhsrsbhwcfsyyiqgghpk6jlbewej2v3tn27yad.onion:8333
+zqv5nepyrwezkym2ba5s2sskmi2qck22snw2rygeke45bxg2o4vckuid.onion:8333
+zqvbnqwwhtoux2sxicng2blfiowk5mvty7c5xnssxwtlsjzalhg3zqqd.onion:8333
+zr222c3ybuqxn6a6piydvfos4zjnaklfgh6kofmujmolpiprfw4z6vqd.onion:8333
+zr6ffisxxo4gelmkoyb7izfm7ehjrbqbnzuguw34to34bqhxeeqzzjad.onion:8333
+zr7sqclimv46jdnmmeazqrhflhiqkhhrz5i3ed7yvyue63swk3qkjnad.onion:8333
+zrrfr5sr5wrgdt6rn44cxnotlvwe7cl67rgssw5dwsax42evokdaw6id.onion:8333
+zrrhgs52ftlylshuwp5e2uesgqnwct7h6cqhzofdduwoi4sz3shmxxad.onion:8333
+zrt3rg4paxmo24ucd56eehl7apindhbubq3ej3q5nhr6i72jv2eznryd.onion:8333
+zrvsjjrb3lgvmeftz2vfjva4pl63htmv5qyviq7zhnfmlk42evrxdpid.onion:8333
+zry2rqlcqf5p5e46wc6nmtcbt5vd45mf4hyf4nxlqogckoniufdjklid.onion:8333
+zs47b66pljpz4ahompanciv73xtztnnzkx4wjklt6hh4drsge4m26iad.onion:8333
+zsalwutefh6m6x6yxccbhulzrz2bmo7dzu2ggu4hxp5zv3xx2j642dyd.onion:8333
+zsbzferezmnyxhpktxtccn2xxuggmdzdnrza7pqjlnwjorgx57y2acyd.onion:8333
+zsgtoyy2svehhfba345dx3dazp7tfdio6o34zxlcgylq6pi67gjq7nqd.onion:8333
+zsi55x2nvjc4oqrpzzopkneukb5fudnm4e6drao4x73lf4zshhcvllqd.onion:8333
+zsipwsjpm4f3p6ueczh7lqei5rp3cusl6t4d6nntnwxq72hori5f7jqd.onion:8333
+zsisadra7jlxp5nhec2vsjwspvvnk6jemjxk7zn7arypl6cm6dy7mwqd.onion:8333
+zsr43xqj6nsrqh6qgxghadctltwytnaw4zmlvx6exqybt2qdt72f5yad.onion:8333
+zsxgefpkofjc3nti4qusk3pdqcfinkljajlwcb2cee2tduxltxbmrpad.onion:8333
+zszufrszpweaoysubpdnqparmyotjnev6nhhcnejhjjftu5sb55kesid.onion:8333
+zt6gkop3n6aggrxucnaqp4yrjeu6htwvuy2nyn3vadjjrodwxfhfv3id.onion:8333
+zt6hvzyoalzm4a576drn7yfvdetdvzwwouvfz435wzrf5pcnxqxplaad.onion:8333
+zt6v7eqh7vvlwy5kjzbdfgkw3syj3nnhckyghlzgmwwfccxvyfusuzqd.onion:8333
+ztcmlrstdkp7coheeolpwj75gp3imzgiw26xnoiucquwhxxcofao63ad.onion:8333
+zthmey4ueoutf7q36nwgujxu7hq76s5ifbtanvze4mxq2s2xq2cmjwad.onion:8333
+ztmwsyo35zkogpftujm2o7oilhucjxe3w6bjagsaiwtb2bu62vgjptid.onion:8333
+ztou4ytvgvpcakjaje2c6l5j53rxcxes7qhkerszi4haffxfpj3kdnyd.onion:8333
+ztwryklhcnfoeck4qntt2aitoilit2cmmr2geyqo6cjc4nwr7jlludid.onion:8333
+zu3ekh3vtqjfnxqjqlmnq3jbqlg2zum4ehgirz5cggwe2thjmgkz4cqd.onion:8333
+zu3yh7mvqw342e7qt5amwtwe2btjubi6t75k7wgcpsyoicsnpgbgj5ad.onion:8333
+zu76ecbahyc6ofjiiutna6myxmfdcsuhcrhtgpifbw3vfo7njd4b5tyd.onion:8333
+zuaotutv2ngbf5ot5kvz75uehbh5e2j726fglhqw7omk3b7xnaastpad.onion:8333
+zubmiztmnfy2vqowqmpyzbqtf2a43jgazsex6zlxokhfmnzmi3rht6yd.onion:8333
+zuc7sobx6ttj7lswk32raexasfbxc5kd6a3l6td35srqzkj3emsv4uid.onion:8333
+zunmnr7czrxvfjgxtvkwk6ziti5kskx4fi3j4dzahhdljfsqtz7yeqyd.onion:8333
+zuoml3m3jdkoh5bdrwfecnew5f4mrlcwhmhkn456qsa72cp274pbgtqd.onion:8333
+zutyd7pzkyejctriyr2lqlrex3arkunntsdjo3kgw2qj5u3fj5uyusyd.onion:8333
+zuzdl7nnjhy6inyqwsc5i7fae2nregm7wnyrtolaxhi6oiufyc7l26qd.onion:8333
+zv2nusexbcrncbutlcprevwhvbtqlyri3stjwmgl23x7fdqkmae6owqd.onion:8333
+zv63heoa7jstwhq3wg2nibip36bw4icd7jphccy3li3nut7gp2gojqqd.onion:8333
+zvbhycudpglrdi3sk7yixe64eknydwzzisc4n6xmxwhb7xyyzevc4nqd.onion:8333
+zvgutw2u7tu4dx7t25leghdp6j5n44u464mmoypafwstayp6ggabtkad.onion:8333
+zvjn5jscn7jncqss44uh53gvi6b4eycjqp42t6pv46bsr7gine5cbrqd.onion:8333
+zvmxfy5z7nxeknglvpbh7rveoppkyvvzvnpwxon2kgkepafnq4igheyd.onion:8333
+zvpcm7eemfvlklgqio3fgzcwa2vukg3n7caov5itik36kdua6mvm43qd.onion:8333
+zvzirfk3h4hk52j4u254y2np6ve2xttd2nugiccsqw2liiw7aqmglkyd.onion:8333
+zw4olgpxujj6iydkmhuxbx37b52syl5bm6embyebesysep2ignp2dgid.onion:8333
+zwbnovgpo4qxidylubpdrhxm34t23iwaniawfshiqrilttwqjnnlohid.onion:8333
+zwbqgh5le73aurfmbwf5ivjb7ycemwnjiq2jnq4sqz6epl7rdtd6rtid.onion:8333
+zweiy44ngrkfzhnaoqov3fopwqd3uhwsen4v6sdyf3ynmhlpuluvzeyd.onion:8333
+zwg2cvvkm37u2hicwbjasqzdqdhcblwvtzsulmz4kpbebf77jheiaaid.onion:8333
+zwrp2kb2covbrr3xdz2pxr6gg6ndnhpcgfvjkjr43eudnl5aswxgvbqd.onion:8333
+zwsapfrsxzsomsoty652jifwii56st6fg7bs2crr6boveh5o6npl7vyd.onion:8333
+zwtjkx5blzs4i6e7hwfeekcwufdl2lba4j65243tvkajder5iodkavad.onion:8333
+zwu3ep3zqki62b7ldjbsxk4dm4rlppkxpzzqfwsfvkoihxltm3y4qaid.onion:8333
+zwwpbfpymszcmkwlfozzl26m66r6n7xzgnw6bs4nf3pypqh36ya2w6yd.onion:8333
+zx37fw5b4eatt3dekaefun3ln67agpt7oqobeacvyq4keurbj26azwid.onion:8333
+zxaujdps5ce6wvk6ykbfquygtbli4ecvpokj7oyfxjqiionn3u3fdsid.onion:8333
+zxbq3k7hwswo2f374ahsmlgkpdj7ju7pyygurkvzqaoh35vmxleewsad.onion:8333
+zxc2bzuqdkippxthxbg7n7e3lznbcnx7zyitlhwvjusbwr5v32oxueid.onion:8333
+zxcnzlo2eigfig66vxyx43znm66a5i4ieuiosycgddgzdff4vhn6zhqd.onion:8333
+zxk4bqrede3tnlb7ymjlsoyupc37r2vqe647otr3nczqmgfeoyiu75id.onion:8333
+zxqdpu4gmvn5vz2kdld6c2swqdzknwh2czwsw55vx323orvtk6a6igyd.onion:8333
+zxqe6efq4odzd2mvyeglqto2cfggagoicgcvlvca4mxycg47jei4uxad.onion:8333
+zxzfz3z4nbb7u3ifcv2p5xenzpbnzuuezelbbjcfrmupxtqyoh7uhyqd.onion:8333
+zxzqhfwi3gdheuxmzagp4aw4aks6cii2llljapcvqhtqrxlksxddo5id.onion:8333
+zy4jeshnpx3i3wjcqrb27qcea4qetpez65wpocat5sqncz24xeo6sxyd.onion:8333
+zyccgvzokepone36ulu74l54ad4dtqv7a2bjzcvopj6rg5xhbc7ihjad.onion:8333
+zydziohabauwybhbqkegn4d5r4257bmfain36fatcxdbj2nw5zoa5vid.onion:8333
+zyetfkanxicfp6tt5tegkxlkoz5rl2i3zsc6hyyqizahywbktezfuwid.onion:8333
+zyjfoui3hrpsw3fo4owxrztclffqhr26wdedizvz5xvlgurgixit2mad.onion:8333
+zyku4bk6pdifla26hympigytlwsx4htajcn43hhobdbrv4tfojv3snqd.onion:8333
+zyl4kfejs3t4vefsvuqrqopboxrmztuun62jick4uh3wpu4mw7dpqlyd.onion:8333
+zyphknlr4ogrknj5t64qya246kdaasgirn4iercvesggqplzzxsisbid.onion:8333
+zyrodumrgvgpinhygbi5molpbhl6ndfs3lwtt55pumd6wy5k7nb3esqd.onion:8333
+zyvgumk5pcanh4zk3z72glefxgbd4dpyhsbzvqlsp2gspaw37lrhjyad.onion:8333
+zyyefl5unnw7lnrjlgfyvnytw4iy4n4cy5bbs2nudjh7wp7psvefmfid.onion:8333
+zznngqwcp6g55wkjg52rzeogk3fcdpopyl3zprh2fz266nykv4sqveyd.onion:8333
+zzntdfpcb3spf5pb3g2gczw2njmhwwksgxt3twbzjhbaisihg7h2ywqd.onion:8333
+zzsi7brufwylb52w3bcbqvp5jx6vribh6geiqfy5jhxpihqjjaox7vad.onion:8333
+zzthz644hdjxn3d54xrfe7snnuyhsx2cguy4kqb6dpc5u7aun5lflbad.onion:8333
+zzuipjogcfvs7uyfhfgesehon6viegga3sc6c6265n235pqmkwyqfmyd.onion:8333
+zzul2xvyhqvajnd6zfs2dzljoppx5lsp2xt4qad7256kpxrv3wzyiuyd.onion:8333
+zzx4r2yrkxul2kg2ojoeijwce3skll4wbkkjw5xprstn2o2xw6n74wid.onion:8333
+zzyp22x6ryzyin43pltkup6jki5ynboh6cwpucscx5a3md2tooqn52yd.onion:8333
+zzzzzzzz5bs2qnoijxlhxd3ibxipajesgprqlrxtpfbygw4zcaf6oaad.onion:8333
-# manually added 2022-01 for minimal cjdns bootstrap support
+# manually updated 2023-04 for minimal cjdns bootstrap support
[fc32:17ea:e415:c3bf:9808:149d:b5a2:c9aa]:8333
[fcc7:be49:ccd1:dc91:3125:f0da:457d:8ce]:8333
+[fcdc:73ae:b1a9:1bf8:d4c2:811:a4c7:c34e]:8333
diff --git a/contrib/seeds/nodes_main_manual.txt b/contrib/seeds/nodes_main_manual.txt
index 286448d95d..a3f00ad52e 100644
--- a/contrib/seeds/nodes_main_manual.txt
+++ b/contrib/seeds/nodes_main_manual.txt
@@ -1,78 +1,1029 @@
-
-# manually updated 2022-08 for minimal torv3 bootstrap support
-5g72ppm3krkorsfopcm2bi7wlv4ohhs4u4mlseymasn7g7zhdcyjpfid.onion:8333
-b64xcbleqmwgq2u46bh4hegnlrzzvxntyzbmucn3zt7cssm7y4ubv3id.onion:8333
-fjdyxicpm4o42xmedlwl3uvk5gmqdfs5j37wir52327vncjzvtpfv7yd.onion:8333
-fpz6r5ppsakkwypjcglz6gcnwt7ytfhxskkfhzu62tnylcknh3eq6pad.onion:8333
-gxo5anvfnffnftfy5frkgvplq3rpga2ie3tcblo2vl754fvnhgorn5yd.onion:8333
-ifdu5qvbofrt4ekui2iyb3kbcyzcsglazhx2hn4wfskkrx2v24qxriid.onion:8333
-itz3oxsihs62muvknc237xabl5f6w6rfznfhbpayrslv2j2ubels47yd.onion:8333
-kpgvmscirrdqpekbqjsvw5teanhatztpp2gl6eee4zkowvwfxwenqaid.onion:8333
-m7cbpjolo662uel7rpaid46as2otcj44vvwg3gccodnvaeuwbm3anbyd.onion:8333
-mwmfluek4au6mxxpw6fy7sjhkm65bdfc7izc7lpz3trewfdghyrzsbid.onion:8333
-rp7k2go3s5lyj3fnj6zn62ktarlrsft2ohlsxkyd7v3e3idqyptvread.onion:8333
-
-# manually updated 2022-08 for minimal i2p bootstrap support
-255fhcp6ajvftnyo7bwz3an3t4a4brhopm3bamyh2iu5r3gnr2rq.b32.i2p:0
-27yrtht5b5bzom2w5ajb27najuqvuydtzb7bavlak25wkufec5mq.b32.i2p:0
-2el6enckmfyiwbfcwsygkwksovtynzsigmyv3bzyk7j7qqahooua.b32.i2p:0
-3gocb7wc4zvbmmebktet7gujccuux4ifk3kqilnxnj5wpdpqx2hq.b32.i2p:0
-3tns2oov4tnllntotazy6umzkq4fhkco3iu5rnkxtu3pbfzxda7q.b32.i2p:0
-4fcc23wt3hyjk3csfzcdyjz5pcwg5dzhdqgma6bch2qyiakcbboa.b32.i2p:0
-4osyqeknhx5qf3a73jeimexwclmt42cju6xdp7icja4ixxguu2hq.b32.i2p:0
-4umsi4nlmgyp4rckosg4vegd2ysljvid47zu7pqsollkaszcbpqq.b32.i2p:0
-52v6uo6crlrlhzphslyiqblirux6olgsaa45ixih7sq5np4jujaa.b32.i2p:0
-6j2ezegd3e2e2x3o3pox335f5vxfthrrigkdrbgfbdjchm5h4awa.b32.i2p:0
-6n36ljyr55szci5ygidmxqer64qr24f4qmnymnbvgehz7qinxnla.b32.i2p:0
-72yjs6mvlby3ky6mgpvvlemmwq5pfcznrzd34jkhclgrishqdxva.b32.i2p:0
-7r4ri53lby2i3xqbgpw3idvhzeku7ubhftlf72ldqkg5kde6dauq.b32.i2p:0
-a5qsnv3maw77mlmmzlcglu6twje6ttctd3fhpbfwcbpmewx6fczq.b32.i2p:0
-aovep2pco7v2k4rheofrgytbgk23eg22dczpsjqgqtxcqqvmxk6a.b32.i2p:0
-bddbsmkas3z6fakorbkfjhv77i4hv6rysyjsvrdjukxolfghc23q.b32.i2p:0
-bitcoi656nll5hu6u7ddzrmzysdtwtnzcnrjd4rfdqbeey7dmn5a.b32.i2p:0
-brifkruhlkgrj65hffybrjrjqcgdgqs2r7siizb5b2232nruik3a.b32.i2p:0
-c4gfnttsuwqomiygupdqqqyy5y5emnk5c73hrfvatri67prd7vyq.b32.i2p:0
-day3hgxyrtwjslt54sikevbhxxs4qzo7d6vi72ipmscqtq3qmijq.b32.i2p:0
-di2zq6fr3fegf2jdcd7hdwyql4umr462gonsns2nxz5qg5vz4bka.b32.i2p:0
-e55k6wu46rzp4pg5pk5npgbr3zz45bc3ihtzu2xcye5vwnzdy7pq.b32.i2p:0
-eciohu5nq7vsvwjjc52epskuk75d24iccgzmhbzrwonw6lx4gdva.b32.i2p:0
-ejlnngarmhqvune74ko7kk55xtgbz5i5ncs4vmnvjpy3l7y63xaa.b32.i2p:0
-g47cqoppu26pr4n2cfaioqx7lbdi7mea7yqhlrkdz3wjwxjxdh2a.b32.i2p:0
-h3r6bkn46qxftwja53pxiykntegfyfjqtnzbm6iv6r5mungmqgmq.b32.i2p:0
-hhfi4yqkg2twqiwezrfksftjjofbyx3ojkmlnfmcwntgnrjjhkya.b32.i2p:0
-hpiibrflqkbrcshfhmrtwfyeb7mds7a3obzwrgarejevddzamvsq.b32.i2p:0
-i4pyhsfdq4247dunel7paatdaq5gusi2hnybp2yf5wxwdnrgxaqq.b32.i2p:0
-iw6tgpmbdykffceku5da6nzf2bmz66fvp5fpcvemfu3df6aq6pga.b32.i2p:0
+iy7go4454pb4p2zmnkwrgsi6v6oqv53zxnmalz6rnfjemxftapfa.b32.i2p:0
+j225nrmndwviihpe7ib6mm5h723cg62wrb7vnwofopv472ue3zwa.b32.i2p:0
+j2m526lqsujvt6b6xl4ipzbjkvkuecrye3vkggwo6jadvzqu7f7q.b32.i2p:0
+j2pyenyhoppsjexenznxvgqrcs4buv4nssctowgpg6czdoo3nyiq.b32.i2p:0
+j3usxovx7ukl645u77jud2mpmrk7ryh5yaxno6rceu77hqlxkuta.b32.i2p:0
+j42dsnjlg4vv33tshgs5jyham6plf3suj2sn2k6ew4tmcz3fpaqq.b32.i2p:0
+j4tjrfxnwcmbhkixmqlnotginhfxgfdvjahr6yn7j7rkbdqngh4a.b32.i2p:0
+jb3iui7grnljdjmsz7qbustrl5vn3ip3upnkzbaegaiklric7cha.b32.i2p:0
+jbmqtghha7hscwbwpi7ps2dnghq2bvxjnfeb5glngnvgjmeackaq.b32.i2p:0
+jd43pc2l73ek6hk2tp6hiyada7ed7vshqo2fvxbga2daylcghfyq.b32.i2p:0
+jd63whebd5yuls7r34mi3lnnuuhqxxr4lns672tzliru4vk7hwrq.b32.i2p:0
+je6ju6ihybxm5wkw5daeqjet74lscvi4ls5wn5wf7kiaczfggafq.b32.i2p:0
+jeidstlwdlt63lju7cnj2mh4fofysjnc2wcvilphynprd7jw64ma.b32.i2p:0
+jeox5nruuoopedsfpuoi6kwewmhbbsnhf7kib2q6oafvchxvmnnq.b32.i2p:0
+jex3ykw2nmw7owhgbtio5flv7us624bxwp46nr7rhmteujrmtvvq.b32.i2p:0
+jfdh65i4nhpg4obnoe4aqi3vzvbi6fyzjj2ee7s3qm2gbcnllkvq.b32.i2p:0
+jh2qxkjqngj2m5tn2ecaidfqac4awgnmkgsajntoqs5qqyjtp5yq.b32.i2p:0
+jh7ev4a5zfzmeyekinhtbqfi6c7xhvc4msdpyi67j3sxl6r44ukq.b32.i2p:0
+jibaw7ynbnxueqsy7k7jyvoj6ldzbuckppfx5wozt7mftihy5vcq.b32.i2p:0
+jicc5kwy4tv4j2nn6gfbis7e6dxy2kdvet3zpxdbyp74h5gpnxuq.b32.i2p:0
+jimdydczt6e2lceezopnl4fgz7q2jeqqhlqaxrgen33ouxk57xiq.b32.i2p:0
+jjangl6h4py2pd2gwamhqlsymyuocmpioneinzf5bb5qvvdjzzqa.b32.i2p:0
+jk56z3febpco6rbkpzzv3jszf4px5uztmoxzkpss7mxnzqlpsdla.b32.i2p:0
jkfuajo4ayvo2rbv5qdj443q6adqmnormbhsf2f7rlp5t24xomda.b32.i2p:0
-jz3s4eurm5vzjresf4mwo7oni4bk36daolwxh4iqtewakylgkxmq.b32.i2p:0
+jkvey2vfdto2ucudi4jlgsbpmlls3uwmlkjonfhk5yminkwzwi2q.b32.i2p:0
+jl4vr5kac7njyltivn7ut5afyq5ipzc5woxl4523emodxixci3zq.b32.i2p:0
+jmebfluhrl6ad5pt4ipevf3g3a4trcu7axalpubpkir6zlwovm5q.b32.i2p:0
+jndr5i4qhxs6aa2bqvufrgttq6enavyghi54dqfuku2qnstdqa5a.b32.i2p:0
+jopiw2tup5h5xh2hwef4oflgskawbpfmswub2iosmqocejijd4fa.b32.i2p:0
+jrert3o2rhbkpquybwg7tq4bdvlxeh6lnlcr5ddexkuguvi2l2pq.b32.i2p:0
+jrobuecgmuuqmpdsbxwbqeldt2735cgcemngoasnbbkdz2ufdlmq.b32.i2p:0
+jrvg22xvbmjyrkqg7mr622zhnda3ijtua65cqngwrven7sf5zd7q.b32.i2p:0
+jsg4dsxvgjcqz3c2qgtwi4ip3l4n4hlxodbvgukwaipycwo26zua.b32.i2p:0
+jt35uwbl5wx7ponyxomksrjjs7zy5yymvtud3nmogt7ci7xxlm2q.b32.i2p:0
+jvaoh33cpczp626ldwr4azh4hb5cjmxlbz3dq3cxisdlzn7z25eq.b32.i2p:0
+jvlj7qyxcmolf76wneyvmdxrpiezsxkiimapwxbdbiw2phvlyjba.b32.i2p:0
+jwqlvqmfvodnrslde2idqt25qxiyvgqdlr2q4uod5s6lkmlempya.b32.i2p:0
+jxjc7oe24vxdepkfvl365qfwrxcad2f3j43fnfuchtvqqkqd2rzq.b32.i2p:0
+k4mch53m72zv7jdda3poa2zn7bi3jacqwfb45peealxbhysdozcq.b32.i2p:0
+k4pjt6m25dcxno3udek6rasooz5ztqnywa3f2owpvcjzvisg7nga.b32.i2p:0
+k5ars7hsrfubadroe5h7oypjnqwi6v2vxxy6rmns7zubf66aivbq.b32.i2p:0
+k6eeshsk4vf34b5gfnraz4p5qb6scv4kw6eiltebel5exw6keppq.b32.i2p:0
+k6gt64xby5igmln5hfcuzspt2tndimzrdvj65yo76h22g5yhlvja.b32.i2p:0
+k7kcnrqe3ybqu2w3fali7zext6na7o5o65rx6f5oqza2lonsry6a.b32.i2p:0
+kbawcieyelwwitrjow537zpmdkncwiq42rhjgayw5o7u562mk23a.b32.i2p:0
+kcqkothplemakipfpeajxmu4xsszpaxpprgtuv5tgfdaqejg2sqq.b32.i2p:0
+kdrcbr6wg2bj6oipsbeqy6bp3v7dqpth6cheviysmvo4bdta7fda.b32.i2p:0
+kehosmgk76fxnjywqjj6nqs4ohg4hsutljdzjo4sswhxlj5l5tca.b32.i2p:0
+khxruoaom7juockko2tbxqo3bnrjmoqjhdoady3yyr4qacz4somq.b32.i2p:0
+kjaa3zlp4sipfxikketgvlx4oxq5ok57ifxenbiewmsrew6lcw7q.b32.i2p:0
+kjvrzgckasb57yqhluvjblx2ngxstumfg6uufz5mc7zyetkjlr7a.b32.i2p:0
+kkihsh2faw2gxil6it4glol4u37ccruuzsusyikquzmkffj3wn6q.b32.i2p:0
+km3b5j6cqrcqewdpuveibptw5gguwktwan36jlow4xykpg2dgr6a.b32.i2p:0
+kppcor54kkge6cgq47nzevlfrhbxingcjfmk2emkrdaejpixkqdq.b32.i2p:0
+kskidltmbigp2etp4pdl67ke2qzjjw66wqairzr4wn2apq4o7bka.b32.i2p:0
+ksxxinje357zctkobwnxsy44ddivq7yp2n3n5gopk4okir2vghaa.b32.i2p:0
+ktua3j43ijxhhhfeljsp32kdiuic5nlnfnkx3ealy7ojva4vwkoq.b32.i2p:0
+kuzu73gzvlnog4cdtdk7edbusxr4pigknvwg2bjo6l46ugsgmrtq.b32.i2p:0
+kw3v6gq5semgt4gg6itum3qtaylanyof7wn6bnbngdeby4xixuoa.b32.i2p:0
+l364nudwoj63fe5nsjmniiun63e3ycdqrjyknbfixxtre5spx7ga.b32.i2p:0
+l3ach5wbdx3n5nq53sv6tagijrbse3nwa2gkqz5oj7aifyaizpcq.b32.i2p:0
+l5fita4r7niir3hxmu7mzcwrigxinkrn4oqeembdkgao7k2yztha.b32.i2p:0
+l5obkk7zzop3nztnt6ijugz4okqsyhhb5o6gkbqottgqzzzcgvla.b32.i2p:0
+lai3534z6zs2tukzixdagrciezum2bkyuask2srxjrn67yu4c57a.b32.i2p:0
+lbif3mgg2b2ir5dkz7u6iatdrui2h2a64vlmffcfgqnpjuvwzaxa.b32.i2p:0
+leu37bptuuu5377mi7cb5t2vsu4hesblyxl5zptnnk4vodhovwea.b32.i2p:0
+lfuvzzzceuik5u5pnd2i67amegel5ua2rrnncxkyyc7bhteq73aa.b32.i2p:0
+lgpojpoix7zd6dhpo5hdrnwm4ueyjvi7tbot4qsqybk3upuocnpa.b32.i2p:0
+lh7qjombcmiekvv6niz5eflr55cnd3oxx7nuus6vmehqfodr67za.b32.i2p:0
+lhupu3owhuc7qwvyfazgkbcmr7sjp5qqxps732vy52v67fsn5guq.b32.i2p:0
+li4vuovafxjrf54kvfg3mjrg2mebs6edpl5yrr2dohddvgmxjyvq.b32.i2p:0
liu75cvktv4icbctg72w7nxbk4eibt7wamizfdii4omz7gcke5vq.b32.i2p:0
-ljsquuu3y4xje6l32p32inn6r2y6ull6oocgup6jtjrohrqxbz6a.b32.i2p:0
+lmlf3yjyg4djrb7wtzmrb4fbkorqba7k4lvk7ax4omay4mbytupa.b32.i2p:0
+lpal67whroip3c2yj4fxbayj46d3tr5osyqog6el5n6ctktdnakq.b32.i2p:0
+lpektonr2uyiohuzi35shtj3oaa77rklmqsivuydxkcxkea2dwuq.b32.i2p:0
+lpffyejskwwap2go7ommmryex2autlkmcnnpk2tm6aitxcalwrha.b32.i2p:0
+lpqkgbek3ci3w4qobpeqepjor3bukz555rzlmghck4o7wwb7ajza.b32.i2p:0
+lprgmkc45te7skx7rffpz72ca5c3zdg3tabiksdboao5w4wceu5a.b32.i2p:0
+lqn32kgic4cincyqlybpwbywcrowcxmscfcm4mqt4fgp24qs3y3q.b32.i2p:0
lrah7acdsgopybg43shadwwiv6igezaw64i6jb5muqdg7dmhj3la.b32.i2p:0
+ls52j74gwtsrqhlgqcai2cjl2rcivfib7jzovc4454h6tq3i6k7q.b32.i2p:0
+ls5otp5mybmxqsaeaid7wlori2ukieehr644adjfwdxux7jxlvga.b32.i2p:0
+lttdnbluvybzbjq52t5vbdkk3pvzc6zyi2oji7yjdpcgtgz732bq.b32.i2p:0
+lunkwblewltvq4spt7j5u2nfpqyndvgepl7edkiru322mmtpy2lq.b32.i2p:0
+lvdbqavgdom5h5denwkmdwslfzxckf6eddwflelbog7tgo2m7usa.b32.i2p:0
+lwjrapkfexjyjqf2rrdr4ghhxmlr3jdygsonetgtheglvmru5x6q.b32.i2p:0
+lyg26sjkcx5ied5a4a7jdxmfeplfcnux3fux5rsxzkm5mgbbsllq.b32.i2p:0
+lyqmygrc6gujxa4xlnwqku3vtfkbrszdiirsagn6xd2yw4kvodrq.b32.i2p:0
lzuu6mjtu7vd55d2biphicihufipoa7vyym6xfnkmmlra3tiziia.b32.i2p:0
+m2k7ajij2wvgfpsbg32zuorbsjt72iye3ozz6dbyxtj57fx7xsqq.b32.i2p:0
+m3hlmj2gz2co5gu4ss3wj4b7ebeg2xbkrr65ogxvhn76uxna5qma.b32.i2p:0
+m4o2kndr75clxemwbq5m6vnok7eiqshf42wjjvag7dtwxtafxhra.b32.i2p:0
m6bpynxkv2ktwxkg6p2gyudjfhdupb6kuzabeqdnckkdkf4kxjla.b32.i2p:0
-m6v454xd6p3bt5swujgmveklsp7lzbkqlqqfc2p36cjlwv5dbucq.b32.i2p:0
-mlgeizrroynuhpxbzeosajt5u4ddcvynxfmcbm6kwjpaufilxigq.b32.i2p:0
-ofubxr2ir7u2guzjwyrvujicivzmvinwa36nuzlrg7tnsmebal7a.b32.i2p:0
-okfxeoh6itu4f5f43dhbzvkqwfrvm5c66lj6lvjj4q2b35i4pk4q.b32.i2p:0
+me6x2p4m6jw3cxi2xl4a37u4orzmv3xdopr5t2vgwjmauiuqrmzq.b32.i2p:0
+mf6tmlegp7uga66cdael5376uaz4qd3wacuh44yvepa3kbu4fk3a.b32.i2p:0
+mhgxec57s6h7eixgemsghlcuhmgh7m7p7phqd5kzmm4wovrp2pqq.b32.i2p:0
+mjpulaafdyuanouslfpjcsvumi4edtckfu3ffn3ipabkxj4sn35q.b32.i2p:0
+mlakhs4ixcqwvk4vo4ce3loa54wmdlfingk73jookrkbra6ppq4q.b32.i2p:0
+mnkqn3r4jmg6vrmlprabenndyft2z2jw6g4nsnolt434coiklmyq.b32.i2p:0
+mnrbc3qi4zuk2tzghmy55kplawncih6jkmt75qczfu27enu3gcea.b32.i2p:0
+mnrrefebq3yxr2avprp3ay7w42sx27ijv6stjljzpwohnfnkg26a.b32.i2p:0
+mo27t6wym666b3wfauhndqocbetdsssxksep6x4dcpuh5dxe76oa.b32.i2p:0
+mo6mp2tymma5l2swob6kqzzb25ccmgccfj5pic6omjkktv4wve2q.b32.i2p:0
+mpi7bivbr2pywsgasslw5we766m757os2667h3hqnhcftaszdv3a.b32.i2p:0
+mpqb3jdmdibarrflyiik5wj3ekitxpe2oqieztlax3uomxspgsvq.b32.i2p:0
+mqocuhx3qwcwfuuin42yuhtqgm76drlmfvzikf7urot75qw3ykpa.b32.i2p:0
+mrbhw6ow77bjqmb67rurbkcl4xs2ocj4pti6hnz4wcsg6bduwtya.b32.i2p:0
+mrypjr2fagjhg6z4ixr73f5npkeyoxsjamcdv5uc6oj5oi2ylsvq.b32.i2p:0
+msjl4a7mdp7x2bcllmbxurhfmtxvolykonz45psmh7j6pptfyy5a.b32.i2p:0
+mtlznxqya5nbuyorybzul4cpdlrnvlrhalx2eogwjce5j32js5wa.b32.i2p:0
+mv7b44duaxqpzbdztnrdvnj6ypsp7yhs4z3dc2q64jov6pritmja.b32.i2p:0
+mvs5a3s6rgfbvvgq44wzyd57vf5pr3jcthc5qdo75xgj4slsm7tq.b32.i2p:0
+mwcqoe2lu7u6ogwo77kr5sr4wx6pxnotkdeck3yyjfh4uklytj2a.b32.i2p:0
+mwevh5r5dkzddlo2ol6bojpdds3kno4xqoy6p6ulid3paamgrtla.b32.i2p:0
+mwyjzdrgtypbwjyulw4ifetejz6xusqstvzylztsphpg2r2zf7ua.b32.i2p:0
+my66tuvzfyy6kkbdeqvgfpk3xuoxerucxt73tw6wxv3ian2p2snq.b32.i2p:0
+n3f4ngbs2igvp3j27vsi7thguqxoyvbfenaqhgypuqdz5iovek2a.b32.i2p:0
+n3fa2yuf3i3opdktiwyxzhbpudcut73valxdrlre2xs2ooepddaa.b32.i2p:0
+n47e4gkf5xujcamnsarfuy7435hfsgs4zhndcxaw2evafn6r2rma.b32.i2p:0
+n4n7bivjb2mffgll2ulpwyb4m2oomv5roxtdj6bmlb4cgpf3wdja.b32.i2p:0
+n4zwusew5coibur4p2g436ktc3cyogz3sklztu6ruulag3je6ita.b32.i2p:0
+n7ykk3cxcqzcoeipo7ghzb62ko4d6bxzfgenzxistvg6fuclebva.b32.i2p:0
+nazasriqoa6qoxdlgzjwsggubxl6i4nge5q7om7nijaqi24ulgua.b32.i2p:0
+ncdjjthck6v6phz4laddyc7a7czoujys55melfcoptvl2h4izqlq.b32.i2p:0
+ndtoi53fz7e6ml6v6jn33675nwciw7mu5msn7afzbhebprusqg7a.b32.i2p:0
+ndunnsjyp6l4w3jebow4zgsfrdsy2lrapjgslb3tv7dg6oypfbwq.b32.i2p:0
+ndx23xqvt4qezezih4wlj7mqtwc4nzbvmgseq6fc6e2ddywrmkwq.b32.i2p:0
+nejmippeopyo75wd3gjrhca3fr5mo2g37owzwdezxmg7uhx6ygxa.b32.i2p:0
+nfsi3fenzrzoccj7bpzuvjbxnij7dmzuprg7ia4geuortoquja7q.b32.i2p:0
+ngn5elnvbm234yyun5kbjyr76oy5nhrvyckn33cqcbx25hw4lfoq.b32.i2p:0
+nhpbv2ravt6t5fhxyvuhrxyma37wph6dzuzpddlw3uoivzl6tx4a.b32.i2p:0
+ni4ns3ou7v6zh5qrawvkwnmshnrzcyc5zojkw647rrniplmurrba.b32.i2p:0
+nigrfbou3zt6wxegn5im4cyminjcjmbsqror7ntcr5i7yv6chwvq.b32.i2p:0
+nij7pzb6mhrra5glb3dyghjt55sngwrikzdlagmpsf7jn2onvoaa.b32.i2p:0
+nisd4was4gm3pkvuwjh3sbaoo35jtxop6y2d7ug4iol4cffkrk5q.b32.i2p:0
+niyz7v5fdhqqtlr4y3tcgdoeu3myntub4trzvgixlgjbmowccgja.b32.i2p:0
+nloq52novup3cawccvaakmbudooatwkw7dqltnr6q3j4qy7r6oia.b32.i2p:0
+nn7p4y7pun3m3txaqbkeptkxykzwrf75ru2zimadnewj7g3r4una.b32.i2p:0
+noj7le7kkj54umo6mdftagvvk327cuir7q75bnvuphrxa7kjujna.b32.i2p:0
+npcmehkhh4z2wtk3f5426izrytvqvyf6aa7hyx6hf6jdbxveqima.b32.i2p:0
+nrrg4p7tztllzthlkqzomqi3dejfcak7t63n7zzuomt5atzz5m4a.b32.i2p:0
+nt3ysas4wpjgkft5pohrfstm2vgj7t2vx34u32voy7rqon7dlbga.b32.i2p:0
+nu2ao72zway2ponkhrf322wyfrrn4mdmyp7n5q5xzmjhcge5odma.b32.i2p:0
+nufliiw3uav3tzdalit224yhbfpcjtgfrm5ic7ob6l3mmsay6cpa.b32.i2p:0
+numilh7hhhf6inzkzway3hzif4kiroqstxqbz7hzvoy2ctgpaqda.b32.i2p:0
+nuwphtuudfrswids22qjq63zgxh5wu7erafl36jyniuxhz75ikyq.b32.i2p:0
+nvmuuajhaw74g565l3a7dpezs4rkzm22ub5jhh6mdvzu43j4a6dq.b32.i2p:0
+nz4lq7pmswngaevv2uqyainqzutfxlkavxgde2w2slo2p6e2kcfq.b32.i2p:0
+o5ijpzor3en5xnndm3ntti7o4fxvv24t3veh4g7mahk7ogesb67a.b32.i2p:0
+o6b747qkpgu6gvsem7leylvmxsaaqby67pu55fmqn52dgazuvbxa.b32.i2p:0
+o6t4fr5ayfadzieutstgwcllvwxeuzjlxmzsmpj3hpkvefhzfaea.b32.i2p:0
+o6vbupdnpd5bwvcx7ivaecgyo7x5vdu5em4va6cmx5iwcf5tyaca.b32.i2p:0
+oaeqbkgpek4qnm3nly76x2tfrad2tun2xefliez7a3uxddeq4i4a.b32.i2p:0
+obf5kfk5n4nnsw7ez6ls6chqu4lz4wlck7utwvmjnlin4nzfnspq.b32.i2p:0
+oeydvkjoeqy3473wxkkbmoc6zz5m6zcmf6ov2hfkci54efsityua.b32.i2p:0
+of2gy2vblht57tn6yfczslnmp2xybdiazzta43y24w76tl6tu2xa.b32.i2p:0
+oggn6qbpmbag224gumagzgno53mgozb65tpzt5lezjbfbbiqky4q.b32.i2p:0
+ognn4mwwtmtjbrnq2kur7spcfohivxlrvz3sfamt3t46pk2e2ibq.b32.i2p:0
+ogqdcq2igslh3n5jn3utz2vpevttul366bt2246vilfnowuyvova.b32.i2p:0
+okjamsyd4wutvhfhsffejwk6ioru4mmvwagfssoy5hcocg2gj76a.b32.i2p:0
+om32whhwvcsbrf4g6uh5hupsl67oapccourkxyr7uf5zwaqxtxbq.b32.i2p:0
+ommky7qetuh45h4lk3raili27fnbhsgxv3zucinoaymnymo5735q.b32.i2p:0
+omngcjfwtiyqwbfqqggzbkttqgm3blywu43kpto2py2e4gp7fhra.b32.i2p:0
+opnpvz7mzfw6nypgmnn5zgtlzx7xuc4w7vat5bsr4mdtp77kz7eq.b32.i2p:0
+oqrl573nw6my2o5mup6uq6pm5immw3gnviahig5cceges4wfnyhq.b32.i2p:0
+orvshryqq24l24e4dvockx2ekj4hu42otqxsvyvy7tm7hhdjsz7a.b32.i2p:0
+oukeldqgovavh3npgb2by7w6hug575uae24z6uqfdl6flh7ma6rq.b32.i2p:0
+ovnk3wfbrkvvute6vkn5glhdtlxr6nyvebiflvr5l6ws6sorpa2q.b32.i2p:0
+owexluejb3eszx4p3b6zuxyggsxxtkxfgxoylkagfecs3bgfnpja.b32.i2p:0
oz2ia3flpm3du2tyusulrn7h7e2eo3juzkrmn34bvnrlcrugv7ia.b32.i2p:0
-qd6jlsevsexww3wefpqs7iglxb3f63y4e6ydulfzrvwflpicmdqa.b32.i2p:0
+oznpphdisfvlcjgkvny6ma62wy637nh4vtpxww47ifpmlqkjv3ba.b32.i2p:0
+p3au2w5jnkqugxnkukj4rusvynvz3oxawdf4ajzeyxvfvyzhmetq.b32.i2p:0
+p4tsqwvdpaitvlgaujfr2m2qbr36qiwusas5zkiut7w2wjcp3sqa.b32.i2p:0
+p6o3tzllswm2j4wah35niry4tcdu6lq5b67ehevcx45sae7pb6da.b32.i2p:0
+p7ifeij3vhds3diihx5qimucyzgck5omfkqxc4pkbbjtfu4hp6wq.b32.i2p:0
+pbag76x5yyo5d3wypvtohxmgbtdrjjb35ljnq4w5fpoguyt5mj6q.b32.i2p:0
+pbftrtdthbj5qcecraden3hdvwomqrgseec6ib5h24n2zcivdqaa.b32.i2p:0
+pc4d5v74tr4vz54pbr57ejga765ep6vwk5kox55gfobi5572apta.b32.i2p:0
+pcc6cnry4maul7zlbd32khalaavkcbw5hdjuk4zjwposaorjicca.b32.i2p:0
+pcdlqw2awppohbiued4rffgs6n3lv3thhon3r67jmx2652qx2khq.b32.i2p:0
+peteksofgwgndsdh6ovh2ydkrgpyqgttit4ususs4bzksvdqkbea.b32.i2p:0
+phendyytrqdr2vfsw3kil6yui5vb2p4v5xuddezg57wsdw5uyquq.b32.i2p:0
+plhoz53xhplmyuejnsg5bkfe24ow3pbldysoovuupu6qwb3nttca.b32.i2p:0
+pm4nukrzndd2lvd3shivpjrcbjlontmxhag2xzdf572snwbr3p6a.b32.i2p:0
+pn5cx32ljrvzj6x7hpgyff3rlftextqpp4zn3nkfufrrpnpuimzq.b32.i2p:0
+pnhspu3rloczdbzsysa2iftsgoiy3zgcd22jodmk7zdjanhiemla.b32.i2p:0
+ppe2jfsb2xrmgwugbq7agy44ucb6yq4qbufaf2sh76b4kwpa4jcq.b32.i2p:0
+ppez53yrs6lanyvyxuxblqxiuvhnqvvtafmwaid2kgp2dx2v5iaq.b32.i2p:0
+pqnqwxl7jsrok7vgpgcvlxwlkg6yckx33n3g4xf5lvuntwn63b6a.b32.i2p:0
+pri376r6uuwgnbnevki7c363h4ryfwjza7pcbfswqqxk6hnrkhja.b32.i2p:0
+pscw5yzaj5js2fn7gzrzoj6teonlsohlbnvdco65ubdefpnpwhpa.b32.i2p:0
+pt3mqmvkv7aleja7vattlysu6x7gjnbwqvwtu4skzabvkjztfi2q.b32.i2p:0
+pu6e2b5bz75qnmp2rox252aksllnitv2grnn7qfyzjkfio7w5h6a.b32.i2p:0
+punslpht6pysnlteht24rgvrkmzdd437lnpflojwakl5dy6mbema.b32.i2p:0
+pv6g7uin653rerdiivdgtoirjvokjowi4b3fwatszdlteyos3i2a.b32.i2p:0
+pvqyvn2lpvoeyhgcgunoqtetkrkp76iegyoii2af4crnlto6gb2q.b32.i2p:0
+pw42656k2vbwxmvrc2qbsz3jslvcxahln7rehsbia5jdio2knh3q.b32.i2p:0
+pxbyhv62tcdqqpl6pbp3og7ajzzcnbximv5kyt3hid3djd3uwkdq.b32.i2p:0
+pyf2csixjugwp6ad3bkry2ulkzj7inc747dsmpk7iebuidk4l3ra.b32.i2p:0
+pyole4gslrmenfcmd4ilqyzvsuyrjyffjbw7angentqjkkljitqq.b32.i2p:0
+q3ueujd332k5qjxdqkjtjlgkm3ktvdy7ats4c2ogcvokog4wm3vq.b32.i2p:0
+q4o7bf37e6afx7evwdyovsqptjwo6td3c6qtjh4rtdngp3trwi3a.b32.i2p:0
+q55g5g6s47hi7pcuomug3vrcd67vji7us2gqmfe7qn2nkq5vz52a.b32.i2p:0
+q6lzsezu4idxpdwro4x6svwz7j6h6gso6enidcxv7jhc2gbepuzq.b32.i2p:0
+q6o3eqnyg44uzjzqeudsankgdouylshkhdhl7b4bqxkbmdnm4iaq.b32.i2p:0
+q76g4lkosb2sxenh47eutqgwwzjyph52rirc635wkwnxsejrzdda.b32.i2p:0
+q7ntdwy6xueyvghbjamfrh62aqtuu3ikwg622em44pa3czomrdjq.b32.i2p:0
+qa77lz7dl64qwtj4fxxlz6otkuvv42dciggnmx62eobs2xqi3vlq.b32.i2p:0
+qaqvxmyvq2m4wombmtaz3our3qmp7eet3qle5flnrs3a5wgfhxba.b32.i2p:0
+qawed5ou5vb42ugi42goxr2s6cqzpyh3s5atkhvfvyhyc6anxyaa.b32.i2p:0
qddg7myylinn4tw6kdjmmp6fsyetkosnrbp2gsjx77tmkqyqv6ua.b32.i2p:0
-rizfinyses2r3or4iubs5wx66gdy6mpf73w7uobfacm2l5cral3q.b32.i2p:0
-s5hhjtmlg53bko3nwwskas7xgsmeqzy6thtsj5aa64djyrljgqaq.b32.i2p:0
-sedndhv5vpcgdmykyi5st4yqhdxl3hpdtglta4do435wupahhx6q.b32.i2p:0
-tsl4dlpu2id252b6crbdnblruct664se6f2iw35fuqwa3te7wcoq.b32.i2p:0
-tugq6wa2ls2bv27pr2iy3da3k5ow3fzefbcvjcr22uc7w5vmevja.b32.i2p:0
-usztavbib756k5vqggzgkyswoj6mttihjvp3c2pa642t2mb4pvsa.b32.i2p:0
+qelsaseevnmz2unpovh4nbpjpshjg45iudiaf5zbngealwwuxe2a.b32.i2p:0
+qfbughfr5hhgoomasyviwk3zin24uerpl6urz5smzxc2div5ixxa.b32.i2p:0
+qfl3i45ipgugo7ueswy3ynnbaet77xawiplvmm3kp4fj72qvzc6a.b32.i2p:0
+qhuk5zq5v7h5p7o62gsxgtqqo7va4i77o5vei6wttxqcgaw47h7a.b32.i2p:0
+qivuqkrr3pv3rul4wgx4o4zon5wegidt5auylv3bhebfuj6oqauq.b32.i2p:0
+qjdftbhcaghdslzxjqx3nmem4z5p5jt7e7ou5bdz5llnqlxshe5a.b32.i2p:0
+qk3iq3wr6emttdilvdqbv6vnqjshuzz6mylwyfo3z6vpjywvnfca.b32.i2p:0
+qkohzoxigef43ro7mf2bd76eyneuuj2vfyremufvufssksbvj3jq.b32.i2p:0
+qksthizqtfdjjxcrahqxkl3bev75k24blagrkoszxen45zelijpa.b32.i2p:0
+qlhklv3q3rrszbrkxw755lpdburxwcj5dkxwicas46flztlkdcja.b32.i2p:0
+qmtg5ukzxemsktsxw2brwmohehyehwlleky3kuzeqzy4ledcou3a.b32.i2p:0
+qndgqhj3cpbxrktu6r7ysaooccqzvselvn2tphu3plx2z5ouocgq.b32.i2p:0
+qnqojlthym7z4gwizcblhpd2thy7v4a6ifme57bzyl3nxzkj6ica.b32.i2p:0
+qorzdjceszf432obxa73tnwhqb7ltxrxlfkkqmw2flmfjhoyv36a.b32.i2p:0
+qp5ppgozzbkuingg22zgamf4ozpe2n5hjlu4i25r6pjqw2ngrhoq.b32.i2p:0
+qpddavnflr5tdmeypeu5lrjjwsgtdhz7hw5emxiyjkcp7m7xysca.b32.i2p:0
+qpo3u565rmgeioruszadbc4vmpgjyoh7qorv4lyefl7geewyyz7a.b32.i2p:0
+qqiakw24obfwz375gfb6muzaz7tr6ani3od6leoox7jwzrizyxkq.b32.i2p:0
+qqmxvujwi4ktgj2cuqmw4kiujkf7ukrkoe5ryy4bjb7tyleplsja.b32.i2p:0
+qrpz67rcwrbpcockid5ml24dtdhhhekty3xd66ekkyatpfjd2wka.b32.i2p:0
+quzkrgzb5pmn4465647ke5lsfbseqnorr6ljvfsxcagj7rzl7hcq.b32.i2p:0
+qv5e4jlcmmkdlmh5spkvv2wgj343vm4yoty2hofuzi4lornn3hzq.b32.i2p:0
+qwhvlprhk3ntswr5xntnc2hhgmvd3bbgzgkbombiibhrsj7k6gyq.b32.i2p:0
+qykavpjbecssape77mrxjxwxces2gbjd6gzewd6zys32uhmnnw3a.b32.i2p:0
+qyqwn5xs24h65rldrle5msyarmqof3lb33uz7sutauwdg5qiuhoq.b32.i2p:0
+r2p5kqr7xjo4ncz7l6ekdx2ge6su2j22j2tdsoxu4jw3u67z7poa.b32.i2p:0
+r4ukdj7c2k557k7qd6siauhhqucshwy2rrkm66twzyh4jiucimaq.b32.i2p:0
+r5d5jgscvs6ix5v646ohwa64vutu7umfeknrc2hrezdjtlr4lm6a.b32.i2p:0
+r6d4moarp22wnnsnmsxqt3s32gzyscaccackcazvimrep7sa26ma.b32.i2p:0
+r6hd3knqi2p6kaw7hybrcf2q5lcarulcczs3sgcuz4yc2saj3gya.b32.i2p:0
+r7bug6wbhevqqlbavouj3ggpa7e57sbd3oivkzqeyagrtxshmjpa.b32.i2p:0
+ra7ztq7oq7jcozpui7c4zv76gh7rjwhq5fkpxp7dvw7ritick66q.b32.i2p:0
+rb7tyjd6gi7evmt5mzvtboramqip43sh72zjxnwhj5k72zfi3g6a.b32.i2p:0
+rb7x26lmepfbcd7wtxu42pf4tdxbe5p5zsf3cwuukd4fs4zhxtba.b32.i2p:0
+rd2cw3iukuth2lwe44q7fipawrne2io6y3fyyv5xew6vd3hos2qa.b32.i2p:0
+refo4v727jmff6ylrpbkvd5emlfr2hamaeh7zho6oval5dmnwlta.b32.i2p:0
+refrtydbdslzcgcsmmph3435qigyajh4q2nvl756f5yojouln4yq.b32.i2p:0
+rfgsjhyvqbunef5b5r2emjuoxx2i7rcsl7gathy2n4gwjyyat6bq.b32.i2p:0
+rg677vpfzyhsckzzcvoyvqdbwtdkqig7lxv4unmxcz63vtr6tgza.b32.i2p:0
+rgbq36syjadm2ex2gftc6xztivckrqzcjszla3jacwfo5hqutzqa.b32.i2p:0
+rizuiypjfhukt3bqnetppoauovuaqq5e6jzgd7tgy24zrwa2ydxq.b32.i2p:0
+rkhb3463btvfozwta37itlkt37iyncpkzak2xhoe4kg7tqafqria.b32.i2p:0
+rl4b3r5h5xodo7kiw4nykd4rhoc4j37kxizzyb6ukgcomyc2qrya.b32.i2p:0
+rnsjgirap5lfhxpb2xczuawgoztb4ptgdwt5rcb2bz72vhtai2jq.b32.i2p:0
+rrm2pems425buhonptp7lbtbprmwwjhbftey4ujvk25nclx7rerq.b32.i2p:0
+rvjzxak3jvwwti7klfb64wrsmlfcs6ceiqhzbbmjynokn5tz3egq.b32.i2p:0
+rwgf2wj2x66xtnjx3dggxhkuy6gvihvur42tbkoej6bd7iukoqiq.b32.i2p:0
+rxatc4b7obgosvznpqrmyrl6ty2yixhi7rpbh45sopqwzglyimga.b32.i2p:0
+ry3iuaabf5ek73otfvchwrqryez3nsgq57bpmzkyzumqhfbhgtaq.b32.i2p:0
+rypsyqod2yq3zagcvvc2643vydtv4zm2ew5r3w5kjzyq2snvzv2a.b32.i2p:0
+s35hlnmumkgdsvj2gepnwro4wo2h7ts7ddjhhihqggywn7qcym2a.b32.i2p:0
+s3rbe5n7lyy6smerpkgr4ictzbvkciu7gxyj6zqw3xyw62rmivha.b32.i2p:0
+s43w4tsmzmddvu2cxugh2lx4o5mup3rkvjhm455u2qqpg4bqlhyq.b32.i2p:0
+s4qlly4iwzevejk4ex5zfqhb4t666o73mvdmy4gpu47tpb775nja.b32.i2p:0
+s5ls42vzfaqzgrjr6cvgkmgifei2rtvj7uzaljkpsmt62jwtmvxq.b32.i2p:0
+s6umfzwe27x7az2yjsgqftjzawoj5lrcrgxldkfwfq2qwobml2ma.b32.i2p:0
+s6vsdby2liaahn2fh7qvrehqfus7gaz3p3u3rpjtfjhm4ahvz46q.b32.i2p:0
+sa3k2xipbuwm62bb5n2mwaqyyjcvxzb53kmzinoojgnjpnqurzeq.b32.i2p:0
+sadnlzguaa4k6kvpiky27izp36er3i5h74l452povbnajqullpca.b32.i2p:0
+saj5uchj7dzmxjv3kdzalgtbqzw6wu4wzxxdiobc23m452ehk3zq.b32.i2p:0
+sbalp2doxyedtr52kj57va2rmbi5npspv4drk4vxnujag72gtpiq.b32.i2p:0
+sdxfzbgwxpf6hbik7k4bqm63wm4xld7qgo3hjlhknnehzxyyeu5a.b32.i2p:0
+sh5hww42vwlsl57cdropaeqmmwozinnr2tg6wq4prg5wrkusvxja.b32.i2p:0
+shpd3cifcjoebw6pskj4pfmrm7lwecrygjnje55heorhsxm2lnrq.b32.i2p:0
+si5x3fon3ew644friidc5o3syrf5v6kk4pxxjvhibev3odxk7nyq.b32.i2p:0
+sikkmrxv6wat265rpay2tk7jywyvlzkekpolmwyp2el5g7iihsvq.b32.i2p:0
+sjpqyf3rq7ojcalldlybvyyh5lqiq5j3ade5w6txe3473ybhk3sa.b32.i2p:0
+sk7aivked563g6g2ri2saggni7jqzxmucuqa6xkudcgjvpbjsyda.b32.i2p:0
+slbbsiq2pmouqht3hznafnowq7sxzlidmwghfch7iiq64rzdhwra.b32.i2p:0
+sle3cbbdom6rknc3drqtawctpy635ica5d5gerjjdahfymkok4ma.b32.i2p:0
+slnmute5o6h23ldim34wro4zh4qa2pchnskmdpek2nzc7u5oz7jq.b32.i2p:0
+snfinsblh4j4wsv2n5kmkfxbvqzcei2ryfyu4heqy6u73mosep6q.b32.i2p:0
+snsw3ewf7wjtwspiuj33h3vtxnybllurzcwm7u62iutf5phoitkq.b32.i2p:0
+sooo7ajo74ajo6m2yomcc6jcofdgkdoyjcbrpl3nyvvusr6fw7ta.b32.i2p:0
+sorobw22rerrhpx5t67joyqai3ou6xsvqxb7wdomtnwnqztm4sga.b32.i2p:0
+sotpvcqqzzmty6llimwlvknqsdcypn4wsnwk677kepzmy76w2gqa.b32.i2p:0
+spbb34lslk2tldwzr4ydi2culk7sxgl3imb2gg746xbxqqcj7vzq.b32.i2p:0
+spuaa2y6qsaywypklz7itcb5klesogef2x66m4flws2r574qjc5a.b32.i2p:0
+sqjjqyrhh45jpgfp66idiirgh5ck7f4s76ee2l5bli4obsotu7zq.b32.i2p:0
+sqjorsqambyienumg5qpw3foftkp44vpsd4lwklgbl4lag4mm6gq.b32.i2p:0
+sqr66feh2g3f6bknt2tnltmnhqdkzoq3jhdaatfusshrv6v2zhma.b32.i2p:0
+stltasmf4b54srrjb3mf7hjtjvmvvms26btxakccdtllgrm2qzgq.b32.i2p:0
+su7d4biurihkyr3qeea7makkxzikxr5zi4znvryh3bjespppfhxq.b32.i2p:0
+swmtaospvaup7me3dvzlw5xoeohhj4zn5q6agivif7kxtseweriq.b32.i2p:0
+syhxehvl6rublw6k5ysmzcsqrzdsnd7eqrbwalfkvhgfccpu2osq.b32.i2p:0
+sykjw3jnb7n6bo574wnpiaxhp2nm4gc6hc4jh4v6trsbpboysooa.b32.i2p:0
+syqxyl67b4hdo5u3jtkkzsabccvtjaerpushov7nrc2f42x67fja.b32.i2p:0
+t2e45js4dn4cfsyyevm26z5ltvmu6lftxziji4fm3v4v2t3ykaoa.b32.i2p:0
+t32qcc2tbjgqxrydr2txgm4ahhhae3zkkojmguehw5gsbtrdvxsa.b32.i2p:0
+t43qqzux7ik7kki2rxtillcgbxrznuhjac7wtqh52sqovk5ay3xq.b32.i2p:0
+t4notlid4bejwz2tzucpvednkeuskenpnu5sqcbdhh3lqouigqxa.b32.i2p:0
+t5cd7q36no6doxduuvk5psdx47zl7ousnckjgw7c6zr3o3ke7ffa.b32.i2p:0
+t7gbmefspnynaezmvx445fjapp24pjjf7wx3evpwlmolzyu3wi5q.b32.i2p:0
+tanmhvkoyd35kf6a2nhj5rmbwpt3shc6thypsle45my565womjya.b32.i2p:0
+tbqehmm3nuuf2spwsjobrc4hg6uxji4mdelivhywz4b7f5lv6rka.b32.i2p:0
+tbrjczwl76v7ob6hon36z6f35otpv5g467q33pgzyyakp525wwfq.b32.i2p:0
+tcx3ftsdl36ukysuuewydapdzuu4alewyg22squei2wda4a74tba.b32.i2p:0
+tetoqjagsf7fpejajiwm4rosqscy5huqbz5hcqgfuha5tdfnlrnq.b32.i2p:0
+tf4tozh5unsgyzpdsmrdcpbgekw2agu7tp5jvyclzcs5kjudwwpa.b32.i2p:0
+tfuvti7yonn5pjptzzvpshh23x4rqjvm2usolrbnlu42laj4mhyq.b32.i2p:0
+tg6goh3flzmcer5voft2nf3tudm7ikyez334zry66vqxmc4ieixa.b32.i2p:0
+tgt7rdhywtlwob47flp6ccq7prrbh4ipnwm3xszuykq7be2pksyq.b32.i2p:0
+th3dj5sqw75lga3tnffbsywajxafv7cvlb7sed6w7q3w3sxuqo6a.b32.i2p:0
+tj2upmck47iktfh4vncmyajnkbatqglqzy4coqef7wioor4hbsjq.b32.i2p:0
+tk63xbzug7def6esivofwq2h2c53ar3ot7hsezdq3amxqqaoyr5a.b32.i2p:0
+tkzuysa4lkad53cywbt6sgpcndvvvdkjeatpkwyfweorx7rfe3ba.b32.i2p:0
+tl3xkknuukvyinyhvt7saz3tvz24ptgyqtzy3igygyfapcf2o3lq.b32.i2p:0
+tl66bkfoqu6eameaqtlwrvfttyc6xj3s57za3hd7omnfnjg3i44a.b32.i2p:0
+tlfttkbshrcixu6i6syntl5xjsoh6mtgfpix54knahyeuhlju4ga.b32.i2p:0
+tmmjmcrwegjke5fzv2hha2wkis7l6xdaa7fkq24ge5rbvqpwxzpa.b32.i2p:0
+tobdew6554c76jhrulcd2ssgvef7dryini2xjxem2zushe37ycua.b32.i2p:0
+trucvlawpufrszky4zzhhxtddnhio4mnqawzc47n7kik6i444m2q.b32.i2p:0
+tsfr6zvcgsmw2ekaxqqtkdrnbib5uio7lgmrtmscrvwe2d46g7jq.b32.i2p:0
+tsrlbxayhihugr723z6rkyafglnhcyzi2zhojzsyfdjsqkkd53bq.b32.i2p:0
+tv3x4kddbu753tnlghgh3txogp26tlydt47rl5scx7eoxgnocf4a.b32.i2p:0
+tvbutrv73xhwqbtosmbp3cesdyc5bbtslay4gjsf7rzdx4ztgzaq.b32.i2p:0
+tvotv5p3emxxnti2bnvucbfy4to7gxptwvh4qznuhy62hghnju4a.b32.i2p:0
+txpr56jvbf3lmqgaozqdqzgckfpugzyd4cwplkjootvf3hk42ibq.b32.i2p:0
+tyfkhz6ggpi2rykez3v3j5f3evnjxfoau7ve7m2heaukrcqiui4a.b32.i2p:0
+tyvsuqy36cx2yvf7jhnkd5ojc52g6vxl2rw5qshqwpk63ptovdda.b32.i2p:0
+tz5txdipkxcnydzcsuqw47qxdvpob644u3cttlbrbfg3zp75vl7q.b32.i2p:0
+tzudbbctweb7rpnf2vswuw26j63ysqztsbt7lfpfj6xautueiklq.b32.i2p:0
+u2tnrysboqqwjn73awg4hfxtfjgbqab6vrdgyu43s672jdcanhca.b32.i2p:0
+u5ixxcd6slvzxouj532njusx7ec4wemrfwmg6gwltlnkruubi63q.b32.i2p:0
+u635477uxqs7z4uvwx224u6ojn3c3ewcb66f3j7qlbzqyrrevxja.b32.i2p:0
+u6wrw47yfjdzk6a7nc6c6scvfokwuqmvuhxehqvymrv7owiajxia.b32.i2p:0
+u7uklnwthbrynr3z2gc3yxfmi5yoemsugjbb4nm44x26f25vxp5q.b32.i2p:0
+u7ygn3heosxu6l2die34y7wteexfp6h2w5j3nhr424yoblysigyq.b32.i2p:0
+uags6hm646f2qsyqfhzjt2xlnjqbiopiodghywosdgz7bwtbggta.b32.i2p:0
+uc52rzz4xu5ikx6hl6r6sqxfmiyyxsffpcu5frrtepczidwjwuha.b32.i2p:0
+udfxh2r5yfu5z7ynzacur7p3g7ug35kfa33ghes2bazpdivxlhsq.b32.i2p:0
+udkwqdo5odg5npn52rueipghn5omhvojthzdmvcvuomgzglum7fa.b32.i2p:0
+udzbx5jyvrp4g3iujlca7jnlaaaa5m3e4jv4sbr7tvp6k6cdjc5q.b32.i2p:0
+ufgoaa6g746zzpphuvxuomuizkyfpz45chqta7skrywqq6cjbqna.b32.i2p:0
+ufittrlr4eautphuqzuotc7b3xx27n4xgy5afm4foc6nsv56q7ka.b32.i2p:0
+ugw5zbhs2pvsgxieklmc6z4z6d5cvyux4pctpf2udhjgxvajot2a.b32.i2p:0
+ujg6b4cyxhi5pf4puwvwupur3iddm23uibapigpwl4bstvlt4cva.b32.i2p:0
+undzufsjeb4qlf7y5llh56tji6zlhtshlsyht4yjdsa2k4ayx7vq.b32.i2p:0
+uobwophnzqq4yhpp54aisud5ojgrxq6pasmq4aq6qw7dhgjcoqpa.b32.i2p:0
+uodycjdscpurlego2nrs7ptoze26p6236t2r2tax5ubdgi6duqaa.b32.i2p:0
+uohuxnjd27cftarbf6kh4czmotwvstpon2sgs2vpffqkgmg7guxa.b32.i2p:0
+up2kudwqomqrwvfognnhz2mjwqvkgpknfyscp4ue5ioev3q4jd5q.b32.i2p:0
+upme7c64dwjgbt7w72yf5ydl3dyp25dtenrkq6z3aw6hbircqzsa.b32.i2p:0
+uppxodf6bz3qibvpzzvtedl5lk3h7fslrwmed2cmqvdpgtvqkv2q.b32.i2p:0
+urqlr3cei7pp2cruga4txxmmvel3bh7nsbqzqzpe7omvmbm4v75a.b32.i2p:0
+usgqijrwhtwgoekjcr26yqcgpncwpsescrr3eek35e3rhkrtptoa.b32.i2p:0
+uu47uxdqqtv2pqorbaxnhhfmcsxmknvpreambqqkosr45b44h5ia.b32.i2p:0
+uv44mjoqrj3m3gzz5wxlnszt5pvgk3iqlc3pmqfe6un6gxays2cq.b32.i2p:0
+uyshm6nokdjyq3l43224at2rigpa4zmiyybuufyq22t4l65ialmq.b32.i2p:0
+uysvdsh2bzicmdqqdl7ezuftxcywzapohbzl5ap5hyiinki354mq.b32.i2p:0
+uyy4dbfyx2i2x3goobc6uxj4nb7ktzsu72zlksypjfisgka3xnta.b32.i2p:0
+uzgfmsjcbjxitt6bed3p3gpdzviyop2rz3cxqyu64ec3z2r5imqa.b32.i2p:0
+vbzp4sjkgqwymn2z4ikbae7rv3clbo7vv4mwv4ft7tu7ubrmbeha.b32.i2p:0
+vcksnyuyw3i6hfviob5yzoynq7okxi677bw7224273fjhsk2kgra.b32.i2p:0
+vdpfoahxse7cjciw5l7ffbwzc6e4xdlf5ulvrk34mzm2gy4mhlwq.b32.i2p:0
+vdv2aitgqica4taqcmjexw5xfbrfbhvf5kuxwvfjf3yiki5a5cjq.b32.i2p:0
+vet6qwwa74jrqrjzcm7ylfprzwpnt3hlzjvkbnaoiv4o2zzkr3sq.b32.i2p:0
+veucihmd74nnumiunvruyjs6kpjs5sqw5dprldlzcf7i3h4igkda.b32.i2p:0
+vewdrismzwnlxlvni7slpq722wlwfami2elghudm2ofcjhpjcs6a.b32.i2p:0
+vf3l3f5unlwrfmr3fiphpomgslxgm6m4chg72itf45yfu3brmy2q.b32.i2p:0
+vfpzasrsrqh3llkudmas5fymwn2ohswqi3vakclgm6fn4nb6s5xq.b32.i2p:0
+vgkou4ysuxvhlxrwf5n2ihn4ffyvvedluun47l6dobi5ycziy3nq.b32.i2p:0
vgu6llqbyjphml25umd5ztvyxrxuplz2g74fzbx75g3kkaetoyiq.b32.i2p:0
-wjrul5jwwb4vqdmkkrjbmly7osj6amecdpsac5xvaoqrti4nb3ha.b32.i2p:0
+vj54d2pkdeqvcuj5ykeggr6jnhhnmq5q6qe7nttvb6yjetweadma.b32.i2p:0
+vlwovj6fxzvtsypnmslocootmphezr5txanyfz2gjhn5lanrn2fa.b32.i2p:0
+vmatpbu2vf5p76k2emzg2tjyqi6p6yj3cl4z32ncdhz37ubprkha.b32.i2p:0
+vmbyttxf6sw6ivdamftxung44mktqb4vphmm4lqzdqqpcmksterq.b32.i2p:0
+vmoogdd5lztt5wpzkwhd67uwnvpupye7ycsbz55jl25sueowcxxq.b32.i2p:0
+vn5rsr26rp7yxrqliq7vo4zb6aoichaybd3urvc5eedaspxjp3la.b32.i2p:0
+vnxjmzogakc2a4xn5w4qormiqt5khnjptnoaro74ehinrv4q3yga.b32.i2p:0
+voi5u3azhajnt7476tcikl5mactxcvtsbnrzixwkj62qhpaw5ujq.b32.i2p:0
+vpevx6tl6ma6mnlj42d4fke57en4v5r76yx6rcmhtvw47guo34uq.b32.i2p:0
+vpmkctqhkdqgkekt72srqm4sqaliug37uq2wp2ywady3p235cpaq.b32.i2p:0
+vptzpxba7oys3w2htjgh4uxogaedursdh2yz5k6e7yh4b3pokuna.b32.i2p:0
+vs67sj5crkcjo7m74tdunzefj6ahgrgohs6egj5jxmneszwaoo7a.b32.i2p:0
+vuqk76jvxfk55bkovqcmmkvycmndee7j3tuv7ezdb2slrfpjyvoa.b32.i2p:0
+vxokhkidetjp4tjrj7idojx45hguhnl2azvqnbulougvdkstf3ma.b32.i2p:0
+vxs2es6f7uw2uuneslb7ipvmg6kqh6ytpjezoj2ptwx7od4jqmxa.b32.i2p:0
+vziy2cbrbvliqpi27feak2hiewovxtlkqppsagtaxeib6nkonknq.b32.i2p:0
+vzqowkd4aoyekapcskylli77aj3e5fomixsjyiawnldzj6c5nxtq.b32.i2p:0
+w2a73mo4grdgwvkzdsh6nyutagd4bmywywacxviodw7xnof72aoa.b32.i2p:0
+w2mgaza75amrvfocl7wt6v7eimprlasuj3bi4xezdr2wyqhkxzwq.b32.i2p:0
+w2zi3xos4jaz3ft5yca2x5zf34esctpmzqlqpdrqntjmi2o3gfba.b32.i2p:0
+w3hyqnlueb4yv5lkzj3wlnrjp7fzpxnig6x6m3w5du2ptfjcm2jq.b32.i2p:0
+w4arykcvc7eckzuqr7kvs2njsjpknzb6vvsodpyzp6tvu27bzoka.b32.i2p:0
+w4k4gm3chiyskfzshilxjchpgtpx2xmc6euvkyzkyjvzvdbqroma.b32.i2p:0
+w55r4ykzu6qt6uhp33exqbqmlt357cts2u2zoi7hkuphqmv5iupa.b32.i2p:0
+w6jl2gubyscdpubizes5bp6s42cito4k27xwcjwh76rvuik2prha.b32.i2p:0
+wacfewi6ehmfxvftxqmracfh7se2t7ozl62u4hsuyd4c5xfzuajq.b32.i2p:0
+weidpvshind3dnblwtb4zpssazeenkf7a63favavkc4crhqdk76a.b32.i2p:0
+wgrbhqemtf7qu4c6acjicb7uyee6rlinafyysvxc2yocq4t2ilca.b32.i2p:0
+wjfukwyohljaxgv4woewdtpoxi3q6hnwcnefpgrtif2kqfrxslnq.b32.i2p:0
+wlepjf4lxs4e553rtpoys6kqp2ozcv4pqjwzoybawcl3zhrdvz2a.b32.i2p:0
+wmly6cz5j54w2g2gibnhlpvuhh3bky26cq3a5jy6dp2hg3hc34oq.b32.i2p:0
+wnp26nyphqfmq3udocgcwenpsgfwk4ssw53st4wvwt6mwf7wm35q.b32.i2p:0
+woanasilvwu3yfurvhvqj3lxd25bzj4fxwy3ef3qjbso3cozvyca.b32.i2p:0
+wpnewole7fofvwvrvkkgf45sgcverlodocu7fstm2axp5jfykraq.b32.i2p:0
+wrqu543ssub7kiwzfug4o7m6lc5ibmaamdc3o4uo6a7ntxiqzd4q.b32.i2p:0
+wsbf5tpo7ecsafusflyym72k6tbyclgvqav56qafvyc4j3spzdoq.b32.i2p:0
+wtfebbwmsxoywu6nw5cowlxqhtokxrxftve2zee6flvrpqg4j6ma.b32.i2p:0
+wtoh5v7xm3wx4rqutbyvqaixybwlprx5ua2yiv2gac3prria5emq.b32.i2p:0
+wuikfwkext6lbl6urhoysr2abcyff5lkm2ojr6mfenqq25nzlluq.b32.i2p:0
+wumjwpr45uhvtggq6jkzfda47e4iqk2onizw6vn5po3bd3uqcduq.b32.i2p:0
+wv335vkr73gsaza4t6foqypnovccubvwfsarkmw3xtc3t3sncmya.b32.i2p:0
wvktcp7hy4l6immhi5cxyz2dlsbhhvtcmskjemrnqehacnoap23q.b32.i2p:0
+wwbojywnrcf2mci7f3zgbomrukcm4d3nv6pttb3dohjpge2sz27a.b32.i2p:0
wwbw7nqr3ahkqv62cuqfwgtneekvvpnuc4i4f6yo7tpoqjswvcwa.b32.i2p:0
-xlqndzjoe5nr2nsxo6xwibh44ghyz4jfqevu62xykvemextpmjbq.b32.i2p:0
+wxfs2ccar4szd66dlmlijh3i3r4muehqjxjmabwbb46cq3gpbsoa.b32.i2p:0
+wy2udklgydh7iknnffbzvldoiwsct6dy3o7fjcsjcdjoq4b65vha.b32.i2p:0
+wzui6sc7667w7aabs6iebiex47o7cysxpryfdaltaklw2z2xgtuq.b32.i2p:0
+wzvki5234ffqhri26fqoxosqq3xengl23eoitkvip4mp7aipo3lq.b32.i2p:0
+x4cetuarbwiqphebitvgv4x4kzh6yhyyvu5c4yjlm4jsyl4bvs5q.b32.i2p:0
+x5qtgyzzgkovoko62l6n54p55xma5pbstbp6t6xc6hbugxz5ck2a.b32.i2p:0
+xasewpiqpzhyggxwsajmnkrppi2ozmapqv6673zuuymoueq67tla.b32.i2p:0
+xbetybs3nyeykskasolpatj4qrfnigz7a2bx7wcsyrniqd3usnaq.b32.i2p:0
+xd2byhr22rqkawocapbxedovmifyk77qrh6br4ctx7ny26hpmusq.b32.i2p:0
+xdoonpwnxhr7sjoyca3lkqsapmefd2puyar22ztocod4drjju6fq.b32.i2p:0
+xdq2g4tkaukzcu6mnvdukchinma7koi6c3noflpjabrzjrgeumfa.b32.i2p:0
+xegcohfrnnnuz3hdmb7r4e6pzxbmtg466n6mty2oz3tcoqutxj7q.b32.i2p:0
+xfyzfugo3qtfpq3s5zccbbqrxfkgy3ttlqhz6t6ovmtgrsuyce7q.b32.i2p:0
+xgbz5vpek6vaeej2zejxrjloqg2sqb67gim72qqpodqfq62rflvq.b32.i2p:0
+xgqzxudkvgbqwosaha7zb26jgza5wb7m66727rk4v2zj72xgg2ia.b32.i2p:0
+xgsk2huqghiftyznr6llr6ztepo523hiwqscxjpawcbme7xtjrta.b32.i2p:0
+xjebyiaydsbb76gqzetsmccgh67oeaxt3c4mkwmt7gjlfym266ea.b32.i2p:0
+xlfxusgnzpmatutaredcvx27zoiecno4tpxm52jicdvn4sr5dyya.b32.i2p:0
+xm55wnfhgmsy4wz24swjs2ziguheut6y72kht4ytwyfdmjsxslnq.b32.i2p:0
+xnb3pxtmai6ofbarycclwwueaarn4r3zt3zgkeepo4pgmswqvfcq.b32.i2p:0
+xnvsgbonlja7cmeokr2msvdelqlasbkwgqndqg7eakw43t3m465q.b32.i2p:0
+xpqubs4ftu7ym4xwrirlz2e36gvyjkil3chvq74bj4lf7djcrw4q.b32.i2p:0
+xrrx2rcpj3zefshtt7kamz3uflnwebpv2gkgd6vlrdazxgln57gq.b32.i2p:0
+xrwuqylcgkr2ovsf4pziosd27ywd7pfaohnreoyzm72qlnvoktrq.b32.i2p:0
+xtxh4wtmbjls76wxnehe57etubuqvsdiunwgve6kwjt4acwswnjq.b32.i2p:0
+xud4fgmeq4hl4cgsbjn3ubz2iyjguogskn7wreesvpsm3ib27kpa.b32.i2p:0
+xuivvnpcj2rhsxmkyyjzmyq6a7gwgusnqwdklgimamvkzu7rnnmq.b32.i2p:0
+xvpzaqftlfx2etqys733mndm7jr3l2j3if3wskfljzaow5s4rrfq.b32.i2p:0
+xvtvmaele7ns725mjaowsajpx4bgfecburyh6pqmdnn37cq7cs2q.b32.i2p:0
+xw6ble42juwkfrjetb3hmk2ep6jnyufhutoenyrou6ieoqiomw4q.b32.i2p:0
+xwlkpubkvsdsyaeylqfmxfk43juk6sz3hxnmwe4zencjq77aznea.b32.i2p:0
+xydzqrwggskdbmeqrhgt6alroglzbkcarzdlhabmvrszm5u6cfuq.b32.i2p:0
+xyhlemqmoeusqbbzr4oqph6kgmvm3a3lrbuanxkmyetwohxoynna.b32.i2p:0
+y365lf3vlh6vg4rs6trnjc4ia2xqplahk26y3tyqjly2q2vpfnqa.b32.i2p:0
+y3equ2tc6zsxqtndugsfzottuenfgxnl7eqgadmnzjkoigxvseka.b32.i2p:0
+y3occl5rqc2mz64esu5mqzoyfzlbxop7tttf2b3gyxjust57txfq.b32.i2p:0
+y45xhqkb43ncokfwhsmr4z6fwykuit6o3p2kbso3emv7stpiwwoq.b32.i2p:0
+y4njm6ftdn562q5thzd3fvb2f5mbi6bglmyupukcmcpt2tuo6slq.b32.i2p:0
+y5wr2bw3rt4rvw7hqqj7qtlf7vdds6zk6cs3mu3myyduasieqoka.b32.i2p:0
+ybjgylnhvk3fzyacxvyh6dwvrh7lk273qh5qws7uquvrhhwr6rka.b32.i2p:0
yc4xwin5ujenvcr6ynwkz7lnmmq3nmzxvfguele6ovqqpxgjvonq.b32.i2p:0
-zdoabsg7ugzothyawodjhq54nvlofa746rxfkxpnjzj6nukmha6a.b32.i2p:0
-zsxwyo6qcn3chqzwxnseusqgsnuw3maqnztkiypyfxtya4snkoka.b32.i2p:0
-zysrlpii5ftrzivfcyhdrwpeyyqddbrdefnfu5q6otk5gtugmh2a.b32.i2p:0
+yemrkyqmjzwwn2yast2ga6dcnsovnxwip2rjpid56grdg7itugpa.b32.i2p:0
+yfplj67xwcblbiu4ozddmzlmjl4ifa7bhkzzu6fu6jkoyqui6v6q.b32.i2p:0
+ygtc5m4mh3qhi7tct44gxqbenhkasp2y4ydjn5qua4l5vh35osdq.b32.i2p:0
+yj3v3ocgldnackxptsjmwasa4xzxj3it6rtuhmlpxvwlq5kmyytq.b32.i2p:0
+yk2srkdlbm7kebv53dx45ss7q2fjcy56m3gywqvw65eya7co7hgq.b32.i2p:0
+ykppjmwunzqzuuqc6qqsijomfzdgieeq2mkidapc4awrww2ninbq.b32.i2p:0
+ykv62rivlxurq2wkecagzs76tulfor765c237bsjn7jt4436kn2q.b32.i2p:0
+yllvqk2utimxjtoyzk7l24s4n5sqp5dbn5vwsbt3g3dd6h4dxseq.b32.i2p:0
+ylpyfcs24ij67dkl7ighyou4z2gpfhjlt2iellj2ad4ddrxci63a.b32.i2p:0
+ymo2cnldmstzqlsdhx7kurii7aaffrhpgafxlli3s47pzbfe5evq.b32.i2p:0
+yny6zqtb7qve7wwfctsozhzhbq4hyitlqco4uhc5q3rvjex77oaq.b32.i2p:0
+ynzhhxlieigtmj6l7f2dq54ypnsaf723au7o3uhnismlgnkmcqjq.b32.i2p:0
+yof4yvv4agwhfmicj5u2drem47nvfkihnp6bil7ocg65gydyzzcq.b32.i2p:0
+yojuyryq6vfoy2mftrdmybmq2hjefuzrwmpqqfvk2kd5hptgr3qa.b32.i2p:0
+ypbq5aleoqqoxto4tkxlmlxh2hrstjxzpgonj3lk7dzweahs3hhq.b32.i2p:0
+yql2k4zjl64dtybuculjgg4v4u6sje4smnyay3vslv7irrigzxka.b32.i2p:0
+ys36rtuedg44sahelbysqi2mbc2l3rcfdy33zdvhvfkx5uocacba.b32.i2p:0
+ys7np3pmfhiyq3z2rcoeylb7agfbyfuhhp7ky2uzvvuzswad6cia.b32.i2p:0
+yuqb55drzrhxfnvobycxqau47kibaaf4voamk3kxl77xbb42xkqa.b32.i2p:0
+ywfauauaekbrxgwaahcjzifemzdq26xsshw54sg4bpr5z74scwiq.b32.i2p:0
+ywpsgu6nlnf2l4sy44tit2av7hfzwwttbjvwbtsbtqur3awiax2a.b32.i2p:0
+z34pw5tlowwi3gpj3ycb2dptgyuq65bpj7w36xahslgikggo5eaa.b32.i2p:0
+z3j2xshl4tpbxaybcprhzq7cuz6urboqoxvvpnfriv4n2lq72jsq.b32.i2p:0
+z3pgyfiwfzcd2g7v4rs6el5tvc55y7a3tai4gcbpso6flaejckea.b32.i2p:0
+z6mlyrxcjddpcaoumxnw5peulnkvj56hgwqmnc5adoutp7piujaa.b32.i2p:0
+z6xsstyq4zynzvagwv3wr7htz4vxttrotzb5izefotlwqm7kjtua.b32.i2p:0
+z7cjxpy4taui2ka3ekfqtoumsb7pg2sok3wfey3m2roeuppcrzhq.b32.i2p:0
+z7cjzfmv6wadjguzaavu7pfsqhujbczspbf5sxxrqndeovu3lt3a.b32.i2p:0
+z7gkesbkbl27lpcpbnhgfofjz5fhnvljzfvyydu7ky3odzdqs4lq.b32.i2p:0
+zafd45c2hzd4w2t24qtjqqbqm3z4hayb6vadj6sd5oukjyij2ara.b32.i2p:0
+zbkqcqtiiw4nwsds5pjel6alr5i4hgiyqf5giwurdygfysacru2a.b32.i2p:0
+zbz722dh7rvu6ugdydmlmtgfyc7rnpeslae525c7mhr7rgsekjba.b32.i2p:0
+zcwgqw7hlw7437a7au6n6obljdb4arnshoibdqo6voree4xiznoq.b32.i2p:0
+zd4ns4zcyvgpwkioftiiftgj74n6mf4m4ieq6aedqaznmdi6rhdq.b32.i2p:0
+zgwseerxwqnid3zhculzuqbkhghthsbvsbnqowredostfqlvawsq.b32.i2p:0
+ziehuxdpyg5dvvnzedmcqxszdcflsrx6fqmgzb7odefqwqaxrs7q.b32.i2p:0
+zk2r7kzzigzu5kz67xnrbe56u5walngylcsk756bkmt66cmeeydq.b32.i2p:0
+zkbjgfp4ouockpsmpbdyli4ilo7f3lbfjsboay3nf47ymir2ldrq.b32.i2p:0
+zki6halesukhfel76pziutgica4zrp5qtbmlmgyqf6dnnomk7hja.b32.i2p:0
+zkij473aummp6rvwvi7wbr5iio6xu2uh4rophbhyot37uxhrygiq.b32.i2p:0
+zpvqqdrcnagad5ayutf7hkp6prtvrbmknhqdul3qweft7oa5ikzq.b32.i2p:0
+zqft7c6riv7aux62qwe5xfqki3dcb4urvbfy6m4wz7f46j2us3la.b32.i2p:0
+zqhoqgf3enj2pv74sjov6dthpr6jqafw5qqzzsvnfdqzycychxpq.b32.i2p:0
+zrrki54mn56fytizkfmhx7eubea37padxa3zliwq6gtknrsxv2aa.b32.i2p:0
+zsfpcnbk4g2bwxl7yy5ebrcvlxd5gpcxatewdrgpige7oqykunwq.b32.i2p:0
+zszq7enaxbz5p3f3idhfkkd2u2ygpeqwj3o6hkofffcmllnymwqa.b32.i2p:0
+ztr3c7qz6v4hrnegmkzjsr52wyi4u6ery4m74sk3m77oup2ws4ka.b32.i2p:0
+ztyxbjae7ucfyupxpy75jwpzdktg4gbvhl43nh2crwqrx2uhveda.b32.i2p:0
+zuamj63ad73jmnw7xnxrmjsbjg7vg23j46w3mpc2udpcgjfkcqcq.b32.i2p:0
+zvchlrjuzqdlx37fhibhnym4y6p56vtlymujjuzhh2cp34yqfrtq.b32.i2p:0
+zxsd3fqczh6ddgejc24nnmb3ww7nalieq3a7cs2mqiy6tmff3wia.b32.i2p:0
+zy2ywvyqds5bgdoo4tgbu3bwjp3ygyn3zfuby44jemc6xa6fbwta.b32.i2p:0
+zzre44vh766jgfordw2ehu2r6p44j23uyovgvm7iwuhp3g5iz4ca.b32.i2p:0
+ycdw2e4ufgfwhcqna4g3m2qsvaly23ozaexawcj3x4gtgcehgwujjgid.onion:8333
+ycfvedulkprd5bmivqejur5aptcs47daqtcvzotnnhfvwu3o6gcp5cyd.onion:8333
+yck6l5ffw6oszgtoc7et4fytvp3sqdf5awyky4tlpgem2n4y6icxqoqd.onion:8333
+ycnepnzktkhfysqijlgbjk5awivls3eiqb5kjudotjvnvlbe6ah2k5yd.onion:8333
+ycwrrabomoixkxggkxldyxkqoc7qqy2t5wxcsxjgodlvuydwch6dqoyd.onion:8333
+ycwwrwkqibvkftpc5kyqs6nf7hrzetrmqgwo4yae7bq5otvubkfsread.onion:8333
+ycxjdh4jr4vun447cdszcoge26pbdnqblfi2osmk5e4uqmrigw7y4byd.onion:8333
+yd2ami3rem3i24q2b76l4ujyq343ycrowrthwqycvpcsofgpwlxyryqd.onion:8333
+yd4nyusqking6tkcwmmopznlxhyfhk3gsw265alz7vpo6toqg3kwn6yd.onion:8333
+yd6b3wtmu6bz5km7hw645omyv65one627xech7f3vnlwkblsvqdtmiyd.onion:8333
+ydforbx54mnz7g5u2mu2ulkomvakdbwxoad6araknijb2i47gkfeh7qd.onion:8333
+ydiqekqpcf536w5uwsdclw5pt4n2fkz52fo4vwdducc5t5l4ghqaxnad.onion:8333
+ydl5kqr2auvie5mtjkm37hzkqh43pobibty4msfzkbu4junpg5gak6yd.onion:8333
+ydojumivjpins2lwgql5xaywbngrmw56nvmtalvfiy7sr42ksvr6apyd.onion:8333
+ydvbxdzs6w5wefifiqsqntpbd7tliofenqih5hlnz34546fvy4ab7iid.onion:8333
+yeat6ea4esvd4nimhg2rcb3ghpusoqzjb44alb3hhdj4d2nimn2vpoad.onion:8333
+yeficzguf443sojjdcmh7lzk7l6y43a6v2jbyk3x2w4n7xokjs4crnqd.onion:8333
+yefjaylovpdhbb5b5bhjx37digt5u62lmzyc54ygtabwdphm3zwd77id.onion:8333
+yeghpcuryadlbxzk6o3ujebmfuumkpoi32dr2ctfmql6vqn5wjioehqd.onion:8333
+yenw26f3i6kf5u2nad6xligxk5iyizjvl7msx3pzjcatiesogdef4zqd.onion:8333
+yeoadueo3ukf6s3fetywtbvgmpvrtkja5rlp7wcp4aich6tfhh35giyd.onion:8333
+yeqjrnnuf4fbgzik74qfhrohcymj7ccbze6ndky4pe673chfsjconfqd.onion:8333
+yernmfgru46g43vsijjv44n7m35tpoznnkd2p2wl3uqzkietukxqxoqd.onion:8333
+yettfzp2vanmkehwxeaugotqcsg3wsomcargvetk4nhwnebrpq7ah2qd.onion:8333
+yfgo33tiu6w3nrvnfyw2nmpcwtfozinctn57566y5l4hfcttuvgff7id.onion:8333
+yfmujam6pa75vm7p5q7gvgkocqzcwm7lgbnodwtmzfw7usy5dvlgqyqd.onion:8333
+yfpqwz4qogg2r5sdweggggz76pmhxtegnisz55urw3egvcq2e3amvkid.onion:8333
+yfpucmv4zspytubs5epnze4xc4joqny52s7ifjk3vu644axwkfyfurad.onion:8333
+yfq3sexjxzuww7tnwc7jj2ethiu5f5r65ewpy66os3ozhoeje7na4hyd.onion:8333
+yftuiua74fspnqanvait246qn6vmab4aoympjd3omppu46jkq777axid.onion:8333
+yfxz53gdbxu5hapg3e5kaa5pyxpbrpiql6j7sfe4i7fqj4blpqpufzyd.onion:8333
+yg5xbesziuiaigwyxjrn5c5hvj6fxef45edl7pir7risnr6un6esjtid.onion:8333
+yg75fc53cicbsarrpfv2s4crpkx6vdjub4va7cvbducwzhsf6qehx5id.onion:8333
+ygczn2llqhks3ohxvfck4ks45ekg4xr3loriyynnejw2jfmi7hjsfead.onion:8333
+ygdfwrg33s3qwiarwxbejalkirmqui3wjz7wfccprjry6bm5la65vhad.onion:8333
+ygh4hx4ugapidwxodkjr6vgl6vkaqvievk2eiie7v3ewuvjvg2mzp5id.onion:8333
+yglvvnb3dk2vh2wwgpcnvm6t4lgbdhnvpy4jfj3ee4ugb4xzvjrrcfqd.onion:8333
+ygospbn7dc5a6haqur4eoe2oj6jttjohs43rhl5m22ltruh4fz5isxyd.onion:8333
+ygowwz67kvvri2lcwknsc5xjdz7ffat5tqkm7fmxrrzfgvqnxoxkvgid.onion:8333
+ygwuwz5autfc4tqluyuoebghc7f6lgjykm6oprynh3h2vfp4xmhiapqd.onion:8333
+yh4edjvpbo55vsankh7e33u77ep7eah5h5gvfgu7t7mbb7kkmjvgirqd.onion:8333
+yh4uoyfzey53dnoj6zm3frihhgwpqfqkw36sjmqsvfnl3rqohs52wqid.onion:8333
+yh5us7dk25ttxkt6miers3bazlm3jiums5nwz6mzd4i6kn5oizjccuqd.onion:8333
+yhddybpp6lgu34i7uurdqg5jznfdajwr7co3twiqf7pgnj4yjgzbnpqd.onion:8333
+yhiswltkrs3upvkrygsuiou5i2njnyxk3gwtsmcr5yn4lfinzifbpkid.onion:8333
+yhjkylctf577degc7ufffvg3gsdxgnx64pdhzfujxjgfhbulmtc7yaad.onion:8333
+yhnzb5pmcbeiqs6bxm3xvzdy2dgblteiswvvtg6vhkum5gjjw7abjzqd.onion:8333
+yhqytulgwdtvozjhuyod2cufnkbh75mgyw43k6w63ah2fzulskfssyid.onion:8333
+yhtxfuf5zxqoqkuodfpmzsnnmtm354y5rtexqplt5l3fkzzksjkkzvyd.onion:8333
+yhvyxjfauptpsjrxrf3oxtv5zlju2gdpitwsabcmj5gdpjr6i4z4ulyd.onion:8333
+yhxcgpy2bwwhhpmgellyghjpkw7cfrjlq6trq2yl3632rxerwbmkvfyd.onion:8333
+yi2k4otmwujg7bi5iw7ewqntnxb26jyplx5xyk7bjvvaut2y2mhcgqid.onion:8333
+yi32omh7hh54oeot4i2ze2tif4l4cwdhzxxn4bzmtqrotfxrepttfead.onion:8333
+yi4gxqy63csutkea3zss2oryz4get22hcfginwcejy65g35ec5t4uzad.onion:8333
+yi4nvghovjd5bzcbhitvezh4uwg32n6r23et633odlacu4eamfym5mad.onion:8333
+yi5x6isngj7pivr5wt6i3drntlqsvbzijpdy254lbjdnihxmfy2cdgad.onion:8333
+yi6umkklbb6vr4j75buoss7kqkgcsdsx5fvgi57h7j5bzuleoe3ae4qd.onion:8333
+yibgffpo7dimyvjlbzfr3dnmnl2r5hbrpxbtcpksthsko6udsrk5uzqd.onion:8333
+yiiyiuwns45zhmkwi3wjumqhnyfkwkahbggd6hrxtnrxfqwn2vdx7pid.onion:8333
+yijdxmlgnfcwrb5zxvchjhgtc5357mecuopminujkono7bwjgqu4acyd.onion:8333
+yise75jksg27th74bxo3a6rcr3huvromhmuhnmy3n3ngcgfpagq445id.onion:8333
+yised7sf3xzsnlggeuioas2of4crrllkpz2gfbdy7c5cysa5sxi23lad.onion:8333
+yisvuvmqtn7wht6dndrqzsdl7vuspxwrmfwwu5o7wldnzn4mbzeb4yad.onion:8333
+yitceyo3wv2mk56omv6mon3n7dcfr7jiggdmzlmtikpoam2otiey64yd.onion:8333
+yiuesqqc73nn7kxadavmlwc7ymciszzk7bxs3bd4fwucaocme6qb7lyd.onion:8333
+yiz7d2lkgk2mftp6i5e2tqhotqkqjgxbdmzbnflwvsioyfydqrvll6qd.onion:8333
+yj3gs4nvumsfztawn7ku4cmner2zlmcn5kke33g4j2vywxsrqmbd7kyd.onion:8333
+yj3q4iustxfcq4bisbuw3jvqc7ph2ggld56mvyxqvgw2tmsinbwlnzyd.onion:8333
+yj666fxjddvz4xzkhtzhh53wvkiobvildczzxb3mixjipqqiqaz3bzid.onion:8333
+yjdhdurh6vqxuykgmuskpabjzjni3ehxxh3zq5redu5hqdmhdw5b5jyd.onion:8333
+yjkojvjsg6yhfj2ln2bpcrh2e6fr42ul3yzsebbz2kkytg7pf2zzjzid.onion:8333
+yjudzsswyvfqyeth2eghfvegxg6z6ubnx72kmqjljhdewrckw56lggyd.onion:8333
+yk2foofoifxgbrp5a45okwbelrsvycgqgw24xv56hmuqxlpmw6msndad.onion:8333
+yk4sercvyzvqxgbgn7srm6eeivlzoa3t4sz363aygcyciubcieihhxqd.onion:8333
+ykh3t44zjojpj76ouqeo662ljhyc2t6e3mike76iqpelcdztgaxuw5id.onion:8333
+ykkhln6x6hcmhyrx5rxaf3c5auh5k4plrpaisits63r33ecwkmtexhqd.onion:8333
+ykqehwl47hwypuhhuuxkpoexocldvllixqhplpsy6ym65vbjfa3yfbid.onion:8333
+yku2clwr3x3ndzfjdk3o4spoztoqy6ndatken5wopgapg7qkvypuqoid.onion:8333
+ykwrwuffwvaxlwivt3hlhyz2yo5xde7dw4x67ygc4xh2t6m4i5cftkid.onion:8333
+yl2preaby2yqyhmviyq46roapupmnijt2g3mzmvwtxptvybz7rbs32ad.onion:8333
+yl2stshaozpyqtut7m6ln47z2qhledknuwhij6kvxsuaai4nwy6fp7qd.onion:8333
+yl37nyh3vujz2fyrz3eoqoteixyiz3dj5rfnnmrglcgcswzbeqbjhiid.onion:8333
+yl3bo5zwwsg5dbhrrcjkvoyvwwxp3kbdgprhe6md52ob2lra7ynrbwid.onion:8333
+ylaoywooejvpfosewxmyxjhc2ahfepjbvuyjc4p7bymwirexlkdituid.onion:8333
+ylaprgwti4dsumx5xvlhul3esf3yi3ebyyubb2dwfgwe3zysv3e6nyad.onion:8333
+ylblnrd2jnfjtustl6yt6pix4mgqr5qqoevunmwk32e6fxq6uj3dchqd.onion:8333
+yldtx7o5y5jf2utrrtqf5yf56akol55wars2uwxuvjoubustrtmuqxid.onion:8333
+ylh3vliup6k27pt2thw4xgfguiziaosb5y3ovee4w6dzwcb6hc6czwqd.onion:8333
+ylsvnjqrcgatkzj5gfkwt6cz236z76yvgpeulggzml3xb7tnbsttjnad.onion:8333
+yluwecwlibf5dw2sup64dq4gs4cfdhtkfhoy5cszrvu75wljeqanr7ad.onion:8333
+ylyuglp5b2p65gmiofhe2irpxswlhecdecg7d27qhcwehegr2efmesyd.onion:8333
+ymgyodvztfs4nnijjnwiv6eadetxjm765iv3ryuyhsq4upnjwncpvsqd.onion:8333
+ymiw3d4klephwuwbkgdpllrs6hssb4svcg2um7sdm3hsnnksbnvj2vqd.onion:8333
+ymnypd7xmz2fka2r4yxvq2ibf7rvdyl6eemppo74rfehu2d2oqkclcqd.onion:8333
+ympp5jlakwfhj2bozw6w33qailkrqbroizxm3pdfxvjdbrkwtyx5iiqd.onion:8333
+ymrunm2vhoarw7rpo6jdmq4mev5hz63umljki65q2v327vmnw6wjyvad.onion:8333
+ymt2hdfgdxo2awvj2k4y5tbpvapj75j7v34tvvlrqy44lsvvdcnjx3qd.onion:8333
+ymuufa5br75liswfrb6pgm3hc6o67gnzhyg7vpfo2qsw3oyw7m7nsaqd.onion:8333
+ymxea74sswjyqvv7jsh74dnvimcsq4rnao5x5g7dfjnbfy67oj37l7id.onion:8333
+yn3avowdk5cox7qz34s3qiz2u5j2xg3irxckhzikfjv5ccjqrdiramid.onion:8333
+yna4zorq57ehghewlega7lb4zgx3t4lgv5k24orv7b4qcg27svymosid.onion:8333
+ync7fc7dz24s32kp6opdkbvohb74obme4jgo3rkkvjzywslxegist2id.onion:8333
+ynilvzuulga2tlv2hcic7ayc5qpd4nz7r7snsyejp4vxwnxlonf4gvid.onion:8333
+ynkv7njh6hj5xewxxy3gvtnu6ocyvu4tgrl3gnw5xxkdpfshalppqmyd.onion:8333
+ynqgzojvdwv2rui2rlechb22e5hwqipltusdnfkv7s65iz6fgrnybnyd.onion:8333
+yo4ykt7hngppavow7f2sz36ajl6w34bw6qrcfee6i3s6jkm6seove7ad.onion:8333
+yoat2b46hzeuhy7n57gjmfxgppei3xnzdxwsl2ipc5ny656j7zp6ovqd.onion:8333
+yobra7r3ketjuhr4g4cfdqumsez4om2eefvmgxrxq7wxnkouzmcemwid.onion:8333
+yogfxdco264tjbbeek22o26lznu2g2kwvs4lmft3ib3xelndagtf3uqd.onion:8333
+yomwxfciljad63gicbd5757og4lypcph5f5mqdou5kj5rowkyotaohid.onion:8333
+yon5gz4q7soici4i7jf2zaciusioym56jo2bat363tr3peoiurransqd.onion:8333
+yoobb72dyt62n5dpsu3aqpqa3lmfj6gfurno46o6vmqdbpwqw32ahjad.onion:8333
+yotcqynj24k2ckilo54hjhftjuvvwiacbzoraqc2kq5vtmsxloswddad.onion:8333
+yp3juo763dmi7ryhkv3kq2l262cllrru6ks5tlzcdlxdakmip3zosuyd.onion:8333
+yp47gud6fjsvjgu54oica4b3ij4zfreactcaon6fx7v7pfbxbrvqhtyd.onion:8333
+yp6klgnrvisq73qg4dk255h7un2k7pbk666jtzc22rxjs2en64ojauqd.onion:8333
+ypaazf2z3t5dqzudlygjjpyb2uvk63guovstzubsohbbeomometn7cad.onion:8333
+ypakyst4bbhh2juqd6r7xymqnrgwx3eajekpg6o5b4fazccy3mwovdqd.onion:8333
+ypkjkt4dnyqy6svecydigttwnsj5x643w6edk6qzhfo2hkxxu4ln6zad.onion:8333
+ypmikts3saaffj2uo5zmkbac5m7xnbblxkbhpw5xtxbamajqf36wgdad.onion:8333
+ypninar2hybv3jdovr7ax7teq6wpzvrw6n74csq7edos3hzumh2h27qd.onion:8333
+ypoinzgql3zo5d3strpmannbkdtndxkxlajwgcpaj4ngbc5mqrzzgpid.onion:8333
+ypp73pv2vcjfq23ltwhojuremxxfknwtgkxsvwe3widlaevyx34pepqd.onion:8333
+yq7s6pe7jzrzj5uxlorytwxd5bs4kljyvp27akdrpang765yd3sexwqd.onion:8333
+yqnal4phy7wz3lsoi23rziyb56bnbzvvypy2mg5ponzrk63qpyvle3qd.onion:8333
+yqoiqt3molj4ygq44zyme5gdbgee7catlf4ndjr4myiicduuwiev3fad.onion:8333
+yqvhbmvc45iy3drl7nceuhugdt2fevwx4x53zafio6h2626kflwtrcqd.onion:8333
+yrambbqlzkm6o5pkc5q563njvrkfallqobvscvpdik5owbdtnhbc5jad.onion:8333
+yrdtnt4lkpysyyrvryqhxw3k427gxwziosdtipf2dcifougwzomdfcqd.onion:8333
+yrlc4r3qfcr4x5wnciutrdvasrpahor3ui25lgdgkxbit3zwtmwfmxad.onion:8333
+yrmpasdjmb77ono4c6rjh24fj5gt7bbjx7nxurytkmxbww2gam6vodyd.onion:8333
+yrqolwaoxpa32cw2zegnaggmniuer66umflznja6dcp7udqpaoanqwqd.onion:8333
+yrwksigpx4foqlwnf6cxwtppx2z2msompig73dkcm34pwsmy5bwwg6yd.onion:8333
+yrybhm2es4siupjnyjffviemvqx24mqj5niwm2wf56spdqlwau44r4id.onion:8333
+yrzwl3rbfjx7eybyjvnjz2y7qmvpnkexkmylqpwsb7ivpg6ch42mmxyd.onion:8333
+ys2muyvcnpdadettzavleh7qrn7t6r7e2tobfp7yxftta7ez2i6rdxad.onion:8333
+yshp2g6b53ndeez34nxnk4bz6cqbzlfxqdggi7btqlwzxzuc7sweqcad.onion:8333
+ysq5rtpfzkz5gt2s62idbsd7secz3jepzlup6hqf5ttdutsdmwg2ryqd.onion:8333
+ysyx5eagwnqpfemz2nhwcxs2c3eueqk5f3jnyvyfqfno3pflcqfw6yqd.onion:8333
+yt2vub6llcegxuucu3iekjqfpmbyz4kreuxx4su2pqcetw7kbkbipzid.onion:8333
+yta7q7v5lkzt4zyp3m44cxcdtymxgmuqdntnagz6h3hwidmqoeavifid.onion:8333
+yti2ofsqg7k4zbln6aqx4zqaor2zpmlsebyljxlu7jczsjqtd4ctd5yd.onion:8333
+ytkkqeik77zjjwabsdlctuum37jr3r2rg6ckxudza7y7tialqr2wfeqd.onion:8333
+ytq4uowr6vwyjmrjvac7aimjjlzylfmhqhn3z4ecenm5dd6u2ccsijyd.onion:8333
+ytqhsolk7pqur5cu2faxruehvx72yiiwb33p4szdnzidjqksanps3nyd.onion:8333
+ytqzrm7fke3kqgh5b62taq7yyejgtd3yxwaifj2pimoqbfq4p7xi7sid.onion:8333
+ytrhvysmp4iq2qumdrpgp54q3ushkf53b6i4oxpddg4rmlk7hbayusqd.onion:8333
+ytyn2e3bkmgavrygpk5rzydfdmhpkercccqcaks3xtnbgq5qsyg4euyd.onion:8333
+ytz6ov6l5ofhjudlfi5k26lsg4v36p7xwciafy2sdau4cn6ozxgmefyd.onion:8333
+ytznm6jwapg5h3firimqb7ao2g7uihakg3gt6hcpfqkkgcyemklfufid.onion:8333
+yu6ilgxjfffdb3fq7srwwmz6ymp3fxberstpl6vdocmxbrrf5e3tw2qd.onion:8333
+yu7c5kjgmlci4arofpgq5d2qs5fvbw3zac52nampn2vc6vximc6qovqd.onion:8333
+yufe3o5x7spybs5tku64r6hzbrc46uq6izky6z3dyvba2ymblvehyiid.onion:8333
+yuhebtpb6urpsrr3g3vk7tcl5lp5dt7kcaj7zpgox5r4x6ptysxzvgqd.onion:8333
+yuqoihr4p76t2yupxuciurcpzsij5i32enjlsynqor25fhdvidx3djid.onion:8333
+yux32z6r5leyhbdrgdpti4sggxyoy336qb73ia6sk5egfli5qsvkxvyd.onion:8333
+yv2ezeqqfeoprti36q4fds3ckq43vdv7vktqfpn2npv6isnbxay47hid.onion:8333
+yv7ainbyxz6wejjhpjgzx6ghcomdwd3k7fclru4woooxcovyjwrp7dqd.onion:8333
+yv7llcydwvi2m4xpnulhgxcrje6vswtsasu5bbmgxuk3lgln37tdvbyd.onion:8333
+yvgzvmh4ngi36zvn7pe3bocsxj6pccafh7v6wmswkdobbxdzh3b56iyd.onion:8333
+yvhvl5bvjp5ljmooujmw74wdyqnhvwlm44766wwgq5thnzctyni6yeyd.onion:8333
+yvnppv3n3hwexlvugfviwv33ycavxdwnh24dps5vp3y7kw6kze36v3qd.onion:8333
+yvsokw66m7kqqqjxb4mntjvwhnpoovoec6rrpqtdze6fdvpbtvt4iyqd.onion:8333
+yvud2f6wb6puec4xq3a6yruax25jydqepowhz65uvlbvblsyi64skoid.onion:8333
+yvvodwqb3szlgkx4egcyq7qmhpyoqxdyxdnksxl6ppnmagnsu4noemqd.onion:8333
+yw7tqaujnglpjmjak5r7sxvjg4gqeubwetm5h54e7fbfn7yx7kgr4kyd.onion:8333
+ywbprsiodgtlc2qoubvot5qm22logutr2dbizmlond4dcifklaxqlcad.onion:8333
+ywkxlaydopi6ygjeggtv5znptkrldzsh7peg6wabkjmcu4k3hmbjivid.onion:8333
+ywmh5zcx3r2rd7zmkyx5kymgxk43lsamie52kbhayqwqyod5togs6aqd.onion:8333
+ywq6oxdfdvlict3cuasd3akvcl47iw6bxykrvkalemrcyqzyzclbf6id.onion:8333
+ywqkdkihpzr3hx6la2lzqsguoqbuwkn36qcrbkhvltd62zdrguprljad.onion:8333
+ywqp3kjwchkto24so4nn4ofq5m5c454btnkux5jxftkkqz66ducu3mad.onion:8333
+ywqygs72qzxbkjekezlhsnrsfnnvm66igkovfoh267ru7ho3qtxtalqd.onion:8333
+ywvpyur4ny6zhfxpsva4mh6cd4htw4q7ylx7tissnxehwg2bid5fumyd.onion:8333
+yx3nnyxy3h4ex22uqdjwephoprte34jelnkpr4ua3d23ks7qxjrqzoqd.onion:8333
+yxa2iu56fp4i4mxzdkmv7xxrluyxtkylqvexuceivx4fqxbjyzme76id.onion:8333
+yxgvp66ll3c6ko7w4hm7xvzofd3cb3ku3jjqc4wihapnyk3wxijafrid.onion:8333
+yxlaxiaatyfnrx3l2vhb4p6d347djzux75gcl2d33aydlwspo5w5wpad.onion:8333
+yxlwpmsjdbpldhi5hlzopision3iqbjzpvyaaeb4yst3z73qbgqy5fad.onion:8333
+yxnuslj7hslwmofh36a37stlm5jjnq46vvvyntf42uw3zuouot3sjaid.onion:8333
+yxq3bjwdrck3lflvwixj2fc2l7pzqnea5l7cucviamoc63a2xozk7iad.onion:8333
+yxreb5ajudnpt3b7z5hyizaj6ufgd46o334wtduuyaakboxwztgji2id.onion:8333
+yy3bnszld2tbbyd45f2j7btrbdz2p5zsuzie27liqr7xgkfh37rcojqd.onion:8333
+yy7rusheh2cq2xghpsdzlrx4gpejgfvsfhq6333d2jttcovhh5jo44ad.onion:8333
+yygxdcvyp6tn46umpmxlsgsi6crg2xjchuhi3okobofsx4dqgwucnnad.onion:8333
+yyo5s4r6wr6p7l5p5umlp7xgb47ugeptugscv4gvpsxvjlwymfpwruyd.onion:8333
+yyr2peqznujer3t63yyhlcasjndbhllvtxxkmcvr7p4yxpuzjrcylcid.onion:8333
+yywmc2hhk7t56e7jun62oidqft6jvtvvlylexihzgcrtkzxe5axsd7id.onion:8333
+yz3izxf6pdtr3ucbriuo4bpgjn2visad4vgocktexnpv3rfgar3kydid.onion:8333
+yz4l7aqcjf3lcdtdcuxoxljedrcrlo3lu6kths2bvjeoil4wqx3d46id.onion:8333
+yz5i6sldywr2mqzh5qmwoqfgsta5f67bgdhqogejjmpengl3llafdjyd.onion:8333
+yzakgornrhzzenpclo4ahyai5lxsg6mjq4zrwlhqt3ff4sblxi42jwad.onion:8333
+yzbka2sygb5eqgrgk2svqin5hl3dfknzfdn6wzwncexsejmrp5wgm4id.onion:8333
+yzh2ineefkzohck7vkwcfe62kvplsly5xn4dmm25fpxbjq2va34bu5id.onion:8333
+yzigosfexpco67cy3e32xehlpwor37fp52my5pwtr2xsnj3mxl7gfoid.onion:8333
+yzijb7pu6mrrdwb7sku2e3epfyrkhl7t2a723vaisqulr3roaxoy4xid.onion:8333
+yzlai35raddd2kdjnukns7u5t4m4ngi5dfrlq72e6lqf2hp5dzkuszqd.onion:8333
+yzo2vz4kuitm53zwynkm7ddfdw5escsp5fp7rgf6uspphe653mvdekqd.onion:8333
+yzqfzw7fgzzs63xpvsgznhnassxcadbfaxxaxbmkffvesgdxizhxkyyd.onion:8333
+yzrw7ukful7rhvlletmabm37wupkhsxwo2esqqotsoh6gxib57ss3tyd.onion:8333
+yzs2bdhwhxfgaozpcic4v66w7wwlxrr3v4xpgzer733qehcwewijipqd.onion:8333
+z23pfizxwpae2sbje722iesvd6rcxntazcaoefabzsudkc4xxmtbqoqd.onion:8333
+z2eky4p4ozlkrrmuq2jqcz6w2k22re6hxrm3um4ypcnmzmpsi4p6l2id.onion:8333
+z2eo4uckd3ymgtsjitag7yqukmjsjpwuf3d3npq4oskeatpkcinxkcad.onion:8333
+z2gnzha7ttijmle75dvqdzaeqz3xyxzjrrqbzribvwbomh74je4xeiad.onion:8333
+z2ihxne7lyodwglkwpvdmz3a6343msirrvjmaf2pytuo3jysabrkiiqd.onion:8333
+z2lhlshxak5owviqqzacj73ioftqmvq5idawmrgt4k347bwr6yubmqad.onion:8333
+z2njilhjl33youet5rbdfmncadpt7tohtconls3qhpvuqfkreoteqfyd.onion:8333
+z2nocd4haqt257cyr6festid7enoe72qpmu27cuvveoon4rcak4femad.onion:8333
+z2yjvxbv3rfpso4cjkxc4i72f55xb5fihthcdbvh6dp7ghxz2q2tabyd.onion:8333
+z33gr6fni32nkhfmkovcbvpuk7s2atoqfbuzdgz2jszh5ua7zdu6uvad.onion:8333
+z36427rantiy4ikleyihwfwh2ga3pyqqz7doezrzkyv52bi3mpcgt2yd.onion:8333
+z3asgzuzdvhrrejqjnkg5qfeynspuwzzrl3sr7seqxlwkiemnrpsrzyd.onion:8333
+z3hdtpvmnaz2izvnlopzmfgdb2synsomzgy62h7vlxvsn3yqhgufqjyd.onion:8333
+z3hgdhj7zxtih2gkjlnex6occtzw3tpd6f5eobwrntrhxtiww6ke43qd.onion:8333
+z3jl2izfxwfmqnbbrac3tustn4bngymj2tia2sn7nuyconbmjskedtyd.onion:8333
+z3m3a6wii62jc37c2fw7huca7mu4eywnssindvhn3hrh3t4y4kwj7dyd.onion:8333
+z3od23fobhkvypxarneq3fqsdsksjt3hmujnlaiwb65hdwa2n5xdjiyd.onion:8333
+z42np5zjd3thnd54h5n45ibynz5vb3flbgypt4me2c3bnvntn4rsgryd.onion:8333
+z4d7f4dvqutzvvqkmj35znzpyorroqg53jhbft34gyk2h34wzorv2rqd.onion:8333
+z4gvqymmj5jmg3dnao7k3vc245pzepqcrevzyh4s5xn5fcc6ape22sqd.onion:8333
+z4mmpbj7md2ljj2nzbk5b6stdromp2sxhysdexiq6kjqp2go2yfhlwyd.onion:8333
+z4pyvdupcieuqtzvhh47sbiahdyegvpgtwgfmlvfsrm4yj6g5mt6cgad.onion:8333
+z4qgvajgk3tr6aomi7zkpiilx5xb6tvavupvw42sgjf3bfqrgwk4tjyd.onion:8333
+z4rgrsudz3wjx7uykg2kmcadwixklibr5b4k5nulwrpxcjkasu6gnjqd.onion:8333
+z4s6g5bqdmo445vu2i6tcm54zjypfhl5uwnxqjq764bbu5h37gkp5gqd.onion:8333
+z4zr3v232rayjy7e4wuxxez2blz6p6apyv4souxjztqnv3mvaytb4nid.onion:8333
+z52bx6657mva3yjtrutjhxojkbwmrmndk3r3nptxc5xqz3nd62frfoqd.onion:8333
+z5ecnh7crpgo54nfll6qbwl4ybvfbq3izazsdu3pp6zqkam47nuux5ad.onion:8333
+z5v63i7lvhkfdqcex3ioeny62glxhptowtrfof54qbl545mlchkul5qd.onion:8333
+z62kddfut74o5njyehkdlj4caa6yg5orz5lznaccpbloqq2siiwbtayd.onion:8333
+z62r52qegmgv4otygobjdsubc6jffaei23he6n553akc4wnf5ryur4ad.onion:8333
+z63d77gd7artekfeamkqycni7tzrkvbc54fqr733veuoaqx45jwmytyd.onion:8333
+z63fpitzdw3ot62wtxtindh5334uatz2flxg6ronyy6jwx2ztjs4meqd.onion:8333
+z642d45aauehr2ycmv4ewv6zkwjlvlhwf5wlueuy5ynpu4qmffc7utyd.onion:8333
+z65lbxuvo5x36vuv5rgwgyoplqjzzciwvb2whvo3tlghzhp6zij6grad.onion:8333
+z6gr5c5yrp5seqsw73b2pkn3i4aqd5idmzgidjchjjm7f2hdgfkl4fad.onion:8333
+z6n3h75u5kkd5xkqfwbqasd2rekxams3jinrrqaj7p33qdxq7fdlmdqd.onion:8333
+z6n5kkyabl2huqtcp332n6xbo7kpilcw4b64govztw3swtzulgtxcjyd.onion:8333
+z6nq6lkmjoyjhqp5j3tg2gcjq4e3hgduo74unmtmnybd7a777hp4asad.onion:8333
+z6nuvxnjicev3v47o4vxjwakfz6g3jvyo3l4rds5qqfjptqie5re27qd.onion:8333
+z6okjxmclwc55pbwioqx5wyua7rjobcmbttpte525tlt2gexjcjtr4qd.onion:8333
+z6qmf32mld7uqjmx6hroqnkieerstp3vle3u3do6odxig3ubmv557qid.onion:8333
+z6s6t6bi4llpuod6rnakc344wn3h6ejpfejxrkjohjjy246shwfd34yd.onion:8333
+z6soa5spkni5ze6p2xg6lnehu3d7hnqn5ddiy34jtedwegf4syqnnaad.onion:8333
+z6t6fxwhgndvi36vra6d5duaryx2m75v6a5yoz3cqjlj53ko4wm7fhyd.onion:8333
+z6tmafvqwf2sd4rchnafg4urcug4xpkylwls2owruyifaduaeneyqkqd.onion:8333
+z6u4s3uz6bxke3tyibyccbg7uaxt4cb4dued3cu3pbjw6frqc5nil5yd.onion:8333
+z72rd3arkarr6eehucg7rrkjmvqnzdbjmppfk7zcvzd7jqrvisf7rpyd.onion:8333
+z745wkcll7vkkrx7zamibvbyqjtcp3y7wdz5kd33gijxfz54cxzg3mad.onion:8333
+z7eb2xkiigjdfay4ch4pubeqxb2jwyzdb5fo5owkbteyhefek76qoqyd.onion:8333
+z7f7lrvup632wkbzinvbkyyrhmguaf4fzt6zleiynk2vuvwdwt6ysnqd.onion:8333
+z7g3tx3nucmd5ozvs7wgq4i2riiufxlutv2usowr3p4lixfbx54fc3yd.onion:8333
+z7g4iekn3i7nliiowlt3ek7o6xlhi5tv2hofycacjqkpeoijghmiyxqd.onion:8333
+z7j2lcfj5b3isqznsb44ivi66lwmidcfspmvdrmhbfuyub2h3wbmnkid.onion:8333
+z7jbbwkyza6e37iqos6u7ln3nedom5i3dcnowdscr7wfj2xygre47aqd.onion:8333
+z7jtpaghm4na5po5p27fwbdh2aq3z4rkpwhhzemlrhsoefru2z5eyvyd.onion:8333
+z7m7rmzhol6swqnk6l4sadrjgxwnggt5zwgp2jx6tadca74o5puyuyid.onion:8333
+z7mcuih5vw5qob6o5qg27jhozuczpqx5lmzl2ghfxra53tov2h5xtmqd.onion:8333
+z7rxmrmvtsbgrrwwh4k37bpkk6dtu3aq7f5d442ys75nepy6r2q2xaad.onion:8333
+z7u326iowflnv6tvy6uiwwkusx4vat5gdaxwamcp6jd2we35ih6zplqd.onion:8333
+za6k2u2t22ohdrpqbirjhl75eadxcjvnqfkl4bzeygbnliqsc45gplyd.onion:8333
+zabx7shizdfchrfthsjcuyypqy473ni23ebi4aedow4bg5c4tl4cxbqd.onion:8333
+zac6qhbqbb5yo4rvcsmbilp33odkzfwrftwma4yo5hor4brj4d3ksiad.onion:8333
+zad5dkykkoelu5tdj7l7mr24pdf6eos4o7cbs5nvx6bcg5443eqwaiid.onion:8333
+zafdafmd2h6ue2pmuj25chhmkqad3jdcxwtaess2opxkrroopwdqfvyd.onion:8333
+zagkhagdzvkgpuo5znflvxcqxal5tweg3vsaoaonsvsl7r7orhlwshqd.onion:8333
+zahrvinucuxpxu56h6nkiiw7cvutxrua65l4jynvwkzt2bzmeuvdpuqd.onion:8333
+zalrhwuj5j47tntffl77xrdehzfwq7c7duhaq4jwnq5vdtdtajwiucad.onion:8333
+zaw7gnlyeqrlpgcmsp3e63anveudschhifaaezu3web3z6pjjdtvviqd.onion:8333
+zayfuym6j35mxprdsm2x7pvws2vyaoinsomdbgrqbe22rcc77j7jtnqd.onion:8333
+zb226sk3eljxccaswfgouu6mitu43sf2dan4feygrqnlvrot6z65oxad.onion:8333
+zb2qixzmsethowd6fqnwikvp3yeeeo3zvhgjmq2yb27tfslscgkp2zid.onion:8333
+zb62u4o5qzst7rzjaq6tafgzoybi2ncogcjp3sf7zbto7b2xmicwvyad.onion:8333
+zbci2c2pkku7hwg64ek4z4cbyn6o5bnzpzyriqwjckzgs34xmu62szid.onion:8333
+zbmhiorqlldelgniyhwogswpvrlcdjqxxcfm6vulenrpwiadvv37anad.onion:8333
+zbnovu66ikceaodzrkpwww4vop6iwvtebbeznngo2mtjkikwknqzgrid.onion:8333
+zbwbqxytihkvupc5zhezoh7oibfb7bopfcw6y4qbhh2kugnsw6zur4qd.onion:8333
+zbwpgu4z2lfuto566v6duz2qw5kkyvor37rpihk244bfjzqiuohdcyid.onion:8333
+zc2c56k7hcdux5wrlpixrx6lfutylfamr676tu2nr5z2vf5gwoyzrnid.onion:8333
+zc4l45jx3txlag7hduov4su5kl633sykaw7guioejg5pq2qyuescabqd.onion:8333
+zcc4wsaenndkzqdp4xsfzn6ilsdhwzpqiswumdc22dv5ejejec3o7qyd.onion:8333
+zcdv7z3vetrpeo7souyie7u3vyy6w43cuautaogldhs4n2fitytsihyd.onion:8333
+zcezifa7mmgv4voul4jf4wbqmr24djgrskwszktkt5hihywblltpahid.onion:8333
+zcif26i4yzp53k3uedswyrqkdmsmkflpmclmasdo6hat57pqjpm2omqd.onion:8333
+zcnl5vojc5aufydmssv4yxeotzeqpvyoxyae4kmoskty77j4dx4aykqd.onion:8333
+zctnwv5ln3yktcyqsbgie3qcee33x44b5quhjdq4zwjprl75r3snduid.onion:8333
+zcugrsfyxb3y5ucbdndifvt5ilp47a2233sv42ryf2cvzoncrgo2mrid.onion:8333
+zcw6xk4bfnl46fx3mkrmlnknbwnpssxsp7hlllj34fdrkutzts6yepyd.onion:8333
+zcyumipuaiotm5fhffmhit3ajzrgqihhibh73lvjo5hdt4aituudguyd.onion:8333
+zd2mgisets23i4mslxjl75froqjygtue4lnoq56qk3ohd4qcxpop7pqd.onion:8333
+zd3fxn7nwlj76qyjseubm4o2gs73jv2g22px6t24z7p5oeogqe3icyid.onion:8333
+zd7irysta3wti4efbjq3di2jfv237nhwotupj3rtufvvav4e5umtkfqd.onion:8333
+zd7uq75dlcseq546lmbqymh37cninokajwkixpvupillb7fgpqgbwjid.onion:8333
+zdi46azujxcjqa2wnvdecld3bdkps5erbodcvw2mn424gk2by5mterad.onion:8333
+zdm5zxotwdsma3jvij3jmlke5wmblwy7qa2kikfctlzltexx6l35u2id.onion:8333
+zdn24r3iovbxfkp5qx5ng7ribn4cqm4v5ers4olnbzugyp2gbhd56yid.onion:8333
+zdovdneke7oxtxdnee7f43vcu5mjzoa5m4bexpxgvopa5kaxyrcwa4qd.onion:8333
+zdovy6gcj6nrmxaygnjqf3ym5hbd3s7h3irznsbrjmgdywd2rkj2m6ad.onion:8333
+zdoyjklv576u3w4paxyjb4jmdhx2id7xoqkd7zn3sspodasmmazbbpqd.onion:8333
+zdqon7u5ofin5gy4rcmkixc7u42xypwklntwceohpektisokskrn5gad.onion:8333
+zdqxfzqxbaa654nsngnaqdz3jfsfe2u4hxs42covbct2dou7z7jpa7id.onion:8333
+zdtchifs5gqldijr7vzcgqqaftlcydhatm57owdwzrgudns5vpdcx3qd.onion:8333
+zdzkcrnoctqhn26hjbngpcl54nmvozbodf4gwf7anfxjrwhjxgurrdad.onion:8333
+zej7mizjlb26qecppzvgyswervt7ov6f4x6fwrot7obvab23xsv5jjid.onion:8333
+zejyatwyaptvvubp6b22cpow3an47bsrve63l6rerkldmuwwb37b74qd.onion:8333
+zepqddw4zaqqawkx7aqezpqwykxmxxeh2opnl3xnq2i6piazcvyb6qid.onion:8333
+zeso2dbskp3curnpgug5mjyvhs7i6rero3zbqo5n534wccstcok6ywad.onion:8333
+zexnlgnfxldyx6leiqvyhuimrfxznjfjoko2ek6rdtu4dvwkvztfysqd.onion:8333
+zf4cm7bgv4qollcjcj7kpx4qrtqzcsa3q7sds2jc3mxu45gvazlts3ad.onion:8333
+zf4k4efdpcwsfyobz444dgdfnsa6tdbd6aor7p2s6mpuol3ladssb6ad.onion:8333
+zf6nwlrrtd6q73svcimgfp54pinn46hbcriqnqqsitz3fbibzmkev3qd.onion:8333
+zf6tbmhchmzo46lmhx6vu3smjj3y4hjjrv4lnwpa3uq7bvtjcwapmqid.onion:8333
+zfhx5nerqkerm3jfoq4763vlmay4pifit5a6a6jtcjxpu7t4galhxwad.onion:8333
+zfo72va3rnioxbhh4kuth4epqwqque74aehlonvde3re6mvhz4uzgaqd.onion:8333
+zfomias3uj7w6sai3ty3coxhnb6voldudbeyldgyedxqo6kfc7rg7sqd.onion:8333
+zg2yslkwabguckkqanyxwbncrtozc2fjivsyesrcd27xxkowkbcwnxqd.onion:8333
+zg7obxhb4c4j3dgzg47zffbetclv2so4foyutdxizfnedhdkhjzo2cid.onion:8333
+zgaubbm4h7qckt4pgtp5zawrcf6aazby2zk7aeo5xsqpgwsc2yrlbiyd.onion:8333
+zgegpxbr7z34gupenib4tuwywyk4nlevo5dkfg3jt6c2jw23len76qad.onion:8333
+zgjrto32gianyp6i4gc73nlilodiqyo2s5dkr5ev73yq4qvcjxkwycad.onion:8333
+zgp3f3dmwbnr7257rouxkgddijr34keobzrtk5gkm2dgfbw2bylcwqyd.onion:8333
+zgrpshddeijmdp34xfyw2kz22la4jxgwce42pupjp3bo6xtchsorrxqd.onion:8333
+zgvklnnz2avqcnyiffw7t6umb3is4tfthnkzbhnyfr76sjtwu5u35pad.onion:8333
+zgwclfbi25s4ta5hfiwylboeitti64xzoan5aewuqimp5j55nye663qd.onion:8333
+zgxg4d4jifuihgozqblrt3kjkrh5zhbr4uyivtrzf2khnbtbe4z3qxad.onion:8333
+zhabxolberrktnga2eixvhe6vmaoxour3ktd6jgjq3emzkgthsmaq3ad.onion:8333
+zhapnpxpk3lmrfsmhluytttodeosmie7yabywa3aaxmtkreh2lmeemqd.onion:8333
+zhdd42th33pv6qnfi7v3w3gddy3tlgu6pjo2bhh5ezuytutxhivbtqqd.onion:8333
+zhea7pvhuzw4cte7pkd7u6lwjyiqczxi7wgvzhfovtjd7qwdc24pleqd.onion:8333
+zhgdvhnh5zymbwrmd2rfjncparbxfiyraqh4imk6kl3tkltgccl5cgqd.onion:8333
+zhhkv5u7pxuu36y7vzu6wlbjpd3wftxfuadsst3ifs3q23eydmako4yd.onion:8333
+zhhxxlz3wvdaj4scdetokkqgs2ndmdvyfwq4qwrn3l3hv2iftlgsucqd.onion:8333
+zhrzks7gkdvyef6s2aogxxuw7iqheixmrdzgkqotpvl5bjz4vq5tkkid.onion:8333
+zhwmsba7q6vn4yfi63p4tc3dobsarso4322ynl5ofggjbyiozefttcid.onion:8333
+zhzpumb4itgdxy53chqowtu43ru23ag3f37r77ydjs3t5o7bookfe3ad.onion:8333
+zi77cxawtknqkjiod4rhf7gsughbvv2z6e7mg5kax465uc4vtg4cwlid.onion:8333
+zike5s7xtcgp6frbjgzjhcz6gsvd3pghkl2jin3sdasrek3vy7l4ibqd.onion:8333
+zip37ysefmcbnyqvt4jiag6dj3h45ie7h56hmw7ktheotkuagippyiyd.onion:8333
+zipzgdr2m6gmjfucup7xpertovt746f57hrgb7lj6m4rxeniem6zdgad.onion:8333
+ziquiv5d3hditb2r2qmt7hn7knosdcokxe3khj3kgn253l6cynl62zyd.onion:8333
+ziyp62u4xfsuljn5ae4n7jea7wfd6vfutket2e73bzrhpstozs5364yd.onion:8333
+zj55khmgsehm24efh4nmye7oao3u3l4tjuk5edghey3mt2ippfste7yd.onion:8333
+zj7jf7o4b3qztdorj2stojv4us7lzqs37fbubqpqq2wu4dxi3cxpa3ad.onion:8333
+zjdf27w3vt4rpyb6usa3r5yi455svyaha4qtsfwvyrmf3hmz5hckbwad.onion:8333
+zjgnxih45rz3kalgxvhyebyavcnohmoa3bcnl5cwkmq5pmbyypavqcyd.onion:8333
+zjx5rmakdzormbwzl27w4xcucehwiat3dnncoqdiwesbmb7dg4fpmgad.onion:8333
+zjy7d5t6rxljc64pvta3hqi6yxzfsnixtbslafamoxiiw6ptcmv3kfyd.onion:8333
+zk3cgisxp3uxevuxmbzbmqyhvkhezspeydo2bmhu72b6mw2kl6v43fqd.onion:8333
+zkc2lid246a5jr2dpxtvmtu2tfiwt5dbry3xybu22b62vguco5a4qvid.onion:8333
+zkisbl3pv7dsz3szdawti4r7mhrhssqxf3uopi3vrib5dpt6u2u7ckyd.onion:8333
+zkjnuuenigzhs6d5y62jct4tira6fzijqx2k3yzsdsyulut6ywp5muid.onion:8333
+zkjoev53w4e547zot35onpmij4fiube4aomnysttqtv576zdr7wex4qd.onion:8333
+zkl2fsiisu3cyhhsua7qlr5afhyvmfh4qmapgubioyhoepqdb46jceqd.onion:8333
+zkl7x3u7365zj6opig53dxtty7ctw2ijidwa4lbdbhcv3wkld22bvxad.onion:8333
+zknqouk6z7g7h5y7rmycqb6sgzykylbbfpvf5efmzibww377iminltyd.onion:8333
+zkq4fgcc4bxksbsi74pjwjfby5tdwn26yhjnmewy2qy6a3l5p6bnaaad.onion:8333
+zkr66xkrvecgu6jkyan6nxvtefynf2mpsls5csvf6lt6ltqvoscw5yqd.onion:8333
+zkxe2fnm4tsmbu4bdge7i7j2cesfrq5oznfzobf4mwtejbhenp7ubxqd.onion:8333
+zkzj45moxjhjvrzqweh5g3iyucdb2qaqby7vdtmlqbvxmm5u337aglid.onion:8333
+zkzj4uhvvpav6ee7djkfj2uem6tyswi7idzupkozspbgr2kfvrk5biid.onion:8333
+zl27cum3gly7nfhwl7ulnob6pyichpxglnss4ffqv3terkquhf3dm7id.onion:8333
+zl3dx4nswje7l5p2fgvypve5wugfqtcru2ud55qo77tqdp2btm6kp3qd.onion:8333
+zl4gt6uafawn452rlqb4w2mujut5tjcnq4ahdr6ucdyeu2gtzlsk2jid.onion:8333
+zl5voqvgyf7deglpxamz6hpg4bierfngqsmmu72wpeut7toja47v6bid.onion:8333
+zliat4frxeuirx3nbijcljvgr5wembicg26fdpgda4pnps4oguaobmid.onion:8333
+zliy5o4uqgpqj2nbgyadqnlomnjtmdlwoxcuduwcfavzsguj4z4iwzqd.onion:8333
+zlkwqytpxbhkg4umwpqiynz6niefzqjbiwzryg2zpwwmvmw6pmssngqd.onion:8333
+zlpztcqey4osd3omtpsm7micrh6jrxuqzeeendpngk25iyfhleieekqd.onion:8333
+zlx2jkuv2iuzffo35hc264rnvoimzccvtlljdbmut4es76qe5pnvs6yd.onion:8333
+zlzhg5hipy7nc4ulsaprgro53f63mjj7je7m5xptgkksibgvbc6r2fyd.onion:8333
+zm2j2k2nl7pug2amadjkrcgs5omdnxctyl7b6kmlywsphcfl6c22gtad.onion:8333
+zmfmdmzlsyy7owe6vpgugvdq664vjhluqura3skjlm6fzpgqe6udm7ad.onion:8333
+zmfmmn72dg5jjkovy4jt56c6btg7pgp7wmeh547zlvavwmlbrbsl5yyd.onion:8333
+zmjncrrwtui476nyn6sqbp67bvgdhotllq33vzwygasumv6d2us64iad.onion:8333
+zmmtddrew2mjtghs7zjiyi2eelmyss7miyj2axzwfgnmvzthx7phevad.onion:8333
+zmn3jyv5a2rod2udnreygi6uan4zq5ul4mhewyfyrf7a3ury72bycuid.onion:8333
+zmqvv2cdxjj3vbclq7l6rfdmjegmixwkxsnzzd6qezwp32vxkr2cbiad.onion:8333
+zmt7psgtnnqxk6tibhvwkdfuhtgtjatz6bpoyyl4ptuv3u6ko2b5o5yd.onion:8333
+zmtd72b4nsa22ocez2hbjsxxrdfuxxyghg3zjtqjob5sgnjpustat4qd.onion:8333
+zmuuhwxhoa6h53jijpb6mczcvtxhw6zyjymm53dwzsbmkc3kkv5v64yd.onion:8333
+zmvriguathsanquofxml7kgcda4tkihm5qked7a6ntbqk7rmz7qadkad.onion:8333
+zmvritlexdmgatfqjlexl7wsx3lmf7y3qxe2kqeergb7ntkfu4nky5ad.onion:8333
+zmyavuyz774c2fo3eb55yokivpr7qfxdpjy2t5wpeygunhulck7yxzid.onion:8333
+zmzjx42yxlpepdgya34rvwb3wc2peggturiedmn4sfjltgy6gjtspsid.onion:8333
+zn3gjkpqkajav76kaem2espqt2bw6ggfvmn4u3gmkonds7pqd5heqkid.onion:8333
+zn3mj2tggwpbzzkvtsovkrbdshbsvac7n676hbi76r72de2b4gknpdyd.onion:8333
+zn5purhx3rnikkks5tx4scnjlhewwll3uzcs4pgde3qeqawof3jefhid.onion:8333
+znaiehv3qrtloxdi5rkbs4eqpmuveazuftob3sqzw3ta5pyakuwhx7qd.onion:8333
+znbv4cupk7rrdk4rqi6xncbouhscxnqdlbxtltp7564isfv5vtbyu7yd.onion:8333
+znc4xhwywjqejoioap3ssxvtsdilsc6i5o5s2rnp2ecmxqe6xe2nh5yd.onion:8333
+znea5ol7qgniizv3og2gfcbxw2wi4qhk7dfkdlt7bbxpy5aflljygbqd.onion:8333
+zngxgkdgkqpfyepa5cvxlaxvlyluzdryhzmviar4ojzaduxw37hhdmqd.onion:8333
+zni7kioacgsy5haqiftnexr74sv7rzvgy5o6lmz6dy26vvwg5lffioad.onion:8333
+znlvmmj4dvpju46kbb6mob4kufyf5a4qivyygmjj36kymbaa4nzi42ad.onion:8333
+znmgbi6qlwwwdlizjxsc6eujnfwgytufu6guo67b54av4y6inwgxllad.onion:8333
+znmwoazdkcffprail6h4p4opy7i4zqomhpdxe5l5nc6ejqagvt4i7yyd.onion:8333
+znt2jb6nivjgl47s2gdcgac3merqjfq5h2n6x6mbjegx6fumtl2ownid.onion:8333
+znvkqu376ienu62x5hprstn36jfqxospcnfhpc3kq5quwcd6436pzuid.onion:8333
+znwekshd4os5a2n222xrllgjuyvsw7hsb2y6br7pkwjatywk5lerbtid.onion:8333
+znxkxyd564sfftgjscsmi3a73jsazxwhsneix3bgto4suyjx356xewid.onion:8333
+zo4fczw4drgcbsumtgmigjkiso4miz34ltauajaawqmqoa6oxmzy4nad.onion:8333
+zo5jasvz5qo7pkgrgn4r45twdic4zake6zpjfemj6x2ioxcwvs7yzlid.onion:8333
+zobj27bempyxsigdvawc7foivyyuek73hemep7zf2tajof54353ok2yd.onion:8333
+zodjfmegrevmjbppq2t46iluruefbgh3b46tbrl2s5qkprvbetk3euyd.onion:8333
+zofseltpp23n2xb6fsmfgkwgqggwhrelxmt7zq7toazybgehbs7d5fad.onion:8333
+zohxazkomcr5ggqlj2edu23zs6xiay7wfsrxuetrn2k2s5gwhwhcngad.onion:8333
+zokmgys3gsgs5oivjcqp3xiki25iexezy33ekzuratdz3j5unqpxrzad.onion:8333
+zosjvclhqzwklml43hvsdmupglajj5lfdb5h5frgym7hsqo25rwrbdad.onion:8333
+zosk6fx2a3mxkfaeayziiuizq3y3j3azzp4ylwyh76wq2sqtaenuwdad.onion:8333
+zovm6wkattzmxc755cgqqd4sxugn3jaxw44izlm4yfpot2ucfeqnukqd.onion:8333
+zowc7rklhd6xhje724xomkftwimuihacwcnxkt7vhbjpvpkdahvlhxid.onion:8333
+zp3vpkpcfdx5lxvnuellqaf5qdvhu4luf4zqfx5xjo2dge7cqsxhsxyd.onion:8333
+zpgobpk2j2suauhuzfmh4iiz3y2zhj3xvb3g2t4a775t72stt3majryd.onion:8333
+zpgybnbaxfvzjeus7qna45zchxdkekjpk5webdkeqtxfwcglgogm2vad.onion:8333
+zphjbml3fqtbez63bjvd4s552yc2xebitadkpw2jon2qkbapbiltijyd.onion:8333
+zpnoo3qordv4xj5hjynkssu6wechvup6to7pamrgbi4ljmfugjyzwwad.onion:8333
+zppmhj76a6dyjch5qtubosxcyvtwjnb6zndsfywxci7dy3vc6lbfusyd.onion:8333
+zpq2nzcnlasmy3rmwtmaybav6t7xfrvorqqdwntnbgbxqujyy3dkwlid.onion:8333
+zpqvo25bxu4n2u3mh2pdzax7wmpsitd3qsszgw2ye3mpfdpjbg52kgid.onion:8333
+zpx2tq27yviwzbpc4nyjfqtlhigoa5k7cwl676nft7bkajo6jq224hid.onion:8333
+zqlwzzfzdoacgngtsnofmyqetag6o44f5r72opj733y434b7npnb4oyd.onion:8333
+zqq4g2eikcfgls64ffstsylfbqrfstm6n2otvrsbtvvjpqwgyqdnmbyd.onion:8333
+zqrj4fhhp4mq5eh5xptzcxjzpae37brkdn3voz32qsohl6noijygdkad.onion:8333
+zqrwah6dn3t5fuj7ohlyka27zzopduhxy4wyknfrtqpx4sykece65fqd.onion:8333
+zqtyvr7h277x5rxin6rhsrsbhwcfsyyiqgghpk6jlbewej2v3tn27yad.onion:8333
+zqv5nepyrwezkym2ba5s2sskmi2qck22snw2rygeke45bxg2o4vckuid.onion:8333
+zqvbnqwwhtoux2sxicng2blfiowk5mvty7c5xnssxwtlsjzalhg3zqqd.onion:8333
+zr222c3ybuqxn6a6piydvfos4zjnaklfgh6kofmujmolpiprfw4z6vqd.onion:8333
+zr6ffisxxo4gelmkoyb7izfm7ehjrbqbnzuguw34to34bqhxeeqzzjad.onion:8333
+zr7sqclimv46jdnmmeazqrhflhiqkhhrz5i3ed7yvyue63swk3qkjnad.onion:8333
+zrrfr5sr5wrgdt6rn44cxnotlvwe7cl67rgssw5dwsax42evokdaw6id.onion:8333
+zrrhgs52ftlylshuwp5e2uesgqnwct7h6cqhzofdduwoi4sz3shmxxad.onion:8333
+zrt3rg4paxmo24ucd56eehl7apindhbubq3ej3q5nhr6i72jv2eznryd.onion:8333
+zrvsjjrb3lgvmeftz2vfjva4pl63htmv5qyviq7zhnfmlk42evrxdpid.onion:8333
+zry2rqlcqf5p5e46wc6nmtcbt5vd45mf4hyf4nxlqogckoniufdjklid.onion:8333
+zs47b66pljpz4ahompanciv73xtztnnzkx4wjklt6hh4drsge4m26iad.onion:8333
+zsalwutefh6m6x6yxccbhulzrz2bmo7dzu2ggu4hxp5zv3xx2j642dyd.onion:8333
+zsbzferezmnyxhpktxtccn2xxuggmdzdnrza7pqjlnwjorgx57y2acyd.onion:8333
+zsgtoyy2svehhfba345dx3dazp7tfdio6o34zxlcgylq6pi67gjq7nqd.onion:8333
+zsi55x2nvjc4oqrpzzopkneukb5fudnm4e6drao4x73lf4zshhcvllqd.onion:8333
+zsipwsjpm4f3p6ueczh7lqei5rp3cusl6t4d6nntnwxq72hori5f7jqd.onion:8333
+zsisadra7jlxp5nhec2vsjwspvvnk6jemjxk7zn7arypl6cm6dy7mwqd.onion:8333
+zsr43xqj6nsrqh6qgxghadctltwytnaw4zmlvx6exqybt2qdt72f5yad.onion:8333
+zsxgefpkofjc3nti4qusk3pdqcfinkljajlwcb2cee2tduxltxbmrpad.onion:8333
+zszufrszpweaoysubpdnqparmyotjnev6nhhcnejhjjftu5sb55kesid.onion:8333
+zt6gkop3n6aggrxucnaqp4yrjeu6htwvuy2nyn3vadjjrodwxfhfv3id.onion:8333
+zt6hvzyoalzm4a576drn7yfvdetdvzwwouvfz435wzrf5pcnxqxplaad.onion:8333
+zt6v7eqh7vvlwy5kjzbdfgkw3syj3nnhckyghlzgmwwfccxvyfusuzqd.onion:8333
+ztcmlrstdkp7coheeolpwj75gp3imzgiw26xnoiucquwhxxcofao63ad.onion:8333
+zthmey4ueoutf7q36nwgujxu7hq76s5ifbtanvze4mxq2s2xq2cmjwad.onion:8333
+ztmwsyo35zkogpftujm2o7oilhucjxe3w6bjagsaiwtb2bu62vgjptid.onion:8333
+ztou4ytvgvpcakjaje2c6l5j53rxcxes7qhkerszi4haffxfpj3kdnyd.onion:8333
+ztwryklhcnfoeck4qntt2aitoilit2cmmr2geyqo6cjc4nwr7jlludid.onion:8333
+zu3ekh3vtqjfnxqjqlmnq3jbqlg2zum4ehgirz5cggwe2thjmgkz4cqd.onion:8333
+zu3yh7mvqw342e7qt5amwtwe2btjubi6t75k7wgcpsyoicsnpgbgj5ad.onion:8333
+zu76ecbahyc6ofjiiutna6myxmfdcsuhcrhtgpifbw3vfo7njd4b5tyd.onion:8333
+zuaotutv2ngbf5ot5kvz75uehbh5e2j726fglhqw7omk3b7xnaastpad.onion:8333
+zubmiztmnfy2vqowqmpyzbqtf2a43jgazsex6zlxokhfmnzmi3rht6yd.onion:8333
+zuc7sobx6ttj7lswk32raexasfbxc5kd6a3l6td35srqzkj3emsv4uid.onion:8333
+zunmnr7czrxvfjgxtvkwk6ziti5kskx4fi3j4dzahhdljfsqtz7yeqyd.onion:8333
+zuoml3m3jdkoh5bdrwfecnew5f4mrlcwhmhkn456qsa72cp274pbgtqd.onion:8333
+zutyd7pzkyejctriyr2lqlrex3arkunntsdjo3kgw2qj5u3fj5uyusyd.onion:8333
+zuzdl7nnjhy6inyqwsc5i7fae2nregm7wnyrtolaxhi6oiufyc7l26qd.onion:8333
+zv2nusexbcrncbutlcprevwhvbtqlyri3stjwmgl23x7fdqkmae6owqd.onion:8333
+zv63heoa7jstwhq3wg2nibip36bw4icd7jphccy3li3nut7gp2gojqqd.onion:8333
+zvbhycudpglrdi3sk7yixe64eknydwzzisc4n6xmxwhb7xyyzevc4nqd.onion:8333
+zvgutw2u7tu4dx7t25leghdp6j5n44u464mmoypafwstayp6ggabtkad.onion:8333
+zvjn5jscn7jncqss44uh53gvi6b4eycjqp42t6pv46bsr7gine5cbrqd.onion:8333
+zvmxfy5z7nxeknglvpbh7rveoppkyvvzvnpwxon2kgkepafnq4igheyd.onion:8333
+zvpcm7eemfvlklgqio3fgzcwa2vukg3n7caov5itik36kdua6mvm43qd.onion:8333
+zvzirfk3h4hk52j4u254y2np6ve2xttd2nugiccsqw2liiw7aqmglkyd.onion:8333
+zw4olgpxujj6iydkmhuxbx37b52syl5bm6embyebesysep2ignp2dgid.onion:8333
+zwbnovgpo4qxidylubpdrhxm34t23iwaniawfshiqrilttwqjnnlohid.onion:8333
+zwbqgh5le73aurfmbwf5ivjb7ycemwnjiq2jnq4sqz6epl7rdtd6rtid.onion:8333
+zweiy44ngrkfzhnaoqov3fopwqd3uhwsen4v6sdyf3ynmhlpuluvzeyd.onion:8333
+zwg2cvvkm37u2hicwbjasqzdqdhcblwvtzsulmz4kpbebf77jheiaaid.onion:8333
+zwrp2kb2covbrr3xdz2pxr6gg6ndnhpcgfvjkjr43eudnl5aswxgvbqd.onion:8333
+zwsapfrsxzsomsoty652jifwii56st6fg7bs2crr6boveh5o6npl7vyd.onion:8333
+zwtjkx5blzs4i6e7hwfeekcwufdl2lba4j65243tvkajder5iodkavad.onion:8333
+zwu3ep3zqki62b7ldjbsxk4dm4rlppkxpzzqfwsfvkoihxltm3y4qaid.onion:8333
+zwwpbfpymszcmkwlfozzl26m66r6n7xzgnw6bs4nf3pypqh36ya2w6yd.onion:8333
+zx37fw5b4eatt3dekaefun3ln67agpt7oqobeacvyq4keurbj26azwid.onion:8333
+zxaujdps5ce6wvk6ykbfquygtbli4ecvpokj7oyfxjqiionn3u3fdsid.onion:8333
+zxbq3k7hwswo2f374ahsmlgkpdj7ju7pyygurkvzqaoh35vmxleewsad.onion:8333
+zxc2bzuqdkippxthxbg7n7e3lznbcnx7zyitlhwvjusbwr5v32oxueid.onion:8333
+zxcnzlo2eigfig66vxyx43znm66a5i4ieuiosycgddgzdff4vhn6zhqd.onion:8333
+zxk4bqrede3tnlb7ymjlsoyupc37r2vqe647otr3nczqmgfeoyiu75id.onion:8333
+zxqdpu4gmvn5vz2kdld6c2swqdzknwh2czwsw55vx323orvtk6a6igyd.onion:8333
+zxqe6efq4odzd2mvyeglqto2cfggagoicgcvlvca4mxycg47jei4uxad.onion:8333
+zxzfz3z4nbb7u3ifcv2p5xenzpbnzuuezelbbjcfrmupxtqyoh7uhyqd.onion:8333
+zxzqhfwi3gdheuxmzagp4aw4aks6cii2llljapcvqhtqrxlksxddo5id.onion:8333
+zy4jeshnpx3i3wjcqrb27qcea4qetpez65wpocat5sqncz24xeo6sxyd.onion:8333
+zyccgvzokepone36ulu74l54ad4dtqv7a2bjzcvopj6rg5xhbc7ihjad.onion:8333
+zydziohabauwybhbqkegn4d5r4257bmfain36fatcxdbj2nw5zoa5vid.onion:8333
+zyetfkanxicfp6tt5tegkxlkoz5rl2i3zsc6hyyqizahywbktezfuwid.onion:8333
+zyjfoui3hrpsw3fo4owxrztclffqhr26wdedizvz5xvlgurgixit2mad.onion:8333
+zyku4bk6pdifla26hympigytlwsx4htajcn43hhobdbrv4tfojv3snqd.onion:8333
+zyl4kfejs3t4vefsvuqrqopboxrmztuun62jick4uh3wpu4mw7dpqlyd.onion:8333
+zyphknlr4ogrknj5t64qya246kdaasgirn4iercvesggqplzzxsisbid.onion:8333
+zyrodumrgvgpinhygbi5molpbhl6ndfs3lwtt55pumd6wy5k7nb3esqd.onion:8333
+zyvgumk5pcanh4zk3z72glefxgbd4dpyhsbzvqlsp2gspaw37lrhjyad.onion:8333
+zyyefl5unnw7lnrjlgfyvnytw4iy4n4cy5bbs2nudjh7wp7psvefmfid.onion:8333
+zznngqwcp6g55wkjg52rzeogk3fcdpopyl3zprh2fz266nykv4sqveyd.onion:8333
+zzntdfpcb3spf5pb3g2gczw2njmhwwksgxt3twbzjhbaisihg7h2ywqd.onion:8333
+zzsi7brufwylb52w3bcbqvp5jx6vribh6geiqfy5jhxpihqjjaox7vad.onion:8333
+zzthz644hdjxn3d54xrfe7snnuyhsx2cguy4kqb6dpc5u7aun5lflbad.onion:8333
+zzuipjogcfvs7uyfhfgesehon6viegga3sc6c6265n235pqmkwyqfmyd.onion:8333
+zzul2xvyhqvajnd6zfs2dzljoppx5lsp2xt4qad7256kpxrv3wzyiuyd.onion:8333
+zzx4r2yrkxul2kg2ojoeijwce3skll4wbkkjw5xprstn2o2xw6n74wid.onion:8333
+zzyp22x6ryzyin43pltkup6jki5ynboh6cwpucscx5a3md2tooqn52yd.onion:8333
+zzzzzzzz5bs2qnoijxlhxd3ibxipajesgprqlrxtpfbygw4zcaf6oaad.onion:8333
-# manually added 2022-01 for minimal cjdns bootstrap support
+# manually updated 2023-04 for minimal cjdns bootstrap support
[fc32:17ea:e415:c3bf:9808:149d:b5a2:c9aa]:8333
[fcc7:be49:ccd1:dc91:3125:f0da:457d:8ce]:8333
+[fcdc:73ae:b1a9:1bf8:d4c2:811:a4c7:c34e]:8333
diff --git a/contrib/seeds/nodes_test.txt b/contrib/seeds/nodes_test.txt
index 5b04791d60..2def8ae644 100644
--- a/contrib/seeds/nodes_test.txt
+++ b/contrib/seeds/nodes_test.txt
@@ -1,89 +1,29 @@
-# List of fixed seed nodes for testnet
-
-# Onion nodes, last verified 2022-08 for minimal torv3 bootstrap support
-24j74ahq6ed4wmfrghdwroyfzimlkhnrb7zh4zw3vl2allzxbjrhaqid.onion:18333
-2fy74te65gm3c3gv3u5mhwdudvbdfh6k5fdz4gduimrltjjrxftbxrqd.onion:18333
-2lsncqdflwk272dhydrxf7ikfy23ppnmm54dnynyxiym6lqf3wowrmqd.onion:18333
-33o6qaidta7s2pmltet6vynd337vamgcifhh44rehwwxqpflcjt2njid.onion:18333
-3oo6bsc5mvf6a6ypmoaikilta6ka7mbdhdwhrnqhuhjlbaxyedvfvaqd.onion:18333
-3pe3fyklipy4sppkkgnhc22kcxtt57uler5kv72t676bbrwmcseo5qad.onion:18333
-4u4mcz2sfvxs7pwcwncswgmmcdzqtzjx7ztfo332jv4pqucb22ikdhad.onion:18333
-5v3i2kfqiqwp75gznjoptss7qgrcgseceqxpzpqkd34qeqzrg726i7id.onion:18333
-5zlrxk6q24t4vz5k4ie7gtuasdjavhoelhinzimxbfhc77u7vafipsid.onion:18333
-67s3af64ehw7xnxv422axm7tns4d6kutrftc6bjq375n74q3kj4pp7ad.onion:18333
-6a4ony53julvnufo632ktgmwvhupz63wbdwx7n7qudjy32qyq6gm3bqd.onion:18333
-6ftyg3nhc6tn2hyzls6zfdsfbroczhkxtdqumqb5q4yafhy5rdpapbid.onion:18333
-7554uw5djruh34j5ddx3iprzgqgzypcjtptwoldymfbgoywqcw2wiwyd.onion:18333
-766lozlabxaqjpbqsvt6sn3c65n6gkwwhoxyvggj7nfwnmw4cpaoccad.onion:18333
-7blv5abnytdf47yvbhxmykprmvjryqob65i2jmdwq3rrajcn2iiysbqd.onion:18333
-7v2ja4igx4v5y2jr6jrr6gaxohjhlzhvgwe4avlraxchozf7ea3kruqd.onion:18333
-7zgbmtzxow2oevd5aaqtsormw7ujv4zprl3oi2355immhq4gk7cyw5ad.onion:18333
-adstabjz7ec2y3jt4w2dvummowzv7g6m2f3kajeejffuaz7ojwj6epqd.onion:18333
-aesy6tfufadkut6flu2bsqgnw2422ur2ynjalguxlzuzuktg3zehttqd.onion:18333
-alxo32b5edi3bn2e224qrgytgxxpic4knyipvpdvctfsrvcaiq5lgeyd.onion:18333
-aoeart34umoonvd2kbqr3bc4sweu6a4msh2gp4skyqvei3shzcxbgmyd.onion:18333
-aprzvj7hgctsde4mkj3ewq35gvykspjvkqiygg7bpnw5tkvse2n7rhid.onion:18333
-awpk6z3xghx6ozouhodcydaqtr6uzzbnw4creuix7mkupxoxlmhhspad.onion:18333
-ayynqazucyh2jd5rehcfggmhunqpdwzlbhzbqgy6lj4ctz2ocj7chpid.onion:18333
-b2ika53aqckv4gs7wmog3byrea2vfzm5p7ye33digcsmvvnpbyqmzoyd.onion:18333
-be7zx3hh6dlahorlvsrrgqm4oahfrgqm2tbwnbd4u53ntu5f765n6hyd.onion:18333
-bluk62wj24bsvdwh47muo54hhwsatkftiqxevt5kba7hstjoex6ueeyd.onion:18333
-bubm6fiopfzkxqrfx6vqpioe5ahlhyubz57ogsqqy4ha5pnngiqlh6id.onion:18333
-d3czabzjj57lgrsr5gawkjd7v3gznrqa7zyizqmk4lryascavmipnyad.onion:18333
-ddj4cuvb32ve5chtp6jattcdnnmxmpoofjthzi7thgxxht7yqoetj3yd.onion:18333
-dqhhlssfwmh3g6zhwxpcfbw64xz5rfikcglinbhoxv5ajv4qzicjyeid.onion:18333
-drthcyb4x4rdfekw5g7xjogxi7aqoluilgulbgwvsme3nw3oibvchbad.onion:18333
-dwb47cmqa2tjpmvjaear7gdcars2lez6niefhi4qf22qehtyta6577qd.onion:18333
-e7tkrf54ng3q5vcn5gn77zwjwm74lkfav4mwdux3pvon6yvqg3tf46qd.onion:18333
-etuymy47s3quepvdaoo72i5e5mc7uovrzu5m4jf5q6mwlwizoxy4xgid.onion:18333
-fbimesnyhzubbzqc3uaufzkbyfmnkxvypoxaveaub7rzpzh2foxrn2yd.onion:18333
-fzbrwmgwmko7quelrhfuskt3ijabac76zx7g52dfrevmhdkj6ivh7qyd.onion:18333
+2yq4xcwzvb2ktyci5lpmb2q3nl6qqywb7nrf6fkcthha7l3tle2q.b32.i2p:0
+4g5uvbkvi5fvyditekvzajldtzgurorqjupuwtmymrjloq6cjm5q.b32.i2p:0
+f3w7soepsy7jqwf7dlo4ro2qkyapg2lrb2dkkvwfwuymgaqvljqa.b32.i2p:0
+nr7nozlb54xv3ozg4ksvcr3ofzfwfeud2n7xijywvt22ixzal7qa.b32.i2p:0
+o6j3b33bv26vthoqzjy3h7a3qsuqbtbe3ulajmjzsl43vaqyieyq.b32.i2p:0
+ocqipbbxx4paopgkkbnj234ie7opzrtca5gtiwr6oda3h32rzgsa.b32.i2p:0
+r2zdpkcslf7e4t2fmglu45xhfw5zgupthdh5pcewdo6jajumveda.b32.i2p:0
+xgctj4seo3ofstiymoyeuzq74bvddrbr6jtia6erodlf5va3cz5a.b32.i2p:0
+y5e6aqz4jkjjoeipoxwurzc2jrfv6ilvfbdqmjqk574maba5uara.b32.i2p:0
+ye3ajv2tgpq7jvvzzn5wxbtmd3txev3axsdla5bkpobeiwccyjjq.b32.i2p:0
+7ph7mrc24te57mvppajfkfj4mk7zuz4teukymt3wgpdpw6vpndeivtyd.onion:18333
+bkzo7mpxuar7rhsbiwdaxqcymixarcbdmb3sdaqtv6yb2svqttz2s6ad.onion:18333
+d63vf45ta4chrewnruyvypm7ybfxtut327crtq6qfyrvcwx434rli5qd.onion:18333
+efqfw6vjq7gpgyhosu3qf24hsshxpbhay426ccsgz54key4cvwund6yd.onion:18333
gy6nih4pmp5esyvvnhlj6qvk7zkbjuoswkxffyiip3dbkvsfxwz5zcqd.onion:18333
-ha62ziqzqdogd75zg7lfh4fqrg3bim3cpqzyupo43w5pw4fen6nr2pyd.onion:18333
-hacjjgj2mbqqrthzimmi6anvin7dljjhfl3ik6ebg3w3nmgsvr3ymmqd.onion:18333
-hbkp5xwpqo4qm75kpglfrclyiuuvdgv7mtiqfys7oqks4dmpqgpeoeid.onion:18333
-hqgoy62hoqjmz37brdfvoeov3cix5fixbqjoert4ydr6herg5oc3iwyd.onion:18333
-hvbmmzvqrpgps2x5u4ip4ksf3e5m2fneac754gtnhjn2rsevni6cz3ad.onion:18333
-hw3vzp32w4h6giplue6ix445oi6wt7gmeksrznb7tdfwhkgit7gnbbad.onion:18333
-iddr66ewkhenivapgianudjkwqcp6dxtssg7ixrdot5az6uh7m5tmjqd.onion:18333
-imya36iexiiiqrkwuxxcehnv4kg5shtirwd2vg4cnjy6lfjlph3fusqd.onion:18333
-iuhhuocns7entrzlxsxktyz2ibs7hqgiggv6sauzqkzka6laslwz7oqd.onion:18333
-ji5wmshokuc63eiulzlwj2zdvnligvrwfvvc76bice3tu43wfzvpmkyd.onion:18333
+hwipziotclxg3ledn5yj5j6n6pkrgnmlksozzlrtlnlpguvixox7naqd.onion:18333
+i5gphw2d224tniqkjebxdwz5ygbbo5gcushoyevv7x7o454b6qlrzeid.onion:18333
+ipbzs2lbe7lab2xaikvkdkwxian6t3nakaoltwbshpevbszdvoyyjiad.onion:18333
jjfuyj7krgzkmpxvn3b2j2hwlzkmze3ezy3ifwk7dnswwawgmzqhjrqd.onion:18333
-jn2p4sgfphkxpow7kjrubrbqat77kkibzqkvuwhxyalcrazwmcqeaqyd.onion:18333
-jrveyz4us6sog6e6czsvr5mvvhgzjgv4idbe4idrolmqeudvt5a2dgid.onion:18333
-jsc4frvvnl2d3bhzyofsc72xpztgm23nl4fnb4dwkzsxr6fhij2q5iyd.onion:18333
-klymxdvje7kccv3tznabo3udopsftkmjemkbi2urqxjm4hefaudejjyd.onion:18333
-kwjxlauwjtecjfsiwopbl5pvn5n6z5rz76uk6osmlurd3uyuymcw7aid.onion:18333
-lc7upz2srw2yhpcvwg4afy64ylcoo6mfwlttqj5ovuglqnhnohpi5iqd.onion:18333
-lf3mpxfyjuovcqdvinl52pvdmmda6xqyfeiarlfamdjpgy3ouzmmlbyd.onion:18333
-mc7k47ndjvvhcgs54wmjzxvate4rtuybbjoryikdssjhcxlx27psbyqd.onion:18333
-mjbg3ggeuelmc7ixty3zjccyo2urg2uyherfqe7ytkm2ejkwlec7h6ad.onion:18333
-nkyqozv6kdwi423s7s2mezzguf5bafot2a3hv4ed2dbvtblisdmad4qd.onion:18333
-nvvqo4xxiwgb3y246jmcbuuveurfdq2zs3a5y7veqkeqv5jfhang7gyd.onion:18333
-o6vfovqxz3oxszfppczpjejwouobztjrgvfojc3emvhan3bkyskzhuad.onion:18333
-oaiw2lnhzgp5ry7ivzneuufmh7lfploquu2rjv5rozmlbefedsnxe5qd.onion:18333
-oln7ybci53wk4g5n42nipyixvyjxbludsbrfsmhnirb6tk7ovlikd5id.onion:18333
-otmfnhc6wrrbf2tpdy6zkisqc3r3urnsuowsnmatoto6yixaocnkseid.onion:18333
-ovc6sajbqfcbwv3wrq7ylklu6q6prvisz4jr4lyycn4kgukzjfe4mjad.onion:18333
-pm57didyzg5ljuvn5ufr5uun2iencuk3af2gzqc5zvgfh452c3rxtjyd.onion:18333
-pmismhpwug34gnqzbutranvx2wjwbshyqj4un2dyzyuvak2eh55psfyd.onion:18333
-polarisultijjhaku6z6u7jyboho5epdsg44ttebfaxmgau2z5sqolad.onion:18333
-qe2jbe447he6panfvpyqhyntf7346gmuf55bxrmdzggmgwyjsyknhxyd.onion:18333
-qz6yd5lsgdajcteoareeptwnipxsezyx5kks6ukpk5tvqinffzunqmyd.onion:18333
-rp6pn3b3oesyr2giolbysbjhqeugxntsu7crnkth4y33ok4zvcl7yrqd.onion:18333
-ujdchuw3hz5gkbouiv4p6pwbfdn7v4k6gluwvd4wiukqc7y7ow754uad.onion:18333
-vctlwaqgmu53eutz2hewuakcipfgtyljsd7czut4dd62xr3rp6fqezad.onion:18333
-vf5ur53tzmdtotvkndcgochklnuav7quqjvkc6mctqfvef6wnmn26mid.onion:18333
-wnxgjgjgplv5iu4mssyuunycvku4qnqr5t4q6cfdt47k7uwrfifuirad.onion:18333
-wpkbkdr7clw7zk3jkwiult6bf422j54u77ml4rgig2xq7icogyrcspid.onion:18333
-wzpdt24tdark26eugredddorik3tqwcj5ialtt2yim4ceiuiq7phkyqd.onion:18333
-xgapnikkbldoggjh5ewxkyauhuwnvf3xkspxroe3ojvfrk4lswkyx5yd.onion:18333
-xkvzdhcirontixbq6pjhru57bf4sgtqylvphk25csfrsy5p5ay3oc3yd.onion:18333
-xnipauenw5wnjb2zbx6v6umgvbb3g6xhf5kjo7pnyn5tdzvzaxtzicid.onion:18333
-yda7kwpii33j2qpq32ftf6lp22znknswipjwaccvsqj7l337jvfesnid.onion:18333
-z3j5foswuhpmtrg3kb56stkzmuoaesvd5jz3eztq46c4cidapglcyuad.onion:18333
+jnphftehkfstwbko34idxlpo5fdw6lromkmeukxh3xclthlstehpg4ad.onion:18333
+jrhpwqahjrj75gtb7gt23eve65x7bbawy7j4edhmgbo5nj2mkaeghbyd.onion:18333
+jun6gdmbgasr57bhr4zs3dfhc6pzpaw27nqb4dadbai7yrbq55zskeid.onion:18333
+o52y7fadtubr4tuqhix6ymrin3qzn7ubh5tewuuehw5wxcbnfj6yaoad.onion:18333
+rigfm3joif5lsl7b7yr6d6cvddukawykm7kgguzfwi6dplckyz6x7gad.onion:18333
+t6d6epb5ccbo4e66iaanukraxpjmqiqsz6poj5uvxu2ownnhcguygdyd.onion:18333
+test2vozlxfznmfyxzkulf3l6qe6dti5hqfjsxar5lml45cjnyeusmyd.onion:18333
+uxtmtmpkfaxc6zcxaxgydrukyd5jdrcp2m5oubpimijy44rnjuywijad.onion:18333
+xuhmq42du7dckfophyr2rmf75aqkp3bk6y3wyyc6jxw7jmpp66zlm3id.onion:18333
zcep44k7unwjm2wxty4ijh2e4fv5zgbrvwlctzyaqnrqhltjfzrtodad.onion:18333
-zmvizz7fd5hdue6wt3lwqumd6qwt4ijymmmotfzh75curq3mzjm53hyd.onion:18333
-zoaa3x7quyuijggii5zl4uyeioodudsgtr2uyv2qtdsslac5ukiwlxid.onion:18333
-zovauxlorl5eswumbsoxv2m5y3sm3qlk7657dcpr2uld7xf35en46sqd.onion:18333
diff --git a/contrib/signet/miner b/contrib/signet/miner
index 61d9f62be7..e5daf9f993 100755
--- a/contrib/signet/miner
+++ b/contrib/signet/miner
@@ -30,7 +30,7 @@ logging.basicConfig(
SIGNET_HEADER = b"\xec\xc7\xda\xa2"
PSBT_SIGNET_BLOCK = b"\xfc\x06signetb" # proprietary PSBT global field holding the block being signed
-RE_MULTIMINER = re.compile("^(\d+)(-(\d+))?/(\d+)$")
+RE_MULTIMINER = re.compile(r"^(\d+)(-(\d+))?/(\d+)$")
def create_coinbase(height, value, spk):
cb = CTransaction()
diff --git a/contrib/tracing/mempool_monitor.py b/contrib/tracing/mempool_monitor.py
index 9d427d4632..afb5e60372 100755
--- a/contrib/tracing/mempool_monitor.py
+++ b/contrib/tracing/mempool_monitor.py
@@ -27,7 +27,7 @@ PROGRAM = """
struct added_event
{
u8 hash[HASH_LENGTH];
- u64 vsize;
+ s32 vsize;
s64 fee;
};
@@ -35,7 +35,7 @@ struct removed_event
{
u8 hash[HASH_LENGTH];
char reason[MAX_REMOVAL_REASON_LENGTH];
- u64 vsize;
+ s32 vsize;
s64 fee;
u64 entry_time;
};
@@ -49,11 +49,11 @@ struct rejected_event
struct replaced_event
{
u8 replaced_hash[HASH_LENGTH];
- u64 replaced_vsize;
+ s32 replaced_vsize;
s64 replaced_fee;
u64 replaced_entry_time;
u8 replacement_hash[HASH_LENGTH];
- u64 replacement_vsize;
+ s32 replacement_vsize;
s64 replacement_fee;
};
diff --git a/contrib/valgrind.supp b/contrib/valgrind.supp
index 9a8edba445..c537f9e7ec 100644
--- a/contrib/valgrind.supp
+++ b/contrib/valgrind.supp
@@ -13,19 +13,8 @@
#
# Note that suppressions may depend on OS and/or library versions.
# Tested on:
-# * aarch64 (Ubuntu 22.04 system libs, clang, without gui)
-# * x86_64 (Ubuntu 22.04 system libs, clang, without gui)
-{
- Suppress libstdc++ warning - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65434
- Memcheck:Leak
- match-leak-kinds: reachable
- fun:malloc
- obj:*/libstdc++.*
- fun:call_init.part.0
- fun:call_init
- fun:_dl_init
- obj:*/ld-*.so
-}
+# * aarch64 (Ubuntu Noble system libs, clang, without gui)
+# * x86_64 (Ubuntu Noble system libs, clang, without gui)
{
Suppress libdb warning - https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=662917
Memcheck:Cond
@@ -71,12 +60,6 @@
fun:_Z8ShutdownR11NodeContext
}
{
- Ignore GUI warning
- Memcheck:Leak
- ...
- obj:/usr/lib64/libgdk-3.so.0.2404.7
-}
-{
Suppress leveldb leak
Memcheck:Leak
match-leak-kinds: reachable
@@ -106,3 +89,9 @@
...
fun:_ZN5BCLog6Logger12StartLoggingEv
}
+{
+ Suppress https://bugs.kde.org/show_bug.cgi?id=472219 - fixed in Valgrind 3.22.
+ Memcheck:Param
+ ppoll(ufds.events)
+ obj:/lib/ld-musl-aarch64.so.1
+}
diff --git a/contrib/verify-binaries/README.md b/contrib/verify-binaries/README.md
new file mode 100644
index 0000000000..04d683e69b
--- /dev/null
+++ b/contrib/verify-binaries/README.md
@@ -0,0 +1,88 @@
+### Verify Binaries
+
+#### Preparation
+
+As of Bitcoin Core v22.0, releases are signed by a number of public keys on the basis
+of the [guix.sigs repository](https://github.com/bitcoin-core/guix.sigs/). When
+verifying binary downloads, you (the end user) decide which of these public keys you
+trust and then use that trust model to evaluate the signature on a file that contains
+hashes of the release binaries. The downloaded binaries are then hashed and compared to
+the signed checksum file.
+
+First, you have to figure out which public keys to recognize. Browse the [list of frequent
+builder-keys](https://github.com/bitcoin-core/guix.sigs/tree/main/builder-keys) and
+decide which of these keys you would like to trust. For each key you want to trust, you
+must obtain that key for your local GPG installation.
+
+You can obtain these keys by
+ - through a browser using a key server (e.g. keyserver.ubuntu.com),
+ - manually using the `gpg --keyserver <url> --recv-keys <key>` command, or
+ - you can run the packaged `verify.py --import-keys ...` script to
+ have it automatically retrieve unrecognized keys.
+
+#### Usage
+
+This script attempts to download the checksum file (`SHA256SUMS`) and corresponding
+signature file `SHA256SUMS.asc` from https://bitcoincore.org and https://bitcoin.org.
+
+It first checks if the checksum file is valid based upon a plurality of signatures, and
+then downloads the release files specified in the checksum file, and checks if the
+hashes of the release files are as expected.
+
+If we encounter pubkeys in the signature file that we do not recognize, the script
+can prompt the user as to whether they'd like to download the pubkeys. To enable
+this behavior, use the `--import-keys` flag.
+
+The script returns 0 if everything passes the checks. It returns 1 if either the
+signature check or the hash check doesn't pass. An exit code of >2 indicates an error.
+
+See the `Config` object for various options.
+
+#### Examples
+
+Validate releases with default settings:
+```sh
+./contrib/verify-binaries/verify.py pub 22.0
+./contrib/verify-binaries/verify.py pub 22.0-rc3
+```
+
+Get JSON output and don't prompt for user input (no auto key import):
+
+```sh
+./contrib/verify-binaries/verify.py --json pub 22.0-x86
+```
+
+Rely only on local GPG state and manually specified keys, while requiring a
+threshold of at least 10 trusted signatures:
+```sh
+./contrib/verify-binaries/verify.py \
+ --trusted-keys 74E2DEF5D77260B98BC19438099BAD163C70FBFA,9D3CC86A72F8494342EA5FD10A41BDC3F4FAFF1C \
+ --min-good-sigs 10 pub 22.0-x86
+```
+
+If you only want to download the binaries for a certain platform, add the corresponding suffix, e.g.:
+
+```sh
+./contrib/verify-binaries/verify.py pub 24.0.1-darwin
+./contrib/verify-binaries/verify.py pub 23.1-rc1-win64
+```
+
+If you do not want to keep the downloaded binaries, specify the cleanup option.
+
+```sh
+./contrib/verify-binaries/verify.py pub --cleanup 22.0
+```
+
+Use the bin subcommand to verify all files listed in a local checksum file
+
+```sh
+./contrib/verify-binaries/verify.py bin SHA256SUMS
+```
+
+Verify only a subset of the files listed in a local checksum file
+
+```sh
+./contrib/verify-binaries/verify.py bin ~/Downloads/SHA256SUMS \
+ ~/Downloads/bitcoin-24.0.1-x86_64-linux-gnu.tar.gz \
+ ~/Downloads/bitcoin-24.0.1-arm-linux-gnueabihf.tar.gz
+```
diff --git a/contrib/verify-binaries/test.py b/contrib/verify-binaries/test.py
new file mode 100755
index 0000000000..22d718ece3
--- /dev/null
+++ b/contrib/verify-binaries/test.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python3
+
+import json
+import sys
+import subprocess
+from pathlib import Path
+
+
+def main():
+ """Tests ordered roughly from faster to slower."""
+ expect_code(run_verify("", "pub", '0.32'), 4, "Nonexistent version should fail")
+ expect_code(run_verify("", "pub", '0.32.awefa.12f9h'), 11, "Malformed version should fail")
+ expect_code(run_verify('--min-good-sigs 20', "pub", "22.0"), 9, "--min-good-sigs 20 should fail")
+
+ print("- testing verification (22.0)", flush=True)
+ _220 = run_verify("--json", "pub", "22.0")
+ try:
+ result = json.loads(_220.stdout.decode())
+ except Exception:
+ print("failed on 22.0 --json:")
+ print_process_failure(_220)
+ raise
+
+ expect_code(_220, 0, "22.0 should succeed")
+ v = result['verified_binaries']
+ assert result['good_trusted_sigs']
+ assert v['bitcoin-22.0-aarch64-linux-gnu.tar.gz'] == 'ac718fed08570a81b3587587872ad85a25173afa5f9fbbd0c03ba4d1714cfa3e'
+ assert v['bitcoin-22.0-osx64.tar.gz'] == '2744d199c3343b2d94faffdfb2c94d75a630ba27301a70e47b0ad30a7e0155e9'
+ assert v['bitcoin-22.0-x86_64-linux-gnu.tar.gz'] == '59ebd25dd82a51638b7a6bb914586201e67db67b919b2a1ff08925a7936d1b16'
+
+
+def run_verify(global_args: str, command: str, command_args: str) -> subprocess.CompletedProcess:
+ maybe_here = Path.cwd() / 'verify.py'
+ path = maybe_here if maybe_here.exists() else Path.cwd() / 'contrib' / 'verify-binaries' / 'verify.py'
+
+ if command == "pub":
+ command += " --cleanup"
+
+ return subprocess.run(
+ f"{path} {global_args} {command} {command_args}",
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+
+
+def expect_code(completed: subprocess.CompletedProcess, expected_code: int, msg: str):
+ if completed.returncode != expected_code:
+ print(f"{msg!r} failed: got code {completed.returncode}, expected {expected_code}")
+ print_process_failure(completed)
+ sys.exit(1)
+ else:
+ print(f"✓ {msg!r} passed")
+
+
+def print_process_failure(completed: subprocess.CompletedProcess):
+ print(f"stdout:\n{completed.stdout.decode()}")
+ print(f"stderr:\n{completed.stderr.decode()}")
+
+
+if __name__ == '__main__':
+ main()
diff --git a/contrib/verify-binaries/verify.py b/contrib/verify-binaries/verify.py
new file mode 100755
index 0000000000..12e6e10d8a
--- /dev/null
+++ b/contrib/verify-binaries/verify.py
@@ -0,0 +1,713 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020-2021 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+"""Script for verifying Bitcoin Core release binaries.
+
+This script attempts to download the sum file SHA256SUMS and corresponding
+signature file SHA256SUMS.asc from bitcoincore.org and bitcoin.org and
+compares them.
+
+The sum-signature file is signed by a number of builder keys. This script
+ensures that there is a minimum threshold of signatures from pubkeys that
+we trust. This trust is articulated on the basis of configuration options
+here, but by default is based upon local GPG trust settings.
+
+The builder keys are available in the guix.sigs repo:
+
+ https://github.com/bitcoin-core/guix.sigs/tree/main/builder-keys
+
+If a minimum good, trusted signature threshold is met on the sum file, we then
+download the files specified in SHA256SUMS, and check if the hashes of these
+files match those that are specified. The script returns 0 if everything passes
+the checks. It returns 1 if either the signature check or the hash check
+doesn't pass. If an error occurs the return value is >= 2.
+
+Logging output goes to stderr and final binary verification data goes to stdout.
+
+JSON output can by obtained by setting env BINVERIFY_JSON=1.
+"""
+import argparse
+import difflib
+import json
+import logging
+import os
+import subprocess
+import typing as t
+import re
+import sys
+import shutil
+import tempfile
+import textwrap
+import urllib.request
+import urllib.error
+import enum
+from hashlib import sha256
+from pathlib import PurePath, Path
+
+# The primary host; this will fail if we can't retrieve files from here.
+HOST1 = "https://bitcoincore.org"
+HOST2 = "https://bitcoin.org"
+VERSIONPREFIX = "bitcoin-core-"
+SUMS_FILENAME = 'SHA256SUMS'
+SIGNATUREFILENAME = f"{SUMS_FILENAME}.asc"
+
+
+class ReturnCode(enum.IntEnum):
+ SUCCESS = 0
+ INTEGRITY_FAILURE = 1
+ FILE_GET_FAILED = 4
+ FILE_MISSING_FROM_ONE_HOST = 5
+ FILES_NOT_EQUAL = 6
+ NO_BINARIES_MATCH = 7
+ NOT_ENOUGH_GOOD_SIGS = 9
+ BINARY_DOWNLOAD_FAILED = 10
+ BAD_VERSION = 11
+
+
+def set_up_logger(is_verbose: bool = True) -> logging.Logger:
+ """Set up a logger that writes to stderr."""
+ log = logging.getLogger(__name__)
+ log.setLevel(logging.INFO if is_verbose else logging.WARNING)
+ console = logging.StreamHandler(sys.stderr) # log to stderr
+ console.setLevel(logging.DEBUG)
+ formatter = logging.Formatter('[%(levelname)s] %(message)s')
+ console.setFormatter(formatter)
+ log.addHandler(console)
+ return log
+
+
+log = set_up_logger()
+
+
+def indent(output: str) -> str:
+ return textwrap.indent(output, ' ')
+
+
+def bool_from_env(key, default=False) -> bool:
+ if key not in os.environ:
+ return default
+ raw = os.environ[key]
+
+ if raw.lower() in ('1', 'true'):
+ return True
+ elif raw.lower() in ('0', 'false'):
+ return False
+ raise ValueError(f"Unrecognized environment value {key}={raw!r}")
+
+
+VERSION_FORMAT = "<major>.<minor>[.<patch>][-rc[0-9]][-platform]"
+VERSION_EXAMPLE = "22.0-x86_64 or 23.1-rc1-darwin"
+
+def parse_version_string(version_str):
+ parts = version_str.split('-')
+ version_base = parts[0]
+ version_rc = ""
+ version_os = ""
+ if len(parts) == 2: # "<version>-rcN" or "version-platform"
+ if "rc" in parts[1]:
+ version_rc = parts[1]
+ else:
+ version_os = parts[1]
+ elif len(parts) == 3: # "<version>-rcN-platform"
+ version_rc = parts[1]
+ version_os = parts[2]
+
+ return version_base, version_rc, version_os
+
+
+def download_with_wget(remote_file, local_file):
+ result = subprocess.run(['wget', '-O', local_file, remote_file],
+ stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
+ return result.returncode == 0, result.stdout.decode().rstrip()
+
+
+def download_lines_with_urllib(url) -> tuple[bool, list[str]]:
+ """Get (success, text lines of a file) over HTTP."""
+ try:
+ return (True, [
+ line.strip().decode() for line in urllib.request.urlopen(url).readlines()])
+ except urllib.error.HTTPError as e:
+ log.warning(f"HTTP request to {url} failed (HTTPError): {e}")
+ except Exception as e:
+ log.warning(f"HTTP request to {url} failed ({e})")
+ return (False, [])
+
+
+def verify_with_gpg(
+ filename,
+ signature_filename,
+ output_filename: t.Optional[str] = None
+) -> tuple[int, str]:
+ with tempfile.NamedTemporaryFile() as status_file:
+ args = [
+ 'gpg', '--yes', '--verify', '--verify-options', 'show-primary-uid-only', "--status-file", status_file.name,
+ '--output', output_filename if output_filename else '', signature_filename, filename]
+
+ env = dict(os.environ, LANGUAGE='en')
+ result = subprocess.run(args, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, env=env)
+
+ gpg_data = status_file.read().decode().rstrip()
+
+ log.debug(f'Result from GPG ({result.returncode}): {result.stdout.decode()}')
+ log.debug(f"{gpg_data}")
+ return result.returncode, gpg_data
+
+
+def remove_files(filenames):
+ for filename in filenames:
+ os.remove(filename)
+
+
+class SigData:
+ """GPG signature data as parsed from GPG stdout."""
+ def __init__(self):
+ self.key = None
+ self.name = ""
+ self.trusted = False
+ self.status = ""
+
+ def __bool__(self):
+ return self.key is not None
+
+ def __repr__(self):
+ return (
+ "SigData(%r, %r, trusted=%s, status=%r)" %
+ (self.key, self.name, self.trusted, self.status))
+
+
+def parse_gpg_result(
+ output: list[str]
+) -> tuple[list[SigData], list[SigData], list[SigData]]:
+ """Returns good, unknown, and bad signatures from GPG stdout."""
+ good_sigs: list[SigData] = []
+ unknown_sigs: list[SigData] = []
+ bad_sigs: list[SigData] = []
+ total_resolved_sigs = 0
+
+ # Ensure that all lines we match on include a prefix that prevents malicious input
+ # from fooling the parser.
+ def line_begins_with(patt: str, line: str) -> t.Optional[re.Match]:
+ return re.match(r'^(\[GNUPG:\])\s+' + patt, line)
+
+ curr_sigs = unknown_sigs
+ curr_sigdata = SigData()
+
+ for line in output:
+ if line_begins_with(r"NEWSIG(?:\s|$)", line):
+ total_resolved_sigs += 1
+ if curr_sigdata:
+ curr_sigs.append(curr_sigdata)
+ curr_sigdata = SigData()
+ newsig_split = line.split()
+ if len(newsig_split) == 3:
+ curr_sigdata.name = newsig_split[2]
+
+ elif line_begins_with(r"GOODSIG(?:\s|$)", line):
+ curr_sigdata.key, curr_sigdata.name = line.split(maxsplit=3)[2:4]
+ curr_sigs = good_sigs
+
+ elif line_begins_with(r"EXPKEYSIG(?:\s|$)", line):
+ curr_sigdata.key, curr_sigdata.name = line.split(maxsplit=3)[2:4]
+ curr_sigs = good_sigs
+ curr_sigdata.status = "expired"
+
+ elif line_begins_with(r"REVKEYSIG(?:\s|$)", line):
+ curr_sigdata.key, curr_sigdata.name = line.split(maxsplit=3)[2:4]
+ curr_sigs = good_sigs
+ curr_sigdata.status = "revoked"
+
+ elif line_begins_with(r"BADSIG(?:\s|$)", line):
+ curr_sigdata.key, curr_sigdata.name = line.split(maxsplit=3)[2:4]
+ curr_sigs = bad_sigs
+
+ elif line_begins_with(r"ERRSIG(?:\s|$)", line):
+ curr_sigdata.key, _, _, _, _, _ = line.split()[2:8]
+ curr_sigs = unknown_sigs
+
+ elif line_begins_with(r"TRUST_(UNDEFINED|NEVER)(?:\s|$)", line):
+ curr_sigdata.trusted = False
+
+ elif line_begins_with(r"TRUST_(MARGINAL|FULLY|ULTIMATE)(?:\s|$)", line):
+ curr_sigdata.trusted = True
+
+ # The last one won't have been added, so add it now
+ assert curr_sigdata
+ curr_sigs.append(curr_sigdata)
+
+ all_found = len(good_sigs + bad_sigs + unknown_sigs)
+ if all_found != total_resolved_sigs:
+ raise RuntimeError(
+ f"failed to evaluate all signatures: found {all_found} "
+ f"but expected {total_resolved_sigs}")
+
+ return (good_sigs, unknown_sigs, bad_sigs)
+
+
+def files_are_equal(filename1, filename2):
+ with open(filename1, 'rb') as file1:
+ contents1 = file1.read()
+ with open(filename2, 'rb') as file2:
+ contents2 = file2.read()
+ eq = contents1 == contents2
+
+ if not eq:
+ with open(filename1, 'r', encoding='utf-8') as f1, \
+ open(filename2, 'r', encoding='utf-8') as f2:
+ f1lines = f1.readlines()
+ f2lines = f2.readlines()
+
+ diff = indent(
+ ''.join(difflib.unified_diff(f1lines, f2lines)))
+ log.warning(f"found diff in files ({filename1}, {filename2}):\n{diff}\n")
+
+ return eq
+
+
+def get_files_from_hosts_and_compare(
+ hosts: list[str], path: str, filename: str, require_all: bool = False
+) -> ReturnCode:
+ """
+ Retrieve the same file from a number of hosts and ensure they have the same contents.
+ The first host given will be treated as the "primary" host, and is required to succeed.
+
+ Args:
+ filename: for writing the file locally.
+ """
+ assert len(hosts) > 1
+ primary_host = hosts[0]
+ other_hosts = hosts[1:]
+ got_files = []
+
+ def join_url(host: str) -> str:
+ return host.rstrip('/') + '/' + path.lstrip('/')
+
+ url = join_url(primary_host)
+ success, output = download_with_wget(url, filename)
+ if not success:
+ log.error(
+ f"couldn't fetch file ({url}). "
+ "Have you specified the version number in the following format?\n"
+ f"{VERSION_FORMAT} "
+ f"(example: {VERSION_EXAMPLE})\n"
+ f"wget output:\n{indent(output)}")
+ return ReturnCode.FILE_GET_FAILED
+ else:
+ log.info(f"got file {url} as {filename}")
+ got_files.append(filename)
+
+ for i, host in enumerate(other_hosts):
+ url = join_url(host)
+ fname = filename + f'.{i + 2}'
+ success, output = download_with_wget(url, fname)
+
+ if require_all and not success:
+ log.error(
+ f"{host} failed to provide file ({url}), but {primary_host} did?\n"
+ f"wget output:\n{indent(output)}")
+ return ReturnCode.FILE_MISSING_FROM_ONE_HOST
+ elif not success:
+ log.warning(
+ f"{host} failed to provide file ({url}). "
+ f"Continuing based solely upon {primary_host}.")
+ else:
+ log.info(f"got file {url} as {fname}")
+ got_files.append(fname)
+
+ for i, got_file in enumerate(got_files):
+ if got_file == got_files[-1]:
+ break # break on last file, nothing after it to compare to
+
+ compare_to = got_files[i + 1]
+ if not files_are_equal(got_file, compare_to):
+ log.error(f"files not equal: {got_file} and {compare_to}")
+ return ReturnCode.FILES_NOT_EQUAL
+
+ return ReturnCode.SUCCESS
+
+
+def check_multisig(sums_file: str, sigfilename: str, args: argparse.Namespace) -> tuple[int, str, list[SigData], list[SigData], list[SigData]]:
+ # check signature
+ #
+ # We don't write output to a file because this command will almost certainly
+ # fail with GPG exit code '2' (and so not writing to --output) because of the
+ # likely presence of multiple untrusted signatures.
+ retval, output = verify_with_gpg(sums_file, sigfilename)
+
+ if args.verbose:
+ log.info(f"gpg output:\n{indent(output)}")
+
+ good, unknown, bad = parse_gpg_result(output.splitlines())
+
+ if unknown and args.import_keys:
+ # Retrieve unknown keys and then try GPG again.
+ for unsig in unknown:
+ if prompt_yn(f" ? Retrieve key {unsig.key} ({unsig.name})? (y/N) "):
+ ran = subprocess.run(
+ ["gpg", "--keyserver", args.keyserver, "--recv-keys", unsig.key])
+
+ if ran.returncode != 0:
+ log.warning(f"failed to retrieve key {unsig.key}")
+
+ # Reparse the GPG output now that we have more keys
+ retval, output = verify_with_gpg(sums_file, sigfilename)
+ good, unknown, bad = parse_gpg_result(output.splitlines())
+
+ return retval, output, good, unknown, bad
+
+
+def prompt_yn(prompt) -> bool:
+ """Return true if the user inputs 'y'."""
+ got = ''
+ while got not in ['y', 'n']:
+ got = input(prompt).lower()
+ return got == 'y'
+
+def verify_shasums_signature(
+ signature_file_path: str, sums_file_path: str, args: argparse.Namespace
+) -> tuple[
+ ReturnCode, list[SigData], list[SigData], list[SigData], list[SigData]
+]:
+ min_good_sigs = args.min_good_sigs
+ gpg_allowed_codes = [0, 2] # 2 is returned when untrusted signatures are present.
+
+ gpg_retval, gpg_output, good, unknown, bad = check_multisig(sums_file_path, signature_file_path, args)
+
+ if gpg_retval not in gpg_allowed_codes:
+ if gpg_retval == 1:
+ log.critical(f"Bad signature (code: {gpg_retval}).")
+ else:
+ log.critical(f"unexpected GPG exit code ({gpg_retval})")
+
+ log.error(f"gpg output:\n{indent(gpg_output)}")
+ return (ReturnCode.INTEGRITY_FAILURE, [], [], [], [])
+
+ # Decide which keys we trust, though not "trust" in the GPG sense, but rather
+ # which pubkeys convince us that this sums file is legitimate. In other words,
+ # which pubkeys within the Bitcoin community do we trust for the purposes of
+ # binary verification?
+ trusted_keys = set()
+ if args.trusted_keys:
+ trusted_keys |= set(args.trusted_keys.split(','))
+
+ # Tally signatures and make sure we have enough goods to fulfill
+ # our threshold.
+ good_trusted = [sig for sig in good if sig.trusted or sig.key in trusted_keys]
+ good_untrusted = [sig for sig in good if sig not in good_trusted]
+ num_trusted = len(good_trusted) + len(good_untrusted)
+ log.info(f"got {num_trusted} good signatures")
+
+ if num_trusted < min_good_sigs:
+ log.info("Maybe you need to import "
+ f"(`gpg --keyserver {args.keyserver} --recv-keys <key-id>`) "
+ "some of the following keys: ")
+ log.info('')
+ for sig in unknown:
+ log.info(f" {sig.key} ({sig.name})")
+ log.info('')
+ log.error(
+ "not enough trusted sigs to meet threshold "
+ f"({num_trusted} vs. {min_good_sigs})")
+
+ return (ReturnCode.NOT_ENOUGH_GOOD_SIGS, [], [], [], [])
+
+ for sig in good_trusted:
+ log.info(f"GOOD SIGNATURE: {sig}")
+
+ for sig in good_untrusted:
+ log.info(f"GOOD SIGNATURE (untrusted): {sig}")
+
+ for sig in [sig for sig in good if sig.status == 'expired']:
+ log.warning(f"key {sig.key} for {sig.name} is expired")
+
+ for sig in bad:
+ log.warning(f"BAD SIGNATURE: {sig}")
+
+ for sig in unknown:
+ log.warning(f"UNKNOWN SIGNATURE: {sig}")
+
+ return (ReturnCode.SUCCESS, good_trusted, good_untrusted, unknown, bad)
+
+
+def parse_sums_file(sums_file_path: str, filename_filter: list[str]) -> list[list[str]]:
+ # extract hashes/filenames of binaries to verify from hash file;
+ # each line has the following format: "<hash> <binary_filename>"
+ with open(sums_file_path, 'r', encoding='utf8') as hash_file:
+ return [line.split()[:2] for line in hash_file if len(filename_filter) == 0 or any(f in line for f in filename_filter)]
+
+
+def verify_binary_hashes(hashes_to_verify: list[list[str]]) -> tuple[ReturnCode, dict[str, str]]:
+ offending_files = []
+ files_to_hashes = {}
+
+ for hash_expected, binary_filename in hashes_to_verify:
+ with open(binary_filename, 'rb') as binary_file:
+ hash_calculated = sha256(binary_file.read()).hexdigest()
+ if hash_calculated != hash_expected:
+ offending_files.append(binary_filename)
+ else:
+ files_to_hashes[binary_filename] = hash_calculated
+
+ if offending_files:
+ joined_files = '\n'.join(offending_files)
+ log.critical(
+ "Hashes don't match.\n"
+ f"Offending files:\n{joined_files}")
+ return (ReturnCode.INTEGRITY_FAILURE, files_to_hashes)
+
+ return (ReturnCode.SUCCESS, files_to_hashes)
+
+
+def verify_published_handler(args: argparse.Namespace) -> ReturnCode:
+ WORKINGDIR = Path(tempfile.gettempdir()) / f"bitcoin_verify_binaries.{args.version}"
+
+ def cleanup():
+ log.info("cleaning up files")
+ os.chdir(Path.home())
+ shutil.rmtree(WORKINGDIR)
+
+ # determine remote dir dependent on provided version string
+ try:
+ version_base, version_rc, os_filter = parse_version_string(args.version)
+ version_tuple = [int(i) for i in version_base.split('.')]
+ except Exception as e:
+ log.debug(e)
+ log.error(f"unable to parse version; expected format is {VERSION_FORMAT}")
+ log.error(f" e.g. {VERSION_EXAMPLE}")
+ return ReturnCode.BAD_VERSION
+
+ remote_dir = f"/bin/{VERSIONPREFIX}{version_base}/"
+ if version_rc:
+ remote_dir += f"test.{version_rc}/"
+ remote_sigs_path = remote_dir + SIGNATUREFILENAME
+ remote_sums_path = remote_dir + SUMS_FILENAME
+
+ # create working directory
+ os.makedirs(WORKINGDIR, exist_ok=True)
+ os.chdir(WORKINGDIR)
+
+ hosts = [HOST1, HOST2]
+
+ got_sig_status = get_files_from_hosts_and_compare(
+ hosts, remote_sigs_path, SIGNATUREFILENAME, args.require_all_hosts)
+ if got_sig_status != ReturnCode.SUCCESS:
+ return got_sig_status
+
+ # Multi-sig verification is available after 22.0.
+ if version_tuple[0] < 22:
+ log.error("Version too old - single sig not supported. Use a previous "
+ "version of this script from the repo.")
+ return ReturnCode.BAD_VERSION
+
+ got_sums_status = get_files_from_hosts_and_compare(
+ hosts, remote_sums_path, SUMS_FILENAME, args.require_all_hosts)
+ if got_sums_status != ReturnCode.SUCCESS:
+ return got_sums_status
+
+ # Verify the signature on the SHA256SUMS file
+ sigs_status, good_trusted, good_untrusted, unknown, bad = verify_shasums_signature(SIGNATUREFILENAME, SUMS_FILENAME, args)
+ if sigs_status != ReturnCode.SUCCESS:
+ if sigs_status == ReturnCode.INTEGRITY_FAILURE:
+ cleanup()
+ return sigs_status
+
+ # Extract hashes and filenames
+ hashes_to_verify = parse_sums_file(SUMS_FILENAME, [os_filter])
+ if not hashes_to_verify:
+ log.error("no files matched the platform specified")
+ return ReturnCode.NO_BINARIES_MATCH
+
+ # remove binaries that are known not to be hosted by bitcoincore.org
+ fragments_to_remove = ['-unsigned', '-debug', '-codesignatures']
+ for fragment in fragments_to_remove:
+ nobinaries = [i for i in hashes_to_verify if fragment in i[1]]
+ if nobinaries:
+ remove_str = ', '.join(i[1] for i in nobinaries)
+ log.info(
+ f"removing *{fragment} binaries ({remove_str}) from verification "
+ f"since {HOST1} does not host *{fragment} binaries")
+ hashes_to_verify = [i for i in hashes_to_verify if fragment not in i[1]]
+
+ # download binaries
+ for _, binary_filename in hashes_to_verify:
+ log.info(f"downloading {binary_filename} to {WORKINGDIR}")
+ success, output = download_with_wget(
+ HOST1 + remote_dir + binary_filename, binary_filename)
+
+ if not success:
+ log.error(
+ f"failed to download {binary_filename}\n"
+ f"wget output:\n{indent(output)}")
+ return ReturnCode.BINARY_DOWNLOAD_FAILED
+
+ # verify hashes
+ hashes_status, files_to_hashes = verify_binary_hashes(hashes_to_verify)
+ if hashes_status != ReturnCode.SUCCESS:
+ return hashes_status
+
+
+ if args.cleanup:
+ cleanup()
+ else:
+ log.info(f"did not clean up {WORKINGDIR}")
+
+ if args.json:
+ output = {
+ 'good_trusted_sigs': [str(s) for s in good_trusted],
+ 'good_untrusted_sigs': [str(s) for s in good_untrusted],
+ 'unknown_sigs': [str(s) for s in unknown],
+ 'bad_sigs': [str(s) for s in bad],
+ 'verified_binaries': files_to_hashes,
+ }
+ print(json.dumps(output, indent=2))
+ else:
+ for filename in files_to_hashes:
+ print(f"VERIFIED: {filename}")
+
+ return ReturnCode.SUCCESS
+
+
+def verify_binaries_handler(args: argparse.Namespace) -> ReturnCode:
+ binary_to_basename = {}
+ for file in args.binary:
+ binary_to_basename[PurePath(file).name] = file
+
+ sums_sig_path = None
+ if args.sums_sig_file:
+ sums_sig_path = Path(args.sums_sig_file)
+ else:
+ log.info(f"No signature file specified, assuming it is {args.sums_file}.asc")
+ sums_sig_path = Path(args.sums_file).with_suffix(".asc")
+
+ # Verify the signature on the SHA256SUMS file
+ sigs_status, good_trusted, good_untrusted, unknown, bad = verify_shasums_signature(str(sums_sig_path), args.sums_file, args)
+ if sigs_status != ReturnCode.SUCCESS:
+ return sigs_status
+
+ # Extract hashes and filenames
+ hashes_to_verify = parse_sums_file(args.sums_file, [k for k, n in binary_to_basename.items()])
+ if not hashes_to_verify:
+ log.error(f"No files in {args.sums_file} match the specified binaries")
+ return ReturnCode.NO_BINARIES_MATCH
+
+ # Make sure all files are accounted for
+ sums_file_path = Path(args.sums_file)
+ missing_files = []
+ files_to_hash = []
+ if len(binary_to_basename) > 0:
+ for file_hash, file in hashes_to_verify:
+ files_to_hash.append([file_hash, binary_to_basename[file]])
+ del binary_to_basename[file]
+ if len(binary_to_basename) > 0:
+ log.error(f"Not all specified binaries are in {args.sums_file}")
+ return ReturnCode.NO_BINARIES_MATCH
+ else:
+ log.info(f"No binaries specified, assuming all files specified in {args.sums_file} are located relatively")
+ for file_hash, file in hashes_to_verify:
+ file_path = Path(sums_file_path.parent.joinpath(file))
+ if file_path.exists():
+ files_to_hash.append([file_hash, str(file_path)])
+ else:
+ missing_files.append(file)
+
+ # verify hashes
+ hashes_status, files_to_hashes = verify_binary_hashes(files_to_hash)
+ if hashes_status != ReturnCode.SUCCESS:
+ return hashes_status
+
+ if args.json:
+ output = {
+ 'good_trusted_sigs': [str(s) for s in good_trusted],
+ 'good_untrusted_sigs': [str(s) for s in good_untrusted],
+ 'unknown_sigs': [str(s) for s in unknown],
+ 'bad_sigs': [str(s) for s in bad],
+ 'verified_binaries': files_to_hashes,
+ "missing_binaries": missing_files,
+ }
+ print(json.dumps(output, indent=2))
+ else:
+ for filename in files_to_hashes:
+ print(f"VERIFIED: {filename}")
+ for filename in missing_files:
+ print(f"MISSING: {filename}")
+
+ return ReturnCode.SUCCESS
+
+
+def main():
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument(
+ '-v', '--verbose', action='store_true',
+ default=bool_from_env('BINVERIFY_VERBOSE'),
+ )
+ parser.add_argument(
+ '-q', '--quiet', action='store_true',
+ default=bool_from_env('BINVERIFY_QUIET'),
+ )
+ parser.add_argument(
+ '--import-keys', action='store_true',
+ default=bool_from_env('BINVERIFY_IMPORTKEYS'),
+ help='if specified, ask to import each unknown builder key'
+ )
+ parser.add_argument(
+ '--min-good-sigs', type=int, action='store', nargs='?',
+ default=int(os.environ.get('BINVERIFY_MIN_GOOD_SIGS', 3)),
+ help=(
+ 'The minimum number of good signatures to require successful termination.'),
+ )
+ parser.add_argument(
+ '--keyserver', action='store', nargs='?',
+ default=os.environ.get('BINVERIFY_KEYSERVER', 'hkps://keys.openpgp.org'),
+ help='which keyserver to use',
+ )
+ parser.add_argument(
+ '--trusted-keys', action='store', nargs='?',
+ default=os.environ.get('BINVERIFY_TRUSTED_KEYS', ''),
+ help='A list of trusted signer GPG keys, separated by commas. Not "trusted keys" in the GPG sense.',
+ )
+ parser.add_argument(
+ '--json', action='store_true',
+ default=bool_from_env('BINVERIFY_JSON'),
+ help='If set, output the result as JSON',
+ )
+
+ subparsers = parser.add_subparsers(title="Commands", required=True, dest="command")
+
+ pub_parser = subparsers.add_parser("pub", help="Verify a published release.")
+ pub_parser.set_defaults(func=verify_published_handler)
+ pub_parser.add_argument(
+ 'version', type=str, help=(
+ f'version of the bitcoin release to download; of the format '
+ f'{VERSION_FORMAT}. Example: {VERSION_EXAMPLE}')
+ )
+ pub_parser.add_argument(
+ '--cleanup', action='store_true',
+ default=bool_from_env('BINVERIFY_CLEANUP'),
+ help='if specified, clean up files afterwards'
+ )
+ pub_parser.add_argument(
+ '--require-all-hosts', action='store_true',
+ default=bool_from_env('BINVERIFY_REQUIRE_ALL_HOSTS'),
+ help=(
+ f'If set, require all hosts ({HOST1}, {HOST2}) to provide signatures. '
+ '(Sometimes bitcoin.org lags behind bitcoincore.org.)')
+ )
+
+ bin_parser = subparsers.add_parser("bin", help="Verify local binaries.")
+ bin_parser.set_defaults(func=verify_binaries_handler)
+ bin_parser.add_argument("--sums-sig-file", "-s", help="Path to the SHA256SUMS.asc file to verify")
+ bin_parser.add_argument("sums_file", help="Path to the SHA256SUMS file to verify")
+ bin_parser.add_argument(
+ "binary", nargs="*",
+ help="Path to a binary distribution file to verify. Can be specified multiple times for multiple files to verify."
+ )
+
+ args = parser.parse_args()
+ if args.quiet:
+ log.setLevel(logging.WARNING)
+
+ return args.func(args)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/contrib/verify-commits/trusted-keys b/contrib/verify-commits/trusted-keys
index 94daf28b15..f25486776f 100644
--- a/contrib/verify-commits/trusted-keys
+++ b/contrib/verify-commits/trusted-keys
@@ -2,3 +2,4 @@ E777299FC265DD04793070EB944D35F9AC3DB76A
D1DBF2C4B96F2DEBF4C16654410108112E7EA81F
152812300785C96444D3334D17565732E08E5E41
6B002C6EA3F91B1B0DF0C9BC8F617F1200A6D25C
+4D1B3D5ECBA1A7E05371EEBE46800E30FC748A66
diff --git a/contrib/verify-commits/verify-commits.py b/contrib/verify-commits/verify-commits.py
index f301964280..a1fe78a643 100755
--- a/contrib/verify-commits/verify-commits.py
+++ b/contrib/verify-commits/verify-commits.py
@@ -178,7 +178,20 @@ def main():
allow_unclean = current_commit in unclean_merge_allowed
if len(parents) == 2 and check_merge and not allow_unclean:
current_tree = subprocess.check_output([GIT, 'show', '--format=%T', current_commit]).decode('utf8').splitlines()[0]
- recreated_tree = subprocess.check_output([GIT, "merge-tree", parents[0], parents[1]]).decode('utf8').splitlines()[0]
+
+ # This merge-tree functionality requires git >= 2.38. The
+ # --write-tree option was added in order to opt-in to the new
+ # behavior. Older versions of git will not recognize the option and
+ # will instead exit with code 128.
+ try:
+ recreated_tree = subprocess.check_output([GIT, "merge-tree", "--write-tree", parents[0], parents[1]]).decode('utf8').splitlines()[0]
+ except subprocess.CalledProcessError as e:
+ if e.returncode == 128:
+ print("git v2.38+ is required for this functionality.", file=sys.stderr)
+ sys.exit(1)
+ else:
+ raise e
+
if current_tree != recreated_tree:
print("Merge commit {} is not clean".format(current_commit), file=sys.stderr)
subprocess.call([GIT, 'diff', recreated_tree, current_tree])
diff --git a/contrib/verifybinaries/README.md b/contrib/verifybinaries/README.md
deleted file mode 100644
index ab831eea28..0000000000
--- a/contrib/verifybinaries/README.md
+++ /dev/null
@@ -1,30 +0,0 @@
-### Verify Binaries
-
-#### Usage:
-
-This script attempts to download the signature file `SHA256SUMS.asc` from https://bitcoin.org.
-
-It first checks if the signature passes, and then downloads the files specified in the file, and checks if the hashes of these files match those that are specified in the signature file.
-
-The script returns 0 if everything passes the checks. It returns 1 if either the signature check or the hash check doesn't pass. If an error occurs the return value is 2.
-
-
-```sh
-./verify.py bitcoin-core-0.11.2
-./verify.py bitcoin-core-0.12.0
-./verify.py bitcoin-core-0.13.0-rc3
-```
-
-If you only want to download the binaries of certain platform, add the corresponding suffix, e.g.:
-
-```sh
-./verify.py bitcoin-core-0.11.2-osx
-./verify.py 0.12.0-linux
-./verify.py bitcoin-core-0.13.0-rc3-win64
-```
-
-If you do not want to keep the downloaded binaries, specify anything as the second parameter.
-
-```sh
-./verify.py bitcoin-core-0.13.0 delete
-```
diff --git a/contrib/verifybinaries/verify.py b/contrib/verifybinaries/verify.py
deleted file mode 100755
index b5e4f1318b..0000000000
--- a/contrib/verifybinaries/verify.py
+++ /dev/null
@@ -1,183 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (c) 2020-2021 The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-"""Script for verifying Bitcoin Core release binaries
-
-This script attempts to download the signature file SHA256SUMS.asc from
-bitcoincore.org and bitcoin.org and compares them.
-It first checks if the signature passes, and then downloads the files
-specified in the file, and checks if the hashes of these files match those
-that are specified in the signature file.
-The script returns 0 if everything passes the checks. It returns 1 if either
-the signature check or the hash check doesn't pass. If an error occurs the
-return value is >= 2.
-"""
-from hashlib import sha256
-import os
-import subprocess
-import sys
-from textwrap import indent
-
-WORKINGDIR = "/tmp/bitcoin_verify_binaries"
-HASHFILE = "hashes.tmp"
-HOST1 = "https://bitcoincore.org"
-HOST2 = "https://bitcoin.org"
-VERSIONPREFIX = "bitcoin-core-"
-SIGNATUREFILENAME = "SHA256SUMS.asc"
-
-
-def parse_version_string(version_str):
- if version_str.startswith(VERSIONPREFIX): # remove version prefix
- version_str = version_str[len(VERSIONPREFIX):]
-
- parts = version_str.split('-')
- version_base = parts[0]
- version_rc = ""
- version_os = ""
- if len(parts) == 2: # "<version>-rcN" or "version-platform"
- if "rc" in parts[1]:
- version_rc = parts[1]
- else:
- version_os = parts[1]
- elif len(parts) == 3: # "<version>-rcN-platform"
- version_rc = parts[1]
- version_os = parts[2]
-
- return version_base, version_rc, version_os
-
-
-def download_with_wget(remote_file, local_file=None):
- if local_file:
- wget_args = ['wget', '-O', local_file, remote_file]
- else:
- # use timestamping mechanism if local filename is not explicitly set
- wget_args = ['wget', '-N', remote_file]
-
- result = subprocess.run(wget_args,
- stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
- return result.returncode == 0, result.stdout.decode().rstrip()
-
-
-def files_are_equal(filename1, filename2):
- with open(filename1, 'rb') as file1:
- contents1 = file1.read()
- with open(filename2, 'rb') as file2:
- contents2 = file2.read()
- return contents1 == contents2
-
-
-def verify_with_gpg(signature_filename, output_filename):
- result = subprocess.run(['gpg', '--yes', '--decrypt', '--output',
- output_filename, signature_filename],
- stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
- return result.returncode, result.stdout.decode().rstrip()
-
-
-def remove_files(filenames):
- for filename in filenames:
- os.remove(filename)
-
-
-def main(args):
- # sanity check
- if len(args) < 1:
- print("Error: need to specify a version on the command line")
- return 3
-
- # determine remote dir dependent on provided version string
- version_base, version_rc, os_filter = parse_version_string(args[0])
- remote_dir = f"/bin/{VERSIONPREFIX}{version_base}/"
- if version_rc:
- remote_dir += f"test.{version_rc}/"
- remote_sigfile = remote_dir + SIGNATUREFILENAME
-
- # create working directory
- os.makedirs(WORKINGDIR, exist_ok=True)
- os.chdir(WORKINGDIR)
-
- # fetch first signature file
- sigfile1 = SIGNATUREFILENAME
- success, output = download_with_wget(HOST1 + remote_sigfile, sigfile1)
- if not success:
- print("Error: couldn't fetch signature file. "
- "Have you specified the version number in the following format?")
- print(f"[{VERSIONPREFIX}]<version>[-rc[0-9]][-platform] "
- f"(example: {VERSIONPREFIX}0.21.0-rc3-osx)")
- print("wget output:")
- print(indent(output, '\t'))
- return 4
-
- # fetch second signature file
- sigfile2 = SIGNATUREFILENAME + ".2"
- success, output = download_with_wget(HOST2 + remote_sigfile, sigfile2)
- if not success:
- print("bitcoin.org failed to provide signature file, "
- "but bitcoincore.org did?")
- print("wget output:")
- print(indent(output, '\t'))
- remove_files([sigfile1])
- return 5
-
- # ensure that both signature files are equal
- if not files_are_equal(sigfile1, sigfile2):
- print("bitcoin.org and bitcoincore.org signature files were not equal?")
- print(f"See files {WORKINGDIR}/{sigfile1} and {WORKINGDIR}/{sigfile2}")
- return 6
-
- # check signature and extract data into file
- retval, output = verify_with_gpg(sigfile1, HASHFILE)
- if retval != 0:
- if retval == 1:
- print("Bad signature.")
- elif retval == 2:
- print("gpg error. Do you have the Bitcoin Core binary release "
- "signing key installed?")
- print("gpg output:")
- print(indent(output, '\t'))
- remove_files([sigfile1, sigfile2, HASHFILE])
- return 1
-
- # extract hashes/filenames of binaries to verify from hash file;
- # each line has the following format: "<hash> <binary_filename>"
- with open(HASHFILE, 'r', encoding='utf8') as hash_file:
- hashes_to_verify = [
- line.split()[:2] for line in hash_file if os_filter in line]
- remove_files([HASHFILE])
- if not hashes_to_verify:
- print("error: no files matched the platform specified")
- return 7
-
- # download binaries
- for _, binary_filename in hashes_to_verify:
- print(f"Downloading {binary_filename}")
- download_with_wget(HOST1 + remote_dir + binary_filename)
-
- # verify hashes
- offending_files = []
- for hash_expected, binary_filename in hashes_to_verify:
- with open(binary_filename, 'rb') as binary_file:
- hash_calculated = sha256(binary_file.read()).hexdigest()
- if hash_calculated != hash_expected:
- offending_files.append(binary_filename)
- if offending_files:
- print("Hashes don't match.")
- print("Offending files:")
- print('\n'.join(offending_files))
- return 1
- verified_binaries = [entry[1] for entry in hashes_to_verify]
-
- # clean up files if desired
- if len(args) >= 2:
- print("Clean up the binaries")
- remove_files([sigfile1, sigfile2] + verified_binaries)
- else:
- print(f"Keep the binaries in {WORKINGDIR}")
-
- print("Verified hashes of")
- print('\n'.join(verified_binaries))
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))