Как проверить работает ли full-RBF в Bitcoin Core

Поскольку подтверждение среднего блока биткойнов занимает около 10 минут, многие криптоматы, обменники и продавцы, принимающие биткойны, сталкиваются с проблемой быстрой обработки платежей. Возникает дилемма: можно ли уже считать платеж полученным, если транзакция депозита находится в мемпуле, но еще не подтверждена? Проще говоря, насколько возможно заменить или отменить транзакцию, которая уже была добавлена в мемпул?

Что такое RBF

RBF (replace by fee) — замена неподтвержденной транзакции новой транзакцией с более высокой комиссией сети. Под заменой имеется в виду, что новая транзакция использует тот же инпут, что и исходная.

Физический смысл RBF в том, что майнеру (создателю блока) выгодней взять транзакцию с более высокой комиссией. А так как у транзакций одинаковый инпут, то вторая транзакция становится невалидной.

В 2016 год вышло обновление ноды Bitcoin Core v0.12.0.

Которое включило в себя поддержку Opt-in RBF. Это функция, которая позволяет создавать транзакции со специальным флагом, сигнализирующим о том, что транзакция может быть заменена. Технически это выглядит так: у каждой транзакции есть свой порядковый номер nSequence, определяющий очередность взятия транзакций в блок. И, чтобы сделать транзакцию потенциально незаменимой, нужно было указать максимально возможный порядковый номер — 0xffffffff. Например, блокчеин эксплорер mempool.space об этом указывает явно:

По правилам протокола Bitcoin, все повторные транзакции с тем же инпутом должны быть отклонены и не распространяться нодами дальше по сети. Это правило называется first seen rule. В крайнем случае, так было раньше.

В декабре 2022 году вышло обновление ноды Bitcoin Core 24.0.1.

Которое включает в себя full-RBF. Это функция, которая позволяет нодам обрабатывать повторные транзакции и считать их легитимными. По дефолту в ноде эта функция выключена, поэтому в настройках ноды для ее активации необходимо задать параметр mempoolfullrbf=1

На февраль 2023 года почти 30% всех нод Bitcoin перешли на версию 24.0.1:

Согласно исследованию, из всех нод версии 24.0.1 минимум 17% активировали full-RBF.

Пошаговая инструкция по замене транзакций

Я решил развернуть ноду Bitcoin v24.0.1 и попробовать заменить транзакцию. Ниже поэтапный план действий.

Системные требования Bitcoin Core с bitcoin.org:

  • Disk space. 350 GB.
  • Download. 500 MB/day (15 GB/month)
  • Upload. 5 GB/day (150 GB/month)
  • Memory (RAM) 1 GB.
  • System. Desktop. Laptop. Some ARM chipsets >1 GHz.
  • Operating system. Windows 7/8.x/10. Mac OS X.

У меня по факту заняло около 480 GB, поэтому лучше заложить дискового пространства побольше.

1. Скачиваем ноду Bitcoin Core v24.0.1

Скачиваем пропатченную ноду Bitcoin Core v24.0.1. Нода специально подключается к пирам, которые поддерживают full-RBF и способствуют распространению повторных транзакций по сети:

git clone -b full-rbf-v24.0.1 https://github.com/petertodd/bitcoin.git

Либо можно скачать оригинальную ноду и затем в настройках указать пиры, у которых стоит full-RBF. Об этом будет еще описано ниже.

2. Компилируем исходники и запускаем ноду

Вначале устанавливаем все необходимые зависимости.

Linux:

sudo apt-get install automake autotools-dev bsdmainutils build-essential ccache clang gcc git libboost-dev libboost-filesystem-dev libboost-system-dev libboost-test-dev libevent-dev libminiupnpc-dev libnatpmp-dev libqt5gui5 libqt5core5a libqt5dbus5 libsqlite3-dev libtool libzmq3-dev pkg-config python3 qttools5-dev qttools5-dev-tools qtwayland5 systemtap-sdt-dev

Mac OS:

brew install automake boost ccache git libevent libnatpmp libtool llvm miniupnpc pkg-config python qrencode qt@5 sqlite zeromq

Дальше компилируем ноду Bitcoin:

./autogen.sh
./configure
make

Если вы хотите запустить компиляцию сразу на нескольких ядрах, то для команды make необходимо задать соответствующие параметры:

Linux

