Pact中capability manager函数与@managed的语义是什么
Pact Managed Capability 与 Manager 函数语义规则
针对托管类capability的manager函数相关语义,规则如下:
Pact 中两类capability的核心差异是,托管(managed)类capability支持动态状态校验,这类动态逻辑完全由绑定的manager函数实现,具体规则对应核心疑问逐一明确:
1. Manager 函数的参数来源
你示例中TRANSFER_mgr的两个参数来源遵循固定逻辑:
managed参数:首次触发manager函数时,传入值是@managed声明的托管参数(即示例里的amount)在第一次调用with-capability时传入的初始值;后续同作用域内嵌套申请同一个capability时,这个参数传入的是上一次manager函数的返回值,也就是存在capability作用域上下文里的当前托管状态。requested参数:就是当前这次with-capability调用时,传入托管字段的实际申请值。
注:托管类capability做身份匹配时会忽略@managed声明的托管参数,只匹配其余所有参数(比如
TRANSFER里的sender和receiver),只要非托管参数完全一致,就会被判定为同一capability的嵌套申请,不会新建独立的capability作用域。
对应常规的TRANSFER_mgr实现和参数逻辑完全匹配:
(defun TRANSFER_mgr:decimal (managed:decimal requested:decimal) ;; 校验本次申请的转账额不超过剩余授权额度 (enforce (<= requested managed) "Transfer amount exceeds authorized allowance") ;; 返回更新后的剩余额度,作为下一次调用manager时的managed入参 (- managed requested) )
2. @managed字段的参数规则
@managed元数据仅支持单个托管参数,不支持同时声明多个托管参数。
对应的manager函数参数结构是固定的:
- 第一个参数:类型和托管参数一致,传入当前存储的托管状态值
- 第二个参数:类型和托管参数一致,传入本次申请的托管参数值
- 返回值:类型必须和托管参数一致,用来更新作用域内的托管状态
不存在多托管参数的语法,自然也没有对应多参数的manager函数签名规则。
3. Manager 函数的调用时机
Manager函数仅在调用with-capability申请对应托管类capability时触发,覆盖两类场景:
- 首次在当前作用域申请该capability、需要新建capability作用域时触发,完成初始托管值的校验和状态初始化
- 已经处于该capability作用域内,再次嵌套申请同一capability时触发,完成新增申请值的校验、更新托管状态
当capability离开作用域(也就是with-capability包裹的代码块执行完)时,不会触发manager函数,托管状态会随作用域销毁直接清除。
内容的提问来源于stack exchange,提问作者trh
相关产品推荐
相关产品推荐

