daml - 有没有一种方法可以尝试通过ID来获取契约(Contract),并且在契约(Contract)处于非事件状态时不会失败?

标签 daml

使用合同密钥,有两个函数fetchByKeylookupByKey,后者允许我处理否定查找。我没有看到针对合同编号执行相同操作的lookup : (Template t) => ContractId t -> Update (Optional t)函数。
我也没有看到尝试捕获的机制,该机制将允许我处理失败的fetch调用。

如何在不重新实现整个DAML逻辑客户端的情况下避免交易失败?

最佳答案

这个问题有很多需要解决的问题:

  • 为什么没有lookup
  • 为什么没有try-catch块?
  • 是否可以避免交易失败?
  • 如何在不复制合同逻辑的情况下编写分类帐客户端?
  • lookupByKey和建议的lookup函数允许事务提交者对合同进行不存在的断言。 NonelookupByKey结果断言特定键不存在,Nonelookup断言特定的ContractId不存在。最大的区别在于,合同的合同密钥包括密钥维护者,验证查询的各方。因此很明显,谁必须授权lookupByKey,谁可以验证否定结果。使用lookup,没有与ContractId关联的各方,因此没有明智的授权或验证规则。

    较弱的版本是fetchIfNotArchived : (Template t) => ContractId t -> Update (Optional t),如果id未知则失败,如果合同ID被存档,则返回None。 DAML事务取决于当前分类帐状态,该状态当前是所有活动合同的集合。诸如fetchIfNotArchived之类的功能会在DAML分类帐模型中引入不存在的合同和已存档合同之间的区别,因此分类帐状态将从一开始就从所有活动合同更改为整个分类帐。 DAML分类帐将不再被截断并随时间线性增长,这是不可取的。

    使用try-catch块会遇到非常相似的问题。假设我进行了一些尝试。我可以写这个函数:
    lookup : (Template t) => ContractId t -> Update (Optional t)
    lookup cid = do
      try do
        c <- fetch cid
        return (Some c)
      catch
        return None
    

    如上所述,没有人可以合理地授权或确认提交者遵循正确的道路。因此,这样的try-catch必须被“取消选中”,这意味着提交者可以自由选择是沿着try还是catch路径。您可以通过将存在传递给以下对象来模拟:
    maybeLookup : (Template t) => ContractId t -> Bool -> Update (Optional t)
    maybeLookup cid cidIsKnown = if cidIsKnown
      then do
        c <- fetch cid
        return (Some c)
      else return None
    

    这需要您从外界传递cidIsKnown,这很烦人。可以想象“未经检查的查询”可以在这里提供帮助。例如。可以引入一个函数uncheckedContractActive : (Template t) => ContractId t -> Update Bool,该函数检查合同在提交者端是否处于活动状态,然后仅将Bool包括在事务中。显然,是否像cid存在一样运行事务是提交者的自由选择,反之亦然。

    到目前为止,未经检查的查询尚未进入DAML的原因很简单,原因是它们混淆了共享,保证和验证的逻辑以及单个客户关心的问题。在当前设计中,该拆分恰好在DAML合同和分类帐客户端之间。

    失败的事务实际上并不那么昂贵,只要它们在解释期间在提交者节点上失败即可。重要的是要设计合同模型和分类帐客户,使fetch调用只会由于竞争条件而失败,并且对合同的争用不会太多,因此交易失败很多。你可以试试
  • 设计每个自动化过程,以使其跟踪“待定集”,即它希望通过其运行中的命令进行归档的一组合​​同ID。这消除了每个自动化过程与自身
  • 的争用
  • 如果同一方有两个自动化方案,它们始终在竞争同一合同,则将合同分为两部分,或将自动化方案合并为一个
  • 如果您有两个针对同一合同的当事方具有两个自动化功能,请调整选择的结构以使工作流更加同步。即DAML中的IE控制,现在变成
  • 如果您有一些自动化部件偶尔执行大批操作而导致与其他自动化部件发生竞争,请引入某种“防护”。例如。将Lock合同写到分类帐,向非分批自动化指示应该暂停,或使用Operation合同保护选择,该合同在批处理开始时被撤销。后者具有更强的保证,但是会增加开销,因为它会为每个选择添加一个fetch

  • 一旦将争用降低到可接受的水平,就可以使用分类账客户端中的重试逻辑来处理失败的fetch调用。

    关于daml - 有没有一种方法可以尝试通过ID来获取契约(Contract),并且在契约(Contract)处于非事件状态时不会失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58075358/

    相关文章:

    daml - DAML场景下,如何复用getParty?

    monads - 使用 getTime 函数时出现问题

    daml - 向导航器添加按钮以进行选择

    java - DAML 使用 Java 绑定(bind)流式传输所有 Activity 合约 - LedgerView

    daml - Main.daml 中的语法错误

    daml - 如何通过JSonApi从Daml中查询Map值?

    java - InvalidProtocolBufferException 尝试获取主模块包 ID

    daml - 通过 Java 或 JavaScript 以外的语言使用 DAML Ledger API