我们可以在演化corda状态的同时修改它的参与者列表吗?
我做了一个Corda项目,其中我有一个策略状态,一个发送者,两个接收者。我有三个节点:卖方、保险公司和LSP。我从卖方节点上的一个帐户创建了一个新的PolicyState,并使用PolicyCreationFlow将其发送到保险公司和LSP上的帐户。这种流动效果很好。但是,当我试图从保险公司的终端更新此状态的字段时,它不起作用并生成异常。这意味着当我创建保单状态时,发送方是卖方节点,当我更新保单状态时,发送方是保险公司,接收方是这两个节点中的其余节点 策略状态的代码如下所示:我们可以在演化corda状态的同时修改它的参与者列表吗?,corda,Corda,我做了一个Corda项目,其中我有一个策略状态,一个发送者,两个接收者。我有三个节点:卖方、保险公司和LSP。我从卖方节点上的一个帐户创建了一个新的PolicyState,并使用PolicyCreationFlow将其发送到保险公司和LSP上的帐户。这种流动效果很好。但是,当我试图从保险公司的终端更新此状态的字段时,它不起作用并生成异常。这意味着当我创建保单状态时,发送方是卖方节点,当我更新保单状态时,发送方是保险公司,接收方是这两个节点中的其余节点 策略状态的代码如下所示: @BelongsT
@BelongsToContract(PolicyContract.class)
public class PolicyState implements LinearState {
//private variables
private final UniqueIdentifier linearID;
private final String sellerID;
private final String policyID ;
private final String insurerID;
private final int policyNo;
private final double faceValue;
private final double deathBenefits;
private final double annualPremium;
private final double cashSurrenderValue;
private final String policyStartDate;
private final boolean isVerfied;
private List<AnonymousParty> receivingparties;
private final AnonymousParty policyOwner;
@Nullable
private final boolean isValid;
// private final AnonymousParty inuranceCompany;
public PolicyState(UniqueIdentifier linearID, String policyID, String sellerID, String insurerID, int policyNo, double faceValue, double deathBenefits, double annualPremium,
double cashSurrenderValue, String policyStartDate, AnonymousParty policyOwner, boolean isVerfied, List<AnonymousParty> receivingparties, boolean isValid) {
this.linearID = linearID;
this.policyID = policyID;
this.sellerID = sellerID;
this.insurerID = insurerID;
this.policyNo = policyNo;
this.faceValue = faceValue;
this.deathBenefits = deathBenefits;
this.annualPremium = annualPremium;
this.cashSurrenderValue = cashSurrenderValue;
this.policyStartDate = policyStartDate;
this.policyOwner = policyOwner;
this.isVerfied = isVerfied;
this.receivingparties = receivingparties;
this.isValid = isValid;
// this.inuranceCompany = receivingparties.get(0);
}
/////Getters for the Fields
public String getPolicyID() {
return policyID;
}
public String getSellerID() {
return sellerID;
}
public String getInsurerID() {
return insurerID;
}
public int getPolicyNo() {
return policyNo;
}
public double getFaceValue() {
return faceValue;
}
public double getDeathBenefits() {
return deathBenefits;
}
public double getAnnualPremium() {
return annualPremium;
}
public double getCashSurrenderValue() {
return cashSurrenderValue;
}
public String getPolicyStartDate() {
return policyStartDate;
}
public boolean isVerfied() {
return isVerfied;
}
public AnonymousParty getPolicyOwner() {
return policyOwner;
}
public boolean isValid() {
return isValid;
}
public List<AnonymousParty> getReceivingparties() {
return receivingparties;
}
public PolicyState withNewPolicyOwner(AnonymousParty newOwner){
return new PolicyState(linearID, policyID,sellerID, insurerID, policyNo, faceValue, deathBenefits, annualPremium, cashSurrenderValue, policyStartDate, newOwner, isVerfied, receivingparties, isValid);
}
public PolicyState deletePolicy(AnonymousParty policyOwner){
return new PolicyState(linearID, policyID,sellerID, insurerID, policyNo, faceValue, deathBenefits, annualPremium, cashSurrenderValue, policyStartDate, policyOwner, isVerfied,receivingparties, false);
}
@NotNull
@Override
public UniqueIdentifier getLinearId() {
return linearID;
}
@NotNull
@Override
public List<AbstractParty> getParticipants() {
// return Arrays.asList(policyOwner,inuranceCompany);
List<AbstractParty> allParts = new ArrayList<>();
allParts.addAll(receivingparties);
allParts.add(policyOwner);
return allParts;
}
}
@InitiatingFlow
@StartableByRPC
public static class PolicyCreation extends FlowLogic<SignedTransaction> {
private final ProgressTracker.Step GENERATING_TRANSACTION = new ProgressTracker.Step("Generating transaction.");
private final ProgressTracker.Step ADDING_POLICY = new ProgressTracker.Step("Adding the Policy State to Transaction.");
private final ProgressTracker.Step VERIFYING_TRANSACTION = new ProgressTracker.Step("Verifying contract constraints.");
private final ProgressTracker.Step SIGNING_TRANSACTION = new ProgressTracker.Step("Signing transaction with our private key.");
private final ProgressTracker.Step GATHERING_SIGS = new ProgressTracker.Step("Gathering the counterparty's signature.") {
@Override
public ProgressTracker childProgressTracker() {
return CollectSignaturesFlow.Companion.tracker();
}
};
private final ProgressTracker.Step FINALISING_TRANSACTION = new ProgressTracker.Step("Obtaining notary signature and recording transaction.") {
@Override
public ProgressTracker childProgressTracker() {
return FinalityFlow.Companion.tracker();
}
};
private final ProgressTracker progressTracker = new ProgressTracker(
GENERATING_TRANSACTION,
ADDING_POLICY,
VERIFYING_TRANSACTION,
SIGNING_TRANSACTION,
GATHERING_SIGS,
FINALISING_TRANSACTION
);
@Override
public ProgressTracker getProgressTracker() {
return progressTracker;
}
//PolicyState Fields
private final String policyID;
private final String sellerID;
private final String insurerID;
private final int policyNo;
private final double faceValue;
private final double deathBenefits;
private final double annualPremium;
private final double cashSurrenderValue;
private final String policyStartDate;
private final String policyOwner;
private final String insuranceCompany;
private final String lsp;
//Constructor for PolicyCreation
public PolicyCreation(String policyID, String sellerID, String insurerID, int policyNo, double faceValue, double deathBenefits, double annualPremium,
double cashSurrenderValue, String policyStartDate, String policyOwner, String insuranceCompany, String lsp) {
this.policyID = policyID;
this.sellerID = sellerID;
this.insurerID = insurerID;
this.policyNo = policyNo;
this.faceValue = faceValue;
this.deathBenefits = deathBenefits;
this.annualPremium = annualPremium;
this.cashSurrenderValue = cashSurrenderValue;
this.policyStartDate = policyStartDate;
this.policyOwner = policyOwner;
this.insuranceCompany = insuranceCompany;
this.lsp = lsp;
}
@Suspendable
@Override
public SignedTransaction call() throws FlowException {
AccountService accountService = getServiceHub().cordaService(KeyManagementBackedAccountService.class);
//Owner Account
AccountInfo policyOwnerAccountInfo = accountService.accountInfo(policyOwner).get(0).getState().getData();
PublicKey policyOwnerKey = subFlow(new NewKeyForAccount(policyOwnerAccountInfo.getIdentifier().getId())).getOwningKey();
//Insurance Company Account
AccountInfo insurerAccountInfo = accountService.accountInfo(insuranceCompany).get(0).getState().getData();
AnonymousParty insuranceCompanyAccount = subFlow(new RequestKeyForAccount(insurerAccountInfo));
//LSP account
AccountInfo lspAccountInfo = accountService.accountInfo(lsp).get(0).getState().getData();
AnonymousParty lspAccount = subFlow(new RequestKeyForAccount(lspAccountInfo));
List<AccountInfo> parties = new ArrayList<>();
parties.add(insurerAccountInfo);
parties.add(lspAccountInfo);
// Step 1. Get a reference to the notary service on our network and our key pair.
// Note: ongoing work to support multiple notary identities is still in progress.
final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
// UniqueIdentifier policyLinearId = new UniqueIdentifier(policyID);
final PolicyState output = new PolicyState(new UniqueIdentifier(policyID), policyID, sellerID, insurerID, policyNo, faceValue, deathBenefits, annualPremium, cashSurrenderValue, policyStartDate,new AnonymousParty(policyOwnerKey), false, Arrays.asList(insuranceCompanyAccount,lspAccount), true);
progressTracker.setCurrentStep(GENERATING_TRANSACTION);
final TransactionBuilder builder = new TransactionBuilder(notary);
//Adding outputState to the transaction
progressTracker.setCurrentStep(ADDING_POLICY);
builder.addOutputState(output, PolicyContract.ID);
builder.addCommand(new PolicyContract.Commands.Create(), Arrays.asList(policyOwnerKey,insuranceCompanyAccount.getOwningKey(),lspAccount.getOwningKey()));
// self sign Transaction
progressTracker.setCurrentStep(SIGNING_TRANSACTION);
builder.verify(getServiceHub());
SignedTransaction locallySignedTx = getServiceHub().signInitialTransaction(builder, Arrays.asList(getOurIdentity().getOwningKey(),policyOwnerKey));
progressTracker.setCurrentStep(GATHERING_SIGS);
FlowSession session = initiateFlow(insurerAccountInfo.getHost());
List<TransactionSignature> accountToMoveToSignature = (List<TransactionSignature>) subFlow(new CollectSignatureFlow(locallySignedTx,
session,insuranceCompanyAccount.getOwningKey()));
SignedTransaction signedByCounterParty = locallySignedTx.withAdditionalSignatures(accountToMoveToSignature);
FlowSession session1 = initiateFlow(lspAccountInfo.getHost());
List<TransactionSignature> accountToMoveToSignature1 = (List<TransactionSignature>) subFlow(new CollectSignatureFlow(signedByCounterParty,
session1,lspAccount.getOwningKey()));
signedByCounterParty = signedByCounterParty.withAdditionalSignatures(accountToMoveToSignature1);
progressTracker.setCurrentStep(FINALISING_TRANSACTION);
return subFlow(new FinalityFlow(signedByCounterParty, session,session1));
// return subFlow(new FinalityFlow(signedByCounterParty,
// Arrays.asList(session).stream().filter(it -> it.getCounterparty() != getOurIdentity()).collect(Collectors.toList())));
}
}
@InitiatedBy(PolicyCreation.class)
public static class PolicyCreationResponder extends FlowLogic<String> {
//private variable
private FlowSession counterpartySession;
//Constructor
public PolicyCreationResponder(FlowSession counterpartySession) {
this.counterpartySession = counterpartySession;
}
@Override
@Suspendable
public String call() throws FlowException {
AtomicReference accountMovedTo = new AtomicReference< AccountInfo>();
SignedTransaction signedTransaction = subFlow(new SignTransactionFlow(counterpartySession) {
@Suspendable
@Override
protected void checkTransaction(SignedTransaction stx) throws FlowException {
// Custom Logic to validate transaction.
}
});
subFlow(new ReceiveFinalityFlow(counterpartySession));
return "Policy Sent";
}
}
卖方节点(更新流的接收者之一)的日志显示:
我如何才能使其正确,因为根据项目要求,卖方将在区块链上添加保单,保险公司将验证相同的保单?通常,发生此问题是因为接收方没有发送方的
AccountInfo
。创建卖方帐户时,您还生成该帐户的公钥,但其他参与者不知道该密钥与卖方节点的X.500名称之间的映射
您可以在保单创建流程的末尾添加以下内容:
subFlow(ShareStateAndSyncAccounts(state, borrowerAccountInfo.state.data.host))
作为参考:和。谢谢Alessandro,但我已使用ShareAccountInfo共享了所有帐户。我是否仍会收到相同的错误?
java.lang.IllegalArgumentException: Could not find Party for Anonymous(DLCtNGZXmvmEJCHLNA1GCCwYv39gGJxsgf7MTfytmKgtT4)
at net.corda.core.identity.IdentityUtils.groupAbstractPartyByWellKnownParty(IdentityUtils.kt:47) ~[corda-core-4.5.jar:?]
at net.corda.core.identity.IdentityUtils.groupAbstractPartyByWellKnownParty(IdentityUtils.kt:63) ~[corda-core-4.5.jar:?]
at net.corda.core.flows.FinalityFlow.extractExternalParticipants(FinalityFlow.kt:252) ~[corda-core-4.5.jar:?]
at net.corda.core.flows.FinalityFlow.call(FinalityFlow.kt:162) ~[corda-core-4.5.jar:?]
at net.corda.core.flows.FinalityFlow.call(FinalityFlow.kt:43) ~[corda-core-4.5.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.subFlow(FlowStateMachineImpl.kt:362) ~[corda-node-4.5.jar:?]
at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:397) ~[corda-core-4.5.jar:?]
at com.BLife.flows.VerifyPolicyFlow$VerifyPolicy.call(VerifyPolicyFlow.java:107) ~[?:?]
at com.BLife.flows.VerifyPolicyFlow$VerifyPolicy.call(VerifyPolicyFlow.java:30) ~[?:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:299) ~[corda-node-4.5.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:66) ~[corda-node-4.5.jar:?]
at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092) ~[quasar-core-0.7.12_r3-jdk8.jar:0.7.12_r3]
at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788) ~[quasar-core-0.7.12_r3-jdk8.jar:0.7.12_r3]
at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100) ~[quasar-core-0.7.12_r3-jdk8.jar:0.7.12_r3]
at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91) ~[quasar-core-0.7.12_r3-jdk8.jar:0.7.12_r3]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:1.8.0_265]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_265]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[?:1.8.0_265]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) ~[?:1.8.0_265]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[?:1.8.0_265]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[?:1.8.0_265]
at net.corda.node.utilities.AffinityExecutor$ServiceAffinityExecutor$1$thread$1.run(AffinityExecutor.kt:63) ~[corda-node-4.5.jar:?]
net.corda.core.flows.UnexpectedFlowEndException: Counter-flow errored
at Received unexpected counter-flow exception from peer O=InsuranceCompany, L=New York, C=US.() ~[?:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.fillInLocalStackTrace(FlowStateMachineImpl.kt:204) ~[corda-node-4.5.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.processEventsUntilFlowIsResumed(FlowStateMachineImpl.kt:192) ~[corda-node-4.5.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.suspend(FlowStateMachineImpl.kt:506) ~[corda-node-4.5.jar:?]
at net.corda.node.services.statemachine.FlowSessionImpl.receive(FlowSessionImpl.kt:67) ~[corda-node-4.5.jar:?]
at net.corda.node.services.statemachine.FlowSessionImpl.receive(FlowSessionImpl.kt:71) ~[corda-node-4.5.jar:?]
at net.corda.core.flows.ReceiveTransactionFlow.call(ReceiveTransactionFlow.kt:103) ~[corda-core-4.5.jar:?]
at net.corda.core.flows.ReceiveTransactionFlow.call(ReceiveTransactionFlow.kt:31) ~[corda-core-4.5.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.subFlow(FlowStateMachineImpl.kt:362) ~[corda-node-4.5.jar:?]
at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:397) ~[corda-core-4.5.jar:?]
at net.corda.core.flows.ReceiveFinalityFlow.call(FinalityFlow.kt:285) ~[corda-core-4.5.jar:?]
at net.corda.core.flows.ReceiveFinalityFlow.call(FinalityFlow.kt:280) ~[corda-core-4.5.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.subFlow(FlowStateMachineImpl.kt:362) ~[corda-node-4.5.jar:?]
at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:397) ~[corda-core-4.5.jar:?]
at com.BLife.flows.VerifyPolicyFlow$VerifyPolicyResponder.call(VerifyPolicyFlow.java:133) ~[?:?]
at com.BLife.flows.VerifyPolicyFlow$VerifyPolicyResponder.call(VerifyPolicyFlow.java:113) ~[?:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:299) ~[corda-node-4.5.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:66) ~[corda-node-4.5.jar:?]
at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092) ~[quasar-core-0.7.12_r3-jdk8.jar:0.7.12_r3]
at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788) ~[quasar-core-0.7.12_r3-jdk8.jar:0.7.12_r3]
at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100) ~[quasar-core-0.7.12_r3-jdk8.jar:0.7.12_r3]
at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91) ~[quasar-core-0.7.12_r3-jdk8.jar:0.7.12_r3]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:1.8.0_265]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_265]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[?:1.8.0_265]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) ~[?:1.8.0_265]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[?:1.8.0_265]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[?:1.8.0_265]
at net.corda.node.utilities.AffinityExecutor$ServiceAffinityExecutor$1$thread$1.run(AffinityExecutor.kt:63) ~[corda-node-4.5.jar:?]
subFlow(ShareStateAndSyncAccounts(state, borrowerAccountInfo.state.data.host))