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

Made initial hash optional (None for new accounts) #529

Merged
merged 5 commits into from
May 6, 2024

Conversation

polydez
Copy link
Contributor

@polydez polydez commented Mar 13, 2024

Made initial_account_hash in ProvenTransaction, ProvenTransactionBuilder and TransactionId constructor optional.

I also considered to make hash in Account optional, but finally decided to leave it without changes.

Resolves #522

@polydez polydez requested review from hackaugusto and bobbinth March 13, 2024 17:45
@polydez polydez self-assigned this Mar 13, 2024
@polydez polydez linked an issue Mar 13, 2024 that may be closed by this pull request
Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

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

Thank you! Looks good! I left a couple of comments inline - the main one is for testing one of the things which I think might have previously been a bug.

Also, let's update the changelog.

@@ -89,7 +91,7 @@ impl From<&ExecutedTransaction> for TransactionId {
let input_notes_hash = tx.input_notes().commitment();
let output_notes_hash = tx.output_notes().commitment();
Self::new(
tx.initial_account().hash(),
tx.initial_account().proof_init_hash(),
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess this was an error before - right? I'm thinking we should create a test to make sure that transaction ID remains the same as a transaction moves from executed to proven (or maybe we can integrate into existing tests?).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, this is not a bugfix, just because of changing in input argument it was more convenient to use proof_init_hash. If it's confusing, it might be better to revert to account's hash usage here and implement additional logic for handling new accounts here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmmm - I still think it was a bug previously. The test you've added is good - but it only tests the case of existing accounts. This case would have worked fine before, I think.

The case which I think would have failed before is when a new account is involved in a transaction. Could we test this as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@bobbinth I'll implement this test and will fix the bug, thank you!

Copy link
Contributor

Choose a reason for hiding this comment

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

Just to clarify: I think the bug is already fixed - we just need to confirm this via a test.

Copy link
Contributor Author

@polydez polydez Mar 19, 2024

Choose a reason for hiding this comment

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

@bobbinth no, actually no tests failed in next branch after adding this check into prove_and_verify_transaction function.

Copy link
Contributor

Choose a reason for hiding this comment

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

hmmm - are we sure then that we are testing executing transactions against new accounts? Is there any test that you see that does that?

(it is of course possible that I'm wrong and there was no bug to begin with, but I'd like to be sure).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried to analyze our tests and now I can say we don't have any tests in miden-base which produce new account in transaction.

Copy link
Contributor

Choose a reason for hiding this comment

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

Could you add one such test? This could be something like consuming a note for a new account.

You could do it in a different PR based on this branch, and then, once it is done, we can merge both these PRs.

Copy link
Contributor Author

@polydez polydez Apr 29, 2024

Choose a reason for hiding this comment

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

@bobbinth, I created an issue for implementing of this test: #529 (comment)
Can we merge this PR then? You would probably want to take a final look.

objects/src/accounts/mod.rs Outdated Show resolved Hide resolved
@polydez polydez changed the title Optional initial hash for new accounts Made initial hash optional (None for new accounts) Mar 14, 2024
@polydez polydez requested a review from bobbinth March 14, 2024 03:53
miden-lib/src/transaction/inputs.rs Outdated Show resolved Hide resolved
CHANGELOG.md Outdated Show resolved Hide resolved
@@ -89,7 +91,7 @@ impl From<&ExecutedTransaction> for TransactionId {
let input_notes_hash = tx.input_notes().commitment();
let output_notes_hash = tx.output_notes().commitment();
Self::new(
tx.initial_account().hash(),
tx.initial_account().proof_init_hash(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmmm - I still think it was a bug previously. The test you've added is good - but it only tests the case of existing accounts. This case would have worked fine before, I think.

The case which I think would have failed before is when a new account is involved in a transaction. Could we test this as well?

Copy link
Contributor

@hackaugusto hackaugusto left a comment

Choose a reason for hiding this comment

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

lgtm, thanks!

edit: ofcourse, don't merge it before finishing @bobbinth 's requests :)

polydez added 2 commits April 26, 2024 18:52
fix: use `core::ops::Not` instead of `std::ops::Not`
fix: address review comments
refactor: rename function
docs: update changelog
tests: add checking proven transaction id for cases when account creation was involved
@polydez polydez force-pushed the polydez-opt-initial-hash branch from c5d581d to 1a7452a Compare April 26, 2024 14:16
Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

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

Thank you! Looks good! I added a couple of comments inline - but looking this over now, I'm not sure this is as much of an improvement as I originally thought. What worries me a bit is the need for debug_assert_ne!(initial_account_hash, Some(Digest::default())) in a couple of places as now we can have potentially redundant representation of initial hash (both None and Digest::default()` semantically mean the same thing).

So, I'm on the fence but leaning a bit toward not merging this. What do you think?

(regardless of the above, I would still rename Account::init_proof_hash() into just Account::init_hash()).

Comment on lines 143 to 154
/// Returns hash of the given account as used for the initial account state hash in transaction
/// proofs.
///
/// For existing accounts, this is exactly the same as [Account::hash()], however, for new
/// accounts this value is set to `None`. This is because when a transaction is executed
/// against a new account, public input for the initial account state is set to [ZERO; 4] to
/// distinguish new accounts from existing accounts, and `None` returned from this method.
/// indicates that `[ZERO; 4]` should be used as a public input. The actual hash of the initial
/// account state (and the initial state itself), are provided to the VM via the advice provider.
pub fn init_account_hash(&self) -> Option<Digest> {
self.is_new().not().then(|| self.hash())
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I would move this method back where it was (i.e., line 93 above). Regarding naming, I'd probably just call it init_hash() (I think the account part is not needed as it is a method on Account struct anyway).

Comment on lines 96 to 99
let initial_account_hash =
tx.initial_account().is_new().not().then(|| tx.initial_account().hash());
Self::new(
tx.initial_account().proof_init_hash(),
initial_account_hash,
Copy link
Contributor

Choose a reason for hiding this comment

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

We could have probably kept this as tx.initial_account().init_hash().

@bobbinth
Copy link
Contributor

bobbinth commented May 3, 2024

@polydez - I'm thinking we should revert most of the changes here except for renaming Account::proof_init_hash() into Account::init_hash().

@polydez polydez requested a review from bobbinth May 6, 2024 06:57
Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

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

Looks good! Thank you!

@polydez polydez merged commit 5f59653 into next May 6, 2024
9 checks passed
@polydez polydez deleted the polydez-opt-initial-hash branch May 6, 2024 07:09
bobbinth pushed a commit that referenced this pull request May 13, 2024
* feat: optional initial hash for new accounts
fix: use `core::ops::Not` instead of `std::ops::Not`
fix: address review comments
refactor: rename function
docs: update changelog
tests: add checking proven transaction id for cases when account creation was involved

* refactor: move `init_account_hash` function back to `Account`

* fix: no-std build

* fix: address review comments
bobbinth pushed a commit that referenced this pull request May 14, 2024
* feat: optional initial hash for new accounts
fix: use `core::ops::Not` instead of `std::ops::Not`
fix: address review comments
refactor: rename function
docs: update changelog
tests: add checking proven transaction id for cases when account creation was involved

* refactor: move `init_account_hash` function back to `Account`

* fix: no-std build

* fix: address review comments
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.

Make ProvenTransaction::initial_account_hash optional
3 participants