trufflesuite / truffle-artifactor

A contract packager for Ethereum and Javascript (formerly ether-pudding)
MIT License
253 stars 54 forks source link

Endless RPC Call loop on return #5

Closed mhhf closed 9 years ago

mhhf commented 9 years ago

Setup: web3: 0.12.0 pudding: 0.10.0 testrpc: 0.1.14

I've got a problem with the following contract:

contract Store {
  uint value;

  function Store(){
    value = 9;
  }

  function query() constant returns (uint val) {
    return value;
  }
}

and the following JS Code:

Store
  .new({ from: web3.eth.coinbase, data: Store.binary })
  .then( function( instance ){
    return instance.query();
  }).then(function( v ){
    console.log( v );
  });

The strange thing is: as log as the value in Store is set to 0-9, Pudding shows the behavior described here: https://github.com/ConsenSys/ether-pudding/issues/4 If the value is set to 10 and above. Pudding works fine. This is probably caused here: https://github.com/ConsenSys/ether-pudding/blob/master/build/ether-pudding.js#L244 as the response( tx ) is an BigNumber Object and not a transaction hash. But I have still to figure out why this works with value=10

tcoulter commented 9 years ago

Hi Denis, try this:

Instead of passing your binary in the new function, put it in Pudding.whisk(), i.e.,:

Store = Pudding.whisk(abi, binary);

However, since you seem to already have the binary (Store.binary), I believe that to have already been done for you. So, your new call should now look like this:

Store.new({from: address}).then(function(instance) {});

I'm not sure why specific numbers worked for you and others didn't, but if you still have the problem after the above changes I'll take another look.

mhhf commented 9 years ago

No luck with this one. Still the same behavior. Here is a minimal example in truffle: https://github.com/mhhf/pudding_minierror truffle test never stops running and the script in browser shows the same looping behavior.

tcoulter commented 9 years ago

Ah, I didn't realize you were using Truffle. Just make it this then. No need to call Pudding.whisk() yourself or pass a coinbase address in the from field.

    Store
      .new()
      .then( function( instance ){
        return instance.query();
      }).then(function( v ){
        console.log( v );
      });
mhhf commented 9 years ago

Changed the code. But it still be behaves the same.

mhhf commented 9 years ago

The problem was caused, because the function querry was declared as constant so they didn't created a transaction and didn't return a hash. But it seems that here every function is synchronized which causes an infinite loop here because the return value isn't a transaction.

I created a pull request, which solves this issue.

tcoulter commented 9 years ago

@mhhf I can't believe I didn't notice this earlier. Can you call instance.query.call() instead of instance.query()? Calling instance.query() will treat the function as a transaction, which you don't want and won't be able to get the return value.

So, try this:

Store
      .new()
      .then( function( instance ){
        return instance.query.call();
      }).then(function( v ){
        console.log( v );
      });
mhhf commented 9 years ago

Ah! .call() works. Tank you!

Are there cases where I want to treat a constant function like a transaction?

tcoulter commented 9 years ago

None that I can think of. Except it might be nice not to have to call .call() as it's not obvious. Will think a lot about the PR you submitted, as it sounds like a good addition.