问题
I am creating a flow to fetch signatures from CollectSignaturesFlow of other party and I am facing the below issue in log.
@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()));
}
}
After deploying and executing, the flow stops, giving me the following error:
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:?]
I believe I am passing the required flow session and I am still getting this. Any ideas on how to solve this?
Edit 1: when I replace the flowsession to multiple sessions using the code below and executing it, the flow struck and even wrote nothing in logs. I would like to know whether the following is the correct way to fetch signatures.
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()));
The getParties() code in BGState:
public List<Party> getParties(){
return Arrays.asList(manufacturer,regulator);
}
The BGState Definition:
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);
}
}
回答1:
The list of FlowSession
s passed to CollectSignaturesFlow
must correspond exactly to the transaction's required signers.
In this case, no FlowSession
was passed for the regulator, who is one of the required signers.
来源:https://stackoverflow.com/questions/51064153/flow-exception-in-collectsignaturesflow