¿Cómo verificar si la cadena de bloques está actualizada usando bitcoind o json-rpc?

Leí la lista completa de métodos api y no encontré ninguno.

Supongo que no hay un comando específico para ese propósito, entonces, ¿cuál es la forma general de hacerlo?

Consideraría verificar la marca de tiempo del último bloque generado, pero el getblockmétodo no se explica con mucho detalle.

EDITAR:

Algunas personas responden que debería comparar el recuento de bloques con uno de un monitor de cadena de bloques en línea. Eso no es realmente una solución práctica. El cliente de Bitcoin-Qt tiene una forma de saber cuándo se realiza la sincronización (el signo V frente al icono de sincronización), entonces, ¿por qué no lo hace bitcoind? ¿Cómo obtiene Bitcoin-Qt esta información?

En resumen: ejecute bitcoind getinfo, compare el número después de 'block count:' con el número aquí .
@BinaryMage Esa pregunta no deja en claro que se trata del demonio en el título. Lo habría ignorado si lo hubiera visto cuando estaba buscando una respuesta.
Mira mi edición.
@StevenRoose Buen punto. Edité la otra pregunta para dejar en claro que se aplicaba al cliente sin cabeza (bitcoind).

Respuestas (10)

Uso un script de python que toma http://blockchain.info/q/getblockcount y lo compara con la salida de bitcoind getblockcount.

Como han dicho otros, no hay una forma absoluta de saber si su cadena de bloques está actualizada.

De todos modos, aquí está mi guión:

    import httplib2
    from bitcoinrpc.authproxy import AuthServiceProxy
    access = AuthServiceProxy('#########')
    try:
            blockCount = access.getblockcount()
    except Exception as e:
            print "Problems connecting to bitcoin wallet:"
    else:
            try:
                    response, trueBlockCount = httplib2.Http().request("http://blockexplorer.com/q/getblockcount/")
            except Exception as e:
                    print "Unable to get true blockcount from blockexplorer:"+str(e)
            else:
                    if (int(trueBlockCount) - 5) > blockCount :
                            print "blockchain not up to date: true block count is: "+str(trueBlockCount)+", while bitcoind is at: "+str(blockCount)
pip install httplib2 y git clone github.com/jgarzik/python-bitcoinrpc.git y python setup.py install me ayudaron a ejecutar este código
en lugar de bitcoind getblockcountno quieres decir bitcoin-cli getblockcount?

No hay forma de verificar si se realizó la sincronización, simplemente porque no se sabe .

De manera un poco abstracta, y probablemente no sea útil en su caso, el cliente siempre se está sincronizando: no hay una diferencia real entre "tener todos los bloques" y "no tener todos los bloques": siempre tiene todos los bloques que conoce y no saber si hay bloques que se pierde.

Lo que la GUI le muestra es una conjetura. Comprueba la antigüedad del último bloque conocido y, si es (IIRC) hace más de 90 minutos, asume que no está sincronizado. Este suele ser un buen indicador, pero rara vez fallará al azar de vez en cuando.

El código central tiene otra heurística incorporada, que utiliza las alturas de bloque informadas por otros nodos (sin verificar esa información de ninguna manera, por lo que es fácil de engañar). Esta información se utiliza para determinar si debe optimizar el comportamiento de la memoria caché para muchas operaciones rápidas o la confiabilidad. Tampoco está expuesto directamente, pero los RPC getwork() y getblocktemplate() fallarán en este modo.

¿Cuál es el beneficio de la heurística incorporada sobre la verificación de la antigüedad del último bloque conocido?

Bitcoind ya no admite llamadas RPC. Probar:

watch bitcoin-cli getblockchaininfo

Cuando el número mostrado de bloques es igual al número mostrado de encabezados, ¡estás sincronizado!

Esto no parece funcionar en todos los casos. Tengo un nodo de red de prueba bitcoin-abc (BCH) que está sincronizado, pero los encabezados siguen siendo significativamente más grandes que los bloques. Creo que tal vez está obteniendo recuentos de encabezados de los nodos BTC.
@NateEldredge: ¿cómo sabes que está sincronizado?
@MaxVernon: debug.logtiene un UpdateTipmensaje que muestra un bloque con una marca de tiempo reciente, que concuerda con el último bloque mostrado por los exploradores de bloques.
Si pudiera incluir información sobre cómo verificar dos veces usando la edad del último bloque conocido, creo que esta sería la mejor respuesta. Usted sabe que no está actualizado hasta que su último bloque verificado es el mismo que su número de encabezados, pero no sabe muy bien que está actualizado incluso cuando eso sucede hasta que verifica las marcas de tiempo de los bloques frente a la hora de la red (y tu propio tiempo)

