Данная статья служит черновиком wiki-статьи по результатам вчерашнего обсуждения в чате Goloscore. Материал призван помочь разработчикам приложений исключить потерю транзакций при работе с блокчейном Голос. Приглашаю @goloscore на review. Текущая версия статьи находится на github.
Устаревание транзакций
Транзакция, отправляемая на golos-ноду, должна содержать поле expiration, указывающее момент времени, до которого транзакция является валидной. Если по каким-то причинам транзакция не будет включена в блок за это время, то она устареет и будет просто удалена нодой.
Что происходит при форках сети
В некоторых случаях происходит такая ситуация, при которой блок генерируется одновременно двумя делегатами, и некоторое короткое время параллельно существуют две цепи блоков. При обнаружении такой ситуации нода просматривает цепочку в обратном порядке до нахождения last irreversible block, при этом читаются все транзакции из блоков и опять попадают в очередь на включение в блоки (см. libraries/chain/database.cpp void database::pop_block()
). Самая длинная цепочка в итоге становится основной.
Чтобы исключить потерю транзакций во время форков сети, следует задавать expiration больше чем время до last_irreversible_block
, например 60 секунд.
Связь с TaPoS
В транзакции так же имеются поля ref_block_num
и ref_block_prefix
, которые как бы указывают, что "данная транзакция является валидной, если она находится в цепи, в которой имеется блок с номером X и с префиксом Y", см. Транзакции как доказательство долей
Соответственно, если транзакция ссылается на блок, который присутствует только в побочной цепи, данная транзакция будет отброшена нодой в любом случае.
Мои opensource-проекты на Голосе
- golos-witness-tools - набор скриптов для делегатов.
- golos-otkat-py - скрипт для выполнения откатов по программам апвот50-50 и апвот100.
- golos-scripts - разные полезные скрипты для Голоса на python
Статья размещена на Golos Wiki - https://wiki.golos.io/golosd/mechanics/trx-expiration.html и участвует в программе Golos Wiki Bounty.
Ваш пост поддержали следующие Инвесторы Сообщества "Добрый кит":
cats, alex2016, spinner, t3ran13, boddhisattva, aim, analise, strecoza, mishka, sergiy, one, vako, ovchinnikov, polyideic, andrvik, max-max, radomir, oleg257, svetlanaaa, dreamer, harhor, dimarss, kot, vasyl73, tinochka, la-bella-vita, tasha, tristamoff, kilobucks, ohlamoon, shuler, vadbars, rusalka, dany2323, maksina, yurgent71, zlody, dr-boo, amikphoto, zlata777, arsar, kotik, vasilisapor2, nefer, oksi969, renat242, markvial, nikalaich, andreyprosto, vict0r, semasping, gans91, gromozeka, lira, drim, gryph0n, frodogrodno, ladynazgool, ladykosha, orezaku, sharps, francesco, ruta, ovtretya, ukrainochka, arturio777, retoldname, stranniksenya, acidgarry, kvg, aivanouski, vika-teplo, igor66, oagalakova, borisss, candy777, sterh, lenutsa, olga-fink, vpervye1, felicita, optimist, yurchello, dayver, bammbuss, seagull15, graff0x, bombo, lomekhuza, mr-nikola, victorskaz, nerengot, lokkie, dim447, now, varja, upper, student61, ili, liseykina, alexmove, process, massatela, nikulinsb, diver76, vlad1m1r, shafarevich, amalinavia, evgeniy73, gogirotsky, vsebudethorosho, sansey, doctormucle, izbushka, alexey77, astramar, goldenriver, onur1s, ramin, propoker, assir, cryptovisitor, zelivsky, mifilin, html, metadon, vredinka2345, fxmonster, carpe-diem, makcl, azarovskiy, leonid96, brainmechanic, sinilga, samael27, kalter, valen-tina, maksh, mister-omortson, apnigrich, lazyphotoshooter, orlova, siddxa, cryptobandera, privet, osra111, prezza, irisworld, esperos, boliwar, wmforum, alexxela
Поэтому я тоже проголосовал за него!
Узнать подробности о сообществе можно тут:
Разрешите представиться - Кит Добрый
Правила
Инструкция по внесению Инвестиционного взноса
Вы тоже можете стать Инвестором и поддержать проект!!!
Если Вы хотите отказаться от поддержки Доброго Кита, то ответьте на этот комментарий командой "!нехочу"
dobryj.kit теперь стал Делегатом! Ваш голос важен для всего сообщества!!!
Поддержите нас:
Мммм. Если приложение считывает очередной (последний) блок, с той или иной api-ноды, то каким образом можно определить, является ли этот блок валидным, а не из побочной цепи, или транзакции из него будут отброшены? И тогда надо будет этот блок получить с другой ноды или просто чуть позже, когда появится блок под этим же номером из основной цепочки.
Приложение может запрашивать либо
last_irreversible_block
, либоhead_block
. Первый случай - это гарантированное наличие блока в чейне. Второй - нет. Это ненадёжный вариант. Если всё же хочется с ним работать, то видимо надо через ~45 секунд проверять, попал ли этот блок в основную цепь.@vvk, по сути запрашивать через database_api
можно get_block_header и get_block, что по нагрузке на ноду, скорее всего равнозначно.
А вот last_irreversible_block - через api-ноду видимо нельзя.
Смотрю тут:
http://ropox.tools/steemjs/
Нет такого в апи. :-(
Для php есть какие-то либы, @t3ran13 может подсказать.
Хотя там @SemasPing добавил много. Надо будет ещё посмотреть, что есть.
Увы, у него очень небогато. Я уже смотрел.Это всё:
Вот тут про это пишут.
Библиотека piston-lib например по умолчанию работает с last_irreversible_block.
Так мне что питон, что js... У меня php. :-)
Библиотек нет, пишу сам.
Но теперь разобрался откуда этот last_irreversible_block.
В вызове api надо брать не
а как раз
Спасибо, разобрался. Оказывается всё в одном месте, самому отслеживать ничего не надо. Буду использовать.
так понятнее
При обнаружении такой ситуации нода просматривает цепочку в обратном порядке до last irreversible block. Самая длинная цепочка в итоге становится основной. При этом транзакции из форков опять попадают в очередь на включение в блоки (см. libraries/chain/database.cpp void database::pop_block()).