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
[move framework][move-prover] Some specs from LIP-6, refactoring of initialization in Genesis #5997
Conversation
b7bee58
to
cff02ba
Compare
cff02ba
to
e82e323
Compare
// to update, and only completes successfully if the signer is the validator operator | ||
// for that validator. | ||
// set_libra_system_config is a private function, so it does not have to preserve the property. | ||
/// Testricts the set of functions that can modify the validator set config. |
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.
"Testricts"?
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.
Overall looks good on the Move side! Only a couple cleanup comments.
use 0x1::LibraVMConfig; | ||
|
||
fun initialize( | ||
lr_account: &signer, | ||
tc_account: &signer, | ||
lr_auth_key: vector<u8>, | ||
tc_addr: address, | ||
_tc_addr: address, |
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.
Nit: can you remove this argument? You'll need to update the call to this in language/tools/vm-genesis/src/lib.rs
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 tried it, but debugging the resulting crashes in Rust were a nightmare. So, I'm going to try to land this and fix it later.
language/stdlib/transaction_scripts/peer_to_peer_with_metadata.move
Outdated
Show resolved
Hide resolved
Is this a breaking change? It certainly changes genesis a bit, but I'm not sure if anything needs to change if you don't rebuild genesis. |
e82e323
to
abb0a61
Compare
/land |
Changes to a bunch of .move files related to LibraAccount and LibraSystem. Added specification that every account has a role in LibraAccount. Refactored Genesis and LibraAccount some to make this easier to prove, and to clean up initialization. Specifically, roles for libra root and treasury compliance were added in Genesis separately from the account creation functions. So, I moved role creation into the account creation functions. Genesis was also creating the libra root and treasury compliance accounts directly, so I moved those into LibraAccount::initialize, which simplifies the Genesis code and eliminates some dependencies. In various places, I renamed accounts to reflect their roles, if known. I also added some assertion checks in SlidingNonce, which was getting errors from unchecked aborts. A fair number of files were touched for this purpose. I experimented in couple of places with cross references. Closes: #5997
💔 Test Failed - commit-workflow |
Cluster Test Result
❗ Cluster Test failed - non-zero exit code for Repro cmd:
|
abb0a61
to
042f3fb
Compare
/// LIP-6 property: validator has validator role. The code does not check this explicitly, | ||
/// but it is implied by the assert ValidatorConfig::is_valid, since | ||
/// a published ValidatorConfig has a ValidatorRole is an invariant (in ValidatorConfig). | ||
ensures Roles::spec_has_validator_role_addr(validator_address); |
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 sounds like the same as the last ensures. What's the difference?
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.
If you mean ensures(is_valid....), that implies that it address has a validator role, via another invariant, but doesn't say so directly. This ensures directly specifies the desired property, and I'm sure it's proved by combining the invariant and is_valid.
@@ -374,10 +372,13 @@ module LibraSystem { | |||
// This function should never throw an assertion. | |||
fun update_ith_validator_info_(validators: &mut vector<ValidatorInfo>, i: u64): bool { | |||
let size = Vector::length(validators); | |||
// TODO (dd): This provably cannot happen |
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.
It is an interesting question whether we should remove the code in such cases. I would say no, for robustness. If you agree, I would remove the TODO but instead just add a comment like "Provably does not happen, but here for sanity".
@@ -394,10 +395,16 @@ module LibraSystem { | |||
pragma opaque; | |||
aborts_if false; | |||
let new_validator_config = ValidatorConfig::spec_get_config(validators[i].addr); | |||
// Amazingly, it is able to prove this because get_validator_index_ ensures it |
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.
Use ///
(here and elsewhere) and don't use expression like "amazingly"? This is documentation part of the artifact, not a note paper.
requires 0 <= i && i < len(validators); | ||
// TODO (dd): Should be able to prove this, but it times out. | ||
// Every member of validators is valid. | ||
// requires ValidatorConfig::is_valid(validators[i].addr); |
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.
There is a new way how to keep such properties type checked but not verified. Use requires [deactivated] P
.
// This also implies that every member has a validator role. | ||
// TODO (dd): Times out. I think it should not be hard, so don't know why. | ||
// spec module { | ||
// let validators = spec_get_validators(); |
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.
Addd [deactivated]
?
// This also implies that every member has a validator role. | ||
// TODO (dd): Times out. I think it should not be hard, so don't know why. | ||
// spec module { | ||
// let validators = spec_get_validators(); |
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.
Remove let? Doesn't buy a lot.
@@ -179,14 +179,15 @@ module Roles { | |||
spec fun grant_role { | |||
pragma opaque; | |||
include GrantRole; | |||
let addr = Signer::spec_address_of(account); | |||
// Requires to satisfy global invariants. | |||
requires role_id == LIBRA_ROOT_ROLE_ID ==> addr == CoreAddresses::LIBRA_ROOT_ADDRESS(); |
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 think this should be assertions in the code and aborts_if in the specs.
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.
As I understand this comment, you're suggesting that I add an assert to grant_role that role_id is libra root. But this seems to me exactly the kind of situation where we would want to use "requires".
grant_role is private and every calling context has an assert that the role_id is libra root. So, this seemed right to me, since it's checked in all calling contexts and helps to prove the invariant.
@@ -21,6 +21,8 @@ module SlidingNonce { | |||
const ENONCE_TOO_NEW: u64 = 2; | |||
/// The nonce was already recorded previously | |||
const ENONCE_ALREADY_RECORDED: u64 = 3; | |||
/// Nonce |
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.
Please make a sentence out of this. This documentation is dumped by a debugging tool @tzakian wrote/is writing.
/// in LibraSystem so we don't have to check whether every validator address has a validator role. | ||
/// <a name="ValidatorConfigImpliesValidatorRole"></a> | ||
spec module { | ||
invariant [global] forall addr1:address where exists_config(addr1): |
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.
Nit: spec after addr1:
042f3fb
to
10456de
Compare
10456de
to
1aeb35c
Compare
There's probably some trailing whitespace issue that needs to be resolved XD |
1aeb35c
to
cf4f1fa
Compare
1c541a2
to
e28476c
Compare
/land |
🔒 Merge Conflict |
/help |
Bors help and documentationBors is a Github App used to manage merging of PRs in order to ensure that CI is always green. It does so by maintaining a Merge Queue. Once a PR reaches the head of the Merge Queue it is rebased on top of the latest version of the PR's General
CommandsBors actions can be triggered by posting a comment which includes a line of the form
OptionsOptions for Pull Requests are configured through the application of labels. |
e28476c
to
abde1f7
Compare
/priority high |
/priority high |
/land |
…esis a bit. Potential breaking change: I'm actually not sure if this is a breaking change. I changed the order of some initialization functions in Genesis.move and it turns out the event handle generator has a counter that is incremented for each new event handle, and that this becomes part of the guid for the event handle. The resulting serialized string appears as *-event-key in the json records in json-rpc. I don't know whether clients depend on the counter values in the guids (it would better to use some other means to identify event streams, if one exists). If clients do depend on these, they might see the names event-keys change when genesis is rebuilt. For example, "received_events_key": "0000000000000000000000000000000000000000000000dd", might become "received_events_key": "0300000000000000000000000000000000000000000000dd", General comments on changes: Changes to a bunch of .move files related to LibraAccount and LibraSystem. Added specification that every account has a role in LibraAccount. Refactored Genesis and LibraAccount some to make this easier to prove, and to clean up initialization. Specifically, roles for libra root and treasury compliance were added in Genesis separately from the account creation functions. So, I moved role creation into the account creation functions. Genesis was also creating the libra root and treasury compliance accounts directly, so I moved those into LibraAccount::initialize, which simplifies the Genesis code and eliminates some dependencies. In various places, I renamed accounts to reflect their roles, if known. I also added some assertion checks in SlidingNonce, which was getting errors from unchecked aborts. A fair number of files were touched for this purpose. I experimented in couple of places with cross references. Closes: #5997
💔 Test Failed - commit-workflow |
Cluster Test Result
Repro cmd:
🎉 Land-blocking cluster test passed! 👌 |
abde1f7
to
9849164
Compare
/priority high |
/land |
…esis a bit. Potential breaking change: I'm actually not sure if this is a breaking change. I changed the order of some initialization functions in Genesis.move and it turns out the event handle generator has a counter that is incremented for each new event handle, and that this becomes part of the guid for the event handle. The resulting serialized string appears as *-event-key in the json records in json-rpc. I don't know whether clients depend on the counter values in the guids (it would better to use some other means to identify event streams, if one exists). If clients do depend on these, they might see the names event-keys change when genesis is rebuilt. For example, "received_events_key": "0000000000000000000000000000000000000000000000dd", might become "received_events_key": "0300000000000000000000000000000000000000000000dd", General comments on changes: Changes to a bunch of .move files related to LibraAccount and LibraSystem. Added specification that every account has a role in LibraAccount. Refactored Genesis and LibraAccount some to make this easier to prove, and to clean up initialization. Specifically, roles for libra root and treasury compliance were added in Genesis separately from the account creation functions. So, I moved role creation into the account creation functions. Genesis was also creating the libra root and treasury compliance accounts directly, so I moved those into LibraAccount::initialize, which simplifies the Genesis code and eliminates some dependencies. In various places, I renamed accounts to reflect their roles, if known. I also added some assertion checks in SlidingNonce, which was getting errors from unchecked aborts. A fair number of files were touched for this purpose. I experimented in couple of places with cross references. Closes: diem#5997
Cluster Test Result
Repro cmd:
🎉 Land-blocking cluster test passed! 👌 |
9849164
to
837052e
Compare
Changes to a bunch of .move files related to LibraAccount and LibraSystem.
Added specification that every account has a role in LibraAccount.
Refactored Genesis and LibraAccount some to make this easier to prove,
and to clean up initialization. Specifically, roles for libra root
and treasury compliance were added in Genesis separately from the
account creation functions. So, I moved role creation into the account creation functions. Genesis was also creating the libra root and treasury compliance accounts directly, so I moved those into LibraAccount::initialize, which simplifies the Genesis code and eliminates some dependencies.
In various places, I renamed accounts to reflect their roles, if
known. I also added some assertion checks in SlidingNonce, which was
getting errors from unchecked aborts.
Motivation
(Write your motivation for proposed changes here.)
Have you read the Contributing Guidelines on pull requests?
(Write your answer here.)
Test Plan
(Share your test plan here. If you changed code, please provide us with clear instructions for verifying that your changes work.)
Related PRs
(If this PR adds or changes functionality, please take some time to update the docs at https://github.com/libra/website, and link to your PR here.)