Implementación de pruebas de callback de Oracle con Truffle/Mocha

Estoy tratando de escribir pruebas en Mocha/JS con Truffle para una función de Solidity que usa Oracle. Quiero probar si el resultado de la devolución de llamada de mi consulta de Oracle es correcto. Como Oraclize necesita algo de tiempo para procesar la consulta, debo esperar la respuesta de la transacción. En este momento estoy logrando esto con una setTimeoutfunción para esperar la transacción de devolución de llamada. Establecer un tiempo de espera puede requerir que espere más de lo necesario o incluso hacer que la prueba falle si el tiempo de espera es demasiado bajo. ¿Hay una mejor manera de lograr esto?

Estoy usando Truffle 3.2.1 con TestRPC 3.0.5 y ethereum-bridge 0.4.21.

Aquí está el fragmento de código de prueba JS:

it("Request computation and send results to Arbiter", function(done) {
  this.timeout(250000);
  var computation;
  var result;
  ComputationService.deployed().then(function(instance) {
    computation = instance;
    return computation.compute("43543", "423543543", 0, 56347573485346, {from:accounts[0], gas: 500000, value: web3.toWei(0.01, "ether")});
  }).then(function(){
    return new Promise(resolve => setTimeout(resolve, 240000));
  }).then(function(){
    return computation.getResult(56347573485346);
  }).then(function(value){
    result = value;
    assert.equal(result, "18442356492849", "The result is wrong (should be 18442356492849)");
    done();
  });
});

Esta es la función de devolución de llamada de Solidity con un newResultevento:

function __callback(bytes32 _oraclizeID, string _result) {
  if (msg.sender != oraclize_cbAddress()) throw;
  newResult(_result);
  requestOraclize[_oraclizeID].result = _result;
}

Respuestas (1)

Podría crear una función que cree una vigilancia de filtro para nuevos tx-s desde la dirección CB de Oracle. Esa función podría resolverse cuando un nuevo tx de la dirección cb de Oraclize coincida con sus criterios.

Aquí hay un ejemplo que creé para un requisito ligeramente diferente (es decir, esperar a que la marca de tiempo del bloque alcance una cierta marca de tiempo), pero podría construir a partir de ella.

var moment = require('moment');

function waitForTimeStamp(waitForTimeStamp) {
    var currentTimeStamp = moment().utc().unix();
    var wait =  waitForTimeStamp - currentTimeStamp;
    wait = wait < 0 ? 0 : wait;
    console.log("... waiting ", wait, "seconds then sending a dummy tx for blockTimeStamp to reach time required by test ...");

    return new Promise( resolve => {
            setTimeout(function () {
                var blockTimeStamp = web3.eth.getBlock( web3.eth.blockNumber).timestamp;
                if( blockTimeStamp < waitForTimeStamp ) {
                    web3.eth.sendTransaction({from: web3.eth.accounts[0]}, function(error, res) {
                        if (error) {
                            console.log("waitForTimeStamp() web3.eth.sendTransaction() error")
                            reject(error);
                        } else {
                            resolve();
                        }
                    });
                } else {
                    resolve();
                }
            }, wait * 1000);
    });

} // waitForTimeStamp()

it("should happen in the future", () => {
    //  your instance setup here...

    return myInstance.myTransaction()
    .then( res => {
        var waitLength = res; // in seconds
        var waitUntil = moment().utc().unix() + waitLength;
        return waitForTimeStamp(waitUntil);
    }).then( res => { 
        done();
    });
});