Merge pull request #4520 from stacks-network/feat/allow-private-func-to-return-any-value

feat: return any value type from `execute_contract_allow_private`
This commit is contained in:
saralab
2024-03-15 13:54:23 +00:00
committed by GitHub
3 changed files with 17 additions and 7 deletions

View File

@@ -55,4 +55,4 @@ default = []
developer-mode = []
slog_json = ["stacks_common/slog_json"]
testing = []
devtools = []

View File

@@ -340,8 +340,8 @@ impl DefinedFunction {
pub fn apply(&self, args: &[Value], env: &mut Environment) -> Result<Value> {
match self.define_type {
DefineType::Private => self.execute_apply(args, env),
DefineType::Public => env.execute_function_as_transaction(self, args, None),
DefineType::ReadOnly => env.execute_function_as_transaction(self, args, None),
DefineType::Public => env.execute_function_as_transaction(self, args, None, false),
DefineType::ReadOnly => env.execute_function_as_transaction(self, args, None, false),
}
}

View File

@@ -1139,8 +1139,7 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> {
return Err(CheckErrors::CircularReference(vec![func_identifier.to_string()]).into())
}
self.call_stack.insert(&func_identifier, true);
let res = self.execute_function_as_transaction(&func, &args, Some(&contract.contract_context));
let res = self.execute_function_as_transaction(&func, &args, Some(&contract.contract_context), allow_private);
self.call_stack.remove(&func_identifier, true)?;
match res {
@@ -1168,6 +1167,7 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> {
function: &DefinedFunction,
args: &[Value],
next_contract_context: Option<&ContractContext>,
allow_private: bool,
) -> Result<Value> {
let make_read_only = function.is_read_only();
@@ -1196,7 +1196,7 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> {
self.global_context.roll_back()?;
result
} else {
self.global_context.handle_tx_result(result)
self.global_context.handle_tx_result(result, allow_private)
}
}
@@ -1726,7 +1726,14 @@ impl<'a, 'hooks> GlobalContext<'a, 'hooks> {
self.database.roll_back()
}
pub fn handle_tx_result(&mut self, result: Result<Value>) -> Result<Value> {
// the allow_private parameter allows private functions calls to return any Clarity type
// and not just Response. It only has effect is the devtools feature is enabled. eg:
// clarity = { version = "*", features = ["devtools"] }
pub fn handle_tx_result(
&mut self,
result: Result<Value>,
allow_private: bool,
) -> Result<Value> {
if let Ok(result) = result {
if let Value::Response(data) = result {
if data.committed {
@@ -1735,6 +1742,9 @@ impl<'a, 'hooks> GlobalContext<'a, 'hooks> {
self.roll_back()?;
}
Ok(Value::Response(data))
} else if allow_private && cfg!(feature = "devtools") {
self.commit()?;
Ok(result)
} else {
Err(
CheckErrors::PublicFunctionMustReturnResponse(TypeSignature::type_of(&result)?)