trufflesuite / truffle

:warning: The Truffle Suite is being sunset. For information on ongoing support, migration options and FAQs, visit the Consensys blog. Thank you for all the support over the years.
https://consensys.io/blog/consensys-announces-the-sunset-of-truffle-and-ganache-and-new-hardhat?utm_source=github&utm_medium=referral&utm_campaign=2023_Sep_truffle-sunset-2023_announcement_
MIT License
14.02k stars 2.32k forks source link

`truffle compile` throws InternalCompilerError with no description #2849

Open safakoks opened 4 years ago

safakoks commented 4 years ago

Issue

I have tried to create a test of my contract which includes a function returns Struct instance. But, it returns a meaningless error.

Steps to Reproduce

Here's my contract which is created by Solidity v0.6.0

pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;

contract Stack{

    struct Item{
        string  name;
        uint256 quantity;
        bool isSolid;
    }

    mapping(address => Item[]) userItemsMap;

    function addItem(string memory _name, uint256 _quantity, bool _isSolid) public {
        userItemsMap[msg.sender].push(Item({
        name:_name, quantity:_quantity,
        isSolid :_isSolid
            }));
    }

    function getItems() public view returns(Item[] memory){
        return userItemsMap[msg.sender];
    }

    function getLastItem() public view returns(Item memory){
        Item[] memory userItems = userItemsMap[msg.sender];
        require(userItems.length>0);
        return userItems[userItems.length - 1];
    }

}

And its sample test contract :

pragma solidity ^0.6.0;

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/Stack.sol";

contract  TestStackContract{

    function testAddingItem() public {

        Stack stackInstance =  Stack(DeployedAddresses.Stack());

        stackInstance.addItem("Apple",125,true);

        Stack.Item memory lastItem = stackInstance.getLastItem();

        Assert.equal(lastItem.name, "Apple", "Name should be Apple");
    }
}

Expected Behavior

I run truffle test and it should pass the test or return an error message

Actual Results

It returns an InternalCompilerError without any error message

Using network 'development'.

Compiling your contracts...
===========================
> Compiling ./test/TestBiddingContract.sol
> Compiling ./test/TestStack.sol

InternalCompilerError:

Compilation failed. See above.
Truffle v5.1.13 (core: 5.1.13)
Node v8.17.0

Environment

eggplantzzz commented 4 years ago

@safakoks Thanks for reporting this, I'll try and reproduce your error to get to the bottom of this!

eggplantzzz commented 4 years ago

Using Truffle without Geth or Quorum I get the following error

InternalCompilerError: Unknown dynamically sized type: struct Stack.Item memory

It looks like that message comes from the decoder and perhaps Geth/Quorum setups give differently formatted messages? Maybe @haltman-at might understand what is going on here a little bit better than I do.

safakoks commented 4 years ago

Is there any solution for this? Because I could not understand what is wrong and why it happens?

haltman-at commented 4 years ago

InternalCompilerError is a solc error message; it's solc throwing that error, not Truffle. This has nothing to do with the decoder, it's a compilation error.

haltman-at commented 4 years ago

Basically, if you see InternalCompilerError, you should report it to the Solidity team. Unless for some reason compiling those tests only fails in Truffle?

safakoks commented 4 years ago

@haltman-at thanks for your answer, yes it happened because of Solidity. I asked them, why it occurs, they recommend me adding pragma experimental ABIEncoderV2; into Test Contract, It works fine on Remix. But still, truffle does not accept the contract during truffle test

It returns the same error without any message :

Using network 'development'.

Compiling your contracts...
===========================
> Compiling ./contracts/Stack.sol
> Compiling ./test/TestStack.sol

InternalCompilerError:

Compilation failed. See above.
Truffle v5.1.13 (core: 5.1.13)
Node v8.17.0
CruzMolina commented 4 years ago

@safakoks , which version of solidity are you specifically using to compile with while testing?

safakoks commented 4 years ago

@CruzMolina , here's my compile config in truffle-config.js

compilers: {
        solc: {
            version: "0.6.0"
        }
    }
