Reference code:
Git clone URL: git clone https://github.com/corda/cordapp-tutorial
Release M14: git checkout -b release-M14.0
I am little bit confused about how the data flows in Corda. I have some database related queries:
Is the database structure fixed or can we add our custom tables in it?
Where can I see the data flowing in tables? When I do a cash transaction, I can see it in the AULT_CASH_BALANCES table in my H2 database client, but apart from cash I am unable to see any details of my other transactions, i.e., if I save a string then I am unable to get the information, I only get the transaction ID for that.
Is it possible to get entire data flow diagram?
Are the Node and Vault tables created every time when I build a code?
You can define how each state type is stored in the node by implementing the QueryableState interface. Each state type that implements QueryableState will have its own custom database table.
See https://github.com/corda/cordapp-tutorial/blob/master/kotlin-source/src/main/kotlin/com/example/state/IOUState.kt for an example. Since the IOU state implements a schema (in the Kotlin version of the CorDapp), you can see the sender, recipient and value from the H2 interface for each IOU state.
In the current implementation, the node's data is stored in the persistence.mv.db file of the deployed node. This will be wiped whenever you run gradlew deployNodes. However, if you simply create an updated CorDapp jar by running gradlew jar, you can then copy the updated CorDapp jar from build/libs into each node's plugins folder, and the node will use the new plugin.
Related
I am getting column "identity_value" is of type byte error while running the Corda node. I am trying to use one existing schema(party_a_schema) for one of my cordapp. I have updated the node.conf file for that node.
After basic analysis, I have found that to use a schema over multiple cordapp in Corda open-source platform, we must execute the below DDL statement.
CREATE SEQUENCE my_schema.hibernate_sequence INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 8 CACHE 1 NO CYCLE;
At the time of script execution, I am getting this error
Above issue has been resolved. This happens when you do a clean deployNodes many times, in which case your node files are deleted (including the truststores,keys,certificates,nodeinfo files) but these are not deleted from the database. Eventually, you corrupt the database with a new entry being added each time you deploy the node, and hence eventually the node does not start properly.
Ideally in production when you deploy, when you deploy your cordapp for the first time all the required tables are created, node info files, identities , certificates etc. Later if you want to make any changes ideally what you do is upgrade your cordapp and perform database migrations (you dont clean up your entire database).
Hence, in development mode when you connect to an external database, whenever you do a clean deployNodes on the terminal also clean up your database.
I am going through this documentation and I have several uncertainties.
Performing explicit contract and state upgrades
Preserve the existing state and contract definitions
Write the new state and contract definitions
Create the new CorDapp JAR
Distribute the new CorDapp JAR
Stop the nodes
Re-run the network bootstrapper (only if you want to whitelist the
new contract)
Restart the nodes
Authorise the upgrade
Perform the upgrade
Migrate the new upgraded state to the Signature Constraint from the
zone constraint
Questions:
1. Preserve the existing state and contract definitions
2. Write the new state and contract definitions
3. Create the new CorDapp JAR
How do I do that? is it meant only to preserve jars with contracts and states on nodes, not preserving them in source code? If I do not preserve them in source code then how can I create the upgrade method?
interface UpgradedContract<in OldState : ContractState, out NewState : ContractState> : Contract {
val legacyContract: ContractClassName
fun upgrade(state: OldState): NewState
}
If I do not preserve old state in source code, then shoud I name the jar differently each time I need to do an upgrade?
Can old jars be reoved from the node when the upgrade was completed?
6. Re-run the network bootstrapper (only if you want to whitelist the
new contract)
8. Authorise the upgrade
Am I right that only those 2 steps are related to Explicit contact upgrades? And If I use implicit flow with signature, then I need to skip only those two steps, while the others are still aplicable and must be performed?
9. Perform the upgrade
Should this be done for each state separately by the owner of the state? In that case should I run it on each node for specific contrcats where the node is the participant of the state? (In doc it is mentioned to be run on single node - but what id=f a single node is not participant of some state)
Other questions
This section describes explicit contracts and states update.
https://docs.corda.net/upgrading-cordapps.html#performing-explicit-contract-and-state-upgrades while signature constraint section (https://docs.corda.net/api-contract-constraints.html#signature-constraints) does not describe an update process for states.
is it the same as for explicit upgrades with the difference only in steps 6,8 or it is somewhat completely different?
Do I need to create the function transforming old states to new states in that case? if not , then how the old states will be handled by new flows?
I see you have many some great questions about contract upgrades. Here is an article that is written by one of our dev-relation engineers. https://medium.com/corda/contract-upgrades-and-constraints-in-corda-425055a9a47f
Feel free to follow up any additional questions that you have.
If you are new to Corda, feel free to join the Corda community channels #http://slack.corda.net/
While performing legacy contract upgrades, you need both the old and new contract jars installed on your node. (present in the cordapps folder).
You can create a new Gradle module say v2-contract and write the new contract in this. This is where you will write your UpgradedContract. You will need to refer to the old v1-conract jar as well as it needs to know what the old state was. To do this add a gradle dependency in v2-contract like below.
dependencies {
// Corda dependencies.
cordapp project(v1_contract)
}
The old jar can be removed from the cordapps folder, once all the states have been upgraded to new v2-contract.
a. For HashConstraints there is no need to run the bootstrapper again. You will write the new contract by implementing UpgradedContractWithLegacyConstraint,run the jar task to build this new jar, add it to the cordapps folder, run the Authorise Flow from all nodes, run the Initiate flow from one of he node's terminal. This is the explicit way of upgrading.
b. However if you are using Whitelistzoneconstraint, you want to make sure to add the new v2-contract jar's hash to whitelist param in network param. You will need to run the network Bootstrapper to whitelist this new v2-contracts jar hash. https://docs.corda.net/network-bootstrapper.html#whitelisting-contracts.
Once you do that you can either go for an explicit upgrade by implementing UpgradedContract, or you can use implicit upgrade.
c. If you are using Signature Constraints, no need to run the network Bootstrapper for the new jar, write the new v2-contract, build it using gradle jar task, replace old jar with new jar. This is the implicit way of upgrading.
You should run the Authorise Flow for all the participants only.
Other questions
There is no explicit upgrade in Signature constraints. You need to make sure you write your state in a backward compatible way, build new jar, replace old jar with new jar. The states will refer to the new contract then.
Hope that helps. Feel free to post more questions on the above answer or ping on Slack.
Is corda support state deletion scenario when don't need to use some state (in both dev/prod)
Because I face exception when start node like "class not found exception", It's happen when I delete state class in project and use same old persistence file.
I think it because of state class already insert in VAULT_STATES and it can't find that class when start node.
I expect to have some method that provide state deletion.
More info
In Dev side I delete persistence file and of course it's work, but I just worry about Production side.
As of Corda 3, if a node has a state stored as part of a transaction in its transaction storage or in its vault, the node needs to keep the state's class definition on its classpath permanently.
You can delete old transactions and states directly via the node's database, but only if the transactions are not required for transaction resolution. You would do this by dropping rows from the NODE_TRANSACTIONS and VAULT_STATES tables in the node's database (as well as any custom tables defined by the state's schemas if it is a QueryableState). However, if the deleted transactions are later required as part of transaction resolution, your node will throw an error.
Future versions of Corda may provide a mechanism to delete old or "non-current" states and transactions. You can find a discussion of what this process may look like here: https://groups.io/g/corda-dev/topic/20405353.
For development purposes you can simply just delete the persistence.mv.db file which is the entire H2 database. This will reset your corda node.
Of course don't do that for any production use.
i created one transaction using . After that i made some changes in code and build and deploy the nodes successfully. I tried to consume previously created data to create new data. But it led to Contract constraints failed error. But i didn’t get any error at the time of creating new data and consuming the same to create another transaction at that instance.
TransactionVerificationException.ContractConstraintRejection
This exception is thrown when you have existing states in the vault and you updated the contract code and redeployed.
Every time at the node startup CorDapp Jar are scanned and Jar which has Contract classes are uploaded to attachment storage, and the hash of the Jar used as Attachment ID to attach the contract to a transaction.
Now, consider, you have a first fresh version of CorDapp - Attachment ID is: 3B6CA18330500C738455444115C49769D54074CE3CFFB194D8943F34494DB0A4
To create State on vault, you build the transaction, Corda auto-attach the contract using Attachment ID given above.
Then, consider, you changed the code and re-ployed the CorDapp, now jar hash changed, new Attachment ID is: F054BA8C1A67BAABF58539F8718B8A62DC770157D9F1D01434B86E73AD2A9217
My finding, when you create any new the transaction, Corda uses new/recent Attachment ID to attach specified contract.
For example, You want to update State already present on vault.
a. You created a transaction which has one input and it's output state.
b. You sent this transaction for verification.
c. There is check verifies that input state contract Attachment Id and current transaction Attachment Id must be same.
d. But right now input state pointing to old Attachment ID and transaction pointing new Attachment ID. Here check fails and throws a TransactionVerificationException.ContractConstraintRejection exception.
Reference code :-
GIT clone url :- git clone https://github.com/corda/cordapp-tutorial
Release M14 :- git checkout -b release-M14.0
I am little bit confused about how the data flows in Corda. I have some database releated queries:
Whether the database structure is fixed or we can add our custom tables in it?
Where can I see the data flowing in tables, when I do a cash transaction which I can see in VAULT_CASH_BALANCES
table in my H2 database client but apart from cash I am unable to see any details of my other transactiosn i.e. if I
save a string then I am unable to get the information, I only get the transaction Id for that.
Is it possible to get entire data flow diagram?
Do the Node and Vault tables created every time when I build a code?
You can define how each state type is stored in the node by implementing the QueryableState interface. Each state type that implements QueryableState will have its own custom database table.
See https://github.com/corda/cordapp-tutorial/blob/master/kotlin-source/src/main/kotlin/com/example/state/IOUState.kt for an example. Since the IOU state implements a schema (in the Kotlin version of the CorDapp), you can see the sender, recipient and value from the H2 interface for each IOU state.
In the current implementation, the node's data is stored in the persistence.mv.db file of the deployed node. This will be wiped whenever you run gradlew deployNodes. However, if you simply create an updated CorDapp jar by running gradlew jar, you can then copy the updated CorDapp jar from build/libs into each node's plugins folder, and the node will use the new plugin.