make -j "$(($(nproc) + 1))"

Mac OS

make -j "$(($(sysctl -n hw.physicalcpu) + 1))"

У меня на 8 GB RAM и 4 ядрах компиляция заняла около 15 минут. 

 3. Создаем конфигурационный файл bitcoin.conf

Файл необходимо создать в корневой папке ./bitcoin.

Есть даже онлайн генератор конфигов:

Мне во время эксперимента понадобились следующие параметры:

mempoolfullrbf=1 #Включает full-RBF функционал
txindex=1 #Индексирует внешние транзакции, которые не принадлежат кошельку ноды
datadir=<dir_path> #Если необходимо сменить директорию, куда нода будет загружать все данные

Остановлюсь подробней на параметре txindex=1. Если не включить этот параметр, то нода не сможет обращаться к входным и выходным параметрам транзакций, которые не относятся к кошельку ноды. Это может понадобиться, когда вы пытаетесь отправить повторную транзакцию с использованием того же входа, который по факту является ссылкой на выход внешней транзакции. Этот параметр потребует дополнительно порядка 20 GB дискового пространства под хранение индексированных данных.

Если у вас оригинальная нода, и вы хотите добавить пиры с включенным full-RBF, то в конфигурационный файл добавьте еще следующие параметры:

addnode=full-rbf1.btc.petertodd.net
addnode=full-rbf2.btc.petertodd.net
addnode=full-rbf3.btc.petertodd.net
addnode=full-rbf4.btc.petertodd.net

4. Запускаем ноду и создаем кошелек

Запускаем ноду при помощи команды ./bitcoind -daemon. Если вы не хотите запускать ноду в фоновом режиме, то запускайте без параметра -daemon

Дальше нода должна начать синхронизацию, у меня весь процесс занял порядка трое суток.

Обращаться к ноде можно при помощи bitcoin-cli. Например, посмотреть сколько уже скачено блоков можно следующей командой: ./bitcoin-cli getblockcount.

Со всеми командами можно ознакомиться здесь:

https://developer.bitcoin.org/reference/rpc/index.html

После полной синхронизации необходимо создать кошелек. Это можно сделать разными способами (импортировать, сгенерировать), например, создать командой createwallet:

./bitcoin-cli createwallet "testwallet"

 5. Подготавливаем скрипт

Для начала стоит убедиться, что вы можете обращаться к локальной Bitcoin ноде через python-bitcoinlib:

python3 /lib/python-bitcoinlib/examples/ssl-rpc-connection.py

Дальше можно взять за основу doublespend.pyи сделать следующее:

  1. Отправить первую транзакцию с network fee значительно меньшим, чем у текущих транзакций в мемпуле. Так, транзакция «застрянет» в мемпуле и не попадет в блок;
  2. Подождать минуту, пока транзакция распространяется по сети;
  3. Отправить вторую транзакцию с network fee в разы превышающим текущих транзакций в мемпуле. Так, у майнера будет мотивация взять именно повторную транзакцию в блок.

Итог

Я проводил эксперимент несколько раз — результат был одинаков. Рассмотрим на примере одной из итераций:

Время созданияNetwork fee
Транзакция №100:000.0000113 BTC (0.26$)
Транзакция №200:190.004068 BTC (±94$)

Первую транзакцию я отправил с network fee = 0.26$. Это значительно ниже рыночных условий. Несмотря на то, что вторая транзакция имела fee в 94$, майнеры (создатели блоков) все равно ее не брали. То есть replace-by-fee не сработал.

Примечательно, как блокчеин эксплореры реагировали на повторные транзакции. В основном все отображали только первую транзакцию (например, mempool.space или blockchair). Эксплорер Blockcypher отображает повторные транзакции и предупреждает о double-spend:

Я предполагаю, что майнеры не могут взять повторную транзакцию в блок, так как этот блок будет отвергнут большинством участников сети. И пока Bitcoin Core v24.0.1 с включенным full-RBF стоит у меньшинства участников, замена транзакций работать не будет.


Читайте больше статей о криптовалютах и майнинге на сайте COOL-MINING.ORG.

Нравится ли вам читать подобные статьи о криптовалютах и майнинге, хотите ли вы поддержать меня как автора или задать вопросы? Узнавайте новости первыми, подписывайтесь на telegram-канал CRYPTO WIKIES | Bitcoin & Altcoins Mining

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *