Глоссарий / Протокол и обновления
Медианное прошедшее время
Другие названия: MTP.
- Что такое медианное прошедшее время?
- Медианное прошедшее время (median time past) является консенсусными часами биткоина: это медиана отметок времени предыдущих одиннадцати блоков и значение, с которым сверяется каждая временная блокировка (locktime).
Определено в BIP-113.
Узлы берут отметки времени одиннадцати блоков, предшествующих проверяемому блоку, сортируют их и используют срединное значение как текущее время. Эта медиана находится примерно на шесть блоков позади, поэтому она отстает от реальных часов примерно на час. Поэтому биткоин, который вы заблокировали до полудня, становится доступным для траты ближе к часу дня.
Как это работает
Медианное прошедшее время вычисляется функцией GetMedianTimePast, которая проходит назад по записям одиннадцати блоков, копирует каждую отметку времени в массив, сортирует его и возвращает средний элемент.
Константа, которую определяет BIP-113, задана как nMedianTimeSpan = 11, поэтому ответ всегда является шестым наименьшим из одиннадцати чисел. Именно сортировка делает результат надежным. Отметка времени одного блока может быть раньше отметки родительского блока, но правила консенсуса уже требуют, чтобы каждая новая отметка времени была выше медианы одиннадцати предыдущих, поэтому медиана может двигаться только вперед. Поэтому искажение одной отметки времени почти ничего не дает майнеру.
Проблема, которую исправил BIP-113, была стимулом, а не ошибкой. По старому правилу допустимость транзакции оценивалась по отметке времени блока, который ее включает, то есть по числу, которое записывает майнер; раздел мотивации BIP называет это "a perverse incentive for miners to lie about the time of their blocks in order to collect more fees" (извращенный стимул для майнеров лгать о времени своих блоков, чтобы собрать больше комиссий). Исправление состояло в одной подстановке: консенсусные вызовы IsFinalTx берут GetMedianTimePast предыдущего блока вместо времени самого блока, и правило охватывает каждую транзакцию, включая транзакцию coinbase.
Оно было выпущено как мягкий форк (soft fork) с версионными битами BIP9 на бите 0, при этом сигнализация в основной сети открылась в полночь 1 мая 2016 года по UTC и истекла год спустя, а развернуто оно было вместе с BIP-68 и BIP112, чтобы три правила временных блокировок появились одним пакетом.
Где это видно
Медианное прошедшее время появляется в выводе RPC Bitcoin Core как поле с именем mediantime, непосредственно рядом с необработанным полем time.
getblock возвращает оба значения для любого блока, а getblockchaininfo сообщает медианное время вершины рядом с отметкой времени вершины, что является самым быстрым способом наблюдать час отставания на работающем узле. getchaintxstats идет дальше и измеряет протяженность своего окна как разницу между медианными временами двух блоков, а не их временами из заголовков, поэтому одна искаженная отметка времени на любом из концов почти не меняет результат.
Заметнее всего это в пуле памяти (mempool). Функция CheckFinalTxAtTip из Bitcoin Core оценивает кандидатную транзакцию по медианному прошедшему времени текущей вершины и по высоте на единицу выше нее, поэтому кошелек, который транслирует транзакцию в момент истечения срока, получает отказ вместо ретрансляции и должен повторять попытки, пока медиана не догонит часы на вашей стене.
Относительные временные блокировки наследуют те же часы на обоих концах. BIP-68 измеряет блокировку последовательности на основе времени, отсчитываемую в единицах по 512 секунд, от медианного прошедшего времени блока, предшествующего тому, в котором был добыт биткоин, до медианного прошедшего времени блока, предшествующего трате, поэтому отставание появляется дважды и в основном взаимно уничтожается.
Медианное прошедшее время vs отметка времени заголовка блока
Медианное прошедшее время вычисляется из одиннадцати отметок времени заголовков, но не хранится ни в одном блоке, тогда как отметка времени заголовка представляет собой поле, которое записывает майнер и которое каждый узел хранит навсегда.
Биткоин использует и то, и другое, для разных задач. Блокировки времени (locktime) используют медиану, потому что она движется монотонно и не может быть сдвинута вперед ради дохода от комиссий. Пересчет сложности по-прежнему читает необработанные времена заголовков: Bitcoin Core берет время блока последнего блока в окне 14 дней, вычитает время первого блока и пересчитывает целевое значение исходя из этой разницы. Двое часов в одной цепи выглядят неаккуратно, и это сделано намеренно. Пересчету нужно фактически прошедшее время за две недели блоков, а блокировке времени нужно число, которое не может сдвинуть ни один отдельный майнер.