A partir de ahora, el minero geth que se ejecuta en mi sistema extrae incluso bloques vacíos. Todo lo que quería es que el minero debe minar solo cuando hay Transacciones para minar, después de minar, el minero debería dormir inmediatamente.
¿Cómo lograr esto?
Puedes cargar este script en tu consola geth
var mining_threads = 1
function checkWork() {
if (eth.getBlock("pending").transactions.length > 0) {
if (eth.mining) return;
console.log("== Pending transactions! Mining...");
miner.start(mining_threads);
} else {
miner.stop();
console.log("== No transactions! Mining stopped.");
}
}
eth.filter("latest", function(err, block) { checkWork(); });
eth.filter("pending", function(err, block) { checkWork(); });
checkWork();
Vea otros fragmentos útiles aquí
Minería hasta que se hayan logrado x confirmaciones
Esta pregunta es particularmente relevante para las cadenas privadas donde las transacciones pueden ser más esporádicas que en las cadenas públicas. En algunas aplicaciones, puede ser beneficioso continuar con la extracción de un número determinado de bloques después de la última transacción para garantizar que se alcancen las confirmaciones adecuadas antes de que se detenga la extracción y evitar que la última transacción solo reciba una confirmación (por ejemplo, cuando se usa mist en redes privadas, le gusta ver 12 confirmaciones):
var mining_threads = 1
var txBlock = 0
function checkWork() {
if (eth.getBlock("pending").transactions.length > 0) {
txBlock = eth.getBlock("pending").number
if (eth.mining) return;
console.log(" Transactions pending. Mining...");
miner.start(mining_threads)
while (eth.getBlock("latest").number < txBlock + 12) {
if (eth.getBlock("pending").transactions.length > 0) txBlock = eth.getBlock("pending").number;
}
console.log(" 12 confirmations achieved; mining stopped.");
miner.stop()
}
else {
miner.stop()
}
}
eth.filter("latest", function(err, block) { checkWork(); });
eth.filter("pending", function(err, block) { checkWork(); });
checkWork();
Esto también puede guardarse como un script .js y precargarse usando la función --preload al iniciar geth:
geth --preload "/path/to/mineWhenNeeded.js"
Si está utilizando geth POA, puede establecer el período de sellado del bloque en 0 en el archivo de génesis, esto forzará automáticamente a geth a crear solo un nuevo bloque cada vez que haya una transacción en la red.
geth
registros cuando las transacciones están pendientes.En POA, en continuación a la respuesta de @ jadd22, durante la migración de trufas nos enfrentamos al siguiente problema.
https://github.com/trufflesuite/truffle/issues/853
Para superar esto, podemos ejecutar suficientes números de transacciones ficticias de forma asincrónica, {from:"0xAcc1",to:"0xAcc1",value:0} para garantizar el éxito de la implementación.
Después de la implementación, todas las demás operaciones se llevan a cabo según sea necesario, es decir, la extracción ocurre solo cuando hay transacciones pendientes. Sin generación innecesaria de bloques vacíos.
Podemos usar "clique.period" dentro del archivo genesis.json a cero, como se indica a continuación, para garantizar la extracción solo cuando sea necesario sin generar bloques vacíos. (Solo para POA)
clique": {
"period": 0,
"epoch": 30000
},
Solo necesitamos manejar la migración de trufas con algunas transacciones ficticias. Espero que esto no sea necesario si la implementación de los contratos se realiza mediante programación utilizando compiladores web3 y solc.
Si usa PoW, puede modificar el código Go en
consenso/ethash/sealer.go
y agregue una condición para rechazar el sello si no hay transacciones:
// Seal implements consensus.Engine, attempting to find a nonce that satisfies
// the block's difficulty requirements.
func (ethash *Ethash) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) {
.....
if len(block.Transactions()) == 0 {
log.Info("Sealing paused, waiting for transactions")
return nil, nil
}
.....
Después de eso, ejecute make geth
para regenerar los ejecutables con el nuevo código.
Estaba usando la respuesta de @niksmac para minar hasta que se lograron n confirmaciones, pero el ciclo while causó un uso de CPU muy alto (más del 110%). Lo cambié por un intervalo y ahora el uso de la CPU está por debajo del 5%. Compruebo cada 600 ms, pero cualquier número que sea < tiempo de bloque funcionaría.
var minimum_confirmations = 3;
var mining_threads = 1
var txBlock = 0
function checkWork() {
if (eth.getBlock("pending").transactions.length > 0) {
txBlock = eth.getBlock("pending").number
if (eth.mining) return;
console.log(" Transactions pending. Mining...");
miner.start(mining_threads)
interval = setInterval(function () {
if (eth.getBlock("latest").number < txBlock + minimum_confirmations) {
if (eth.getBlock("pending").transactions.length > 0) txBlock = eth.getBlock("pending").number;
} else {
console.log(minimum_confirmations + " confirmations achieved; mining stopped.");
miner.stop()
clearInterval(interval);
}
}, 600)
}
}
eth.filter("latest", function (err, block) { checkWork(); });
eth.filter("pending", function (err, block) { checkWork(); });
checkWork();
admin.sleep(1)
para dormir por 1 segundoPuede instalar eth-mine-when-need . Que inicia un cliente web3 y escucha eventos. Cuando haya transacciones pendientes o transacciones aún por confirmar, iniciará el minero hasta que se confirmen. Funciona igual que la respuesta de @niksmac. Pero no tiene que ejecutar el script cada vez que inicia eth
y le permite especificar la cantidad de subprocesos para la minería y la cantidad de bloques que se necesitan para decir que una transacción está confirmada al pasar esos valores como argumentos (para detalles puede ver el archivo Léame en npm
).
jeffrey w.
niksmac
Subhod I
checkWork=null
tobías
admin.sleep()
pero esto parece no funcionar. La minería se realiza al instante.niksmac
tobías
0TTT0