De From EIP 2 , el algoritmo de ajuste de dificultad de Homestead es:
block_diff = parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99) + int(2**((block.number // 100000) - 2))
donde // es el operador de división de enteros, p. 6 // 2 = 3, 7 // 2 = 3, 8 // 2 = 4.
¿Como funciona esto?
(Esta pregunta fue provocada por la pregunta ¿Cuál fue el primer bloque extraído con Homestead? )
Otras preguntas y respuestas relacionadas:
Si la diferencia de marca de tiempo (block_timestamp - parent_timestamp)
es:
parent_diff // 2048 * 1
parent_diff // 2048 * -1
un ajuste hacia abajo máximo deparent_diff // 2048 * -99
Esto es consistente con la declaración de ethdocs.org - Ethereum Homestead - The Homestead Release :
EIP-2/4 elimina el incentivo excesivo para establecer la diferencia de marca de tiempo exactamente en 1 para crear un bloque que tenga una dificultad ligeramente mayor y que, por lo tanto, garantice superar cualquier bifurcación posible. Esto garantiza mantener el tiempo de bloqueo en el rango de 10-20 y, según las simulaciones, restaura el tiempo de bloqueo objetivo de 15 segundos (en lugar de los 17 segundos efectivos actuales).
Y según Ethereum Network Status , el tiempo promedio de bloqueo actualmente es de 13,86 segundos.
La fórmula de ajuste de dificultad:
block_diff = parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99) + int(2**((block.number // 100000) - 2))
donde // es el operador de división de enteros, p. 6 // 2 = 3, 7 // 2 = 3, 8 // 2 = 4.
se puede dividir en las siguientes partes:
Subfórmula B : la parte de la bomba de dificultad, que aumenta la dificultad exponencialmente cada 100,000 bloques.
+ int(2**((block.number // 100000) - 2))
La bomba de dificultad no se discutirá aquí, ya que ya se trata en las siguientes preguntas y respuestas:
Subfórmula A : la parte de ajuste de dificultad, que aumenta o disminuye la dificultad del bloque según el tiempo entre la marca de tiempo del bloque actual y la marca de tiempo del bloque principal:
+ parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99)
Subfórmula A1 - Vamos a separar parte de la Subfórmula A
+ max(1 - (block_timestamp - parent_timestamp) // 10, -99)
y considere cuál es el efecto de ajuste debido a la diferencia de marca de tiempo entre el bloque actual y el bloque principal:
cuando (block_timestamp - parent_timestamp)
es
max(1 - 0, -99) = 1
+parent_diff // 2048 * 1
max(1 - 1, -99) = 0
+parent_diff // 2048 * 0
max(1 - 2, -99) = -1
+parent_diff // 2048 * -1
max(1 - 3, -99) = -2
+parent_diff // 2048 * -2
max(1 - 100, -99) = -99
+parent_diff // 2048 * -99
max(1 - {number greater than 100}, -99) = -99
+parent_diff // 2048 * -99
Entonces, si la diferencia de marca de tiempo (block_timestamp - parent_timestamp)
es:
parent_diff // 2048 * 1
parent_diff // 2048 * -1
un ajuste hacia abajo máximo deparent_diff // 2048 * -99
De Go Ethereum - core/block_validator.go, líneas 264-311 :
func calcDifficultyHomestead(time, parentTime uint64, parentNumber, parentDiff *big.Int) *big.Int {
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.mediawiki
// algorithm:
// diff = (parent_diff +
// (parent_diff / 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
// ) + 2^(periodCount - 2)
bigTime := new(big.Int).SetUint64(time)
bigParentTime := new(big.Int).SetUint64(parentTime)
// holds intermediate values to make the algo easier to read & audit
x := new(big.Int)
y := new(big.Int)
// 1 - (block_timestamp -parent_timestamp) // 10
x.Sub(bigTime, bigParentTime)
x.Div(x, big10)
x.Sub(common.Big1, x)
// max(1 - (block_timestamp - parent_timestamp) // 10, -99)))
if x.Cmp(bigMinus99) < 0 {
x.Set(bigMinus99)
}
// (parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
y.Div(parentDiff, params.DifficultyBoundDivisor)
x.Mul(y, x)
x.Add(parentDiff, x)
// minimum difficulty can ever be (before exponential factor)
if x.Cmp(params.MinimumDifficulty) < 0 {
x.Set(params.MinimumDifficulty)
}
// for the exponential factor
periodCount := new(big.Int).Add(parentNumber, common.Big1)
periodCount.Div(periodCount, ExpDiffPeriod)
// the exponential factor, commonly referred to as "the bomb"
// diff = diff + 2^(periodCount - 2)
if periodCount.Cmp(common.Big1) > 0 {
y.Sub(periodCount, common.Big2)
y.Exp(common.Big2, y, nil)
x.Add(x, y)
}
return x
}
El algoritmo de Ethereum hubiera sido mejor si no se hubiera utilizado max(). parent_diff/2048*(1-t/10) podría haberse expandido para evitar el cero que resulta de la división de enteros. Esto habría resultado en
diferencia = diferencia_principal + diferencia_principal/N - diferencia_principal*t/T/N
donde t = tiempo de resolución principal T = tiempo de resolución objetivo N = coeficiente de extinción, también conocido como "vida útil media", también conocido como número de bloques para "temperar" o "amortiguar" el tamaño de la respuesta. No puede ser demasiado pequeño o una dificultad negativa puede resultar de largos tiempos de resolución.
Esto está muy cerca del mejor algoritmo teórico que es un promedio móvil exponencial (EMA) que yo y otros hemos investigado. Es una aproximación de la EMA por la expansión de la serie de Taylor de la función exponencial:
e^x = 1 + x + x^2/2! + ...
Donde usas la aproximación e^x = 1 + x en el algoritmo EMA:
diferencia = diferencia_principal*( 1 - A + A*T/t )
donde A = alfa = 1-e^(-t/T/N)
Ver https://github.com/zawy12/difficulty-algorithms/issues/17
Este algoritmo fue descubierto por Jacob Eliosoff, quien ya estaba muy familiarizado con los EMA para los precios de las acciones. Necesitaba modificarlo para adaptarlo a la dificultad, y el resultado resulta ser una versión conocida que se menciona en Wikipedia con respecto a la estimación del rendimiento de la computadora:
https://en.wikipedia.org/wiki/Moving_average#Application_to_measuring_computer_rendimiento
Digo que teóricamente es mejor porque puede reducir N hasta "1" y los tiempos de resolución medio y mediano están cerca de la esperada T y ln(2)*T. Por lo tanto, es el mejor estimador (que conozco) para adivinar el hashrate actual basado solo en el bloque anterior.
galáhad
20-29
segundos y30-39
segundos, ¿no es el resultado de A1-1
y-2
respectivamente?gran lobo
2048
número mágico? ¿Cuál es la idea detrás de dividirlo y por2048
qué ese número?herman junge
Piotr Dobrogost
(19,20)
rango.Pablo Razvan Berg