-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Revert with error message when release validation fails #37
Merged
Merged
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,21 @@ import {ReleaseDB} from "./ReleaseDB.sol"; | |
/// @title Database contract for a package index. | ||
/// @author Piper Merriam <[email protected]> | ||
contract ReleaseValidator { | ||
|
||
/// @dev Maps integer error codes returned by `validateRelease` to human readable error strings. | ||
mapping (uint8 => string) public errors; | ||
|
||
/// @dev Initializes `errors` map with human readable error messages. | ||
constructor() public { | ||
errors[1] = "escape:ReleaseValidator:package-db-not-set"; | ||
errors[2] = "escape:ReleaseValidator:release-db-not-set"; | ||
errors[3] = "escape:ReleaseValidator:caller-not-authorized"; | ||
errors[4] = "escape:ReleaseValidator:version-exists"; | ||
errors[5] = "escape:ReleaseValidator:invalid-package-name"; | ||
errors[6] = "escape:ReleaseValidator:invalid-lockfile-uri"; | ||
errors[7] = "escape:ReleaseValidator:invalid-release-version"; | ||
} | ||
|
||
/// @dev Runs validation on all of the data needed for releasing a package. Returns success. | ||
/// @param packageDb The address of the PackageDB | ||
/// @param releaseDb The address of the ReleaseDB | ||
|
@@ -28,28 +43,31 @@ contract ReleaseValidator { | |
) | ||
public | ||
view | ||
returns (bool) | ||
returns (uint8 code) | ||
{ | ||
require(address(packageDb) != 0x0, "escape:ReleaseValidator:package-db-not-set"); | ||
require(address(releaseDb) != 0x0, "escape:ReleaseValidator:release-db-not-set"); | ||
|
||
if (!validateAuthorization(packageDb, callerAddress, name)) { | ||
if (address(packageDb) == 0x0){ | ||
// packageDb address is null | ||
return 1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These error numbers seem like they should be an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yes nice! 🙂 |
||
} else if (address(releaseDb) == 0x0){ | ||
// releaseDb address is null | ||
return 2; | ||
} else if (!validateAuthorization(packageDb, callerAddress, name)) { | ||
// package exists and msg.sender is not the owner not the package owner. | ||
return false; | ||
return 3; | ||
} else if (!validateIsNewRelease(packageDb, releaseDb, name, majorMinorPatch, preRelease, build)) { | ||
// this version has already been released. | ||
return false; | ||
return 4; | ||
} else if (!validatePackageName(packageDb, name)) { | ||
// invalid package name. | ||
return false; | ||
return 5; | ||
} else if (!validateReleaseLockfileURI(releaseLockfileURI)) { | ||
// disallow empty release lockfile URI | ||
return false; | ||
return 6; | ||
} else if (!validateReleaseVersion(majorMinorPatch)) { | ||
// disallow version 0.0.0 | ||
return false; | ||
return 7; | ||
} | ||
return true; | ||
return 0; | ||
} | ||
|
||
/// @dev Validate whether the callerAddress is authorized to make this release. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe instead of returning the code, the revert should just be thrown from within the
releaseValidator
? That way you don't have to juggle a return code.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pipermerriam Agree - that's a more elegant solution and works perfectly for the case where you're attempting a release and have an error.
There's a small tradeoff - if you
call
validateRelease on its own - say as a pre-flight check - the errors don't propagate because it's aview
function. It can be structured to correctly return true/false for that case though.Your suggestion is simpler/cleaner (probably lighter) ... on reflection definitely prefer.
@gnidan WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So right now the benefit is that errors propagate easily via
eth_call
...To continue to get errors to propagate, we could just leave it as a client concern (say, sendTransaction to the view function on a forked network). But this is messy and heavy-handed in implementation...
It does make it a lot simpler in Solidity, to revert with errors inside ReleaseValidator. To get a pre-flight check we'd need another method, though, one that doesn't error opaquely.
I'm not sure. I don't feel strongly either way, but I guess my vote is that pre-flight checks are valuable enough to warrant providing that capability in some form, even if it means a bit of ugly code somewhere. But I'll abstain from voting on where the ugly code to support this should live.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TLDR: Do what you think is best.
Lately I've structured my APIs to look something like this:
I find I almost always want both of these and it is easy to make one a wrapper around the other. In this case it isn't trivial because we don't have good error handling so you might need a 3rd internal method which returns a status code which can then be converted to either a boolean, or an exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pipermerriam Yes, makes sense. For now opting to revert from the validator per suggestion because its cleaner/less weird. Will possibly add a second
is_valid_thing
-like method that returns error string or "ok" for pre-flight checks in a later PR. After the revisions in 61e356a the behavior is:send
call