-
Notifications
You must be signed in to change notification settings - Fork 113
UINT256_MAX in Domain Proofs #771
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
Conversation
1816a9e to
8c10dc8
Compare
8c10dc8 to
8842b7d
Compare
8842b7d to
5f02665
Compare
area
left a comment
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.
This is a good change - nothing substantive comment wise from me.
Noting for completeness on GH that we can't merge yet. Because of the changes required to OneTxPayment, a colony using the app that upgraded to a version with this change will need to upgrade OneTxPayment. This will require changes to the dapp, but ideally it'd be changes that supported #714 in general and made extension upgrades straightforward in the future.
fc6b9fa to
65826cf
Compare
65826cf to
a085cfb
Compare
c7d1f34 to
ada1a85
Compare
eb29b41 to
1f6a4cd
Compare
952ed98 to
58460db
Compare
58460db to
4569fb5
Compare
Now that unsupported upgrades are not displayed in the app, we have merged this, but it is still true. If #714 is done by the time this is deployed, the app will have to support that, otherwise the app will have to, as part of the upgrade process, deploy a new OneTxPayment extension (which is a flow that will have to be able to be recovered from - something I know has given us grief in the past). |
The issue
Taking DLP actions (see #553) requires submitting a "domain proof" of the form (
permissionDomainId, childSkillIndex, domainId). These three inputs allow us to verify, in constant time, that both a) the user has the permission needed to take the action, and b) the domain of action is in the inheritance path of the domain of permission. There was one hiccup -- ifpermissionDomainIdanddomainIdwere the same (i.e. a user was taking an action in the same domain where they had the permission, a common occurrence), then the semantics ofchildSkillIndexbecame murky -- since children are 0-indexed,childSkillIndex = 0meant the "first child" -- there was no value which represented "the domain itself".Our initial solution was to say, "alright, when
permissionDomainId == domainId, we just ignorechildSkillIndex" -- the user can put in whatever value they want, we just ignore it. That worked pretty well.However, that degree of ambiguity, where
(permissionDomainId, childSkillIndex, domainId)is not strictly unique, came back to bite us in the butt when implementing disputes.Why? A confluence of two factors. First, in order to make disputes as general as possible, all actions are represented as
bytesarrays, to be executed by the disputes extension. Second, in order to ensure that only appropriate reputation is voting on disputes, we must be able to infer, from the action, what domain it acts in. How to do this? By parsing thebytesarray, extracting thepermissionDomainIdandchildSkillIndex(which, by fortunate convention, are always the first two arguments), and using those to inferdomainId.Herein lies the problem: it is not always possible to exactly infer
domainIdfrom the other two arguments, as achildSkillIndexof 0 can be interpreted to mean EITHERpermissionDomainIditself OR the first child. This creates a problem for disputes since it means that an action in a domain could potentially be voted on by the first child domain, a clear violation of the semantics of DLP.The answer
Fortunately, we have a solution, and it is relatively simple: adopt a new convention, where
UINT256_MAX(the largest possible number) is passed aschildSkillIndexwheneverpermissionDomainId == domainId. In a sense, it becomes a "pseudo index" for a non-existent value.While a slight hack, this approach is justifiable in that there is no way for any domain to have
UINT256_MAXchild domains (for reasons of gas limits and also of time), so there will never be a case whereUINT256_MAXactually indexes a child domain, making it's usefulness as a special index valid.The consequences
Fortunately, since
childSkillIndexmust almost always be supplied by users, this change will not* break any existing contracts. It may, however, require client updates to ensure that the correct value is being passed. These updates can be as simple as a line to the effect of:*Unfortunately,
OneTxPaymentwill need to be updated, since that contract does havechildSkillIndexhardcoded for the root domain.