-
Notifications
You must be signed in to change notification settings - Fork 112
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
UINT256_MAX in Domain Proofs #771
Conversation
1816a9e
to
8c10dc8
Compare
8c10dc8
to
8842b7d
Compare
8842b7d
to
5f02665
Compare
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
8b2c862
to
c7d1f34
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 -- ifpermissionDomainId
anddomainId
were 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 ofchildSkillIndex
became murky -- since children are 0-indexed,childSkillIndex = 0
meant 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
bytes
arrays, 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 thebytes
array, extracting thepermissionDomainId
andchildSkillIndex
(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
domainId
from the other two arguments, as achildSkillIndex
of 0 can be interpreted to mean EITHERpermissionDomainId
itself 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 aschildSkillIndex
wheneverpermissionDomainId == 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_MAX
child domains (for reasons of gas limits and also of time), so there will never be a case whereUINT256_MAX
actually indexes a child domain, making it's usefulness as a special index valid.The consequences
Fortunately, since
childSkillIndex
must 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,
OneTxPayment
will need to be updated, since that contract does havechildSkillIndex
hardcoded for the root domain.