Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error with Initiating Flow ConfidentialMoveFungibleTokens() #169

Open
TywinLannister1313 opened this issue Dec 17, 2019 · 4 comments
Open

Comments

@TywinLannister1313
Copy link

Operating System: Windows 10
Corda: 4.3
tokens_release_version = '1.1-RC06-PRESIGN'
Testing with a MockNetwork

I hope I am not making a rookie mistake but I am getting an error when I call:

ConfidentialMoveFungibleTokens(partyAndAmount, observers, queryCriteria, changeHolder));

  1. The error occurs ONLY if there is change. If there is an amount in the vault that exactly matches the move request then no error occurs.

  2. The vault does not get updated (i.e. no states are consumed and no tokens are moved).

Here is the error:

java.lang.IllegalArgumentException: You must provide sessions for all parties.
at com.r3.corda.lib.tokens.workflows.internal.flows.confidential.AnonymisePartiesFlow.call(AnonymisePartiesFlow.kt:23) ~[tokens-workflows-1.1-RC06-PRESIGN.jar:?]
at com.r3.corda.lib.tokens.workflows.internal.flows.confidential.AnonymisePartiesFlow.call(AnonymisePartiesFlow.kt:16) ~[tokens-workflows-1.1-RC06-PRESIGN.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.r3.corda.lib.tokens.workflows.flows.confidential.ConfidentialTokensFlow.call(ConfidentialTokensFlow.kt:41) ~[tokens-workflows-1.1-RC06-PRESIGN.jar:?]
at com.r3.corda.lib.tokens.workflows.flows.confidential.ConfidentialTokensFlow.call(ConfidentialTokensFlow.kt:28) ~[tokens-workflows-1.1-RC06-PRESIGN.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.r3.corda.lib.tokens.workflows.flows.move.ConfidentialMoveFungibleTokensFlow.call(ConfidentialMoveFungibleTokensFlow.kt:63) ~[tokens-workflows-1.1-RC06-PRESIGN.jar:?]
at com.r3.corda.lib.tokens.workflows.flows.move.ConfidentialMoveFungibleTokensFlow.call(ConfidentialMoveFungibleTokensFlow.kt:30) ~[tokens-workflows-1.1-RC06-PRESIGN.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.r3.corda.lib.tokens.workflows.flows.rpc.ConfidentialMoveFungibleTokens.call(MoveTokens.kt:149) ~[tokens-workflows-1.1-RC06-PRESIGN.jar:?]
at com.r3.corda.lib.tokens.workflows.flows.rpc.ConfidentialMoveFungibleTokens.call(MoveTokens.kt:120) ~[tokens-workflows-1.1-RC06-PRESIGN.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.USDConfidentialMove.call(USDConfidentialMove.java:78) ~[main/:?]
at com.template.flows.USDConfidentialMove.call(USDConfidentialMove.java:27) ~[main/:?]
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_192]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_192]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[?:1.8.0_192]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) ~[?:1.8.0_192]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[?:1.8.0_192]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[?:1.8.0_192]
at net.corda.node.utilities.AffinityExecutor$ServiceAffinityExecutor$1$thread$1.run(AffinityExecutor.kt:63) ~[corda-node-4.3.jar:?]

Let me know if I can provide more information. I will test ConfidentialRedeemFungibleTokens() next.

@TywinLannister1313
Copy link
Author

I am getting the same error with the inline confidential moves:
ConfidentialMoveFungibleTokensFlow / ConfidentialMoveTokensFlowHandler

Example:

ConfidentialMoveFungibleTokensFlow(
partyAndAmount, 
ImmutableList.of(counterPartySession),
changeHolder,
queryCriteria,
ImmutableList.of(observerSession)
)

... so I am either making the same mistake in both places and not seeing it (very possible) or something is fishy.

@roastario
Copy link
Contributor

@TywinLannister1313 sorry this languished so long - I will try and replicate this.

@TywinLannister1313
Copy link
Author

@roastario - no worries I am sure you guys are busy. Let me know if you find anything. I assume it uses Confidential Identities - ? I haven't had a chance to learn/test ci yet. If I had to guess I'd bet I am doing something wrong with ci's setup.

@TywinLannister1313
Copy link
Author

TywinLannister1313 commented Sep 17, 2020

@roastario I am still getting this error testing ConfidentialMoveFungibleTokens with:
Corda = 4.5
Token-SDK = 1.2

The error message has changed slightly but it occurs under the same circumstances (anytime there is change to be returned in a transaction using ConfidentialMoveFungibleTokens):

java.util.concurrent.ExecutionException: net.corda.core.CordaRuntimeException: java.lang.IllegalArgumentException: You must provide sessions for all parties. No sessions provided for parties: [O=PartyA, L=London, C=GB]

I tried to walk through the ConfidentialMoveFungibleTokens code as best I could and I admit - I don't see anywhere that a FlowSession is created to the Party that has been identified as the changeHolder. Which makes sense because you generally return change to yourself and should not create a flowsession to yourself. I did get a better understanding of who/how FlowSessions are created and if I calculate the change myself and include it in the List<PartyAndAmount> then it works fine but I don’t think that is the intent and it’s not how the non-confidential MoveFungibleTokens works.

Here are is a simple Test and Flow:

public class TokenTests {

    private final MockNetwork mockNetwork = new MockNetwork(ImmutableList.of(
            "com.r3.corda.lib.tokens.contracts",
            "com.r3.corda.lib.tokens.workflows.flows"
    ));

    private StartedMockNode partyANode = mockNetwork.createNode(new CordaX500Name("PartyA", "London", "GB"));
    private StartedMockNode partyBNode = mockNetwork.createNode(new CordaX500Name("PartyB", "New York", "US"));

    Party partyA = partyANode.getInfo().getLegalIdentities().get(0);
    Party partyB = partyBNode.getInfo().getLegalIdentities().get(0);

    @Before
    public void setup() {
        mockNetwork.startNodes();
    }

    @After
    public void tearDown() {
        mockNetwork.stopNodes();
    }

    @Test
    public void confidentialFungibleTokenIssueAndMove() {

        long issueAmount = 1000L;
        Long moveAmount = 750L;

        try {

            // Create your tokens
            TokenType kWh = new TokenType("kWh", 0);
            IssuedTokenType issuedkWh = new IssuedTokenType(partyA, kWh);
            Amount<IssuedTokenType> amountIssuedkWh = new Amount<>(issueAmount, issuedkWh);
            FungibleToken fungibleToken = new FungibleToken(amountIssuedkWh,
                    partyA,
                    TransactionUtilitiesKt.getAttachmentIdForGenericParam(kWh)
            );

            // A issues tokens to A
            FungibleTokenConfidentialIssue fungibleTokenConfidentialIssue = new FungibleTokenConfidentialIssue(
                    fungibleToken,
                    Collections.emptyList()
            );
            CordaFuture<SignedTransaction> futureIssue = partyANode.startFlow(fungibleTokenConfidentialIssue);
            mockNetwork.runNetwork();

            // A moves tokens to B
            FungibleTokenConfidentialMove fungibleTokenConfidentialMoveToB = new FungibleTokenConfidentialMove(
                    kWh,
                    moveAmount,
                    partyB,
                    Collections.emptyList(),
                    new QueryCriteria.VaultQueryCriteria(Vault.StateStatus.UNCONSUMED),
                    partyA
            );
            CordaFuture<SignedTransaction> futureMoveToPartyB = partyANode.startFlow(fungibleTokenConfidentialMoveToB);
            mockNetwork.runNetwork();

        } catch(InterruptedException | ExecutionException e) {
            System.out.println("An error has occurred: " + e);
        }
    }
}
@InitiatingFlow
@StartableByRPC
public class FungibleTokenConfidentialIssue extends FlowLogic<SignedTransaction> {

    private FungibleToken fungibleToken;
    private List<Party> observers;

    public FungibleTokenConfidentialIssue(FungibleToken fungibleToken, List<Party> observers) {
        this.fungibleToken = fungibleToken;
        this.observers = observers;
    }

    @Suspendable
    @Override
    public SignedTransaction call() throws FlowException {

        return subFlow(new ConfidentialIssueTokens(Collections.singletonList(fungibleToken), observers));
    }
}
@InitiatingFlow
@StartableByRPC
public class FungibleTokenConfidentialMove extends FlowLogic<SignedTransaction> {
    private final TokenType tokenType;
    private final Long quantity;
    private final Party receiver;
    private final List<Party> observers;
    private final QueryCriteria queryCriteria;
    private final Party changeHolder;

    public FungibleTokenConfidentialMove(
            TokenType tokenType,
            Long quantity,
            Party receiver,
            List<Party> observers,
            QueryCriteria queryCriteria,
            Party changeHolder)
    {
        this.tokenType = tokenType;
        this.quantity = quantity;
        this.receiver = receiver;
        this.observers = observers;
        this.queryCriteria = queryCriteria;
        this.changeHolder = changeHolder;
    }

    @Suspendable
    @Override
    public SignedTransaction call() throws FlowException {

        Amount<TokenType> amount = new Amount<>(quantity, tokenType);
        PartyAndAmount<TokenType> partyAndAmount = new PartyAndAmount<>(receiver, amount);

        return subFlow(new ConfidentialMoveFungibleTokens(partyAndAmount, observers, queryCriteria, changeHolder));
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants