provable-things/ethereum-api

Random number proof verification fails if delay is set

Closed this issue · 11 comments

If oraclize_newRandomDSQuery(delay, N, callbackGas); is executed with a delay different than 0, when the callback is fired, the oraclize_randomDS_proofVerify__returnCode call will fail verification of proof.

The expected behavior would be for the callback to properly verify the random number generated even if it was delayed.

Tested on ropsten. Here's the code to reproduce it.
call scheduleRandomNumOnCreation(0); and it will work properly. -reaches event Testeo(2014)-
call scheduleRandomNumOnCreation(30); and the callback will fail the proof verification

pragma solidity ^0.4.4;

import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";

contract Raffle is usingOraclize{

  event Testeo(uint _number);

  function Raffle(){
    scheduleRandomNumOnCreation(0);
  }

   function __callback(bytes32 _queryId, string _result, bytes _proof)
  {
      Testeo(1022);
      // If we already generated a random number, we can't generate a new one.
      // if we reach this point successfully, it means that the attached authenticity proof has passed!
      require (msg.sender == oraclize_cbAddress());

      //Before using the random number we have to check if the minimum amount of participants was reached.
      //If not, we should abort. LATER, when dealing with money, we should also return funds to the participants.

      if (oraclize_randomDS_proofVerify__returnCode(_queryId, _result, _proof) != 0) {
        Testeo(1023);
          // the proof verification has failed, do we need to take any action here? (depends on the use case)
      } else {
          // the proof verification has passed
          Testeo(1024);
          // for simplicity of use, let's also convert the random bytes to uint if we need
          uint maxRange = 100; // this is the highest uint we want to get. It should never be greater than 2^(8*N), where N is the number of random bytes we had asked the datasource to return
          uint randomNumber = uint(sha3(_result)) % maxRange; // this is an efficient way to get the uint out in the [0, maxRange] range
          Testeo(randomNumber);
      }
    }

  function scheduleRandomNumOnCreation(uint _timeFromNow) internal{
    //Called on raffle constructor only
    oraclize_setProof(proofType_Ledger); // sets the Ledger authenticity proof in the constructor
    uint N = 4; // number of random bytes we want the datasource to return
    uint delay = _timeFromNow; // number of seconds to wait before the execution takes place
    uint callbackGas = 200000; // amount of gas we want Oraclize to set for the callback function
    bytes32 queryId = oraclize_newRandomDSQuery(delay, N, callbackGas); // this function internally generates the correct oraclize_query and returns its queryId
    
  }
  
}

Good catch, this is due to a missing implementation in the Solidity verification function of the time delay option (when it is != 0). Let's keep this issue open to keep track of the progress: we will update the Solidity verification function soon to support any delay.

Any news?

I'm also wondering whether this has been fixed yet since I need this functionality.

@quantum13 @borisblizzard by using the latest version of the oraclizeAPI you will be able to set a randomDS delay up to 120 seconds (~8 blocks on mainnet). This is already quite a stronger guarantee compared to having 0 delay (default). If you need to schedule the query for a future execution you can still call oraclize_query with a non-zero first argument.

I hope this answers to your question, let us know if you need anything else!

Actually I noticed that rand stopped working on Rinkeby myself. Main net still works fine.

Not working on Rinkeby, I am suing Oraclize 'RandomExample' and the proof fails all the time, but the ether is deducted from my account!!. Also, I am a bit concern about the amount of gas that takes to deploy the contract, It hits the limits and is impossible to deploy the contract as it is, I had to remove the call to update in the constructor to be able to deploy the contract.

I am also finding it isn't working on Rinkeby even when set to 0. Always failing the proof verification.

The Random DS on Rinkeby is confirmed to be working now. Please try again.

Specifically in regards to Rinkeby, it appears to work with up to a 54 second delay.

Hello!
I am fighting with randomness error for a day already...

  1. I have set up oraclize-truffle-box from here - https://github.com/oraclize/truffle-starter
  2. unit tests works fine;
  3. edited my code for randomness with "oraclize_newRandomDSQuery"
  4. run unit tests - fails.
    4.1. run my code in Remix with "remixd" - works.
  5. changed query to - "oraclize_query("URL", "xml(https://www.fueleconomy.gov/ws/rest/fuelprices).fuelPrices.diesel");" - works;
  6. again changed to - "oraclize_query("URL", "json(https://api.kraken.com/0/public/Ticker?pair=ETHXBT).result.XETHXXBT.c.0");" - works again;
  7. edited "N", "delay", "callbackGas" in "oraclize_newRandomDSQuery" - nothing works...

why is that..?
screen shot 2019-03-05 at 18 46 12

@VanijaDev Are you trying to run that from the Javascript VM of Remix? The random DS only works on mainnet and public testnets as per: https://github.com/oraclize/ethereum-examples/tree/master/solidity/random-datasource