Skip to content
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

Bugfix allow account code change #784

Closed
wants to merge 13 commits into from

Conversation

hackaugusto
Copy link
Contributor

@hackaugusto hackaugusto commented Jul 2, 2024

The account delta check only allows the nonce to change if the storage or the vault changes. This is a problem, because it forbids changes to the account's code.

This relaxes the test, to fix the immediate issue, allowing the account code to change. In the future, however, the correct fix is to also track code changes in the account delta and include that in the nonce check.

@hackaugusto hackaugusto requested review from bobbinth and polydez July 2, 2024 20:51
@@ -86,22 +86,19 @@ end

#! Sets an item in the account storage. Panics if the index is out of bounds.
#!
#! Stack: [index, V']
#! Stack: [index, V', 0, 0, 0]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is because of #783

Copy link
Contributor

Choose a reason for hiding this comment

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

As I mentioned in the comment for #783, I'm not sure I understood the motivation for this change. I think it was working as intended (e.g., the user would be able to do exec.account::set_item and it would not insert any extra zeros into the stack. Or am I missing something?

@@ -98,7 +98,7 @@ impl fmt::Display for TransactionKernelError {
)
},
TransactionKernelError::UnknownAccountProcedure(proc_root) => {
write!(f, "account procedure with root {proc_root} is not in the advice provider")
write!(f, "Could not find account procedure with digest {proc_root} is in the advice provider, check the transactinon's account code")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this was confusing, it was unclear if it was the account procs hash, or the mast root of the procedure.

inputs: Vec<(Word, Vec<Felt>)>,
targets: Vec<ScriptTarget>,
},
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a bit annoying, the tx script doesn't allow phantom calls, so the script must be compiled with an assembler which had the account loaded into it.

As the tests are currently setup, the assembler is kinda "hidden" inside the context. This structure is just to allow the test to pass script code that calls the account, and to have it compiled with the same assembler. Which then finally allows the tests to run against main.masm instead of stand alone scripts, which is leading me to find issues like the one this PR is fixing.


pub fn set_tx_args(&mut self, tx_args: TransactionArgs) {
self.tx_args = tx_args;
}
Copy link
Contributor Author

@hackaugusto hackaugusto Jul 2, 2024

Choose a reason for hiding this comment

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

The args are no longer created when instantiating the context, now it is created just before executing the transaction, this too is because of the tx script (because one needs the tx script object to create the tx arg one).

@@ -29,77 +29,56 @@ pub fn read_root_mem_value<H: Host>(process: &Process<H>, addr: u32) -> Word {
process.get_mem_value(ContextId::root(), addr).unwrap()
}

/// Given an slice of [Note]s, generates a procudere to initialize the VM's memory with the note's
/// data.
pub fn output_notes_data_procedure(notes: &[Note]) -> String {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This should allow one to simplify the context builder, and remove notes which are no longer needed, since the number of notes now can vary.

In the future it should also support notes with a variable number of assets.

} else if nonce.is_some() {
return Err(AccountDeltaError::InconsistentNonceUpdate(
"nonce updated for empty delta".to_string(),
));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the temporary bug fix.

Copy link
Collaborator

@igamigo igamigo Jul 2, 2024

Choose a reason for hiding this comment

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

I think this check specifically has been discussed in the context of one of the pioneer's projects and a possibility was to remove it altogether (#765)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

even better :)

let new_acct_code_ast =
ModuleAst::parse(source).map_err(AccountError::AccountCodeParsingError)?;
AccountCode::new(new_acct_code_ast, &Assembler::default())
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just a convenience constructor. We never construct code directly from the AST, always from a string builder or str slice.


# acct proc 2
export.incr_nonce
push.0 swap
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is done by account::incr_nonce already.

@hackaugusto hackaugusto changed the title Hacka bugfix allow account code change Bugfix allow account code change Jul 2, 2024
@hackaugusto hackaugusto force-pushed the hacka-bugfix-allow-account-code-change branch from 4dbbb6b to 8f6df50 Compare July 2, 2024 23:35
Comment on lines 77 to 87
#! Increments the account nonce by the provided value.
#!
#! Stack: [value]
#! Output: []
#!
#! - value is the value to increment the nonce by. value can be at most 2^32 - 1 otherwise this
#! procedure panics.
export.incr_nonce
exec.account::incr_nonce
# => []
end
Copy link
Contributor

Choose a reason for hiding this comment

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

Adding this procedure would lead to a security vulnerability: it will allow anyone to bypass an account's authentication mechanism. What is the motivation for adding it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The authentication mechanism is done in the kernel:

# authenticate that the procedure invocation originates from the account context
exec.authenticate_account_origin

This is not skipping it (just like the other methods in this file)

Copy link
Contributor

Choose a reason for hiding this comment

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

I mean the transaction authentication (e.g., where we require the user to provide a signature against an account's public key). Exposing this method publicly would allow anyone to bypass signature verification and update the account state at will.

Copy link
Contributor Author

@hackaugusto hackaugusto Jul 3, 2024

Choose a reason for hiding this comment

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

Ah, so the plan is to have the signature verification code calling the nonce increment? That makes sense, I was unaware of that flow.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved it back to the test only.

Comment on lines 89 to 99
#! Sets the code of the account the transaction is being executed against. This procedure can only
#! executed on regular accounts with updatable code. Otherwise, this procedure fails.
#!
#! Stack: [CODE_ROOT]
#! Output: []
#!
#! - CODE_ROOT is the hash of the code to set.
export.set_code
exec.account::set_code
# => []
end
Copy link
Contributor

Choose a reason for hiding this comment

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

Ability to update account code is not yet supported. Making it work properly is a relatively big task and I'm not sure we need to tackle it yet.

In either case though, adding it to the basic wallet interface is probably not the right approach (i.e., when we do make it work, it should probably be a part of a separate interface).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved it back to the test only.

@hackaugusto hackaugusto force-pushed the hacka-tests-cleanup-2 branch from 273d0c0 to 04e42d2 Compare July 3, 2024 14:10
Base automatically changed from hacka-tests-cleanup-2 to next July 3, 2024 14:26
@hackaugusto hackaugusto force-pushed the hacka-bugfix-allow-account-code-change branch 2 times, most recently from a704e72 to 15b07a3 Compare July 3, 2024 16:14
@bobbinth
Copy link
Contributor

bobbinth commented Jul 5, 2024

@hackaugusto - could you rebase this from the latest next?

Changes to the account code were forbidden in the Rust code, because the
account delta nonce validation assumed the nonce would only change with
changes to the vault or storage.

Currently the account delta doesn't track changes to the account code,
so as an intermediary solution this changes the check to allow code
changes anytime. The correct solution would be to introduce the code
change to the account delta too, and introduce that as another case in
which the delta must change, and then forbid changes otherwise.
@hackaugusto hackaugusto force-pushed the hacka-bugfix-allow-account-code-change branch from 5f9641a to dcdc4c9 Compare July 5, 2024 12:23
@hackaugusto
Copy link
Contributor Author

@hackaugusto - could you rebase this from the latest next?

done

@bobbinth bobbinth deleted the hacka-bugfix-allow-account-code-change branch November 6, 2024 23:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants