在corda帐户中找不到匿名(DLC2IDBLTXABXK2UGFJZEJ8RBX6HUQUCJYBDJATYJYAJW)错误的参与方

在corda帐户中找不到匿名(DLC2IDBLTXABXK2UGFJZEJ8RBX6HUQUCJYBDJATYJYAJW)错误的参与方,corda,Corda,在我的cordapp中使用帐户net.corda.core.CordaRuntimeException:java.lang.IllegalArgumentException:找不到匿名的参与方(DLBBYFJYHPQXemCtZKG8IXPTU92L3DQIN4BOD1O2FN)时,我在其中一个流中遇到此错误 此错误出现在最终性流程线上 这是错误日志 java.lang.IllegalArgumentException: Could not find Party for Anonymous(DL

在我的cordapp中使用帐户net.corda.core.CordaRuntimeException:java.lang.IllegalArgumentException:找不到匿名的参与方(DLBBYFJYHPQXemCtZKG8IXPTU92L3DQIN4BOD1O2FN)时,我在其中一个流中遇到此错误 此错误出现在最终性流程线上

这是错误日志

java.lang.IllegalArgumentException: Could not find Party for Anonymous(DLKiQpwdw3E7CewLhUatjRpKvCMkHDhEoEYXfAUrp33z7)
    at net.corda.core.identity.IdentityUtils.groupAbstractPartyByWellKnownParty(IdentityUtils.kt:47) ~[corda-core-4.3.jar:?]
    at net.corda.core.identity.IdentityUtils.groupAbstractPartyByWellKnownParty(IdentityUtils.kt:63) ~[corda-core-4.3.jar:?]
    at net.corda.core.flows.FinalityFlow.extractExternalParticipants(FinalityFlow.kt:224) ~[corda-core-4.3.jar:?]
    at net.corda.core.flows.FinalityFlow.call(FinalityFlow.kt:134) ~[corda-core-4.3.jar:?]
    at net.corda.core.flows.FinalityFlow.call(FinalityFlow.kt:39) ~[corda-core-4.3.jar:?]
    at net.corda.node.services.statemachine.FlowStateMachineImpl.subFlow(FlowStateMachineImpl.kt:330) ~[corda-node-4.3.jar:?]
    at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:326) ~[corda-core-4.3.jar:?]
    at com.template.flows.LoanTransferFlow.call(LoanTransferFlow.java:129) ~[?:?]
    at com.template.flows.LoanTransferFlow.call(LoanTransferFlow.java:29) ~[?:?]
    at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:270) ~[corda-node-4.3.jar:?]
    at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:46) ~[corda-node-4.3.jar:?]
    at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
    at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
    at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
    at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:1.8.0_212]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_212]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[?:1.8.0_212]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) ~[?:1.8.0_212]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[?:1.8.0_212]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[?:1.8.0_212]
    at net.corda.node.utilities.AffinityExecutor$ServiceAffinityExecutor$1$thread$1.run(AffinityExecutor.kt:63) ~[corda-node-4.3.jar:?]
该流处于输入状态&3输出状态

以下是流程代码:

@InitiatingFlow
@StartableByRPC
public class LoanTransferFlow extends FlowLogic<SignedTransaction> {

    final AccountInfo borrower;
    final AccountInfo lender;
    UniqueIdentifier loanId = null;
    StateAndRef<InfoState> inputBorrowerState = null;
    private final static Logger logger = LoggerFactory.getLogger(LoanTransferFlow.class);


    public LoanTransferFlow(AccountInfo borrower, AccountInfo lender, UniqueIdentifier loanId, StateAndRef<InfoState> inputBorrowerState) {
        this.borrower = borrower;
        this.lender = lender;
        this.loanId = loanId;
        this.inputBorrowerState = inputBorrowerState;
    }

