Golos Blockchain
  • База знаний Golos
  • ПОЛЬЗОВАТЕЛЯМ
    • Способы регистрации
    • Старт на Golos Блоги
      • Кошелёк
    • Вопросы и ответы
    • Полезные статьи
    • Обновления на Голосе
  • Разработчикам
    • Основы
      • Операции и их типы
      • Объекты и структуры
      • Состояние (стэйт) системы
      • Плагины и их API
      • Библиотеки для работы
      • Примеры кода
      • Формирование транзакций
      • Пропускная способность
      • Тестнет (ноды для тестов)
    • API-документация
      • API part 1
      • API part 2
      • API part 3
      • API part 4
      • Cli-wallet API
    • Обновления (HardForks)
      • HF18: Данные по установке
      • HF18: Новые возможности
      • HF18: Изменения в API
      • HF18: Изменения в cli_wallet
      • SF18.4: Новые функции
      • HF19: Новые возможности
      • HF20: Устранение бага
      • HF22: Новые возможности
      • HF23: Новые возможности
      • HF24: Новые возможности
      • HF25: Новые возможности
      • HF26: Новые возможности
      • HF27: Новые возможности
      • HF28: Новые возможности
    • Руководства (HowTo)
      • Скрипт регистрации аккаунтов
      • Операции на бирже
      • Как использовать мультиподписи
      • Как объединять операции в одну транзакцию
      • Пример запуска тестнета
  • Делегатам
    • Делегатство и роли нод
    • Установка ноды
      • Гайд для witness/seed ноды
      • Настройка для API-ноды
      • Настройка ноды для бирж
      • Настройка ElasticSearch
      • Нода с отладкой GDB
    • Медианные параметры
    • Скрипты для price feed
Powered by GitBook
On this page
  • Пропускная способность аккаунта
  • forum и market bandwidth
  • Механизм вычисления bandwidth
  • Получение значений bandwidth в килобайтах
  • Глобальная пропускная способность
  • post bandwidth
  1. Разработчикам
  2. Основы

Пропускная способность

Блокчейн Голос является системой с нулевыми комиссиями за транзакции. Однако, объём информации, который можно записать в блокчейн в единицу времени, не бесконечен. Для контроля над расходованием общей пропускной способности был разработан специальный механизм её распределения.

Пропускная способность аккаунта

Максимально доступная bandwidth аккаунта в системе напрямую зависит от количества Силы Голоса (vesting shares).

У аккаунта в системе существует 3 ограничителя пропускной способности:

  1. forum bandwidth: ограничивает объём операций постинга постов и комментариев, апвоутов.

  2. market bandwidth: ограничивает объём операций трансфера монет и выставления/отмены рыночных ордеров на внутренней бирже.

  3. post bandwidth: штрафует аккаунт уменьшением выплаты за пост, если аккаунт постит слишком много постов.

forum и market bandwidth

При превышении данного типа bandwidth возникает ошибка: Account exceeded maximum allowed bandwidth per vesting share.

Данные типы bandwidth по сути являются единой сущностью. Отличие в том, что market bandwidth представляет собой 1/10 от общей bandwidth аккаунта. Например, пусть bandwidth аккаунта - 100 KB. Тогда:

  • forum bandwidth: 100 KB

  • market bandwidth: 10 KB

Время восстановления bandwidth от 0 до 100% определяется константой STEEMIT_BANDWIDTH_AVERAGE_WINDOW_SECONDS и составляет 7 дней (актуально для 0.17.0).

Механизм вычисления bandwidth

В исходных текстах происходит в database.cpp в bool database::update_account_bandwidth.

При получении транзакции аккаунта нода golosd проверяет, не превысил ли аккаунт отведённую ему полосу пропускания. Это происходит по следующей формуле:

has_bandwidth = (account_vshares * max_virtual_bandwidth) > (account_average_bandwidth * total_vshares)

  • has_bandwidth: результат сравнения, получается True если есть доступная полоса, и False если нет

  • account_vshares - Сила Голоса аккаунта в виде vesting shares

  • max_virtual_bandwidth - максимальная виртуальная пропускная способность сети.

  • account_average_bandwidth - показатель использования аккаунтом своей полосы

  • total_vshares - суммарное значение vesting shares всех аккаунтов в блокчейне

Если вышеуказанную формулу записать как (account_vshares * max_virtual_bandwidth) / (account_average_bandwidth * total_vshares), то получится число, показывающее долю использования аккаунтом своей полосы.

