trufflesuite / ganache-cli-archive

Fast Ethereum RPC client for testing and development. See https://github.com/trufflesuite/ganache for current development.
https://www.trufflesuite.com/ganache
MIT License
3.36k stars 696 forks source link

Error: VM Exception while processing migration transaction: invalid opcode when testing on different machines #813

Closed SteveHigham closed 3 years ago

SteveHigham commented 3 years ago

This looks like a reopening of issue #397.

I have a very simple sample contract with a couple of tests. These run fine on my Ubuntu 20 machine. When I run the same process on my Mac (Big Sur Version 11.1) I get an error - VM Exception while processing transaction: invalid opcode

Expected Behavior

The migration should complete successfully as it does on my Ubuntu machine.

Current Behavior

Starting migrations...

Network name: 'development' Network id: 1610638314568 Block gas limit: 6721975 (0x6691b7)

1_initial_migration.js

Deploying 'Migrations'

transaction hash: 0xf01d65996587bf5056877fd43048c8837a1be1e8de50df87d785b7a4f44979ab Blocks: 0 Seconds: 0 contract address: 0xe277019Afe3370C5B61Ad324004A7F9EA6A43d36 block number: 5 block timestamp: 1610638478 account: 0xc923118ffa38A5e2f8371DD7bA79Ec960147C67A balance: 99.71402796 gas used: 284884 (0x458d4) gas price: 20 gwei value sent: 0 ETH total cost: 0.00569768 ETH

⠋ Saving migration to chain. Error: Returned error: VM Exception while processing transaction: invalid opcode at Migration._deploy (/Users/steve/dev/crypto/ethereum/SimpleVoting/node_modules/truffle/build/webpack:/packages/migrate/Migration.js:97:1) at process._tickCallback (internal/process/next_tick.js:68:7) Truffle v5.1.61 (core: 5.1.61) Node v10.23.0

Possible Solution

Don't use OSX for Truffle development?

Steps to Reproduce (for bugs)

I contract I'm trying to migrate (partially written) is as follows:

// SPDX-License-Identifier:UNLICENSED pragma solidity 0.8.0;

contract SimpleVoting { // Users

address public administrator = msg.sender;

struct Voter
{
    bool isRegistered;
    bool hasVoted;
    uint votedForProposalId;
}

mapping (address => Voter) public voters;

modifier onlyAdministrator ()
{
    require ( msg.sender == administrator,
        "Function can only be called by the administrator" );
    _;
}

modifier onlyRegisteredVoter ()
{
    require ( voters [msg.sender].isRegistered,
        "Function can only be called by a registered voter" );
    _;
}

event VoterRegisteredEvent (address voterAddress);

// Voting on proposals

struct Proposal
{
    string description;
    uint voteCount;
}

Proposal [] public proposals;

event ProposalRegisteredEvent (uint proposalId);
event VoteCastEvent (address voter, uint proposalId);

uint private winningProposalId;

// Workflow

enum WorkflowStatus
{
    RegisteringVoters,
    RegisteringProposals,
    WaitingToStartVoting,
    Voting,
    VotingCompleted,
    VotesCounted
}

WorkflowStatus public workflowStatus = WorkflowStatus.RegisteringVoters;

event ProposalsRegistrationStartedEvent ();
event ProposalsRegistrationEndedEvent ();
event VotingSessionStartedEvent ();
event VotingSessionEndedEvent ();
event VotesCountedEvent ();

event WorkflowStatusChangeEvent (
    WorkflowStatus previousStatus,
    WorkflowStatus newStatus );

// Workflow timestamps as per unix time - seconds since start 01-Jan-1970 GMT
// uint64 is adequate for 584,942,417,355 years after 1970
uint64 public voterRegistrationStartedTimestamp = uint64 ( block.timestamp);
uint64 private proposalRegistrationStartedTimestamp;
uint64 private proposalRegistrationEndedTimestamp;
uint64 private votingStartedTimestamp;
uint64 private votingEndedTimeStamp;
uint64 private votesCountedTimestamp;

modifier onlyDuringVoterRegistration ()
{
    require ( workflowStatus == WorkflowStatus.RegisteringVoters,
              "Function can only be called when registering voters" );
    _;
}

modifier onlyAfterVoterRegistration ()
{
    require ( workflowStatus > WorkflowStatus.RegisteringVoters,
        "Function can only be called after voter registration completes" );
    _;
}

modifier onlyDuringProposalsRegistration ()
{
    require ( workflowStatus == WorkflowStatus.RegisteringProposals,
        "Function can only be called when registering proposals" );
    _;
}

modifier onlyAfterProposalsRegistration ()
{
    require ( workflowStatus > WorkflowStatus.RegisteringProposals,
        "Function can only be called after proposal registration completes" );
    _;
}

modifier onlyWhenVoting ()
{
    require ( workflowStatus == WorkflowStatus.Voting,
        "Function can only be called during voting" );
    _;
}

modifier onlyAfterVotingStarted ()
{
    require ( workflowStatus >= WorkflowStatus.Voting,
        "Function can only be called after voting" );
    _;
}

modifier onlyAfterVotingCompletes ()
{
    require ( workflowStatus > WorkflowStatus.Voting,
        "Function can only be called after voting" );
    _;
}

modifier onlyAfterVotesCounted ()
{
    require ( workflowStatus == WorkflowStatus.VotesCounted,
        "Function can only be called after votes have been counted" );
    _;
}

}

// End of file.

Context

As stated in issue #397 it's worrying when something works fine on the Ubuntu platform but fails on OSX. Does this mean I should not develop using Truffle on OSX.

Your Environment

davidmurdoch commented 3 years ago

What version of ganache-cli is being used?

SteveHigham commented 3 years ago

Ganache CLI v6.12.2 (ganache-core: 2.13.2)

I have just upgraded the Mac to node version 10.23.1 and that has fixed the issue. I have just checked my Ubuntu machine and it is running node 10.23.0.

I'm fine to close the issue if you like as it is resolved under latest node 10 version. I'm also happy to experiment further if that helps.

davidmurdoch commented 3 years ago

Sounds like it's been resolved. Let's just plan to reopen if it happens again. :-)