¿Dónde está exactamente el error de dificultad "off-by-one"?

Leí todo ¿Cómo se calcula la dificultad? y quiero entender dónde está el error "off-by-one" en el cálculo de la dificultad. Aquí hay un fragmento de Matlab que escribí para calcular la dificultad. ¿Cuáles son los intervalos de paso de bloque correctos que debo usar? Nota: minvy maxvson las alturas de bloque (más 1) del intervalo. Por lo tanto, las marcas de tiempo de las alturas de bloque 0 y 2015 se utilizan en el primer cálculo de dificultad.

% Calculate difficulty
num = floor(length(block_chain)/2016);
minv = 1;
maxv = 2016;
target = 1209600;
difficulty = ones(num,4);
delta = zeros(num,1);
timedif = delta;

for i = 1:num
    if i == 1
        difficulty(1,3) = 1;
        timedif(i) = block_chain(maxv,2) - block_chain(minv,2);
    else
        timedif(i) = block_chain(maxv,2) - block_chain(minv,2);
        delta(i) = max(0.25,min(target/timedif(i),4));
        difficulty(i,3) = max(1,difficulty(i-1,3)*delta(i));
    end
    difficulty(i,:) = [block_chain(minv,1), block_chain(maxv,1),...
        difficulty(i,3), timedif(i)];
    minv = maxv + 1;
    maxv = maxv + 2016;
end

Respuestas (1)

De la wiki de Litecoin :

Error de distorsión del tiempo[14]: el cálculo de la dificultad de Bitcoin está desviado por un bloque, por lo que un atacante puede intentar repetidamente generar el último bloque de cada ventana de reorientación y usar una marca de tiempo fabricada de 2 horas en el futuro para hacer el tiempo diferencia del primer bloque en la ventana de retarget alta, lo que reduce la dificultad en un 0,5%. Debido al error, la marca de tiempo falsa no se usa como el primer bloque en la siguiente ventana de reorientación y, por lo tanto, las 2 horas adicionales no se compensan en el siguiente cálculo de dificultad. Una vez que la dificultad es baja, el atacante puede minar muchas monedas rápidas o, en el caso de una cadena pequeña, un atacante con un poder de hash del 51 % podría reducir la dificultad a 1 y extraer una nueva bifurcación del bloque génesis. Este no es un ataque factible contra Bitcoin, porque la probabilidad de generar repetidamente el último bloque una vez cada 2 semanas con dificultades tan altas es insignificante. Aunque es posible solucionar este problema en Bitcoin, debe hacerse con cuidado (agregando reglas que animen a los nodos a actualizarse con el tiempo) para evitar una bifurcación de la cadena, es decir, los clientes antiguos que no actualizaron podrían operar con otra dificultad y, por lo tanto, no estar de acuerdo con respecto a qué bloques son válidos. En Litecoin este error está arreglado

El error "off-by-one" o Time Warp se debe a que el algoritmo de cálculo de dificultad no usa períodos superpuestos, para el primer recálculo usa bloques 1 hasta 2016 y para el segundo usa bloques 2017 hasta 4032.

Esto por sí solo no es un problema en absoluto, pero como el protocolo tiene en cuenta las diferencias de tiempo entre los nodos, esto hace posible reducir la dificultad de forjar bloques con tiempo de resolución en el futuro.

El algoritmo usa T(2016) - T(1) para calcular la velocidad de la red si el bloque 2016 se crea con una marca de tiempo de 2 horas en el futuro (máximo permitido por el protocolo), entonces la dificultad será un 0,5 % menor de lo que debería ser.

Si luego se encuentra el bloque 2017 y el tiempo es real (T(2017) puede ser menor que T(2016)), entonces el tiempo adicional agregado al bloque 2016 no se compensará en el próximo recálculo como lo sería si se usara el bloque 2 T(4032) - T(2016) para encontrar la velocidad.

Puede encontrar un esquema de ataque más detallado en: https://bitcointalk.org/index.php?topic=43692.msg521772#msg521772

Interesante. Todavía no tengo claro cómo esto es necesariamente un problema incluso después de leer bitcointalk. Esta es una perturbación del tiempo local y forzará una dificultad aún mayor del próximo bloque ya que la competencia por estos bloques más fáciles será mayor. Parece que mi cálculo puede ser correcto, pero todavía tengo un error del 0,4 % en mi dificultad.
El objetivo debe ser 1209000 ya que solo hay intervalos de tiempo de 2015 en la generación de una cadena de bloques de 2016.
El principal problema es que los mineros podrían trabajar juntos para establecer una dificultad menor. El gran problema es que un atacante con un poder de hashing realmente alto puede crear una bifurcación más grande que la principal sin publicar los bloques y luego reemplazar la principal, "borrando" todas las transacciones anteriores y obteniendo todas las recompensas mininig. Si revisas el mensaje de ArtForz puedes ver que como los límites para viajar en el tiempo no son fijos, puedes forjar una cadena bajando la dificultad (el 2do periodo baja el diff a la mitad), superando al principal y luego puedes publicar y reemplace el principal.
Parecía que había un ataque de este tipo en la cadena de bloques alrededor de una ID de bloque de 200.000 o más. Parecía que se desarrollaban dos cadenas paralelas, y luego las cadenas bifurcadas terminaban quedando huérfanas. Pero como los otros mineros no aceptaron la cadena bifurcada (unos 60 bloques más o menos) la bifurcación murió. Gracias por el seguimiento.
Lo ejecuté, la dificultad calculada para los bloques 278318-280223 fue 1.7023E9, que es demasiado baja.