-
Notifications
You must be signed in to change notification settings - Fork 0
Fix dispatch for multisig and other cases #92
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
jberthold
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.
Makes sense - if we don't use the accounts[2] in the non-multisig case, we should not even set it up. However this will cause trouble in the inner_test_validate_owner function which will explore the "multisig" branch.
We may have to use a different owner validation function for the "account" case which avoids accessing data which is not present.
|
|
||
| cheatcode_is_account(&accounts[0]); | ||
| cheatcode_is_account(&accounts[1]); | ||
| cheatcode_is_account(&accounts[2]); |
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.
The accounts[2] is passed as owner_account_info into inner_test_validate_owner. Inside that function, there is a branch for the multisig case which accesses the account data.
So if we aren't setting up any data via cheat code, this branch will be explored in the "account" case, too, because it may well be that the length matches the "multisig", the data_len and the owner key are just variables. Without setting up data, that branch will access data that is not set up (undefined behaviour).
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.
I see what you mean, I think that means we need some other cheatcode for the authority to remove this case, cheatcode_is_not_multisig since that is the only restriction on that AccountInfo
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.
Is that as reasonable as the cheatcode_is_multisig?
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.
Although it might be easier to just separate the Multisig block as you said when validating
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.
An easy fix for this could be this.
maybe_multisig_is_initialised is always None for non-multisig cases. So I've added that to the path condition to check for the multisig case.
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.
Oh that fix is much better than what I did, I like that.
|
@JuanCoRo I tested it concretely and it passed both |
|
Just tested this concretely with the latest changes and it's passing both test suites. See this branch for the modifications. |
dkcumming
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.
Nice I think this is good to go
This PR is the product of a joint investigation with @dkcumming.
The
inner_process_instructionfunction(s) incorrectly dispatch the cases for the owner being an account vs. a multisig.In the way it was done before we had:
datafield of theownerhadAccount::LENlength, then it would dispatch it assumingcheatcode_is_account(owner)datafield of theownerhadMultisig::LENlength, then it would dispatch it assumingcheatcode_is_multisig(owner)Turns out, this is not correct on how ownership works. Anything able to cast a signature can be an owner. This means that an account with no data can also be an owner. Upon closer inspection to the validate owner function, the only data requirement is for the multisig case.
Therefore, the correct approach seems to be:
ownerhasMultisig::LENlength and is owned by P-TokenTOKEN_PROGRAM_ID. Dispatch it to the multisig case if so, assumingcheatcode_is_multisig(owner)cheatcode_is_account(owner). If the owner is to fail, it should do so in the test, not in the dispatcher.The problem with dispatching through the multisig case when the account's data length is
Multisig::LENbut it's not owned by P-Token is that it might just be a coincidence that the data length matches. This particular case makes the concrete tests crash.Testing: The changes introduced in this PR have successfully passed the concrete test suites for P-Token and SPL. Refer to this branch for the modifications needed to run the concrete tests.