В данной формуле все переменные являются легко доступными параметрами, кроме account_average_bandwidth. Для получения данного значения требуется провести ряд вычислений.

  1. В результатах вышеупомянутого вызова так же присутствует поле "last_bandwidth_update", оно показывает момент последнего обновления bandwidth.

  2. Если с момента последнего обновления прошло больше времени чем STEEMIT_BANDWIDTH_AVERAGE_WINDOW_SECONDS, то account_average_bandwidth автоматически становится 0, это означает, что аккаунт может воспользоваться всей своей доступной полосой пропускания.

  3. Если же времени прошло меньше, то следует подсчитать, на сколько восстановилась bandwidth. Для этого применяется следующая формула: new_bandwidth = ((STEEMIT_BANDWIDTH_AVERAGE_WINDOW_SECONDS - elapsed_time) * account_average_bandwidth) / STEEMIT_BANDWIDTH_AVERAGE_WINDOW_SECONDS, где

    • elapsed_time - сколько прошло времени с момента последнего обновления bandwidth

    • account_average_bandwidth - значение bandwidth на момент последнего обновления

  4. Теперь у golosd есть данные о текущем состоянии bandwidth аккаунта, но теперь ему так же нужно определить, можно ли разрешить аккаунту совершить транзакцию. Для этого golosd подсчитывает, как изменится bandwidth после принятия транзакции, и не будет ли при этом превышена полоса пропускания. Для этого вычисляется bandwidth транзакции: trx_bandwidth = trx_size * STEEMIT_BANDWIDTH_PRECISION, где

    • trx_size - размер транзакции в байтах. Для market-операций этот размер дополнительно умножается на 10, из-за чего и происходит то, что для market операций доступная bandwidth в 10 раз меньше чем для forum

    • STEEMIT_BANDWIDTH_PRECISION - константа, определяющая точность вычислений при работе с bandwidth

  5. Вычисляется финальное значение account_average_bandwidth = new_bandwidth + trx_bandwidth

Получение значений bandwidth в килобайтах

Мы можем самостоятельно вычислять максимально доступную bandwidth аккаунта и потреблённую на текущий момент.

Для получения значения потреблённой полосы, получается формула следующего вида: used_kb = account_average_bandwidth / STEEMIT_BANDWIDTH_PRECISION / 1024

Для получения максимально доступной аккаунту полосы получается следующая формула. Какую долю от суммарной СГ имеет аккаунт, такую долю он и может взять из общей max_virtual_bandwidth:

avail_kb = account_vshares/total_vesting_shares * max_virtual_bandwidth / STEEMIT_BANDWIDTH_PRECISION / 1024

Глобальная пропускная способность

При общей высокой загруженности сети срабатывает механизм ограничения общей пропускной способности через снижение max_virtual_bandwidth.

В исходных текстах механизм реализован в database.cpp в функции void database::update_global_dynamic_data() и работает по следующему алгоритму:

  1. Примерно раз в минуту (каждые 20 блоков) происходит пересчёт max_virtual_bandwidth. Первым делом проверяется, не превышает ли средний размер блока (average_block_size) 1/4 от максимального размера блока (maximum_block_size).

    1. Если превышает, то current_reserve_ratio уменьшается в 2 раза, что по сути приводит к уменьшению max_virtual_bandwidth так же в 2 раза.

    2. Если не превышает, и ранее current_reserve_ratio был ограничен, то происходит линейный рост этого показателя путём инкремента на 1 единицу.

Таким образом, ограничение общей пропускной способности активируется, когда средний размер блока становится более 25% от текущего максимально размера блока. При этом ограничение срабатывает достаточно резко, т.к. max_virtual_bandwidth падает сразу в 2 раза. При этом, недостаток bandwidth сразу же могут испытать те пользователи, которые имеют потребление полосы выше 50%. Восстановление же общей доступной полосы после включения ограничения происходит плавно, в течение 3-4 дней.

post bandwidth

Является самостоятельным ограничителем и никак не связана с пропускной способностью сети. Предназначение - штрафовать аккаунт, который постит слишком часто.

Реализация в исходных текстах находится в steem_evaluator.cpp в void comment_evaluator::do_apply()

PreviousФормирование транзакцийNextТестнет (ноды для тестов)

Last updated 5 years ago

С помощью API-метода можно получить значение bandwidth на момент последней совершённой транзакции. Данное значение не будет актуальным на текущий момент времени, так как bandwidth всё время восстанавливается (уменьшается % потраченной пропускной способности). Note: это же значение bandwidth можно получить с помощью API-вызова get_accounts, однако в этом случае bandwidth будет находиться в поле 'new_average_bandwidth' (а поле 'average_bandwidth' следует проигнорировать, так как оно относится к устаревшему механизму контроля bandwidth и является deprecated).

Практическую реализацию вычисления bandwidth вы можете посмотреть в функции get_bandwidth в , которая используется в скрипте .

get_account_bandwidth
functions.py
get_bandwidth.py