kleash
kleash

Reputation: 1319

Architecture question for state evolution

I have a sample loan usecase, where I have two states:

Loan State is created by passing Invoice State as input.

enter image description here

Now as Corda follows UTXO model, when I do the default vault query, the Invoice state is not showed as it's consumed now.

To solve this, there are two possible ways:

  1. Either, I query on all states i.e consumed and unconsumed.
  2. Or, I can maintain a status at Invoice state and mark the status to something as Invoice paid after consuming it to create Loan State (So this is more like evolving state, something like bitcoin where balance is always getting transferred.). Something like this:

enter image description here

Can anybody please recommend what would be the correct architecture decision?

Upvotes: 2

Views: 234

Answers (3)

bartman250
bartman250

Reputation: 56

Your Invoice should have a 'state' field with and enum of at least 'UNPAID' and 'PAID' Your 'payInvoice' command should have the following inputs and outputs: inputs: Invoice - state=UNPAID outputs Invoice - state=PAID Loan

The verify function should check that the inputs and outputs for this command are as above. After which the 'UNPAID' invoice state is spent and cannot be used again. I hope that makes sense.

Check out the 'MeteringInvoiceCommands.Pay' method in the following code. This is similar to what you need, but in this case, it is checking that a payment is produced as well as the input state is 'ISSUED' and output state is 'PAID'

https://gitlab.com/cordite/cordite/blob/master/cordapps/metering-contracts-states/src/main/kotlin/io/cordite/metering/contract/MeteringInvoiceContract.kt

Upvotes: 2

Cais Manai
Cais Manai

Reputation: 966

I agree with bartman250. The second example makes the most sense in my view as it keeps options open in a more obvious way.

Let's say for example, for some reason the invoice needs to be reset to unpaid because there is a chargeback on a credit card, having the invoice as unconsumed works well.

The issue of worrying about it being consumed again can be handled by ensuring that the loan contract only consumes invoices that are marked as unpaid. We do something very similar with a purchase order in the letter of credit demo found here.

Having the invoice available to be queried from the vault as unconsumed is also the default query mode. It also provides the advantage of ensuring we're dealing with the latest version of the state by default.

Upvotes: 2

bartman250
bartman250

Reputation: 56

The second example above is the best in my view. Basically, if you hold an Enum on the Invoice with all the different states - i.e. UNPAID, PAID, REJECTED etc. You can then evolve this state in your flows. You can then use the contract verify function for the 'paid command to check that a loan state has been created.

Upvotes: 1

Related Questions