Skip to content
This repository has been archived by the owner on Jan 24, 2022. It is now read-only.

Libraries can link to other libraries with public functions #1252

Merged
merged 15 commits into from
Nov 28, 2019

Conversation

asselstine
Copy link
Contributor

I needed to deploy a library that linked to another library that had public functions. I made changes to allow the deployment of any dependent libraries.

  • Altered NetworkController#_getAllSolidityLibNames to recursively retrieve libraries and detect cycles
  • Altered NetworkController#uploadSolidityLibs to push libraries in order so that dependencies to ensure linking addresses exist
  • Altered NetworkController#_uploadSolidityLib to link libraries

@spalladino
Copy link
Contributor

Hey @asselstine, thanks for the contribution! We'll check why the CI is complaining (there is some error with truffle apparently). In the meantime, could we ask you to add a test for this, in order to merge it? Thanks!

@spalladino spalladino added the status:changes-requested PR needs changes before approving label Oct 18, 2019
@asselstine
Copy link
Contributor Author

@spalladino I didn't see any tests for the NetworkController so I thought I might get away with no tests ;) I'll make sure to add one.

I did notice that I had to add the CI flag when running locally; i.e. CI=true npm test. It couldn't seem to compile the artifacts correctly otherwise.

@asselstine
Copy link
Contributor Author

@spalladino tests added!

@spalladino
Copy link
Contributor

Awesome, thanks so much Brendan! Will review during the week :-)

@spalladino spalladino added status:to-review Awaiting review and removed status:changes-requested PR needs changes before approving labels Oct 29, 2019
Copy link
Contributor

@spalladino spalladino left a comment

Choose a reason for hiding this comment

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

Awesome work Brendan, thanks a lot! I left a question on the loop detection. I may be wrong, but I think there is a scenario where it may yield false positives. Let me know if you have the availability to review this!

packages/cli/src/models/network/NetworkController.ts Outdated Show resolved Hide resolved
@asselstine
Copy link
Contributor Author

@spalladino I've improved the algorithm and added a test to ensure that it orders dependencies correctly. I think this is the one!

@ylv-io
Copy link
Contributor

ylv-io commented Nov 5, 2019

Hey @asselstine! Thanks for the awesome work 🚢
I have an idea to try to use a recursion for the _getAllSolidityLibNames method just to make it more compact and readable. What do you think about that?

@asselstine
Copy link
Contributor Author

@ylv-io Good idea; it would be a good use of recursion. I've added you as a collaborator to the fork, so feel free to push to this branch.

@ylv-io
Copy link
Contributor

ylv-io commented Nov 5, 2019

@asselstine for some reason it didn't work. I can't push and not on the list of collaborators.

@asselstine
Copy link
Contributor Author

@ylv-io Github's "invitations" are overly complicated, in my opinion. I've had this problem countless times.

Your invite to the fork is still pending, so I'm guessing you need to check the email that is attached to your Github profile. There will be an invite email from the Github repo. Once you click that you'll be able to push to the branch.

@ylv-io
Copy link
Contributor

ylv-io commented Nov 6, 2019

@asselstine That is exactly the case. Indeed, this is a confusing system.

@asselstine
Copy link
Contributor Author

Come to think of it, cycle detection is needed for this function. It should throw an error if there is a library dependency ordering such as:

Lib_1 requires Lib_2
Lib_2 requires Lib_3
Lib_3 requires Lib_1

While the above can be compiled, it can't be deployed all at once so OZ SDK should throw an error here.

@ylv-io
Copy link
Contributor

ylv-io commented Nov 7, 2019

Hey @asselstine. I've added suggested changes. Thanks again for your amazing contribution!

Copy link
Contributor Author

@asselstine asselstine left a comment

Choose a reason for hiding this comment

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

@ylv-io great collaboration! I like the recursion and the tests are tight.

packages/cli/test/models/network/NetworkController.test.js Outdated Show resolved Hide resolved
@asselstine
Copy link
Contributor Author

I realize that we are still treating loop as legit DAGs; as per Santiago's original comment.

What we need is a topological sort.

I'll have a look at integrating one.

asselstine and others added 6 commits November 7, 2019 16:24
- Altered NetworkController#_getAllSolidityLibNames to recursively retrieve libraries and detect cycles
- Altered NetworkController#uploadSolidityLibs to push libraries in order so that dependencies to ensure linking addresses exist
- Altered NetworkController#_uploadSolidityLib to link libraries
@asselstine
Copy link
Contributor Author

asselstine commented Nov 8, 2019

@ylv-io Ok. This should be it!

It now recursively builds up a graph which is then topologically sorted.

  • Repeated deps
  • cycle detection.

I think we're done.

@ylv-io
Copy link
Contributor

ylv-io commented Nov 8, 2019

@asselstine. It is a pleasure to collaborate with you!
Using TopologicalSort is a great idea. Just reminds me that we should always stand of the shoulders of giants!
I've polished code a bit and If there will be any CI tests errors let me handle that!

Copy link
Contributor

@nventuro nventuro left a comment

Choose a reason for hiding this comment

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

Great work @asselstine and @ylv-io! Topological sorting indeed seems like the perfect solution for this problem

packages/cli/package.json Outdated Show resolved Hide resolved
packages/cli/src/models/network/NetworkController.ts Outdated Show resolved Hide resolved
packages/cli/test/models/network/NetworkController.test.js Outdated Show resolved Hide resolved
packages/cli/test/models/network/NetworkController.test.js Outdated Show resolved Hide resolved
@ylv-io
Copy link
Contributor

ylv-io commented Nov 28, 2019

I've replaced the topological-sort library with toposort. I also had to adjust tests which is not ideal but required because toposort outputs libs in the different order which is still valid.

Copy link
Contributor

@nventuro nventuro left a comment

Choose a reason for hiding this comment

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

Thank you very much @asselstine and @ylv-io! This looks ready to merge 😁


contractNames.forEach(contractName => {
const deps = this._getContractDependencies(contractName);
deps.forEach(dependencyContractName => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice, I hadn't realized this loop was duplicated 👍

@nventuro nventuro merged commit 813ab58 into OpenZeppelin:master Nov 28, 2019
@nventuro
Copy link
Contributor

The CI test run is done on the branch, not on the result of the merge: it turns out this PR broke tests on the CLI due to #1288.

@nventuro
Copy link
Contributor

Fixed in 7f641a7

@asselstine
Copy link
Contributor Author

Great collab @ylv-io! I'm pleased to help and I'm excited to have this in the build. Now I won't have to worry about our library structure.

@ylv-io
Copy link
Contributor

ylv-io commented Nov 29, 2019

@nventuro this is a great example of how CI tests can be successful on a branch but break a master.

@spalladino
Copy link
Contributor

Hey @asselstine, this PR is now part of the 2.7 RC if you want to try it!

@asselstine
Copy link
Contributor Author

@spalladino Fantastic!

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

Successfully merging this pull request may close these issues.

4 participants