Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Issue with contract function call in truffle 4.1.14 #1195

Closed
Bowfish opened this issue Aug 17, 2018 · 7 comments
Closed

Issue with contract function call in truffle 4.1.14 #1195

Bowfish opened this issue Aug 17, 2018 · 7 comments

Comments

@Bowfish
Copy link

Bowfish commented Aug 17, 2018

Issue

I installed truffle 4.1.14. When I run `truffle init' the contracts are deployed correctly, but the migration scripts where I set some contract addresses aborts without any error message after the first contract call. I deleted 4.1.14 again and reinstalled 4.1.13 and everything worked as expected again. It is the same when I call a contract function in my dapp. It executes the first function as expected but, but the second function is called but it is not executed.

Environment

  • Linux:
  • Ethereum client:
  • Truffle version (4.1.14):
  • node version (8.11.3):
  • npm version (6.4.0):
@Bowfish Bowfish changed the title Issue with contract function call in tuffle 4.1.14 Issue with contract function call in truffle 4.1.14 Aug 17, 2018
@cgewecke
Copy link
Contributor

@Bowfish Thanks for reporting.

4.1.14 contains a small of set changes (mostly targeting the debugger). One of them addresses the way truffle commands exit in order to prevent a persistent hanging problem people have seen when using hd-wallet provider. It's possible that there's an issue managing async methods in your code that's been hidden by a bug on our side in previous versions...

  • Could you show the code that's causing this problem or provide reproduction steps? (We have E2E and unit tests that run migrations / testing commands and they're passing in CI).
  • Could you identify your ethereum client?

@Bowfish
Copy link
Author

Bowfish commented Aug 17, 2018

Here is the migration script. It works with 4.1.13 but a soon as I switch to 4.3.14 it will stop at the point where it put the Note. If there is an issue with my async methods I would be grateful if you could point it out.

I use canache v1.2.1

Thanks for you help

var Pilot       = artifacts.require("./Pilot.sol");
var Rating      = artifacts.require("./Rating.sol");
var License     = artifacts.require("./License.sol");
var Logbook     = artifacts.require("./Logbook.sol");
var Medical     = artifacts.require("./Medical.sol");

// Now, configure the deployed contracts.

module.exports = function(deployer) {

  // the contract instances we will need later

  var pilotContract;
  var ratingContract;
  var licenseContract;
  var logbookContract;
  var medicalContract;

  // the trusted contracts

  var pilotLogbookContract;
  var pilotMedicalContract;
  var pilotLicenseContract;
  var ratingLicenseContract;
  var licensePilotContract;
  var licenseRatingContract;
  var logbookPilotContract;
  var medicalPilotContract;

  // instantiate the deployed contracts

  var accounts = web3.eth.accounts;

  console.log(accounts)

  Pilot.deployed()
  .then(function(instance) {
    pilotContract = instance;
    return Rating.deployed();
  })
  .then(function(instance) {
    ratingContract = instance;
    return License.deployed();
  })
  .then(function(instance) {
    licenseContract = instance;
    return Logbook.deployed();
  })
  .then(function(instance) {
    logbookContract = instance;
    return Medical.deployed();
  })

  .then(function(instance) {
    medicalContract = instance;
    return pilotContract.setLogbookContract(logbookContract.address, {from: accounts[0]});
   ///  
   //Note: it executes this function and than terminates the script without an error message
   ///
  })

  // now set the contract addresses so they know each other.
  //

  .then(function(success) {
    console.log("setPilotContract")
    return pilotContract.setMedicalContract(medicalContract.address, {from: accounts[0]});
  })
  .then(function(success) {
    console.log("setPilotContract")
    return pilotContract.setLicenseContract(licenseContract.address);
  })
  .then(function(success) {
    return ratingContract.setLicenseContract(licenseContract.address);
  })
  .then(function(success) {
    return licenseContract.setPilotContract(pilotContract.address);
  })
  .then(function(success) {
    return licenseContract.setRatingContract(ratingContract.address);
  })
  .then(function(success) {
    return logbookContract.setPilotContract(pilotContract.address);
  })
  .then(function(success) {
    return medicalContract.setPilotContract(pilotContract.address);
  })

  // now let's fetch them back

  .then(function(success) {
    return pilotContract.logbookContract();
  })
  .then(function(response) {
    pilotLogbookContract = response;
    return pilotContract.medicalContract();
  })
  .then(function(response) {
    pilotMedicalContract = response;
    return pilotContract.licenseContract();
  })
  .then(function(response) {
    pilotLicenseContract = response;
    return ratingContract.licenseContract();
  })
  .then(function(response) {
    ratingLicenseContract = response;
    return licenseContract.pilotContract();
  })
  .then(function(response) {
    licensePilotContract = response;
    return licenseContract.ratingContract();
  })
  .then(function(response) {
    licenseRatingContract = response;
    return logbookContract.pilotContract();
  })
  .then(function(response) {
    logbookPilotContract = response;
    return medicalContract.pilotContract();
  })
  .then(function(response) {
    medicalPilotContract= response;

    // helpful output

    console.log("");
    console.log("MIGRATION SUMMARY");
    console.log("");
    console.log("Pilot Contract @   ", pilotContract.address);
    console.log(" - logbook @       ", pilotLogbookContract);
    console.log(" - medical @       ", pilotMedicalContract);
    console.log(" - license @       ", pilotLicenseContract);
    console.log("");
    console.log("Rating Contract @  ", ratingContract.address);
    console.log(" - license @       ", ratingLicenseContract);
    console.log("");
    console.log("License Contract @ ", licenseContract.address);
    console.log(" - pilot @         ", licensePilotContract);
    console.log(" - rating @        ", licenseRatingContract);
    console.log("");
    console.log("Logbook Contract @ ", logbookContract.address);
    console.log(" - pilot @         ", logbookPilotContract);
    console.log("");
    console.log("Medical Contract @ ", medicalContract.address);
    console.log(" - pilot @         ", medicalPilotContract);
    console.log("");
    console.log("Compiler warnings about unused vars in abstract interface contracts may be safely ignored.");
    console.log("Done");

  });

 };

@cgewecke
Copy link
Contributor

@Bowfish Could you try wrapping the entire contents of your migration file in a deployer.then block which you return your promise to as below and see if that works? (see this issue comment for another example).

module.exports = function(deployer) {
  deployer.then(function(){
    var pilotContract;
    var ratingContract;
    
    ... etc ...
    return Pilot.deployed()  // <-- Important: return this promise
      .then(function(instance) { 
      ... etc ...
  });

@Bowfish
Copy link
Author

Bowfish commented Aug 17, 2018

@cgewecke That solved the issue.

Nevertheless, I still don't understand why it worked with 4.1.13 without the deployer.then(function() {}) wrapper and it didn't work with 4.1.14. Is this documented anywhere?

Thanks for your support.

@cgewecke
Copy link
Contributor

cgewecke commented Aug 17, 2018

@Bowfish Not sure... it's possible the provider was hanging open and allowing those promises to resolve. The pattern of returning the promise to the deployer is technically 'correct' and should work for all cases though.

FWIW the migrations function and the deployer API has been a source of confusion for many and there have been problems integrating it with async/await as well. We've tried to remedy this for our upcoming Truffle V5 release (available in a pre-release on npm as truffle@next). In the new format the top-level migrations method can be declared async and you can run arbitrary promise logic there without worrying about deployer.then.

Ex:

const One = artifacts.require("One");
const Two = artifacts.require("Two");

module.exports = async function(deployer) {
  await deployer.deploy(One);

  const one = await One.deployed();
  const value = await one.value();

  await deployer.deploy(Two, value);
};

There are draft release notes for V5 (including a list of breaking changes) at PR #1129 .

@cgewecke
Copy link
Contributor

Duplicate of #501.

@Bowfish
Copy link
Author

Bowfish commented Aug 18, 2018

I installed truffle v 5 and it works like a charm. That is a big improvement. Thanks for the good work

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants