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

Add support for option --allow-paths #1010

Merged
merged 14 commits into from
Mar 9, 2018
Merged

Add support for option --allow-paths #1010

merged 14 commits into from
Mar 9, 2018

Conversation

tglaeser
Copy link
Contributor

Following through on my proposal as outlined in ticket #1006.

@coveralls
Copy link

coveralls commented Feb 16, 2018

Coverage Status

Coverage increased (+0.2%) to 56.811% when pulling ccbadb4 on afide:develop into ca6d8f3 on ethereum:develop.

@tglaeser
Copy link
Contributor Author

@mkalinin @zilm13 Any objections to get those changes merged into develop branch?

Copy link
Collaborator

@zilm13 zilm13 left a comment

Choose a reason for hiding this comment

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

Great improvement, but I'd change several things

return getInstance().compileSrc(sourceDirectory, false, combinedJson, options);
}

public enum Options {
public static final class Options {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you, please, add comment here, that it's here for backward compatibility

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will do.

String getName();
}

public static class ListOption implements Option {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This code currently designed only for --allow-paths, maybe make it just AllowPathsOption or at least make AllowPathsOption extends ListOption or any other shortcut, so user will not need to write ListOption("allow-paths",

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are absolutely right; I'll do the necessary changes.

@@ -372,15 +372,15 @@ public void createContractFork() throws Exception {
"}";

StandaloneBlockchain bc = new StandaloneBlockchain();
SolidityContract parent = bc.submitNewContract(contractSrc, "Parent");
SolidityContract parent = bc.submitNewContract(contractSrc, "<stdin>:Parent");
Copy link
Collaborator

@zilm13 zilm13 Feb 27, 2018

Choose a reason for hiding this comment

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

I think it's a bad thing with all this <stdin>'s.
We are making interface to proxy user from solc and add some simplicity and programming-language interface to interact with. Also all method declarations call it "Contract name" already. Plus we want it to work with several versions of solc.
I'd suggest modify CompilationResult.parse to remove "<stdin>:" part when it exists in the beginning and revert all method calls in tests. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, I didn't spent a lot of thoughts on this, simply adjusted the tests to work with the new Solidity compiler version.

To me it seems that the creators of Solidity, with version 0.4.9, added some form of a poor men's namespace support; that is, requiring to prefix each contract with ${filename}:. Only if the contract is read from standard input instead, the prefix becomes <stdin>:. Please follow the link above for the release notes.

I don't see how the new contract's namespace information could be ignored in the production code. Thoughts/concerns?

Copy link
Collaborator

@zilm13 zilm13 Feb 28, 2018

Choose a reason for hiding this comment

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

Ok, what I suggest:

  1. Adding public String path into ContractMetadata. If there is anything on first line before :, it's saved there (and removed from contract name)
  2. public Map<String, ContractMetadata> contracts becomes public Map<String, List<ContractMetadata>> contracts in CompilationResult

What do you think?
We are braking backward compatibility but I see only weird ways to preserve it.
Anyway remembering path which is specific to filesystem to get contract from compilation is not a good thing, I think, and we need to get it over.

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 understand your suggestion, but I believe that would not be as designed by the creators of Solidity.

To me it seems, since Solidity version 0.4.9, that the compiler returns a contract key, not contract name anymore, which will always be prefixed with ${filename}: or <stdin>:, that's a breaking change at the side of the Solidity compiler. You cannot ditch this information and use the contract name instead of the contract key as the key in Map<String, ContractMetadata>. This breaking change was introduced to allow contracts of the same name but different location to coexists, e.g. map entries with keys /foo/file1.sol:test, /foo/bar/file2.sol:test.

We need to agree on this first before we can think about how to better address this change.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Look, now contract name just contains more information: path (or <stdin>) and contract name. I just suggest to store it separately in our Java model. Contract name is not {filename}:realContractName. It's just new part of information, they've added in output in such way. You are not able to call one contract from another with such prefix, so it's not a part of contract name, yeah?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, I've called @mkalinin for his opinion, he will reply later.
I don't like paths (or combined key as originally comes from solc) as a first key because paths are even different on different filesystems and we make life of all users more difficult for rare cases when someone needs to compile the same names at once. Let's see what Michael will say.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I noticed, our messages somehow overlapped. I can relate to the discontent towards java.io.File, so maybe Map<URI, ?> would actually better reflect reality.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

One more thing, doing contracts.get("MyContract").getValue(0) as suggested by @zilm13 above would allow keeping the current tests more or less the same, however any general provider of this functionality would still have to check the entries in LinkedMap<String, ContractMetadata> in order to make sure that he doesn't miss any contract. It just unnecessarily complicates the code IMHO.

Copy link
Contributor

Choose a reason for hiding this comment

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

Both of you have thoughts meaningful to me. I agree with @zilm13 that contract name is just a name and it's incorrect to prefix it with contract source, cause that will definitely confuse the user. On the other hand @tglaeser is right pointing that CompilationResult contains solidity output where key in contracts map is not a contract name but its identifier. So, what would I do: hide CompilationResult.contracts and provide getters to access it. I.e. something like getContract(String name) for general usage which returns first matching contract with no matter for path, getContract(String name, String path) - this method requires additional work in path transformation depending on the OS (need to check how solc handles that). Also, this change requires additional getter which returns just the first contract from that map (I saw that this case is also can take place). That is my opinion guys and that solution combines both of your suggestions, hence it should work :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the input. I'll go forward and make the necessary changes and update the pull request...

@tglaeser
Copy link
Contributor Author

tglaeser commented Mar 3, 2018

@zilm13 @mkalinin Please let me know in case you have additional thoughts/suggestions...

@tglaeser
Copy link
Contributor Author

tglaeser commented Mar 8, 2018

@zilm13 @mkalinin Please advise.

Copy link
Collaborator

@zilm13 zilm13 left a comment

Choose a reason for hiding this comment

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

Sorry for delay. Looks almost complete. Just a bit of polishing.

return entry.getValue();
}
}
throw new UnsupportedOperationException("Source contains more than 1 contact. Please specify a valid contract name. Available keys (" + getContractKeys() + ").");
Copy link
Collaborator

Choose a reason for hiding this comment

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

There should be something with "not found"
Contract %s was not found in compilation result or something like this.

}
}

@JsonIgnore public ContractMetadata getContract(String contractName) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you add javadoc to getters, especially to this one. There should be mentioned, that if there are more than 1 contract with the same name, only first will be returned, so you should use {@link getContract(Path contractPath, String contractName)} for this cases.

CompilationResult.ContractMetadata a = result.getContract(source, "test3");
CallTransaction.Contract contract = new CallTransaction.Contract(a.abi);
System.out.print(contract.functions[0].toString());
}
Copy link
Collaborator

@zilm13 zilm13 Mar 8, 2018

Choose a reason for hiding this comment

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

could you assert here that there are 2 contracts totally and second is not null too and could be queried by name.

@tglaeser
Copy link
Contributor Author

tglaeser commented Mar 9, 2018

@zilm13 Made the requested changes.

@zilm13 zilm13 merged commit 65ef5a1 into ethereum:develop Mar 9, 2018
@zilm13
Copy link
Collaborator

zilm13 commented Mar 9, 2018

@tglaeser Thank you!

@tglaeser
Copy link
Contributor Author

@zilm13 Thank you for reviewing. Since the Solidity compiler options changed quite a bit with the upgraded version, there is more work to do in this area. If I get a chance I'll come back and do the remaining work...

@mkalinin
Copy link
Contributor

guys, have you an idea of what went wrong? ether-camp/ethereum-harmony#63

@zilm13
Copy link
Collaborator

zilm13 commented Mar 10, 2018

@mkalinin I'll fix it

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.

4 participants