corda - CollectSignaturesFlow 中的流异常
问题描述
我正在创建一个流程以从另一方的 CollectSignaturesFlow 中获取签名,并且我在日志中面临以下问题。
@InitiatingFlow
@StartableByRPC
public static class BGInitiator extends FlowLogic<SignedTransaction> {
private final Party manufacturer;
private final Party regulator;
private final String bgData;
public BGInitiator(Party manufacturer,Party regulator, String bgData) {
this.manufacturer = manufacturer;
this.regulator = regulator;
this.bgData = bgData;
}
private final Step GENERATING_TRANSACTION = new Step("Generating transaction based on YO.");
private final Step BUILDING_TRANSACTION = new Step("Verifying contract constraints.");
private final Step SIGNING_TRANSACTION = new Step("Signing transaction with our private key.");
private final Step GATHERING_SIGS = new Step("Gathering the counterparty's signature.") {
@Override
public ProgressTracker childProgressTracker() {
return CollectSignaturesFlow.Companion.tracker();
}
};
private final Step FINALISING_TRANSACTION = new Step("Obtaining notary signature and recording transaction.") {
@Override
public ProgressTracker childProgressTracker() {
return FinalityFlow.Companion.tracker();
}
};
private final ProgressTracker progressTracker = new ProgressTracker(
GENERATING_TRANSACTION,
BUILDING_TRANSACTION,
SIGNING_TRANSACTION,
GATHERING_SIGS,
FINALISING_TRANSACTION
);
@Override
public ProgressTracker getProgressTracker() {
return progressTracker;
}
@Suspendable
@Override
public SignedTransaction call() throws FlowException {
progressTracker.setCurrentStep(GENERATING_TRANSACTION);
Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
BGState bgState = new BGState(getOurIdentity(),manufacturer,regulator,bgData);
progressTracker.setCurrentStep(BUILDING_TRANSACTION);
final List<PublicKey> requiredSigners = bgState.getParticipantKeys();
final List<Party> parties = bgState.getParties();
final PublicKey me = bgState.getSeller().getOwningKey();
final TransactionBuilder tb = new TransactionBuilder(notary)
.addOutputState(bgState,BGContract.BG_CONTRACT_ID)
.addCommand(new BGContract.Commands.Send(),requiredSigners);
progressTracker.setCurrentStep(SIGNING_TRANSACTION);
final SignedTransaction ptx = getServiceHub().signInitialTransaction(tb,me);
progressTracker.setCurrentStep(GATHERING_SIGS);
FlowSession manufacturerflow = initiateFlow(manufacturer);
final SignedTransaction stx = subFlow(new CollectSignaturesFlow(ptx,ImmutableSet.of(manufacturerflow),ImmutableList.of(me),GATHERING_SIGS.childProgressTracker()));
progressTracker.setCurrentStep(FINALISING_TRANSACTION);
return subFlow(new FinalityFlow(stx,FINALISING_TRANSACTION.childProgressTracker()));
}
}
部署和执行后,流程停止,给我以下错误:
java.lang.IllegalArgumentException: The Initiator of CollectSignaturesFlow must pass in exactly the sessions required to sign the transaction.
at net.corda.core.flows.CollectSignaturesFlow.call(CollectSignaturesFlow.kt:108) ~[corda-core-2.0.0.jar:?]
at net.corda.core.flows.CollectSignaturesFlow.call(CollectSignaturesFlow.kt:64) ~[corda-core-2.0.0.jar:?]
at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:243) ~[corda-core-2.0.0.jar:?]
at com.example.flow.BGFlow$BGInitiator.call(BGFlow.java:107) ~[java-source-0.1.jar:?]
我相信我正在通过所需的流程会话,我仍然得到这个。关于如何解决这个问题的任何想法?
编辑 1:当我使用下面的代码将 flowsession 替换为多个会话并执行它时,流程发生了变化,甚至在日志中什么也没写。我想知道以下是否是获取签名的正确方法。
List<FlowSession> flowSessions = parties.stream().map(a -> initiateFlow(a)).collect(Collectors.toList());
final SignedTransaction stx = subFlow(new CollectSignaturesFlow(ptx,flowSessions,ImmutableList.of(me),GATHERING_SIGS.childProgressTracker()));
BGState 中的 getParties() 代码:
public List<Party> getParties(){
return Arrays.asList(manufacturer,regulator);
}
BGState 定义:
public class BGState implements LinearState,QueryableState {
private final Party seller;
private final Party manufacturer;
private final Party regulator;
private final String senderToReceiverInformation;
private final UniqueIdentifier linearId;
public BGState(Party seller, Party manufacturer,Party regulator,String senderToReceiverInformation) {
this.seller = seller;
this. manufacturer= manufacturer;
this.regulator = regulator;
this.senderToReceiverInformation = senderToReceiverInformation;
this.linearId = new UniqueIdentifier();
}
public Party getSeller() {
return seller;
}
public Party getManufacturer() {
return manufacturer;
}
public Party getRegulator() {
return regulator;
}
@NotNull
@Override
public UniqueIdentifier getLinearId() {
return linearId;
}
@NotNull
@Override
public PersistentState generateMappedObject(MappedSchema schema) {
if (schema instanceof BGSchema) {
return new BGSchema.Bg760(
this.seller,
this.manufacturer,
this.regulator,
this.senderToReceiverInformation,
this.linearId
);
} else {
throw new IllegalArgumentException("Unrecognised schema $schema");
}
}
@NotNull
@Override
public Iterable<MappedSchema> supportedSchemas() {
return ImmutableList.of(new BGSchema());
}
@NotNull
@Override
public List<AbstractParty> getParticipants() {
return Arrays.asList(seller,manufacturer,regulator);
}
public List<PublicKey> getParticipantKeys(){
return getParticipants().stream().map(AbstractParty :: getOwningKey).collect(Collectors.toList());
}
public List<Party> getParties(){
return Arrays.asList(manufacturer,regulator);
}
}
解决方案
FlowSession
传递给的 s 列表CollectSignaturesFlow
必须与交易所需的签名者完全对应。
在这种情况下,监管机构没有FlowSession
通过,监管机构是必需的签名者之一。
推荐阅读
- html - Angular 忽略了在较少文件上设置的样式类
- three.js - 使用四元数进行旋转会导致我的对象以特定角度缩放
- c# - 并发队列
多线程/任务? - java - Netbeans(11)中如何排除module-info.java?
- docker - 在 docker 容器中启动 RabbitMQ
- asp.net-mvc - 如何修剪
来自 MVC cshtml - xamarin.ios - 如何在 Xamarin.iOS 中将 IMTLTexture 分配给 SCNMaterialProperty 的内容?
- java - 如何使用 jms/activemq 发送视频剪辑和图像附件?
- javascript - 从服务器脚本获取变量到客户端脚本
- reactjs - Map 只创建一个 li - React