Skip to content

Commit

Permalink
Implement rust logics for permissioned signer
Browse files Browse the repository at this point in the history
  • Loading branch information
runtian-zhou committed Sep 10, 2024
1 parent fa646c8 commit dad258f
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 0 deletions.
5 changes: 5 additions & 0 deletions aptos-move/framework/src/natives/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub mod hash;
pub mod object;
pub mod object_code_deployment;
pub mod randomness;
pub mod permissioned_signer;
pub mod state_storage;
pub mod string_utils;
pub mod transaction_context;
Expand Down Expand Up @@ -91,6 +92,10 @@ pub fn all_natives(
"dispatchable_fungible_asset",
dispatchable_fungible_asset::make_all(builder)
);
add_natives_from_module!(
"permissioned_signer",
permissioned_signer::make_all(builder)
);

if inject_create_signer_for_gov_sim {
add_natives_from_module!(
Expand Down
106 changes: 106 additions & 0 deletions aptos-move/framework/src/natives/permissioned_signer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Copyright © Aptos Foundation
// SPDX-License-Identifier: Apache-2.0
use aptos_native_interface::{
safely_pop_arg, RawSafeNative, SafeNativeBuilder, SafeNativeContext, SafeNativeError,
SafeNativeResult,
};
use move_vm_runtime::native_functions::NativeFunction;
use move_vm_types::{
loaded_data::runtime_types::Type,
values::{StructRef, Value, SignerRef},
};
use smallvec::{smallvec, SmallVec};
use std::collections::VecDeque;

/***************************************************************************************************
* native fun is_permissioned_signer
*
* Returns true if the signer passed in is a permissioned signer
* gas cost: base_cost
*
**************************************************************************************************/
fn native_is_permissioned_signer(
_context: &mut SafeNativeContext,
_ty_args: Vec<Type>,
mut arguments: VecDeque<Value>,
) -> SafeNativeResult<SmallVec<[Value; 1]>> {
debug_assert!(arguments.len() == 1);

let s_arg = safely_pop_arg!(arguments, SignerRef);

// context.charge()?;
let result = s_arg.is_permissioned()?;


Ok(smallvec![Value::bool(result)])
}

/***************************************************************************************************
* native fun permission_signer
*
* Returns the permission signer if the signer passed in is a permissioned signer
* gas cost: base_cost
*
**************************************************************************************************/
fn native_permission_signer(
_context: &mut SafeNativeContext,
_ty_args: Vec<Type>,
mut arguments: VecDeque<Value>,
) -> SafeNativeResult<SmallVec<[Value; 1]>> {
debug_assert!(arguments.len() == 1);

let s_arg = safely_pop_arg!(arguments, SignerRef);

// context.charge()?;
if !s_arg.is_permissioned()? {
return Err(SafeNativeError::Abort { abort_code: 3 });
}

Ok(smallvec![s_arg.permissioned_signer()?])
}

/***************************************************************************************************
* native fun signer_from_permissioned
*
* Returns the permission signer from a master signer.
* gas cost: base_cost
*
**************************************************************************************************/
fn native_signer_from_permissioned(
_context: &mut SafeNativeContext,
_ty_args: Vec<Type>,
mut arguments: VecDeque<Value>,
) -> SafeNativeResult<SmallVec<[Value; 1]>> {
debug_assert!(arguments.len() == 1);

let s_arg = safely_pop_arg!(arguments, StructRef);

// context.charge()?;

Ok(smallvec![s_arg.read_ref()?])
}

/***************************************************************************************************
* module
*
**************************************************************************************************/
pub fn make_all(
builder: &SafeNativeBuilder,
) -> impl Iterator<Item = (String, NativeFunction)> + '_ {
let natives = [
(
"is_permissioned_signer",
native_is_permissioned_signer as RawSafeNative,
),
(
"permission_signer",
native_permission_signer
),
(
"signer_from_permissioned_impl",
native_signer_from_permissioned
),
];

builder.make_named_natives(natives)
}
32 changes: 32 additions & 0 deletions third_party/move/move-vm/types/src/values/values_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,10 @@ impl Container {
fn signer(x: AccountAddress) -> Self {
Container::Struct(Rc::new(RefCell::new(vec![ValueImpl::Address(x)])))
}

fn permissioned_signer(x: AccountAddress, permission_address: AccountAddress) -> Self {
Container::Struct(Rc::new(RefCell::new(vec![ValueImpl::Address(x), ValueImpl::Address(permission_address)])))
}
}

/***************************************************************************************
Expand Down Expand Up @@ -1060,6 +1064,30 @@ impl SignerRef {
pub fn borrow_signer(&self) -> PartialVMResult<Value> {
Ok(Value(self.0.borrow_elem(0)?))
}

pub fn is_permissioned(&self) -> PartialVMResult<bool> {
match &self.0 {
ContainerRef::Local(Container::Struct(s)) => {
Ok(s.borrow().len() == 3)
}
_ => Err(
PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR)
.with_message(format!("unexpected signer value: {:?}", self)),
)
}
}

pub fn permissioned_signer(&self) -> PartialVMResult<Value> {
match &self.0 {
ContainerRef::Local(Container::Struct(s)) if s.borrow().len() == 3 => {
Ok(Value::signer(*s.borrow()[1].as_value_ref::<AccountAddress>()?))
}
_ => Err(
PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR)
.with_message(format!("unexpected signer value: {:?}", self)),
)
}
}
}

/***************************************************************************************
Expand Down Expand Up @@ -1221,6 +1249,10 @@ impl Value {
Self(ValueImpl::Container(Container::signer(x)))
}

pub fn permissioned_signer(x: AccountAddress, permission_address: AccountAddress) -> Self {
Self(ValueImpl::Container(Container::permissioned_signer(x, permission_address)))
}

/// Create a "unowned" reference to a signer value (&signer) for populating the &signer in
/// execute function
pub fn signer_reference(x: AccountAddress) -> Self {
Expand Down

0 comments on commit dad258f

Please sign in to comment.