CruzMolina commented 4 years ago

Hmmm. odd. this is what I see

➜  reprod-error truffle test

Compiling your contracts...
===========================
> Compiling ./contracts/Migrations.sol
> Compiling ./contracts/Stack.sol
> Compiling ./test/TestExample.sol

InternalCompilerError: Unknown dynamically sized type: struct Stack.Item memory

Compilation failed. See above.
Truffle v5.1.14 (core: 5.1.14)
Node v10.18.0

Same output when using Node v8.17.0.

safakoks commented 4 years ago

@CruzMolina may it happens because I am using Truffle v5.1.13?

CruzMolina commented 4 years ago

@safakoks Hmmm. No, I'm not seeing any changes to the relevant code in v5.1.14.

At this point, I think we need to see a repo of a truffle project example where this exact bug is consistently reproduced.

pynixwang commented 3 years ago

you call another contract returns memory struct but you do not use pragma experimental ABIEncoderV2;

pynixwang commented 3 years ago

I run into this today

lobsterhands commented 3 years ago

Using solc-js directly may provide better debugging information.

solcjs path/to/Contract.sol --abi

cameel commented 3 years ago

@safakoks

It returns the same error without any message :

Are you sure you are running it on the same code? There was another variation of the issue you reported in https://github.com/ethereum/solidity/issues/8379 where solc would return InternalCompilerError with no message instead: https://github.com/ethereum/solidity/issues/9270. You can trigger it by simply by removing the string from your struct to make it statically sized. See the repro below.

So I think that InternalCompilerError is not a Truffle issue but a compiler issue instead and that it was fixed along with the other issue in solc 0.7.4.

It was really a bunch of related bugs, for example also https://github.com/ethereum/solidity/issues/9969 and https://github.com/ethereum/solidity/issues/9970. They were all triggered by the compiler running into something that requires ABIEncoderV2 and is defined in a file that enables it but then being used in another file that does not have it enabled. On earlier versions the workaround is simply to make sure you have the pragma in every file where you are using stuff that depends on ABIEncoderV2.

Repro with a dynamically-sized struct

mkdir -p /tmp/truffle-test/
cd /tmp/truffle-test/
npm install truffle
npx truffle init
echo 'module.exports.compilers.solc.version = "0.6.0";' >> truffle-config.js

cat << EOF > contracts/Stack.sol
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;

contract Stack {
    struct Item {
        string name;
    }

    function getLastItem() public view returns(Item memory) {}
}
EOF

cat << EOF > test/TestStack.sol
pragma solidity ^0.6.0;

import "../contracts/Stack.sol";

contract TestStackContract {
    function testAddingItem() public {
        Stack(0x0).getLastItem();
    }
}
EOF

npx truffle test

Output:

Compiling your contracts...
===========================
> Compiling ./contracts/Migrations.sol
> Compiling ./contracts/Stack.sol
> Compiling ./test/TestStack.sol

InternalCompilerError: Unknown dynamically sized type: struct Stack.Item memory

Compilation failed. See above.
Truffle v5.4.10 (core: 5.4.10)
Node v16.9.1

Repro with a statically-sized struct

mkdir -p /tmp/truffle-test/
cd /tmp/truffle-test/
npm install truffle
npx truffle init
echo 'module.exports.compilers.solc.version = "0.6.0";' >> truffle-config.js

cat << EOF > contracts/Stack.sol
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;

contract Stack {
    struct Item {
        uint value;
    }

    function getLastItem() public view returns(Item memory) {}
}
EOF

cat << EOF > test/TestStack.sol
pragma solidity ^0.6.0;

import "../contracts/Stack.sol";

contract TestStackContract {
    function testAddingItem() public {
        Stack(0x0).getLastItem();
    }
}
EOF

npx truffle test

Output:

Compiling your contracts...
===========================
> Compiling ./contracts/Migrations.sol
> Compiling ./contracts/Stack.sol
> Compiling ./test/TestStack.sol

InternalCompilerError:

Compilation failed. See above.
Truffle v5.4.10 (core: 5.4.10)
Node v16.9.1