Forma óptima de esperar a que se extraigan las transacciones en geth

Actualmente estoy comprobando si se ha extraído una transacción usando la siguiente función (usando web3.js ):

function waitForTx(tx_hash) {
        var result = null;

        // This is not really efficient but nodejs cannot pause the running process
        while(result === null) {
            result = web3.eth.getTransactionReceipt(tx_hash);
        }
    }

¿Hay alguna manera de evitar el bucle de bloqueo?

Respuestas (4)

Xavier tiene una buena solución con ejemplos de uso claros aquí: https://gist.github.com/xavierlepretre/88682e871f4ad07be4534ae560692ee6 . Obtiene un recibo de transacción disponible. Esta es una solución sin bloqueo, por lo que el subproceso de javascript no se atasca mientras espera que se devuelva la promesa.

Está bien resuelto usando promesas e implementado como una extensión de web3. Incluya el código en getTransactionReceiptMined.js palabra por palabra. Luego, interactúe con él como en sus ejemplos... extracto destacado a continuación.

Envía una transacción y obtiene el hash de la transacción (rápido), luego llama a su función para configurar una promesa de esperar a que se extraiga la transacción (tiempo de bloque). Luego, ejecute su código con su recibo de transacción extraído.

Tomado de su ejemplo (con comentario agregado):

...
  // do something that sends a transaction 
  return meta.sendCoin(account_two, 6, { from: account_one });
})
.then(function (txnHash) {
  // now you have the unmined transaction hash, return receipt promise
  console.log(txnhash); // follow along
  return web3.eth.getTransactionReceiptMined(txnHash);
})
.then(function (receipt) {
  // now you have the mined transaction receipt as "receipt"
  console.log(receipt); // explore it :-) 
  // carry on with the next step
  return meta.getBalance.call(account_two);
})

Aquí hay una versión ECMAScript 2016 de esperar a que se extraiga un contrato (o cualquier hash de transacción):

// await sleep trick
// http://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

// We need to wait until any miner has included the transaction
// in a block to get the address of the contract
async function waitBlock() {
  while (true) {
    let receipt = web3.eth.getTransactionReceipt(contract.transactionHash);
    if (receipt && receipt.contractAddress) {
      console.log("Your contract has been deployed at http://testnet.etherscan.io/address/" + receipt.contractAddress);
      console.log("Note that it might take 30 - 90 sceonds for the block to propagate befor it's visible in etherscan.io");
      break;
    }
    console.log("Waiting a mined block to include your contract... currently in block " + web3.eth.blockNumber);
    await sleep(4000);
  }
}

waitBlock();
var getPendingTransactions = function (ip, port) {
  var https = 'http://'+ip+':'+port;
  var webPo = new Web3(new web3.providers.HttpProvider(https));
  var n = webPo.txpool.status.pending;
  return n;
};
var pendingCount = 0;
do
{
  // sleep a while;
  pendingCount  = getPendingTransactions(ip,port);
}while(pendingCount ==0)
// confirm transaction has included in blockchain now.

a partir de la versión geth Geth/v1.6.7-stable-ab5646c5/linux-amd64/go1.8.1, tiene la admin.sleepBlocksfunción, que requiere un número entero de bloques para esperar, también admin.sleepque requiere un número de segundos de coma flotante.