Как узел находит транзакцию в блокчейне?

Если (легкий) клиент SPV запрашивает у полного узла ветку Merkle, содержащую конкретную транзакцию (или значение адреса), как полный узел находит эту транзакцию (или UTXO) в блокчейне? Сканирует ли полный узел линейно всю цепочку блоков или есть более быстрый способ связать транзакции и блоки?

Мне нравится ваш вопрос, я никогда не думал об этом подробно. Поскольку я совсем не уверен, а скорее просто предположил, что публикую это как комментарий (возможно, кто-то может использовать его в качестве отправной точки для ответа): клиенты SPV в основном спрашивают узлы о шаблонах , таких как фильтр цветения, который разрешает платежи на их адреса. Поскольку клиенты SPV заинтересованы исключительно в монетах, которые все еще существуют (или будут существовать), вся эта информация будет найдена либо путем поиска в наборе UTXO, либо в пуле памяти. -Конец предположений-.
@Murch UTXO не содержит корней Меркла, чтобы доказать, что выход существует, в этой модели узел может просто придумывать чепуху. Вы правы в том, что UTXO можно искать в миллисекундах, но это не даст никакой истории подключения клиента.

Ответы (2)

Вы можете прочитать спецификацию bip37 , чтобы узнать все подробности.

как полный узел находит эту транзакцию (или UTXO) в блокчейне?

Клиент создает фильтр, который содержит то, что его интересует, будь то сценарий вывода (адреса), открытые ключи или TXID. Затем они отправляют это на узел, к которому они подключены. Когда они запрашивают данные для определенного блока, узел фильтрует их, чтобы они содержали только те вещи, которые соответствуют фильтру Блума клиентов, и отправляет их им. Чтобы найти все свои неизрасходованные UTXO, они по очереди запрашивают каждый блок в цепочке и ищут вещи, которые могут принадлежать им. Как вы в основном выяснили, для каждого клиента это означает, что узел загружает 80 ГБ блоков с диска и выполняет над ними чрезвычайно дорогие операции фильтрации.

Современные узлы осознают, насколько ужасна эта идея, и позволяют пользователям полностью отключать функциональность из-за большой нагрузки и связанного с этим риска отказа в обслуживании. С помощью специально созданных транзакций удаленный одноранговый узел с помощью одной команды размером менее 50 байт может заставить узел загрузить блок размером 1 МБ с диска, хэшировать его более миллиона раз, а затем ничего не вернуть.

Разве они не запрашивают данные по блокам, по которым у них еще нет информации? То есть, если кошелек был создан на блоке 423 000, он будет запрашивать блоки только после этого. И потом, поскольку он будет знать, что в прошлый раз догнал до 430 000, только после этого новые блоки?
Да. Они также могут пропускать блоки, которые, как они знают, произошли до «даты рождения» кошелька, поскольку с этого времени не может быть транзакций, которые они могут потратить. На практике это мало помогает, потому что основная часть цепочки приходится на последние несколько месяцев.

Обычно легкий клиент спрашивает «эта транзакция находится в этом блоке», а не «в каком блоке эта транзакция». Последнее можно сделать без особых проблем, если есть txindex (индекс транзакций), для которого у bitcoind есть опция.

Спасибо за Ваш ответ! Тем не менее, мне непонятна пара вещей: (1) Как клиент SPV определяет X в вопросе «Эта транзакция находится в блоке X»? Поддерживая все блоки (допустим, я только что установил новый клиент SPV, и он должен определить, сколько биткойнов у меня есть на основе моих публичных адресов)? (2) Как это работает в случае фильтра Блума? Насколько я понимаю, полная нода должна вычислять хэши всех транзакций и сравнивать их с фильтром? Это кажется слишком трудоемким для более чем 80 ГБ данных.
Узлы не поддерживают txindexпо умолчанию, потому что он будет постоянно расти и будет чрезмерно дорогим (включение этого параметра значительно замедляет скорость вставки блоков и увеличивает количество операций записи на диск).