假设我有parties A, B, and Z
。
并说明S1 between A and Z
和S2 between B and Z
。 A不是S2,也不是B到S1。
我希望Z修改S1和S2 原子,这样当'事务'正在进行时,A和B都不能分别对S1或S2进行更新。
到目前为止,我们的想法是:Z将首先在S1和S2上获得软锁,然后启动流程来修改S1,其中A作为交易对手,而S2则以B作为交易对手。然后,释放S1和S2上的软锁。
我写了州的合同,以便修改命令要求Z签名。
至关重要的是,如果A或B试图修改S1或S2,如果Z在Z的第一次交易进行时接收到该修改的受主流,它就会拒绝签名。但我必须要实现这一点吗?在S1和S2上获取软锁是否会阻止接受器流对S1和S2做任何事情?
或者有更好的方法吗?
答案 0 :(得分:2)
是的,这非常正确。如果S1和S2是需要{A,Z}和{B,Z}分别签名的多方状态,那么Z可以作为公证人的锁定管理员。
如果软锁不能锁定,则会抛出它。因此,您只需在流程开始时为状态添加预留。如果另一个流程并行锁定,那么您将会抛出并且交易对手会找出原因。
将来我们可能会将软锁定与TransactionBuilder集成在一起,所以只需将一个状态添加到TransactionBuilder就可以自动软锁定它,如果不能,则抛出它。
答案 1 :(得分:1)
在其他答案的基础上,这是使用软锁定API防止节点立即进入涉及两种状态的交易的一种方式:
@InitiatingFlow
@StartableByRPC
class AtomicFlow(val stateRefToSpend: StateRef, val stateRefToLock: StateRef) : FlowLogic<Unit>() {
@Suspendable
override fun call() {
try {
serviceHub.vaultService.softLockReserve(runId.uuid, NonEmptySet.of(stateRefToSpend, stateRefToLock))
} catch (e: StatesNotAvailableException) {
logger.error("A transaction is already underway using S2.")
return
}
val stateToSpend = serviceHub.loadState(stateRefToSpend)
// Continue with transaction...
}
}
答案 2 :(得分:1)
只是为 soft-locking
添加一些清晰度软锁定是一种单节点机制(当前),以防止多个流量花费/修改相同的状态。 no 与其他节点(可能具有相同的共享状态)协调。
正如Mike所指出的那样,公证人是最终的独特性(双重花费预防)协调员。因此,在上面的场景中,竞争条件(例如A和Z试图同时改变S1; B和Z试图同时改变S2)最终将由公证服务解决。
总而言之,软锁定是一种本地节点功能,可通过及早检测双重花费/修改尝试来提高性能,而无需公证。在多节点(分布式状态支出/修改方案)中,公证人是协调员(以及双重支出/共享状态修改的检测器)。