Skip to content

Commit

Permalink
implement rust logics and specs
Browse files Browse the repository at this point in the history
  • Loading branch information
runtian-zhou committed Nov 25, 2024
1 parent 69db8e1 commit c6019db
Show file tree
Hide file tree
Showing 29 changed files with 591 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ crate::gas_schedule::macros::define_gas_parameters!(
[account_create_address_base: InternalGas, "account.create_address.base", 1102],
[account_create_signer_base: InternalGas, "account.create_signer.base", 1102],

// Permissioned signer gas parameters_
[permission_address_base: InternalGas, "permissioned_signer.permission_address.base", 1102],
[is_permissioned_signer_base: InternalGas, "permissioned_signer.is_permissioned_signer.base", 1102],
[signer_from_permissioned_handle_base: InternalGas, "permissioned_signer.signer_from_permissioned_handle.base", 1102],

// BN254 algebra gas parameters begin.
// Generated at time 1701559125.5498126 by `scripts/algebra-gas/update_bn254_algebra_gas_params.py` with gas_per_ns=209.10511688369482.
[algebra_ark_bn254_fq12_add: InternalGas, { 12.. => "algebra.ark_bn254_fq12_add" }, 809],
Expand Down
5 changes: 5 additions & 0 deletions aptos-move/e2e-move-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,10 @@ pub(crate) fn build_package_with_compiler_version(
) -> anyhow::Result<BuiltPackage> {
let mut options = options;
options.compiler_version = Some(compiler_version);
if options.compiler_version.unwrap() != CompilerVersion::V1 {
options.language_version = Some(move_model::metadata::LanguageVersion::latest_stable());
} else {
options.language_version = Some(move_model::metadata::LanguageVersion::V1);
}
BuiltPackage::build(package_path.to_owned(), options)
}
10 changes: 7 additions & 3 deletions aptos-move/e2e-move-tests/src/tests/gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use aptos_types::{
transaction::{EntryFunction, TransactionPayload},
};
use aptos_vm_environment::prod_configs::set_paranoid_type_checks;
use move_core_types::{identifier::Identifier, language_storage::ModuleId};
use move_core_types::{identifier::Identifier, language_storage::ModuleId, value::MoveValue};
use rand::{rngs::StdRng, SeedableRng};
use sha3::{Digest, Sha3_512};
use std::path::Path;
Expand All @@ -57,7 +57,9 @@ fn test_modify_gas_schedule_check_hash() {
"set_for_next_epoch_check_hash",
vec![],
vec![
bcs::to_bytes(&CORE_CODE_ADDRESS).unwrap(),
MoveValue::Signer(CORE_CODE_ADDRESS)
.simple_serialize()
.unwrap(),
bcs::to_bytes(&old_hash).unwrap(),
bcs::to_bytes(&bcs::to_bytes(&gas_schedule).unwrap()).unwrap(),
],
Expand All @@ -66,7 +68,9 @@ fn test_modify_gas_schedule_check_hash() {
harness
.executor
.exec("reconfiguration_with_dkg", "finish", vec![], vec![
bcs::to_bytes(&CORE_CODE_ADDRESS).unwrap(),
MoveValue::Signer(CORE_CODE_ADDRESS)
.simple_serialize()
.unwrap(),
]);

let (_, gas_params) = harness.get_gas_params();
Expand Down
17 changes: 14 additions & 3 deletions aptos-move/e2e-tests/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ use move_core_types::{
identifier::Identifier,
language_storage::{ModuleId, StructTag, TypeTag},
move_resource::{MoveResource, MoveStructType},
value::MoveValue,
};
use move_vm_runtime::{
module_traversal::{TraversalContext, TraversalStorage},
Expand Down Expand Up @@ -1011,13 +1012,23 @@ impl FakeExecutor {
let mut arg = args.clone();
match &dynamic_args {
ExecFuncTimerDynamicArgs::DistinctSigners => {
arg.insert(0, bcs::to_bytes(&extra_accounts.pop().unwrap()).unwrap());
arg.insert(
0,
MoveValue::Signer(extra_accounts.pop().unwrap())
.simple_serialize()
.unwrap(),
);
},
ExecFuncTimerDynamicArgs::DistinctSignersAndFixed(signers) => {
for signer in signers.iter().rev() {
arg.insert(0, bcs::to_bytes(&signer).unwrap());
arg.insert(0, MoveValue::Signer(*signer).simple_serialize().unwrap());
}
arg.insert(0, bcs::to_bytes(&extra_accounts.pop().unwrap()).unwrap());
arg.insert(
0,
MoveValue::Signer(extra_accounts.pop().unwrap())
.simple_serialize()
.unwrap(),
);
},
_ => {},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,7 @@ Returns the inner entry function payload of the multisig payload.


<pre><code><b>pragma</b> opaque;
<b>aborts_if</b> [abstract] <b>false</b>;
<b>ensures</b> [abstract] result == <a href="transaction_context.md#0x1_transaction_context_spec_generate_unique_address">spec_generate_unique_address</a>();
</code></pre>

Expand All @@ -1055,6 +1056,7 @@ Returns the inner entry function payload of the multisig payload.


<pre><code><b>pragma</b> opaque;
<b>aborts_if</b> [abstract] <b>false</b>;
// This enforces <a id="high-level-req-3" href="#high-level-req">high-level requirement 3</a>:
<b>ensures</b> [abstract] result == <a href="transaction_context.md#0x1_transaction_context_spec_generate_unique_address">spec_generate_unique_address</a>();
</code></pre>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
spec aptos_framework::permissioned_signer {

spec module {
axiom forall a: GrantedPermissionHandles:
(
forall i in 0..len(a.active_handles):
forall j in 0..len(a.active_handles):
i != j ==>
a.active_handles[i] != a.active_handles[j]
);
}

spec fun spec_is_permissioned_signer(s: signer): bool;

spec is_permissioned_signer(s: &signer): bool {
pragma opaque;
aborts_if [abstract] false;
ensures [abstract] result == spec_is_permissioned_signer(s);
}

spec fun spec_permission_address(s: signer): address;

spec permission_address(permissioned: &signer): address {
pragma opaque;
aborts_if [abstract]!spec_is_permissioned_signer(permissioned);
ensures [abstract] result == spec_permission_address(permissioned);
}

spec fun spec_signer_from_permissioned_handle_impl(
master_account_addr: address, permissions_storage_addr: address
): signer;

spec signer_from_permissioned_handle_impl(
master_account_addr: address, permissions_storage_addr: address
): signer {
pragma opaque;
ensures [abstract] result
== spec_signer_from_permissioned_handle_impl(
master_account_addr, permissions_storage_addr
);
}

spec create_permissioned_handle(master: &signer): PermissionedHandle {
use aptos_framework::transaction_context;
pragma opaque;
aborts_if [abstract] spec_is_permissioned_signer(master);
let permissions_storage_addr = transaction_context::spec_generate_unique_address();
modifies global<PermissionStorage>(permissions_storage_addr);
let master_account_addr = signer::address_of(master);
ensures result.master_account_addr == master_account_addr;
ensures result.permissions_storage_addr == permissions_storage_addr;
}

spec create_storable_permissioned_handle(master: &signer, expiration_time: u64): StorablePermissionedHandle {
use aptos_framework::transaction_context;
pragma opaque;
aborts_if [abstract] spec_is_permissioned_signer(master);
let permissions_storage_addr = transaction_context::spec_generate_unique_address();
modifies global<PermissionStorage>(permissions_storage_addr);
let master_account_addr = signer::address_of(master);
modifies global<GrantedPermissionHandles>(master_account_addr);
ensures result.master_account_addr == master_account_addr;
ensures result.permissions_storage_addr == permissions_storage_addr;
ensures result.expiration_time == expiration_time;
ensures vector::spec_contains(
global<GrantedPermissionHandles>(master_account_addr).active_handles,
permissions_storage_addr
);
ensures exists<GrantedPermissionHandles>(master_account_addr);
}

spec destroy_permissioned_handle(p: PermissionedHandle) {
ensures !exists<PermissionStorage>(p.permissions_storage_addr);
}

spec destroy_storable_permissioned_handle(p: StorablePermissionedHandle) {
ensures !exists<PermissionStorage>(p.permissions_storage_addr);
let post granted_permissions = global<GrantedPermissionHandles>(
p.master_account_addr
);
// ensures [abstract] !vector::spec_contains(granted_permissions.active_handles, p.permissions_storage_addr);
}

spec revoke_permission_storage_address(s: &signer, permissions_storage_addr: address) {
// aborts_if spec_is_permissioned_signer(s);
}

spec authorize<PermKey: copy + drop + store>(
master: &signer, permissioned: &signer, capacity: u256, perm: PermKey
) {

// use aptos_std::type_info;
// use std::bcs;
pragma aborts_if_is_partial;
aborts_if !spec_is_permissioned_signer(permissioned);
aborts_if spec_is_permissioned_signer(master);
aborts_if signer::address_of(permissioned) != signer::address_of(master);
ensures exists<PermissionStorage>(
spec_permission_address(permissioned)
);
// let perms = global<PermissionStorage>(permission_signer_addr).perms;
// let post post_perms = global<PermissionStorage>(permission_signer_addr).perms;
// let key = Any {
// type_name: type_info::type_name<SmartTable<Any, u256>>(),
// data: bcs::serialize(perm)
// };
// ensures smart_table::spec_contains(perms, key) ==>
// smart_table::spec_get(post_perms, key) == old(smart_table::spec_get(perms, key)) + capacity;
// ensures !smart_table::spec_contains(perms, key) ==>
// smart_table::spec_get(post_perms, key) == capacity;
}

spec check_permission_exists<PermKey: copy + drop + store>(s: &signer, perm: PermKey): bool {
pragma opaque;
aborts_if false;
ensures result == spec_check_permission_exists(s, perm);
}

spec fun spec_check_permission_exists<PermKey: copy + drop + store>(s: signer, perm: PermKey): bool {
use aptos_std::type_info;
use std::bcs;
let addr = spec_permission_address(s);
let key = Any {
type_name: type_info::type_name<PermKey>(),
data: bcs::serialize(perm)
};
if (!spec_is_permissioned_signer(s)) { true }
else if (!exists<PermissionStorage>(addr)) { false }
else {
simple_map::spec_contains_key(global<PermissionStorage>(addr).perms, key)
}
}

spec check_permission_capacity_above<PermKey: copy + drop + store>(
s: &signer, threshold: u256, perm: PermKey
): bool {
use aptos_std::type_info;
use std::bcs;
let permissioned_signer_addr = spec_permission_address(s);
ensures !spec_is_permissioned_signer(s) ==> result == true;
ensures (
spec_is_permissioned_signer(s)
&& !exists<PermissionStorage>(permissioned_signer_addr)
) ==> result == false;
let key = Any {
type_name: type_info::type_name<SimpleMap<Any, u256>>(),
data: bcs::serialize(perm)
};
// ensures (spec_is_permissioned_signer(s) && exists<PermissionStorage>(permissioned_signer_addr) && !smart_table::spec_contains(global<PermissionStorage>(permissioned_signer_addr).perms, key)) ==>
// result == false;
// ensures (spec_is_permissioned_signer(s) && exists<PermissionStorage>(permissioned_signer_addr) && smart_table::spec_contains(global<PermissionStorage>(permissioned_signer_addr).perms, key)) ==>
// result == (smart_table::spec_get(global<PermissionStorage>(permissioned_signer_addr).perms, key) > threshold);
}

spec check_permission_consume<PermKey: copy + drop + store>(
s: &signer, threshold: u256, perm: PermKey
): bool {
let permissioned_signer_addr = spec_permission_address(s);
ensures !spec_is_permissioned_signer(s) ==> result == true;
ensures (
spec_is_permissioned_signer(s)
&& !exists<PermissionStorage>(permissioned_signer_addr)
) ==> result == false;

}

spec capacity<PermKey: copy + drop + store>(s: &signer, perm: PermKey): Option<u256> {
// let permissioned_signer_addr = signer::address_of(spec_permission_address(s));
// ensures !exists<PermissionStorage>(permissioned_signer_addr) ==>
// option::is_none(result);
}

spec consume_permission<PermKey: copy + drop + store>(
perm: &mut Permission<PermKey>, weight: u256, perm_key: PermKey
): bool {
// ensures perm.key != perm_key ==> result == false;
// ensures perm.key == perm_key && old(perm.capacity) < weight ==> result == false;
// ensures perm.key == perm_key
// && perm.capacity >= weight ==>
// (perm.capacity == old(perm.capacity) - weight
// && result == true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@ spec aptos_framework::transaction_context {
}
spec generate_unique_address(): address {
pragma opaque;
aborts_if [abstract] false;
ensures [abstract] result == spec_generate_unique_address();
}
spec fun spec_generate_unique_address(): address;
spec generate_auid_address(): address {
pragma opaque;
aborts_if [abstract] false;
// property 3: Generating the unique address should return a vector with 32 bytes, if the auid feature flag is enabled.
/// [high-level-req-3]
ensures [abstract] result == spec_generate_unique_address();
Expand Down
2 changes: 2 additions & 0 deletions aptos-move/framework/aptos-stdlib/doc/smart_table.md
Original file line number Diff line number Diff line change
Expand Up @@ -1479,6 +1479,7 @@ map_spec_has_key = spec_contains;


<pre><code><b>pragma</b> verify = <b>false</b>;
<b>pragma</b> opaque;
</code></pre>


Expand All @@ -1495,6 +1496,7 @@ map_spec_has_key = spec_contains;


<pre><code><b>pragma</b> verify = <b>false</b>;
<b>pragma</b> opaque;
</code></pre>


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ spec aptos_std::smart_table {

spec destroy<K: drop, V: drop>(self: SmartTable<K, V>) {
pragma verify = false;
pragma opaque;
}

spec clear<K: drop, V: drop>(self: &mut SmartTable<K, V>) {
pragma verify = false;
pragma opaque;
}

spec split_one_bucket<K, V>(self: &mut SmartTable<K, V>) {
Expand Down
Loading

0 comments on commit c6019db

Please sign in to comment.