Teniendo en cuenta que siempre está algo desincronizado, así es como puede calcular cuánto tiempo en segundos, y luego puede dividirlo por 60 o 3600 para obtenerlo en minutos u horas.

Si quieres hacerlo manualmente:

# bitcoin-cli getblockcount
2345
# bitcoin-cli getblockhash 2345
000000007024f233aa44bc7784a78926fb1c325f9985c936ae57b94530505062
# bitcoin-cli getblock 000000007024f233aa44bc7784a78926fb1c325f9985c936ae57b94530505062 | grep "time"
    "time" : 1233313208,
# echo $((`date +%s`-1233313208))
<number of seconds>

O lo mismo en dos pasos

bitcoin-cli getblock `bitcoin-cli getblockhash \`bitcoin-cli getblockcount\`` | grep time
    "time" : 1233313208,
echo $((`date +%s`-1233313208))
<number of seconds>

No encontré una manera de hacerlo en una sola llamada, así que aquí hay un script que hace todo, sin verificar errores, como puede ver:

#!/bin/bash
cnt=`bitcoin-cli getblockcount`
hash=`bitcoin-cli getblockhash ${cnt}`
timeline=`bitcoin-cli getblock $hash | grep '"time"'`
ltrimtime=${timeline#*time\" : }
newest=${ltrimtime%%,*}
echo $((`date +%s`-$newest))

Entonces puedes reemplazar

echo $((`date +%s`-$newest))

Para obtener el número de minutos así:

echo $(((`date +%s`-$newest)/60))

O el número de horas así:

echo $(((`date +%s`-$newest)/3600))

O, suponiendo que tiene perl (que probablemente tenga) y que prefiere tener la fecha del último bloque:

perl -le "print scalar localtime $newest;"
El tiempo que está en el bloque es el tiempo que informó un minero, aunque probablemente esté cerca del tiempo correcto, puede que no sea correcto. Ver esta pregunta .
Estoy tratando de usar este método para determinar la edad del bloque más nuevo en la cadena de mi billetera, para estimar la actualización. a través de llamadas RPC, ejecuto getblockcounty devuelve el número de bloque. Luego corro getblockhash $counta buscar el hachís. Todo parece ir bien. Pero luego, cuando lo ejecuto getblock $hash, arroja un error de análisis cada vez (-32700). ¿Alguna idea sobre por qué? A pesar de mis variables en este comentario, he confirmado que los comandos que se envían son correctos. Por ejemplo: getblock 000000000000000000114801309313f1fa84f8ce4e6f6e0bcc23eea91aeca343arroja un error de análisis :(

Actualización 7 de agosto de 2015 ~ inicio

Entonces, después de tener una IP o dos prohibidas debido a la frecuencia de verificación... entonces, proporcionaré algunas opciones sobre cómo evitar la prohibición. Primero, no use el script en esta actualización; las preformas de Bash de expansión variable provocan múltiples llamadas a https://blockchain.info en poco tiempo. Puede intentar agregar sleep 120entre la asignación y las llamadas, pero eso sería muy lento. En segundo lugar, las cosas clave son; Comprobación del recuento local $(bitcoin-cli getblockcount)y Comprobación de un nodo conocido $(wget -q -O - http://blockchain.info/q/getblockcount)y Comprobación del estado de sincronización local$(bitcoin-cli getblocktemplate)

Para combinar el Blockchain de tu nodo a otro en una línea

$($(wget -q -O - http://blockchain.info/q/getblockcount)-$(bitcoin-cli getblockcount))
# To print this with echo and date stamp
echo "    $(date) : $($(wget -q -O - http://blockchain.info/q/getblockcount)-$(bitcoin-cli getblockcount))"
# To redirect and exit with 0 : ie place in crontab
echo "$($(wget -q -O - http://blockchain.info/q/getblockcount)-$(bitcoin-cli getblockcount))" > /var/log/btc_blocks_left_to_sync.log 2>&1

El último de arriba es probablemente el mejor para las secuencias de comandos, ya que el archivo en el que se guarda se puede leer solo por el número que contiene o la última vez que se modificó.

Actualización 7 de agosto de 2015 ~ fin

De hecho, la llamada de función correcta se muestra allí, @BinaryMage, gracias.

posible duplicado de Cuando descargo la cadena de bloques por primera vez, ¿cómo sé cuándo ha terminado? agregado 04 Abril 2013 en el 0:50, el autor BinaryMage, fuente

La persona que mostró la función correcta fue @LoHoris, sin embargo, las actualizaciones del software del nodo de Bitcoin ahora se usan bitcoin-cli getblocktemplatey no bitcoindpara estas búsquedas.

Gracias a ambos, es posible ofrecerles a todos una combinación de ambas respuestas envueltas en un script de verificación; listo para su personalización y actualizado para el año 2015


    #!/bin/bash
    timed_wait=600
    vars_to_load(){
        ## Set vars to function such that they are set upon every call
        localCheck=$(bitcoin-cli getblockcount)
        crossCheck=$(wget -q -O - http://blockchain.info/q/getblockcount)
        diffBlocks=$(($crossCheck-$localCheck))
        localSize=$(ls -hal ~/.bitcoin/blocks | awk '/total/{print $2}')
    }
    check_sync(){
        while true
        do
            current_time=$(date)
            echo $current_time
            bitcoin-cli getblocktemplate
            if [ $? = 0 ]
            then
                echo "All synced up"
            else
                echo "Uh oh, running available checks"
                ## call function that runs it all on a timer
                networked_sync
                echo "Node has $localCheck of $crossCheck blocks available."
                echo "Size of local blockchain is $localSize"
            fi
            echo "Sleeping for $timed_wait seconds or $(($timed_wait/60)) minuets."
            sleep $timed_wait
        done
    }
    networked_sync(){
        vars_to_load
        ## Function to print difference in node sync
        if [ $diffBlocks -eq 0 ]
        then
            echo "Sync is good with $diffBlocks blocks off"
        else
            echo "Sync has $diffBlocks blocks left to download"
        fi
    }
    check_sync

Este script primero verifica el estado de salida bitcoin-cli getblocktemplateporque cualquier cosa que no 0sea un error generalmente ejecutará las otras partes solo si bitcoin-cli getblocktemplatemuestra un error. Por supuesto, es posible verificar códigos de error específicos en su lugar y hacer cosas para códigos de error específicos... pero esto funciona bien como plantilla para mí cuando configuro nodos BTC en un entorno sin cabeza. Las otras comprobaciones luego comparan el conteo de bloques locales con https://blockchain.info e imprimen cuántos bloques está apagado su sistema. Estos solo se ejecutan cuando se verifica el error de estado de sincronización local, por lo tanto, si está en un estado más lento como @Steven Roose mencionado, entonces este script es ideal.

De forma predeterminada, el tiempo de espera entre comprobaciones es 600de segundos (10 minutos) para mantener al mínimo las comprobaciones de red y las comprobaciones locales; sin embargo, para el registro y una mejor gestión de recursos, es bastante fácil comentar las líneas while, doy doney sleep $timed_wait. Y agregue una línea a crontab para lograr la ejecución según un cronograma. Modifique por última vez el final del script para escribir la salida en un archivo.


La función modificada;

    check_sync(){
    #   while true
    #   do
            current_time=$(date)
            echo $current_time
            bitcoin-cli getblocktemplate
            if [ $? = 0 ]
            then
                echo "All synced up"
            else
                echo "Uh oh, running available checks"
                ## call function that runs it all on a timer
                networked_sync
                echo "Node has $localCheck of $crossCheck blocks available."
                echo "Size of local blockchain is $localSize"
            fi
            echo "Sleeping for $timed_wait seconds or $(($timed_wait/60)) minuets."
    #       sleep $timed_wait
    #   done
    }

Y correr cada 10 minutos

    sudo nano /etc/crontab
        */10 *  * * *   root    /pathTo/script.sh 2>&1

Luego, para habilitar el registro, modifique la llamada que inicia todo dentro del script;

    check_sync | tee -a /tmp/BTCsync_log.txt

Con suerte, esta es una respuesta lo suficientemente aceptable como para marcar esta pregunta como [Resuelta] de modo que los futuros buscadores web puedan tener esto más fácil.

No veo ninguna respuesta trivial aquí. Esto es lo que hice.

Use API CALL "getblockchaininfo" El parámetro "verificationprogress" será ~= 1.0, si está sincronizado.

Advertencia: esto parece estar basado en el tiempo, su reloj deberá ser algo preciso.

Verifico que sea >= 0.999 para determinar si estoy sincronizado.

Esto parece una forma bastante simple y lógica de determinar esto. ¿Alguna segunda o tercera opinión sobre el uso de este método? ¿Peligros potenciales?

Un poco raro, pero el registro de depuración muestra su "progreso" en lo que respecta a bitcoind.

tail -n 1 ~/.bitcoin/debug.log

te da algo como

2016-04-26 19:02:21 UpdateTip: new best=000000000000000002a9b8f81c231c99b86f79fae383fb1fc046974f7fdcf118  height=405098  log2_work=84.399379  tx=119389857  date=2016-03-31 10:06:53 
progress=0.982752  cache=0.5MiB(0tx)

En este caso, estoy 98 por ciento "hecho".

Aquí hay algunas soluciones ingeniosas, y tal vez esto sea demasiado simple, pero, si se está poniendo al día legítimamente con la cadena de bloques y no básicamente al final, por lo que solo obtiene ese nuevo bloque una vez cada ~ 10 minutos, mire su uso de la CPU.

Si está en Linux, ejecute "top". bitcoind trabajará duro calculando cada hash de cada bloque a través de la cadena de bloques. Una vez que se pone al día, está básicamente inactivo.

No funciona cuando su conexión a Internet tiene problemas. O cuando su conexión es simplemente lenta. bitcoind itera entre descargar bloques y verificarlos, por lo que en un período de descarga y conexión lenta, el uso de la CPU también será bajo.
Sí, eso es verdad. Si tiene una conexión a Internet lo suficientemente lenta como para que su CPU solo esté ocupada procesando cada 10 minutos más o menos, no puede notar la diferencia entre ese problema y realmente estar atrapado. Sin embargo, nunca se pondrá al día si no supera la velocidad a la que se crean los bloques. Incluso si solo ve actividad una vez por minuto, sigue siendo una clara indicación de que se está poniendo al día. Una vez que estés al día, solo tendrás actividad real una vez cada 10 minutos.

Ingrese el siguiente script en su archivo /home/$USER/.bashrc y reinicie su shell.

alias bitcoindSynced='

bitcoindSynced() {
blockCount=`bitcoind getblockcount`
blockChain=`wget -O - http://blockchain.info/q/getblockcount`
blockDiff=`expr $blockChain - $blockCount`

if [ $blockDiff = 0 ]
then
    echo "up to date"
else
    echo "$blockDiff blocks behind"
fi
}

bitcoindSynced 2>/dev/null'

Luego, cuando ejecutas el comando

bitcoindSynced

se le proporcionará la cantidad de bloques que quedan por sincronizar,
o si su cliente está actualizado, se lo hará saber.


Además, si no desea reiniciar su shell, puede ejecutar el comando

source /home/$USER/.bashrc

y hará lo mismo.

Esa es una forma realmente extraña de hacer una definición de función bash.
Y tengo problemas para creer que así es como lo hace el cliente Bitcoin-Qt...
¿Como lo harias? Se alisa porque necesita llamar a la función después con '2>/dev/null' después de definirla y no puede hacerlo dentro de la función o se repetirá para siempre cuando se inicie el shell. No soy un gurú de Linux, si hay una forma correcta de hacerlo, por favor enséñame :)
Además, no es así como lo hace el cliente Bitcoin-Qt, es un truco para el demonio bitcoind.

Más rudimentario pero útil para saber si el monedero está sincronizado o no

Mediante el uso de los comandos:

  • "getinfo" (indique la altura de su bloque actual)
  • "getpeerinfo" (indique la altura del bloque con el campo "altura inicial" para cada conexión).

Luego, puede comparar fácilmente los valores y averiguar cuánto porcentaje tiene para descargar la cadena de bloques.

Por getinfosupongo que te refieres getblockchaininfo. Si eso es cierto, esto no parece funcionar ya que el número medio de los compañeros en este momento es 637967, pero getblockchaininfome muestra que tiene 637974 bloques. Así que estoy mágicamente por delante de todos mis compañeros. Algo no está bien con este método.