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

New Migrations #1028

Merged
merged 76 commits into from
Jul 12, 2018
Merged

New Migrations #1028

merged 76 commits into from
Jul 12, 2018

Conversation

cgewecke
Copy link
Contributor

@cgewecke cgewecke commented Jun 18, 2018

Opening to keep track of what still needs to be done this week.

  • Color
  • Remove support for batch deployments
  • Fix E2E CI at wild-truffle for monorepo and check colonyNetwork / aragon migrations
  • Should we have a classic migrations output option? To minimize noise in CI?
  • Publish hd-wallet-provider V5 (fork provider-engine to Truffle / merge cgewecke's in)

Gists of the output (So we can start to make this look better)

E2E Testing vs. Rinkeby / Ropsten / MintTestNet (Settlemint/Parity POA network)

Everything is set up here to deploy Consensys/PLCRToken to these testnets. Just clone repo (recursively), set up a secrets.js with a funded mnenomic, and follow README instructions to install and run at this branch's current commit.

Known Problems

  • geth ws is broken for large data sends & web3 1.0 has broken confirmations polling over rpc. (Fix w/ block-polling)
  • HDWallet uses web3-provider-engine which isn't web3 1.0 compatible because the latter stopped supporting the sendAsync method, renaming it send. provider-engine hates send though because it used to be sync. Believe this will require we temporarily fork provider-engine.
  • Account are not really forking. (Fixed at ganache, awaiting publication)

Goals

  • Add substantive tests / fixtures for this feature so it can be maintained & debugged.
  • Make async/await behave intuitively without breaking the current 'then-able' pattern.
  • Meaningful error handling. Should detect constructor reverts/OOG/nonce etc and offer advice.
  • Expose revert reason strings (ganache only atm)
  • Configurable confirmation delays (by network)
  • Configurable block timeouts (by network)
  • Display more data, more clearly
  • --dry-run
    • Auto-runs when it detects that a migration targets a public network
    • Interactive prompt before running real migration
  • Decouple logging and migrations logic with an async Reporter

Example command

$ truffle migrate --network rinkeby --interactive

Example config

networks: {
  rinkeby: {
    provider: () => new HDWalletProvider(mnemonic, `https://rinkeby.infura.io/${infura}`),
    network_id: 4,
    gas: 6000000,
    gasPrice: 20000000000,
    confirmations: 2,     // # confirmations to wait between each deployment
    timeoutBlocks: 75   // # of blocks to wait for network to mine a deployment before erroring
  },
}

GIF

migrations_a

Visual Review (future improvements):

  • @gnidan thinks migrations have too much data.
  • dry-run should be clearly distinguished
  • 4 second increments are weird (we should lie)
  • more interactivity
  • Make sure block limits are same dry-run and real.
  • Move error handling to truffle-contract / truffle-error
  • --only flag
  • Spinner for saving migrations

await Promise.all(deployments);
await self.emitter.emit('postDeployMany', arr);
};
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete this.

Copy link
Contributor

@gnidan gnidan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(first pass)

}
}

if (isString && res.result.includes('0x08c379a0')){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

}
};

module.exports = Deployment;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No new line at end of file

For those of us old-heads that like to cat their files on the terminal

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But really I came here to say that _methods should not be called outside of this class

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

contract.transactionHash = instance.transactionHash;
return instance;
};
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is a bit long? Maybe worth chopping it into pieces? Up to you

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah but we should at least move the public methods above the private ones.

if (options.save === false) return;

// Write migrations record to chain
const Migrations = resolver.require("./Migrations.sol");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolver.require("Migrations")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm. Need to investigate this a bit. Is the hard-coding of the path (carried over from original) the cause of the bug identified here. Or.....?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just more canonical. Artifacts are by contract name, not filename.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The older migrate tests at truffle-core crash when this change is made. I want to deal with separately from this PR as a bug in the resolver - not sure what's going here....

@cgewecke cgewecke changed the title [WIP] New Migrations New Migrations Jul 4, 2018
Copy link
Contributor

@gnidan gnidan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's another round of review. I think you said you have some more changes you want to make, so I'll wait for those to then try to catch anything I missed.

All-in-all, this is an impressive effort.

}

web3
.eth
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kind of prefer the way you had it with web3.eth. I'd also be into web3.eth.estimateGas(params) all on one line, but I can see why separating it looks nice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

web3.currentProvider.send(packet, (err, response) => {
if (response && (response.error || response.result)) {
reason = execute.extractReason(response, web3)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the if just be moved into extractReason here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah so provider.send() still only uses a callback

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

(params.gas)
? accept({gas: params.gas, error: err})
: accept({gas: null, error: err});
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is all really pretty

return web3.eth.abi.decodeParameter('string', data[hash].return.slice(10))
}

} else if (isString && res.result.includes('0x08c379a0')){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's that value? I think let's make this a const at the top of the function so it gets a name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmm. yes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess derived from this axic comment in the EIP ? 🙂

Now we could instead just assume that there is a generic error with a signature of Error(string), which hashes to 08c379a0 followed by an ABI encoded string, therefore revert("oh noes") would result in the data 08c379a0 00...20 00..07 6f68206e6f6573..00

@@ -131,6 +176,7 @@ var execute = {
var args = Array.prototype.slice.call(arguments);
var params = utils.getTxParams.call(constructor, args);
var promiEvent = new Web3PromiEvent();
var reason;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't appear to be used


const util = require('util');

class Migration {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh nice, one of these!

};
}

// ------------------------------------- Public -------------------------------------------------
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wait you're doing private first? That's cool as long as we're consistent.

" ⠏"
]
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like there's gotta be a better way to get indents under control.

}
}

module.exports = MigrationsMessages;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dig the messages separation of concerns

}

module.exports = Reporter;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Contributor

@gnidan gnidan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

@@ -13,6 +13,7 @@ contract Example {
// Constructor revert
require(val != 13);
require(val != 2001, 'reasonstring');
require(val != 20001, 'solidity storage is a fun lesson in endianness');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😄

@cgewecke
Copy link
Contributor Author

Aiiii!!!! It's over.

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

Successfully merging this pull request may close these issues.

3 participants