A fondo · Cómo funciona · 16 min
El time warp: cómo mentir sobre la hora podría romper la dificultad de Bitcoin
Una costura en el código de Bitcoin de 2009 le permitiría a un minero con la mayor parte del hashrate llevar la dificultad a su mínimo en cuestión de semanas, y en menos de seis con todo el hashrate. Se ha usado en otras monedas y se plantó una vez en la testnet, nunca se ha usado en Bitcoin, y la corrección está escrita y espera un soft fork.
Traducción hecha con ayuda de IA, pendiente de revisión humana. Lee el original (en inglés).
Adónde vas: Bitcoin no tiene reloj. Los mineros escriben la hora en cada bloque, y cada dos semanas la red fija su propia dificultad a partir de dos de esas horas. Una línea del código de Satoshi de 2009 deja entre esas ventanas de dos semanas una costura que un minero con la mayor parte del hashrate podría usar para llevar la dificultad a su mínimo en cuestión de semanas, y uno con todo el hashrate, en menos de seis. Este capítulo cuenta cómo lleva Bitcoin la hora, cómo podría mentir un minero, qué vendría después, dónde ha pasado, por qué la corrección espera desde 2011 y si hay que preocuparse.
Varios bloques por segundo
El viernes 9 de septiembre de 2011, un usuario del foro llamado Lolcust anunció GeistGeld, una moneda construida a partir del código de Bitcoin, como "an experimental currency intended to test out the limits of block generation rate empirically" (una moneda experimental pensada para poner a prueba, de forma empírica, los límites de la tasa de generación de bloques). Para la noche del lunes 12 de septiembre producía bloques mucho más rápido de lo que nadie había planeado. Su creador escribió en BitcoinTalk a las 20:09 UTC que "another run-in of same kind is in progress" (hay en curso otro episodio del mismo tipo), y diez minutos después un minero informó: "Looks like 20k+ blocks again" (parece que otra vez van más de 20,000 bloques).
A las 21:39 UTC, un desarrollador que publicaba como ArtForz explicó cómo. Una moneda así recalcula su dificultad, cuánto trabajo cuesta un bloque, a intervalos fijos, y ese recálculo, escribió, "ignores one block interval every period" (ignora un intervalo entre bloques en cada periodo). Un minero podía usar el hueco para hacer que una cadena "jump backwards in time" (salte hacia atrás en el tiempo) sin romper una sola regla de marcas de tiempo. Lo explicó paso a paso con una cadena de juguete de ventanas de cuatro bloques y después agregó: "This was done on the GeistGeld chain yesterday/today, so it's not a theoretical problem" (esto se hizo en la cadena de GeistGeld ayer y hoy, así que no es un problema teórico).
A las 12:30 UTC del 13 de septiembre, su corrección ya estaba en el código de GeistGeld, bajo un comentario que termina "Code courtesy of Art Forz" (código cortesía de Art Forz). A las 15:06 UTC, Gavin Andresen, entonces el desarrollador principal de Bitcoin, planteó el tema en la lista de correo bitcoin-dev.
La falla que describía ArtForz venía de una línea del código de Satoshi, que GeistGeld había copiado. Bitcoin tenía la misma costura en septiembre de 2011, y la sigue teniendo en noviembre de 2026. Hoy se le llama ataque time warp (en inglés), algo así como "ataque de distorsión del tiempo", y nadie lo ha usado en la cadena principal de Bitcoin.
Cómo lleva Bitcoin la hora sin un reloj
Cada minero escribe una hora, la marca de tiempo del bloque, en el encabezado del bloque en el que trabaja, y ninguna regla exige que sea correcta. En cambio, la red le pone dos límites al número, las reglas de marca de tiempo de los bloques (en inglés).
El piso mira hacia atrás. Un bloque debe llevar una marca posterior a la mediana del tiempo pasado (en inglés) (median time past), el valor central de las marcas de los once bloques anteriores, o todos los nodos lo rechazan como time-too-old. Como cada marca nueva tiene que superarla, la mediana nunca retrocede, aunque puede quedarse quieta. Los bloqueos de tiempo usan la misma mediana, por el BIP 113 (en inglés). Las marcas sueltas sí pueden ir hacia atrás, y pasa a menudo. En todos los encabezados que sacamos el 2 de noviembre de 2026 del nodo de Bitcoin Core que hay detrás de ChainQuery, 16,248 de 974,264 bloques, alrededor de uno de cada sesenta, llevan una hora anterior a la del bloque previo, y todos son válidos.
El techo sale del propio reloj de cada nodo. Ningún nodo acepta un bloque con una marca de más de dos horas por delante de ese reloj. La primera versión de Satoshi encabezaba su código de manejo del tiempo con una vieja regla de marineros, "Never go to sea with two chronometers; take one or three" (nunca salgas al mar con dos cronómetros; lleva uno o tres), y le daba tres a cada nodo: su reloj del sistema, la mediana de los relojes de sus pares y servidores de hora que todavía no consultaba. Desde Bitcoin Core 27.0 (abril de 2024, pull request #28956), el nodo usa el reloj del sistema de la propia computadora, ya sin ajustarlo según lo que informan sus pares, y desde la 28.0 (pull request #29623) le avisa a quien lo opera cuando la mediana de los relojes de sus pares salientes se desvía más de diez minutos.
Dentro de esos límites, el ajuste de dificultad, o reajuste (retarget), hace sus cuentas; el capítulo sobre minería (en inglés) explica la dificultad desde el principio. Bitcoin cuenta los bloques en ventanas de 2,016, unas dos semanas a diez minutos por bloque. Al final de cada ventana, cada nodo le resta a la última marca de tiempo de la ventana la primera, dos marcas que eligieron los mineros, y compara el resultado con dos semanas, 1,209,600 segundos. Una ventana que tardó una semana duplica la dificultad; una que tardó cuatro semanas la reduce a la mitad. Ningún paso puede superar un factor de cuatro. Ese límite se ha alcanzado una sola vez en la historia de Bitcoin, hacia arriba, en el bloque 68,544, el 16 de julio de 2010, después de una ventana de 3.35 días.
Una línea, dos rarezas
El reajuste no siempre se construyó así. Una copia del código de Satoshi fechada a mediados de noviembre de 2008 miraba 30 días hacia atrás con un objetivo de un bloque cada 15 minutos, cambiaba la dificultad solo duplicándola o reduciéndola a la mitad, contaba cada intervalo entre bloques y exigía que cada bloque llevara una marca posterior a la de su bloque padre. El whitepaper (PDF en inglés) describe "a moving average targeting an average number of blocks per hour" (un promedio móvil que apunta a un número promedio de bloques por hora), más cerca de ese borrador que de lo que salió.
Cuando salió la 0.1.0, el 9 de enero de 2009, unas ocho semanas después, tenía ventanas fijas de 2,016 bloques, el límite de un factor de cuatro, la mediana de once bloques en lugar de aquella regla de que cada bloque fuera posterior a su padre, y este bucle para encontrar el primer bloque de una ventana:
for (int i = 0; pindexFirst && i < nInterval-1; i++)
pindexFirst = pindexFirst->pprev;
Desde el último bloque de la ventana, retrocede nInterval-1 veces, es decir 2,015, hasta el primer bloque de esa misma ventana. La misma aritmética es la línea 42 de src/pow.cpp en Bitcoin Core v32.1, y tiene dos efectos.
El primero es un error por uno (off-by-one). Una ventana de 2,016 bloques tiene solo 2,015 intervalos entre su primera y su última marca, y el código compara esos intervalos con 2,016 veces diez minutos, así que de hecho apunta a dos semanas divididas entre 2,015, o 600.3 segundos por bloque. Un efecto estadístico que Pieter Wuille documentó en 2019, con crédito para Ian Goldberg, suma más o menos lo mismo otra vez, para un promedio de unos 600.6 segundos con un hashrate constante. Ninguno de los dos se nota en la práctica, porque el hashrate (el poder de cómputo de la red) no deja de crecer; los bloques reales han promediado unos 577 segundos desde 2009.
El segundo es la costura. Como el bucle se detiene en el primer bloque de la propia ventana, ningún bloque pertenece a dos ventanas, y nada compara el último bloque de una ventana con el primero de la siguiente, salvo la regla de la mediana, que deja que un solo bloque lleve una hora bastante anterior a la de sus vecinos. Así que el primer bloque de una ventana puede llevar una marca muy anterior a la del bloque previo, y el reajuste medirá toda la ventana desde esa marca temprana. Con la regla de noviembre de 2008, en la que cada bloque era posterior a su padre, eso no habría podido pasar.
Doblar el reloj
Lo que sigue es una simulación. Escribimos en Python la aritmética del reajuste de Bitcoin Core, comprobamos que reproduce exactamente los 483 reajustes de la historia de Bitcoin y le dimos a un atacante todo el hashrate, a partir de la dificultad fijada el 29 de octubre de 2026, unos 148 billones. El día 0 es el último bloque honesto, el que cierra una ventana, alrededor del 12 de noviembre de 2026.
Desde el día 0, el atacante pone en cada bloque la hora más temprana que permite la regla de la mediana, así que el reloj de la cadena, la hora que dicen sus bloques, avanza a paso de tortuga, un segundo por cada seis bloques, unos 5.6 minutos por ventana, mientras pasan dos semanas reales. Solo el último bloque de cada ventana lleva la hora real, porque esa es la marca que el reajuste lee como el final de la ventana. El bloque siguiente, el primero de la ventana nueva, vuelve de golpe a la hora rezagada. En la ventana 2 eso son 44 minutos antes del día 0, porque la hora rezagada partió de la mediana de los últimos bloques honestos, 50 minutos antes del día 0. Es válido, porque un solo bloque muy por delante del resto no mueve una mediana de once.
El reajuste solo mira los dos extremos. La ventana 1 empezó en el día 0, así que mide 14 días honestos y la dificultad casi no se mueve. La ventana 2 se mina del día 14 al día 28, pero su primer bloque lleva una marca anterior al día 0, así que el reajuste cree que tardó 28 días y reduce la dificultad a la mitad. La ventana 3, con la mitad de dificultad, tarda siete días reales, pero también se mide desde antes del día 0, así que parece de 35 días, y la dificultad cae otro 60 por ciento. De ahí en adelante, cada ventana pasa entre dos veces y media y tres veces más rápido que la anterior. En la tabla, T son billones (millones de millones).
| Ventana | Días reales | Dificultad durante el minado | Minutos por bloque | Lapso que ve el reajuste |
|---|---|---|---|---|
| 1 | de 0 a 14.0 | 148.4 T | 10.0 | 14.0 días |
| 2 | de 14.0 a 28.0 | 148.0 T | 10.0 | 28.0 días |
| 3 | de 28.0 a 34.9 | 74.0 T | 5.0 | 35.0 días |
| 4 | de 34.9 a 37.7 | 29.6 T | 2.0 | 37.8 días |
| 5 | de 37.7 a 38.8 | 11.0 T | 0.74 | 38.8 días |
En la ventana 5 llegan 2,016 bloques en unas 25 horas mientras el reajuste cree que tardaron 38.8 días, y para el día 39.4 la cadena produce más de diez bloques por segundo.
Cuánto tarda depende de cuándo empieza el atacante. Desde el principio de una ventana, como en nuestra corrida, la dificultad llega a su mínimo en unos 39.4 días, el 22 de diciembre de 2026 si se empieza el 12 de noviembre; el ejemplo bloque por bloque de Antoine Poinsot de mayo de 2024, que también empezaba en el límite entre dos ventanas, dio unos 39. Empezar unos seis días antes de que termine una ventana es un poco más rápido, unos 37.4 días, y el BIP 54 (en inglés), la propuesta que cerraría la costura, sitúa el peor caso en 38 días como mucho.
En el mínimo, el reloj de la cadena sigue más de 39 días por detrás del tiempo real, así que ninguna de las dos reglas de marca de tiempo frena al atacante. En el modelo, todas las monedas que le quedan al subsidio de bloque, unos 888,300 BTC que una cadena honesta pagaría a lo largo de los próximos 113 años, salen en un solo día simulado. En la realidad, el límite sería la velocidad a la que el atacante pudiera construir unos seis millones de bloques y cada nodo pudiera verificarlos. Con ellos vencería todo bloqueo de tiempo contado en bloques, desde los plazos de los canales de Lightning hasta las demoras de las bóvedas (vaults).
Todos los demás se interponen. El ataque necesita la mayoría del hashrate durante semanas, a la vista de todos, y no gana nada hasta que la dificultad cae por primera vez, el día 28 si el ataque empieza en el límite entre dos ventanas o hacia el día 20 si se elige el mejor momento para empezar. Un minero honesto que gane el primer bloque de cualquier ventana y le ponga la hora real le da a esa ventana un punto de partida verdadero, así que se mide cerca de su duración real, y cada marca honesta intermedia empuja hacia adelante la mediana, y con ella el piso del atacante. Una minoría no gana casi nada; Poinsot dijo que la ganancia de los juegos oportunistas con las marcas de tiempo es "ridiculously small for any minority hashrate" (ridículamente pequeña para cualquier hashrate minoritario).
Ningún pool ha dicho que podría o que querría usar el time warp. La única declaración de un pool que encontramos es una respuesta en la lista de desarrolladores de minería de Bitcoin, con fecha del 3 de septiembre de 2024, a una pregunta sobre la versión de diez minutos de la corrección en testnet4: "This would be no problem for MARA Digital Holdings" (esto no sería un problema para MARA Digital Holdings), porque las marcas de tiempo que usa salen de getblocktemplate.
Dónde ha pasado
GeistGeld es el primer caso registrado. Su configuración de entonces recalculaba la dificultad cada 16 bloques, cuatro minutos por ventana a su ritmo objetivo, así que las pocas ventanas que necesita el ataque pasaban en minutos y no en semanas. Su cadena ya no existe, así que nadie puede contar lo que se llevó el atacante.
Litecoin todavía lleva la corrección de ArtForz. Cada ventana se mide desde el último bloque de la anterior, así que las ventanas vecinas comparten un bloque, y el comentario sobre el código termina como el de GeistGeld, con "Code courtesy of Art Forz". Freicoin, también construida a partir del código de Bitcoin, tiene el mismo cambio, con crédito para ArtForz, en un commit con fecha de autoría del 6 de agosto de 2013, cuyo título empieza "Hardfork: Fix Art Forz's time-traveller attack" (hard fork: corrige el ataque del viajero en el tiempo de Art Forz).
La propia testnet de Bitcoin guarda el único time warp minado alguna vez en una red de Bitcoin, puesto ahí a propósito. Greg Maxwell escribió en la lista bitcoin-dev en diciembre de 2012 sobre "adding the timewarp attack to the testnet chain" (agregar el ataque time warp a la cadena de testnet), y en agosto de 2018: "I put a demonstration of timewarp early in the testnet3 chain" (puse una demostración del time warp al principio de la cadena de testnet3). El bloque 8,063 lleva fecha del 23 de julio de 2012. El bloque 8,064, el primero de la ventana siguiente, lleva fecha del 28 de mayo de 2012, ocho semanas antes. El salto se repite en los bloques 10,079 y 10,080. Las dos ventanas midieron un segundo más de 56 días, el punto donde entra en juego el límite, así que la dificultad cayó el máximo dos veces, de 16 a 4 y de 4 a 1. El tramo se minó a fines de julio de 2012, después de que Gavin Andresen anunciara testnet3 el 29 de mayo; el bloque 10,078 lleva fecha del 29 de julio, y ningún nodo con el reloj en hora lo habría aceptado antes de ese día.
Verge cayó ante un pariente de este ataque en abril y mayo de 2018. Se podía minar con varios algoritmos distintos, y recalculaba la dificultad de cada uno en cada bloque a partir de los bloques recientes de ese algoritmo; su código además dejaba que un bloque llevara una marca hasta dos horas anterior a la de su padre. Los bloques con fecha atrasada, intercalados con los honestos, hacían que un algoritmo pareciera mucho más lento de lo que era, y su dificultad cayó hasta que los bloques llegaban con un segundo de diferencia. Es una debilidad distinta de la costura de Bitcoin, porque la dificultad de Verge no tiene ventanas fijas. El primer parche de Verge, del 4 de abril, decía quince minutos en un comentario y fijaba 30 segundos en el código. El 5 de abril siguió una regla más estricta, pero el 6 de abril se borró y volvió el margen de dos horas, así que el ataque de mayo usó la misma debilidad hasta que un parche del 25 de mayo lo redujo a diez minutos. Los relatos sobre las monedas robadas no coinciden, y no damos ninguna cifra.
Las tormentas de bloques de testnet3 en abril de 2024, cuando Jameson Lopp se propuso sabotear la testnet y la cadena sumó unos 221,000 bloques en nueve días, vinieron de otra debilidad, exclusiva de la testnet, su regla de dificultad mínima, y ninguna costura de esos nueve días retrocedió más de unos 40 minutos.
Las costuras del propio Bitcoin
Si alguien hubiera intentado el time warp en Bitcoin, las costuras lo mostrarían. En los 483 reajustes, del bloque 2,016 al bloque 973,728, comparamos el primer bloque de la ventana nueva con el último de la anterior. Diez veces, el primer bloque llevaba una marca anterior. La peor fue de 18 minutos y 47 segundos, en el bloque 203,616, el 16 de octubre de 2012, y ahí parece que el adelantado fue el bloque previo, porque lleva una marca posterior a la de los tres siguientes. Desde 2015, la peor es de 43 segundos, en el bloque 812,448, el 16 de octubre de 2023. La costura mediana, 410 segundos, está cerca del intervalo mediano entre un bloque y el siguiente, 402 segundos.
El ataque también necesita bloques con la marca en el piso, un segundo después de la mediana. Solo 48 bloques en la historia de Bitcoin llevan una marca así de baja, el último a la altura 156,368, en diciembre de 2011. Un bloque típico de 2026 lleva una marca casi una hora posterior a su piso.
Los mismos datos ponen a prueba las dos versiones de la corrección. La regla de diez minutos de testnet4, el BIP 94, habría rechazado exactamente un bloque en la historia de Bitcoin, ese de 2012, salvo que su minero le hubiera puesto la hora 23:04:55 o una posterior. La regla de dos horas del BIP 54 no habría rechazado ninguno; la peor costura de la historia queda más de 100 minutos dentro de ella. La segunda regla de marcas de tiempo del BIP 54, la regla de la ventana negativa, dice que el último bloque de una ventana no puede llevar una marca anterior a la del primero, y ningún bloque la ha violado tampoco. Lo comprobamos todo de dos maneras con encabezados del nodo de Bitcoin Core que hay detrás de ChainQuery: leímos todos los encabezados de una sola vez y pedimos en crudo los 967 encabezados de los límites entre ventanas para volver a calcular su hash, y comprobamos cada costura negativa contra un explorador de bloques público. Cualquiera con un nodo puede repetirlo con getblockheader, y la tabla completa se puede descargar en CSV.
Cuando una regla de dificultad sí falló
La falla más clara de una regla de dificultad pasó en la casa de al lado, y muestra lo que ocurre cuando los mineros pueden jugar con una. Cuando Bitcoin Cash (en inglés) se separó de Bitcoin el 1 de agosto de 2017, heredó la dificultad de Bitcoin con una pequeña parte de los mineros, la apertura que necesita una espiral de la muerte (en inglés). Sus desarrolladores habían agregado un ajuste de dificultad de emergencia (en inglés): cada vez que seis bloques habían tardado doce horas o más, la dificultad del bloque siguiente bajaba un 20 por ciento, y también la del siguiente mientras se mantuviera la condición. La regla solo podía recortar; volver a subir la dificultad le quedaba al reajuste ordinario.
Los mineros aprendieron a jugar con ella. Dejaban la cadena hasta que se acumulaban los huecos, volvían por bloques baratos, los minaban con minutos de diferencia hasta que el reajuste los alcanzaba, y se iban otra vez. La regla de emergencia se activó 43 veces en 104 días, incluidas dos rachas de seis recortes en menos de cuatro horas, y tres reajustes chocaron con el límite de un factor de cuatro. El 28 de octubre de 2017 la cadena minó 1,254 bloques en un día, y para el 13 de noviembre, 104.32 días después de la separación, había minado 25,473 bloques donde el reloj permitía 15,022, lo que la ponía 10,451 bloques, unas 130,600 monedas, por delante del calendario. Su halving de 2020 llegó 33 días antes que el de Bitcoin.
Bitcoin sintió las olas, porque el hashrate que entraba en Bitcoin Cash era el que salía de Bitcoin. El domingo 12 de noviembre de 2017, la cadena de Bitcoin Cash registró más o menos tanto trabajo como la de Bitcoin, según su propio registro un poco más, y Bitcoin encontró 80 bloques, donde el calendario pide 144. Un nodo con un mempool sin límite, el de Johoe, contó unas 48,000 transacciones en espera el 9 de noviembre y 180,000 el 12 de noviembre. Al día siguiente, Bitcoin Cash cambió a una regla que recalculaba la dificultad en cada bloque a partir de más o menos el último día de trabajo. Otra, aserti3-2d, la reemplazó en noviembre de 2020, e incluso esa dejó a la cadena minoritaria de la división de ese año, la de Bitcoin ABC, más tarde rebautizada eCash, arrastrándose a entre 3 y 8 bloques por día durante cinco días.
Lo peor para el propio Bitcoin llegó en 2021, cuando el cierre de la minería en China dejó fuera de línea cerca de la mitad del hashrate. La dificultad bajó en cuatro reajustes seguidos: un 15.97 por ciento el 30 de mayo, un 5.30 el 13 de junio, un 27.94 el 3 de julio y un 4.81 el 17 de julio, un 45.4 por ciento en 65.6 días. La ventana que terminó el 3 de julio tardó 19.4 días, a 13.9 minutos por bloque, la más lenta desde que la dificultad subió por primera vez, en diciembre de 2009 (en 2009, con la dificultad mínima, hubo ventanas de hasta 41.5 días). La ventana siguiente corrió a 10.5 minutos por bloque.
Irse durante doce horas, que en Bitcoin Cash daba resultado, no gana nada en Bitcoin, y las dos horas que un minero puede adelantar su marca solo pueden estirar una ventana de dos semanas un 0.6 por ciento. El costo son unas semanas lentas cada vez que el hashrate se va de golpe, como en las cuatro ventanas de 2021.
Por qué sigue ahí
Hay dos maneras de cerrar la costura. Una cambia la aritmética para que cada ventana se mida desde el último bloque de la ventana anterior, como hace Litecoin. Cada encabezado tiene que llevar exactamente la dificultad que calcula un nodo, así que los nodos viejos y los nuevos rechazarían los bloques de los otros en el primer reajuste: un hard fork. La otra mantiene la aritmética y agrega una regla sobre la marca de tiempo del primer bloque. Todo bloque que la cumple ya cumplía las reglas viejas, así que los nodos que nunca se actualizan siguen la misma cadena: un soft fork.
El 14 de septiembre de 2011, en el hilo que había abierto, Andresen juzgó que una corrección que bifurcara la cadena era "too high risk for too little benefit and shouldn't be done until we have a really compelling reason to introduce a forking change" (demasiado riesgo para muy poco beneficio, y no debería hacerse hasta que tengamos una razón de verdad convincente para introducir un cambio que bifurque la cadena). El 7 de noviembre, Pieter Wuille esbozó la segunda clase: mantener la aritmética y exigir que el primer bloque de cada ventana lleve una marca posterior a la más tardía de los once bloques anteriores, "essentially just using a maximum instead of a median" (en esencia, usar un máximo en lugar de una mediana). Nadie lo llevó más lejos.
De 2015 a 2017, la corrección quedó archivada en la primera clase, como el hard fork inofensivo que los desarrolladores citaban una y otra vez durante la guerra del tamaño de bloque (en inglés). Jorge Timon la puso como cambio de ejemplo en el BIP 99, su propuesta de 2015 sobre cómo desplegar bifurcaciones, y escribió el 29 de marzo de 2017: "I cannot think of a hf that is easier to implement or has less potential for controversy than that" (no se me ocurre un hard fork más fácil de implementar o con menos potencial de controversia que ese). Nunca se programó ningún hard fork.
El 20 de agosto de 2018, Greg Maxwell retomó la corrección como soft fork y explicó la espera: "I, and I assume others, haven't put a big priority into fixing this vulnerability because it requires a majority hashrate and could easily be blocked if someone started using it" (yo, y supongo que otros, no le hemos dado mucha prioridad a corregir esta vulnerabilidad porque requiere un hashrate mayoritario y se podría bloquear fácilmente si alguien empezara a usarla). En marzo de 2019, Matt Corallo metió la regla en su Great Consensus Cleanup junto con varias restricciones a los scripts de las transacciones, que recibieron la objeción de que podían invalidar algunas transacciones prefirmadas, y el paquete se estancó. Al cerrar un pull request complementario el 29 de julio de 2020, Corallo escribió que "it seems unlikely to be picked back up" (parece poco probable que alguien lo retome). El 17 de septiembre de 2022, Anthony Towns, en respuesta a la queja de Corallo del día anterior sobre la falta de impulsores, culpó al proceso: "If we did have a good answer for how to progress a soft-fork" (si tuviéramos una buena respuesta sobre cómo hacer avanzar un soft fork), la limpieza "would have made more progress over the past 3.5 years" (habría avanzado más en los últimos 3.5 años).
Antoine Poinsot revivió la limpieza en Delving Bitcoin el 24 de marzo de 2024, y descartó el consuelo de que un ataque sería lento y evidente: "a month isn't a lot of time to coordinate and change Bitcoin's consensus rules" (un mes no es mucho tiempo para coordinarse y cambiar las reglas de consenso de Bitcoin). Mark Friedenbach, autor registrado de aquel commit de Freicoin de 2013, quería conservar la costura. Su propuesta Forward Blocks, de 2018, usaba un time warp controlado para hacer pasar más transacciones por los nodos viejos sin un hard fork, y en abril de 2024 defendió mantener esa opción. Poinsot respondió el 18 de abril que "the cost of not fixing timewarp objectively far exceeds the cost of making 'forward blocks' impossible" (el costo de no corregir el time warp supera objetivamente, y con mucho, el costo de hacer imposibles los "forward blocks"). Friedenbach se mantuvo firme el 30 de abril, en una respuesta posterior en el mismo hilo: "Once thrown, this fuse switch can't be undone" (una vez accionado, este interruptor no tiene vuelta atrás).
El borrador de Corallo dejaba que el primer bloque de una ventana quedara hasta diez minutos antes del bloque que lo precede, la regla que aplica testnet4. En testnet4, cierto software de pool fechaba los bloques con su propio reloj en lugar de usar la plantilla, así que los autores del BIP 54 eligieron dos horas como precaución, lo mismo que el techo para las marcas futuras, lo que significa que un minero que ponga la hora actual nunca puede romper la regla. En la simulación de Wuille de un ataque sostenido, la holgura extra deja que los bloques lleguen unos tres segundos más rápido: cada 599.9997 segundos con la regla de diez minutos, cada 596.7211 con dos horas. La peor costura de la red principal (mainnet), la de 2012, habría violado la regla de diez minutos, una razón más para el margen. El BIP 54 no toca la aritmética, así que el error por uno se queda.
En noviembre de 2026, el BIP 54 figura como completo (Complete, versión 1.0.0 del 22 de mayo de 2026). Además de las dos reglas de marca de tiempo, trae tres correcciones sin relación entre sí: un tope a las operaciones de firma para los bloques construidos para validarse despacio, una prohibición de las transacciones de 64 bytes y una regla sobre la transacción coinbase que retira una vieja comprobación de transacciones duplicadas. Bitcoin Inquisition, una versión de Bitcoin Core hecha para probar cambios de reglas propuestos, lo aplica todo en signet (en inglés) desde el bloque 291,168, con fecha del 12 de febrero de 2026. Bitcoin Core construye plantillas de bloque, los bloques en borrador que les entrega a los mineros, que respetan la regla contra el time warp desde la 29.0 (abril de 2025) y la regla de la ventana negativa desde la 32.1 (28 de octubre de 2026), así que los mineros que lo usen no romperían ninguna de las dos por accidente. Las reglas en sí, sin activación en la red principal, están en el pull request #35793 de Bitcoin Core, que está abierto y necesita ponerse al día con el código actual. Nadie ha propuesto cuándo ni cómo activarlas; ese paso pasa por el proceso lento y público (en inglés) que Bitcoin usa para cada cambio de reglas.
Qué ganamos con esto
Nadie que tenga bitcoin necesita hacer nada respecto al time warp. El ataque sería visible durante semanas antes de dar frutos, necesita una mayoría del hashrate que ya podría censurar transacciones, y la corrección solo estrecha lo que cuenta como bloque válido, así que los nodos que nunca se actualicen se quedan en la misma cadena. Bitcoin se ha movido rápido contra los bugs que se estaban explotando, como con el bug de inflación de agosto de 2010 (en inglés).
- Sabes de dónde sale el reloj. Lo escriben los mineros, entre la mediana de once bloques y dos horas por delante del reloj de cada nodo.
- Sabes qué necesita el ataque. Una mayoría del hashrate, semanas de marcas retenidas en el piso a la vista de todos, y tres o cuatro semanas de paciencia antes de que la dificultad caiga por primera vez.
- Sabes que aquí no se ha intentado. Diez costuras negativas de 483, ninguna peor que 18 minutos y 47 segundos, y ningún bloque en el piso desde diciembre de 2011.
- Sabes por qué espera la corrección. Está escrita y probada, y Bitcoin cambia sus reglas despacio a propósito.
Consejo pro: Si corres un nodo, mantén su reloj en hora. Desde Bitcoin Core 27.0, el límite de dos horas se comprueba contra la hora de tu propia computadora, y las notas de la versión le dejan a quien opera el nodo la responsabilidad de mantenerla correcta para que el nodo no se desfase del resto de la red. Activa la sincronización automática de la hora y déjala activada.
Más en Cómo funciona
Fuentes
- BitcoinTalk, GeistGeld announcement by Lolcust, 9 September 2011: 'an experimental currency intended to test out the limits of block generation rate empirically'
- BitcoinTalk, GeistGeld restart thread, 12 September 2011: Lolcust at 20:09 UTC, 'another run-in of same kind is in progress'; a miner at 20:19 UTC, 'Looks like 20k+ blocks again'
- ArtForz, BitcoinTalk, 12 September 2011, 21:39 UTC: retargeting 'ignores one block interval every period'; 'This was done on the GeistGeld chain yesterday/today'
- Lolcust/GeistGeld commit f9523f33ec, 13 September 2011 12:30 UTC: the reset with ArtForz's fix, 'Go back the full period unless it's the first retarget after genesis. Code courtesy of Art Forz'
- Gavin Andresen, bitcoin-dev, 13 September 2011, 15:06 UTC: 'Difficulty adjustment / time issues', the list's first word on it, linking ArtForz's post
- Gavin Andresen, bitcoin-dev, 14 September 2011: a forking fix is 'too high risk for too little benefit'
- Pieter Wuille, bitcoin-dev, 7 November 2011: stamp the first block of each window later than the latest of the previous eleven stamps, 'essentially just using a maximum instead of a median'
- Bitcoin Core v32.1 - src/pow.cpp lines 14-48: GetNextWorkRequired recalculates only at multiples of 2,016 (line 20) and steps back DifficultyAdjustmentInterval()-1 blocks to the window's first block (line 42)
- Bitcoin Core v32.1 - src/pow.cpp lines 50-85: CalculateNextWorkRequired, last stamp minus first stamp (line 56), the factor-of-four clamp (lines 57-60), the scaling (lines 78-79)
- Bitcoin Core v32.1 - src/validation.cpp lines 4088-4129, ContextualCheckBlockHeader: bad-diffbits (4096-4097), time-too-old against the median time past (4099-4101), testnet4's time-timewarp-attack (4103-4113), time-too-new (4115-4118)
- Bitcoin Core v32.1 - src/chain.h: MAX_FUTURE_BLOCK_TIME, two hours (line 29); GetMedianTimePast over eleven blocks (lines 231-245)
- Bitcoin Core v32.1 - src/kernel/chainparams.cpp lines 126-131: mainnet's two-week timespan, ten-minute spacing and enforce_BIP94 = false
- Bitcoin Core v32.1 - src/node/miner.cpp lines 57-75, GetMinimumTime: templates stamp a window's first block no more than 600 seconds before its parent and its last block no earlier than its first
- Bitcoin Core PR #28956 - Nuke adjusted time from validation (attempt 2) (merged 31 January 2024, in 27.0): block times judged against the node's own clock
- Bitcoin Core 27.0 release notes: the change 'increases the importance of the node operator ensuring their system time is (and stays) correct'
- Bitcoin Core PR #29623 - Simplify network-adjusted time warning logic (merged 30 April 2024, in 28.0): warns when outbound peers' median clock is more than ten minutes off
- BIP-113 - Median time-past as endpoint for lock-time calculations
- Bitcoin 0.1.0 (9 January 2009), src/main.cpp lines 685-729, trottier/original-bitcoin mirror: the nInterval-1 loop (line 701), the unsigned span (line 706), the clamp (lines 708-711)
- Bitcoin 0.1.0, src/util.cpp lines 320-327: 'Never go to sea with two chronometers; take one or three.'
- Satoshi Nakamoto Institute - code archive: Bitcoin v0.1.0 (9 January 2009) and the pre-release of 15 November 2008
- The November 2008 pre-release, main.cpp (BiDPHILOSOPHER/bitcoin-nov08 mirror): a 30-day look-back at 15-minute blocks, one-bit difficulty steps, every block later than its parent
- Bitcoin whitepaper, section 4: difficulty set by 'a moving average targeting an average number of blocks per hour'
- Pieter Wuille - Oddities of Bitcoin's difficulty adjustment (gist, 20 February 2019): honest blocks average 600(2016/2014) seconds, crediting Ian Goldberg
- Matt Corallo - Great Consensus Cleanup draft BIP (created 28 January 2019): footnote 1 on 600.3 against 600.6 seconds; the ten-minute first-block rule; 'no known attempts to exploit' on mainnet
- LearnBitcoin - time warp simulation using Bitcoin Core's retarget arithmetic (2 November 2026), window by window from a 12 November 2026 start to minimum difficulty (CSV)
- Antoine Poinsot, Delving Bitcoin, 24 March 2024 - Great Consensus Cleanup Revival: the minority gain is 'ridiculously small'; 'a month isn't a lot of time to coordinate'
- Antoine Poinsot, Delving Bitcoin, 17 May 2024: a block-level simulation from block 842,688, a window boundary, 'about 39 days' to difficulty 1
- BIP-54 - Consensus Cleanup (Complete, 1.0.0 of 22 May 2026): the two timestamp rules; the minimum 'within 38 days' in the worst case; two hours 'out of an abundance of caution'
- Bitcoin mining development list, 'Mitigation for Timewarp Attack in Testnet 4', reply dated 3 September 2024: 'This would be no problem for MARA Digital Holdings'
- Litecoin v0.21.5.8 - src/pow.cpp lines 40-54: each window measured back the full period, 'Code courtesy of Art Forz'
- Freicoin commit beb2fa54: 'Hardfork: Fix Art Forz's time-traveller attack', code credited to ArtForz (author of record Mark Friedenbach, author date 6 August 2013; committed by Jorge Timon, 2015)
- BIP-99 - the time warp fix as the sample uncontroversial hard fork (Jorge Timon, 2015; closed)
- Gavin Andresen, bitcoin-dev, 29 May 2012: the testnet3 announcement
- Gregory Maxwell, bitcoin-dev, 22 December 2012: 'when adding the timewarp attack to the testnet chain'
- Gregory Maxwell, bitcoin-dev, 20 August 2018: the testnet3 demonstration, and why the fix had low priority
- mempool.space - testnet3 block 8,064, stamped 28 May 2012, after block 8,063 stamped 23 July 2012
- Verge source at 8ade4269 - src/main.cpp: per-algorithm DarkGravityWave3 difficulty; a block may be stamped up to two hours before its parent (line 2307)
- Verge commit 7294e062a6, 4 April 2018: 'change drift from 2 hours to 15 mins', which set 30 seconds
- Verge commit a3dd53f40a, 5 April 2018: no block stamped before its parent
- Verge commit 80c81aef63, 6 April 2018: 'Force different algos', which also deleted the 5 April rule
- Verge commit 2b6faff66e, 6 April 2018: 'Change clock drift back to old value'
- Verge commit f8ca082646, 25 May 2018: 'fix drift', ten minutes from block 2,218,500
- The Next Web, 22 May 2018 - the May 2018 Verge attack, blocks 'one second apart' (the only contemporaneous account found)
- Jameson Lopp - Griefing Bitcoin's Testnet (4 May 2024): the 2024 block storms through the minimum-difficulty rule
- LearnBitcoin - every retarget seam on mainnet, blocks 2,016 to 973,728, from the Bitcoin Core node behind ChainQuery (CSV)
- BIP-94 - Testnet 4: the first block of a window no more than 600 seconds before the previous block
- UAHF technical specification v1.6 (24 July 2017), REQ-7: the Bitcoin Cash emergency difficulty adjustment
- Bitcoin ABC v0.14.6 - src/pow.cpp: the emergency rule as shipped, a 20 percent cut per block while the twelve-hour condition holds
- Blockchair - raw daily Bitcoin Cash block dumps (heights, timestamps and difficulty for 2017, checked against independent raw headers)
- Jochen Hoenicke - mempool statistics from one Bitcoin Core node with an unlimited mempool (November 2017)
- Bitcoin Cash November 13 hard fork specification v1.3: difficulty from the last 144 blocks of work, every block
- ASERT difficulty adjustment algorithm (aserti3-2d) specification v0.6.3, activated 15 November 2020
- mempool.space - hash rate and difficulty chart (the 2021 fall, from about 176 to about 86 EH/s on seven-day averages)
- Cambridge Centre for Alternative Finance - New data reveals timeline of China's bitcoin mining exodus (15 July 2021)
- Jorge Timon, bitcoin-dev, 29 March 2017: 'I cannot think of a hf that is easier to implement or has less potential for controversy than that'
- Matt Corallo, bitcoin-dev, 6 March 2019: the Great Consensus Cleanup
- Bitcoin Core PR #15482 - the 2019 Great Consensus Cleanup implementation (closed by Corallo, 12 November 2019)
- Bitcoin Core PR #15481 - the companion mining change, closed 29 July 2020: 'it seems unlikely to be picked back up'
- Anthony Towns, bitcoin-dev, 17 September 2022: 'If we did have a good answer for how to progress a soft-fork'
- Mark Friedenbach - Forward Blocks (Scaling Bitcoin, October 2018): a 'Coordinated Time-Warp' on the old chain
- Antoine Poinsot, bitcoin-dev, 18 April 2024: 'the cost of not fixing timewarp objectively far exceeds the cost'
- Mark Friedenbach, bitcoin-dev, 30 April 2024: 'Once thrown, this fuse switch can't be undone'
- Pieter Wuille, Delving Bitcoin, 8 January 2025: under a sustained attack, 599.9997 seconds a block with a ten-minute grace and 596.7211 with two hours
- Antoine Poinsot, Delving Bitcoin, 30 January 2025: the switch to a two-hour grace period, at about 0.1 against 0.65 percent extra block rate under attack
- Bitcoin Core PR #31376 - never create a template which exploits the timewarp bug (merged 23 January 2025, in 29.0)
- Bitcoin Core PR #35949 - templates enforce BIP-54's last-block rule (merged 7 September 2026, first released in 32.1)
- Bitcoin Core PR #35793 - Implement BIP 54 (Consensus Cleanup) without mainnet activation (open, needs rebase, as of 2 November 2026)
- Antoine Poinsot, bitcoin-dev, 13 February 2026: BIP-54 active on Bitcoin Inquisition (signet) since block 291,168
Publicado el . No hay correcciones registradas para esta página.
Editar esta página en GitHub