    @Suspendable
    @Override
    public SignedTransaction call() throws FlowException {
        final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
        List<StateAndRef<InfoState>> matchingLenderStates = null;

        StateAndRef<InfoState> inputInfoLenderState = null;
        StateAndRef<LoanState> inputLoanState = null;


//
//        PublicKey myKey = subFlow(new RequestKeyForAccount(lender.getHost(), lender.getIdentifier().getId())).getOwningKey();
//        PublicKey borrowerKey = subFlow(new RequestKeyForAccount(borrower.getHost(), borrower.getIdentifier().getId())).getOwningKey();

        try {

            Vault.Page<InfoState> lenderStateresults = (Vault.Page<InfoState>) subFlow(new CheckAccountInfoFlow(lender.getName()));
            matchingLenderStates = lenderStateresults.getStates();

        } catch (Exception e) {
            throw new FlowException(e);

        }
        if ((matchingLenderStates == null) || (matchingLenderStates.isEmpty())) {
            throw new FlowException("No Initial Borrower State Exists");
        } else {
            inputInfoLenderState = matchingLenderStates.get(matchingLenderStates.size() - 1);
        }

        QueryCriteria criteriaForLoanVault = new QueryCriteria.LinearStateQueryCriteria(
                null,
                ImmutableList.of(loanId),
                Vault.StateStatus.UNCONSUMED,
                null);
        List<StateAndRef<LoanState>> matchingLoanStates = getServiceHub().getVaultService().queryBy(LoanState.class, criteriaForLoanVault).getStates();
        if ((matchingLoanStates == null) || (matchingLoanStates.isEmpty())) {
            throw new FlowException("No Initial Loan State Exists");
        } else {
            inputLoanState = matchingLoanStates.get(0);
        }

        subFlow(new ShareStateAndSyncAccounts(inputLoanState, borrower.getHost()));

        subFlow(new ShareStateAndSyncAccounts(inputLoanState, lender.getHost()));

        PublicKey myKey = inputLoanState.getState().getData().getLender();
        PublicKey borrowerKey = inputLoanState.getState().getData().getBorrower();

        logger.info("inputState" + inputLoanState.getState().getData().getBorrower() + inputLoanState.getState().getData().getLender());
        logger.info("mykey" + myKey);
        logger.info("borrowerKey" + borrowerKey);

        float updatedBorrowerCreditscore = inputLoanState.getState().getData().getCreditScore() - 15;
        float updatedLenderCreditscore = inputInfoLenderState.getState().getData().getCreditScore() + 30;
        float amount = inputLoanState.getState().getData().getAmount();
        float borrowerBalance = inputBorrowerState.getState().getData().getBalance();
        float lenderBalance = inputInfoLenderState.getState().getData().getBalance();
        if (amount > lenderBalance) {
            throw new FlowException("Insufficient Lender Balance");
        }
        float updatedBorrowerBalance = borrowerBalance + amount;
        float updatedLenderBalance = lenderBalance - amount;

        final Command<LendingContract.Commands.Transfer> command = new Command<LendingContract.Commands.Transfer>(new LendingContract.Commands.Transfer(), Arrays.asList(myKey, borrowerKey));

        LoanState outputLoanState = new LoanState(borrowerKey, myKey, amount, updatedBorrowerCreditscore, "approved", new UniqueIdentifier());
        logger.info("outputState" + outputLoanState.getLender() + outputLoanState.getBorrower());

        InfoState outputBorrowerState = new InfoState(new AnonymousParty(borrowerKey), updatedBorrowerCreditscore, updatedBorrowerBalance, new UniqueIdentifier());

        InfoState outputLenderState = new InfoState(new AnonymousParty(myKey), updatedLenderCreditscore, updatedLenderBalance, new UniqueIdentifier());

        TransactionBuilder txBuilder = new TransactionBuilder(notary);
        txBuilder.addInputState(inputLoanState);
        txBuilder.addCommand(command);
        txBuilder.addOutputState(outputBorrowerState, LendingContract.ID);
        txBuilder.addOutputState(outputLenderState, LendingContract.ID);
        txBuilder.addOutputState(outputLoanState, LendingContract.ID);
        txBuilder.verify(getServiceHub());

        SignedTransaction signedInitialTransaction = getServiceHub().signInitialTransaction(txBuilder, Arrays.asList(getOurIdentity().getOwningKey(), myKey));

        FlowSession counterPartySession = initiateFlow(borrower.getHost());

        List<? extends TransactionSignature> accountToMoveToSignature = subFlow(new CollectSignatureFlow(signedInitialTransaction, counterPartySession, borrowerKey));

        SignedTransaction fullySignedTx = signedInitialTransaction.withAdditionalSignature(accountToMoveToSignature.get(0));

        return subFlow(new FinalityFlow(fullySignedTx));
FYI还使用了该州借款人和贷款人的公钥数据类型

仅供参考,流程在不使用输入状态的情况下工作正常 账户创建流程

    @Suspendable
    override fun call(): AccountInfo {
        //Create a new account
        try {
            val existingAccount = accountService.accountInfo(name = acctName)
            if (existingAccount.size >= 1) {
                throw FlowException("Account Already Exists")
            }
            val newAccount = accountService.createAccount(name = acctName).toCompletableFuture().getOrThrow()
            val acct = newAccount.state.data
            return acct
        } catch (e: Exception) {
            throw FlowException(e)
        }
    }
帐户共享流

   @Suspendable
    override fun call(): Boolean {

        //Create a new account
        val AllmyAccounts = accountService.ourAccounts()
        val SharedAccount = AllmyAccounts.single { it.state.data.name == acctNameShared }.state.data.identifier.id
        accountService.shareAccountInfoWithParty(SharedAccount,shareTo)
        return true
}

供参考-有两个帐户都位于不同的节点上

同时添加输入状态流

public LoanRequestFlow(AccountInfo borrower, AccountInfo lender, float amount) {
    this.borrower = borrower;
    this.amount = amount;
    this.lender = lender;
}

private final ProgressTracker progressTracker = new ProgressTracker();

private final static Logger logger = LoggerFactory.getLogger(LoanRequestFlow.class);


@Override
public ProgressTracker getProgressTracker() {
    return progressTracker;
}

@Suspendable
@Override
public SignedTransaction call() throws FlowException {
    final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
    List<StateAndRef<InfoState>> matchingBorrowerStates = null;

    StateAndRef<InfoState> inputInfoBorrowerState = null;

    PublicKey myKey = subFlow(new NewKeyForAccount(borrower.getIdentifier().getId())).getOwningKey();
    PublicKey lenderKey = subFlow(new RequestKeyForAccount(lender)).getOwningKey();

    try {

        Vault.Page<InfoState> borrowerStateresults = (Vault.Page<InfoState>) subFlow(new CheckAccountInfoFlow(borrower.getName()));
        matchingBorrowerStates = borrowerStateresults.getStates();

    } catch (Exception e) {
        throw new FlowException(e);

    }
    if ((matchingBorrowerStates == null) || (matchingBorrowerStates.isEmpty())) {
        throw new FlowException("No Initial Borrower State Exists");
    } else {
        inputInfoBorrowerState = matchingBorrowerStates.get(matchingBorrowerStates.size() - 1);
    }


    final Command<LendingContract.Commands.Request> command = new Command<LendingContract.Commands.Request>(new LendingContract.Commands.Request(), Arrays.asList(myKey, lenderKey));

    LoanState loanOutputState = new LoanState(myKey, lenderKey, amount, inputInfoBorrowerState.getState().getData().getCreditScore(), "pending", new UniqueIdentifier());

    TransactionBuilder txBuilder = new TransactionBuilder(notary);
    txBuilder.addCommand(command);
    txBuilder.addOutputState(loanOutputState, LendingContract.ID);
    txBuilder.verify(getServiceHub());

    SignedTransaction signedInitialTransaction = getServiceHub().signInitialTransaction(txBuilder, Arrays.asList(getOurIdentity().getOwningKey(), myKey));

    FlowSession counterPartySession = initiateFlow(lender.getHost());

    List<? extends TransactionSignature> accountToMoveToSignature = subFlow(new CollectSignatureFlow(signedInitialTransaction, counterPartySession, lenderKey));

    SignedTransaction fullySignedTx = signedInitialTransaction.withAdditionalSignature(accountToMoveToSignature.get(0));

    return subFlow(new FinalityFlow(fullySignedTx));
公共贷款请求流(账户信息借款人、账户信息贷款人、浮动金额){
this.借款人=借款人;
这个。金额=金额;
this.leader=贷方;
}
private final ProgressTracker ProgressTracker=新ProgressTracker();
私有最终静态记录器Logger=LoggerFactory.getLogger(LoanRequestFlow.class);
@凌驾
公共ProgressTracker getProgressTracker(){
返回进程跟踪器;
}
@暂停
@凌驾
public SignedTransaction调用()引发流异常{
最终参与方公证人=getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
列表匹配借款状态=null;
StateAndRef InputFoFrooderState=null;
PublicKey myKey=subFlow(NewKeyForAccount(forrower.getIdentifier().getId()).getOwningKey();
PublicKey-lenderKey=子流(新的RequestKeyForAccount(贷方)).getOwningKey();
试一试{
Vault.Page借用器StateResults=(Vault.Page)子流(新的CheckAccountInfoFlow(借用器.getName());
matchingBorrowerStates=borrowerStateresults.getStates();
}捕获(例外e){
抛出新的FlowException(e);
}
if((matchingBorrowerStates==null)| |(matchingBorrowerStates.isEmpty()){
抛出新的FlowException(“不存在初始借款人状态”);
}否则{
InputFoFrooderState=MatchingFrooderStates.get(MatchingFrooderStates.size()-1);
}
final Command Command=new命令(new LendingContract.Commands.Request(),Arrays.asList(myKey,lenderKey));
LoanState loanOutputState=新的LoanState(myKey,lenderKey,amount,inputinfobrowerstate.getState().getData().getCreditScore(),“待定”,新的UniqueIdentifier());
TransactionBuilder txBuilder=新TransactionBuilder(公证人);
txBuilder.addCommand(命令);
txBuilder.addOutputState(loanOutputState,LendingContract.ID);
验证(getServiceHub());
SignedTransaction SignedInitialtTransaction=getServiceHub().signInitialTransaction(txBuilder,Arrays.asList(GetTouridenty().getOwningKey(),myKey));
FlowSession counterPartySession=initiateFlow(leander.getHost());

List出现此错误的原因是,最终流正在查看您的输出状态和输入状态,并从中检索参与者

然后,它尝试通过公钥将这些参与者解析为各方

如果节点在抛出您看到的错误之前没有看到这些公钥

因为问题中只有代码片段,所以不太清楚问题的起因

但是,以下示例将复制该问题:

public class SaveLoanFlow extends FlowLogic<SignedTransaction> {
  private AnonymousParty borrower;
  private AnonymousParty lender;
  private float amount;
  private float creditScore;

  public SaveLoanFlow(AnonymousParty borrower, AnonymousParty lender, float amount, float creditScore) {
    this.borrower = borrower;
    this.lender = lender;
    this.amount = amount;
    this.creditScore = creditScore;
  }

  @Suspendable
  @Override
  public SignedTransaction call() throws FlowException {
    final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
    List<PublicKey> signingPubKeys = Arrays.asList(getOurIdentity().getOwningKey());
    TransactionBuilder txBuilder = new TransactionBuilder(notary);
    LoanState loanState = new LoanState(borrower, lender, amount, creditScore, "NEW", new UniqueIdentifier());
    txBuilder.addOutputState(loanState);
    txBuilder.addCommand(new LendingContract.Commands.Transfer(), signingPubKeys);

    SignedTransaction signedInitialTransaction = getServiceHub().signInitialTransaction(txBuilder, signingPubKeys);

    return subFlow(new FinalityFlow(signedInitialTransaction));
  }
}


public class LendingContract implements Contract {

  public static final Party ID = null;

  @Override
  public void verify(@NotNull LedgerTransaction tx) throws IllegalArgumentException {

  }

  /**
   * This contract only implements one command, Transfer.
   */
  public interface Commands extends CommandData {
    class Transfer implements Commands {}
  }
}

@BelongsToContract(LendingContract.class)
public class LoanState implements LinearState {
  private AnonymousParty borrower;
  private AnonymousParty lender;
  private float amount;
  private float creditScore;
  private String status;
  private UniqueIdentifier linearId;

  public LoanState(AnonymousParty borrower, AnonymousParty lender, float amount, float creditScore, String status, UniqueIdentifier linearId) {
    this.borrower = borrower;
    this.lender = lender;
    this.amount = amount;
    this.creditScore = creditScore;
    this.status = status;
    this.linearId = linearId;
  }

  @NotNull
  @Override
  public List<AbstractParty> getParticipants() {
    return ImmutableList.of(borrower, lender);
  }

  @NotNull
  @Override
  public UniqueIdentifier getLinearId() {
    return linearId;
  }

//
//other getters/setters
//
 }
但是,如果更改这两行:

    val borrowerPartyFuture = borrowerNode.startFlow(RequestKeyForAccount(borrowerAccount))
    val lenderPartyFuture = lenderNode.startFlow(RequestKeyForAccount(lenderAccount))
因此,从流将运行且测试将通过的同一节点请求密钥

    val borrowerPartyFuture = lenderNode.startFlow(RequestKeyForAccount(borrowerAccount))
    val lenderPartyFuture = lenderNode.startFlow(RequestKeyForAccount(lenderAccount))
原因是现在贷款人已经知道这两个账户的密钥

因此,在代码中您没有显示的某个地方,您有一个类似的问题,即帐户密钥在两个节点上都不可用

看起来您在问题中发布的流之前运行了另一个流,因为您执行了vault查找并将其用作输入状态

其中一个节点上可能不存在保存状态中的一个密钥

出于(不可预见的?)设计原因,当您在流中保存状态时,生成的密钥不会保存,您必须运行额外的流以确保所有生成的密钥同步

您可以在未显示的流末尾作为子流执行此操作,它可能会解决问题

//If you don't do this you can't lookup accounts by PublicKey on the other host
subFlow(ShareStateAndSyncAccounts(state, lenderAccount.state.data.host))

追踪更多信息。

确保您正在使用Corda 4.3.Yup,使用它。.帐户是在同一个节点上还是在不同的节点上?如果它们在不同的节点上,您是否与每个节点共享了帐户?是的,共享了帐户,有一个与此类似的流在不同的节点上工作,即不使用输入状态Viraz,有太多个uch正在您的流程中进行;很难找出导致错误的原因。谢谢@opticyclic,是的,我在一个只有一个帐户的状态下对该帐户进行了vault查询,但我正在以前的流程中生成新密钥,该流程在没有输入状态的情况下工作,因此您建议我在这里做什么。?早些时候我与您共享了一个帐户一个节点,但现在我与另一个节点共享了计数器帐户,但我仍然遇到相同的问题。是否这样做(ShareStateAndSyncAccounts)在这两个帐户的流程中,但仍然不起作用。相同的错误您说您正在执行Share State和SyncAccounts,但您发布的新代码清楚地表明您没有。我建议将此答案中的代码复制到您的项目中,运行测试以查看错误,然后进行更改以查看修复程序。然后您可以看到它在哪里工作适用于您的代码。在GitHub上创建一个复制该问题的演示项目也会使您更容易获得帮助。您还没有看到流代码,请查看子流(new ShareStateAndSyncAccounts(inputLoanState,borrower.getHost());子流(new ShareStateAndSyncAccounts(inputLoanState,Leader.getHost());
    val borrowerPartyFuture = borrowerNode.startFlow(RequestKeyForAccount(borrowerAccount))
    val lenderPartyFuture = lenderNode.startFlow(RequestKeyForAccount(lenderAccount))
    val borrowerPartyFuture = lenderNode.startFlow(RequestKeyForAccount(borrowerAccount))
    val lenderPartyFuture = lenderNode.startFlow(RequestKeyForAccount(lenderAccount))
//If you don't do this you can't lookup accounts by PublicKey on the other host
subFlow(ShareStateAndSyncAccounts(state, lenderAccount.state.data.host))