Skip to content
Snippets Groups Projects
Commit ac324552 authored by Miguel Montes's avatar Miguel Montes
Browse files

Versión inicial de sealer_status

parent 8787a396
No related branches found
No related tags found
No related merge requests found
# Sealer status
Se trata de dos _scripts_ que reportan la última aparición de cada uno de los selladores, buscando en los últimos bloques de la cadena hasta un cierto máximo (por default 720 bloques, es decir una hora).
## `sealer_status.js`
Escrito en JavaScript, puede ejecutarse desde la consola JavaScript de `geth`.
Por ejemplo, en una instalación típica de BFA:
```
bfa@bootnode:~$ geth attach ipc:/home/bfa/bfa/network/node/geth.ipc --exec 'loadScript("sealer_status.js")'
9b3ac6719b02ec7bb48: 466728
998c2651db6f76ca568: 466727
c0310a7b3b25f49b11b: 466726
609043ebde4a06bd28a: 466725
46991ada2a2544468eb: 466724
91c055c6478bd0ad6d1: 466723
39170a1ce03729d141d: 466722
2feb6a8876bd9e2116b: 466721
19fe7b9b3a1bebde77c: 466720
342e1d075d820ed3f9d: -1
true
bfa@bootnode:~$
```
Para cada sellador reporta el último bloque que selló. Si un sellador no apareció en los últimos 720 bloques, reporta -1.
## `sealer_status.py`
Este es un _script_ escrito en Python, que requiere Python 3 y la biblioteca web3 (que puede instalarse con `pip`).
Para funcionar requiere conocer el directorio donde está el _socket_ `geth.ipc` (asume que es `${BFANETWORKDIR}/node/geth.ipc` o, en su defecto `~/bfa/network/node/geth.ipc`), y el puerto RPC (asume que es el 8545). Ambos valores pueden especificarse en la línea de comandos.
El control de errores es nulo. Cualquier error de conexíón con `geth` producirá un _stacktrace_.
```
bfa@bootnode:~$ bfa/src/sealer_status.py --help
usage: sealer_status.py [-h] [-n N] [-b] [--ipc-path IPC_PATH]
[--rpc-port RPC_PORT]
Muestra la cantidad de bloques transcurridos desde la ultima aparición de cada
uno de los selladores de la BFA. Si un sellador no ha aparecido por un cierto
tiempo (por default 1 hora) imprime -1.
optional arguments:
-h, --help show this help message and exit
-n N Máxima cantidad de bloques a recorrer. Default: 720 (1
hora)
-b, --blockNumber Muestra el número de bloque en lugar de la cantidad de
bloques transcurridos
--ipc-path IPC_PATH Path del archivo geth.ipc. Default:
/home/bfa/bfa/network/node/geth.ipc
--rpc-port RPC_PORT Puerto RPC. Default: 8545
bfa@bootnode:~$ bfa/src/sealer_status.py
c0310a7b3b25f49b11b: 0
9b3ac6719b02ec7bb48: 1
46991ada2a2544468eb: 2
39170a1ce03729d141d: 3
91c055c6478bd0ad6d1: 4
609043ebde4a06bd28a: 5
19fe7b9b3a1bebde77c: 6
2feb6a8876bd9e2116b: 9
998c2651db6f76ca568: 10
342e1d075d820ed3f9d: -1
(web3py) bfa@bfa-3:~$ bfa/src/sealer_status.py -b
998c2651db6f76ca568: 466927
c0310a7b3b25f49b11b: 466926
9b3ac6719b02ec7bb48: 466925
46991ada2a2544468eb: 466924
39170a1ce03729d141d: 466923
91c055c6478bd0ad6d1: 466922
609043ebde4a06bd28a: 466921
19fe7b9b3a1bebde77c: 466920
2feb6a8876bd9e2116b: 466917
342e1d075d820ed3f9d: -1
bfa@bootnode:~$
\ No newline at end of file
function vanity2address(vanity){
var address = "";
for (i = 0; i < 38; i+=2)
address += String.fromCharCode(parseInt(vanity.substr(i,2),16));
return address;
}
function address2vanity(address){
var vanity = "";
for (i = 0; i < 19; i++)
vanity += address.charCodeAt(i).toString(16);
return vanity;
}
function blockSigner(blockNumber){
return eth.getBlock(blockNumber).extraData.substr(2,38);
}
function getSigners(){
var signers = clique.getSigners();
var dict = {};
for (var i = 0; i < signers.length; i++){
dict[address2vanity(signers[i].substr(2,19))] = true;
}
return dict;
}
function lastSeen(){
var signers = getSigners();
var last = eth.blockNumber;
for(var i = 0; i < 720; i++){
if (Object.keys(signers).length == 0) break;
var block = last - i;
var signer = blockSigner(block);
if (signer in signers){
console.log(vanity2address(signer)+": "+block);
delete signers[signer];
}
}
for (signer in signers)
console.log(vanity2address(signer)+": -1");
}
lastSeen();
#!/usr/bin/env python3
from os import environ
ipc_path = "{}/node/geth.ipc".format(environ.get('BFANETWORKDIR', "~/bfa/network"))
rpc_port = 8545
rpc_host = "localhost"
import requests
from web3 import Web3, IPCProvider
from web3.middleware import geth_poa_middleware
import argparse
def getSigners():
session = requests.Session()
payload = {"jsonrpc":"2.0", "method":'clique_getSigners',"params":[],"id":1}
headers = {'Content-type':'application/json'}
response = session.post(
"http://{}:{}".format(rpc_host,rpc_port),
json=payload,
headers=headers)
return response.json()['result']
def lastSeen(n = 720, use_block_number = False):
last = w3.eth.blockNumber
signers = set(map(lambda x: x[2:21],getSigners()))
for i in range(n):
if not signers: break
block = last - i
address = w3.eth.getBlock(block).proofOfAuthorityData[:19].decode('ascii')
if address in signers:
print("{}: {}".format(address, block if use_block_number else i))
signers.remove(address)
for address in signers:
print("{}: -1".format(address))
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=
"""Muestra la cantidad de bloques transcurridos desde la ultima aparición
de cada uno de los selladores de la BFA. Si un sellador no ha aparecido por
un cierto tiempo (por default 1 hora) imprime -1.""")
parser.add_argument("-n", help='Máxima cantidad de bloques a recorrer. Default: 720 (1 hora)',type=int, default=720)
parser.add_argument("-b", "--blockNumber", help="Muestra el número de bloque en lugar de la cantidad de bloques transcurridos", action="store_true")
parser.add_argument("--ipc-path", help ="Path del archivo geth.ipc. Default: {}".format(ipc_path))
parser.add_argument("--rpc-port", help ="Puerto RPC. Default: {}".format(rpc_port),type=int)
args = parser.parse_args()
if args.ipc_path:
ipc_path = args.ipc_path
if args.rpc_port:
rpc_port = args.rpc_port
w3 = Web3(Web3.IPCProvider(ipc_path))
w3.middleware_stack.inject(geth_poa_middleware, layer=0)
lastSeen(args.n, args.blockNumber)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment