Once Corda node failed, what is the appropriate process of recovery? Corda transactions are shared only with qualified nodes for specific business network, not with every nodes. Therefore, when recovering failure node, copying data from other node would not work well, recovering from backup is required. However, backup image is not completely same for other correct nodes, I would like to know how recover consistency of corda node.
Node data storage
A Corda node stores its vital information as follows:
The node's data is stored in a standard SQL database
By default, in an H2 database file called persistence.mv
The node's keys and certificates are stored in Java keystores in the certificates folder
Recovery from node crashes
If the node crashes:
The database and the contents of the certificates folder will not be affected
In-flight flows can be restarted from their most recent checkpoint
Artemis messages can be replayed
In other words, you can generate a new node, re-add the persistence.mv file, certificates folder and CorDapps, and the node will behave as if nothing happened when you start it up again.
Recovery from corruption/deletion of the node's files
Loss/corruption of data is non-fatal as long as you are able to recover:
The node's database
The contents of the node's certificates folder
It is the responsibility of the node's owner to ensure they protect and back-up these files using standard business procedures. If both of these can be recovered and re-added to a new node, the node should spin up as usual.
If the contents of the node's certificates folder cannot be recovered, you will no longer have your private key, and will not be able to spend your assets on the ledger.
If certain pieces of data cannot be recovered from the node's database, the node could attempt to re-request this data from other nodes where applicable (e.g. the transaction history). However, there is no way to force the counterparties to share this information.
Related
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.
If we are trying to host corda node database in a SQL server can we host all of them in a single database? If yes how to do it and what will be its impact.
Can the built in H2 database which gets generated while a node is deployed be stored locally in a system such that data becomes permanent and is not lost in the next build?
Sharing an H2 database
As of Corda 3, each node spins up its own H2 database by default.
However, you can point multiple nodes to a single, stand-alone H2 database as follows:
Start a standalone H2 instance (e.g. java -jar ./h2/bin/h2-1.4.196.jar -webAllowOthers -tcpAllowOthers)
In the node.conf node configuration file, set dataSource.url = "jdbc:h2:tcp://localhost:9092/~/nodeUniqueDatabaseName", where nodeUniqueDatabaseName is unique to that node
For each nodeUniqueDatabaseName, H2 will create a file nodeUniqueDatabaseName.mv.db in the user's home directory.
You can also set a specific absolute path as well (e.g. dataSource.url = "jdbc:h2:tcp://localhost:9092/~/Users/szymonsztuka/IdeaProjects/corda3/nodeUniqueDatabaseName"). This will create a database file under Users/szymonsztuka/IdeaProjects/corda3/.
Note that this approach is not secure since the h2 server is started with -webAllowOthers -tcpAllowOthers, meaning that anyone can log in and modify the database.
Maintaining data across node builds
The H2 database is discarded when re-running deployNodes, because you are considered to be creating an entirely new set of nodes. If you only want to make changes to the installed CorDapps, you can shut down the node, update its CorDapps (by creating the new CorDapp JARs as described here and copying the CorDapp JARs into its cordapps folder) and restart the node. The new CorDapps will be installed, but the old node data will still be present.
PFB Following questions:
1) In my local, I don't have a networkMap so the maxTransactionSize and maxMessageSize needs to be made part of the extraConfig in deployNodes for each node?
2) Let's say I have an Excel of 100MB which I Zip and then upload to Node using rpc.uploadAttachment the SecureHash received will now be added to a Tx. After Successful Completion of the TX will both parties have the attachment? or The Receiver will get the file only when he opens the attachment?
3) If it's when the receiver opens the attachment, it's requested from the sender, the file travels over the network and reaches to the receiver and is stored in the H2 DB for future use. If attachment is required later, the blob can directly be provided from the DB?
4) Now where, how does attachmentContentCacheSizeMegaBytes come into picture? Since we are already storing it in the H2 DB where is it used? as a blob limit to the node_attachment table?
5) Also, is the file ever stored in the file system ? at the time of upload to the node? does it get stored directly to the H2 DB?
The maxTransactionSize and maxMessageSize is set by the network operator, and individual nodes cannot modify it. This is for compatibility reasons. All the nodes on the network need to be able to handle the largest-possible transaction to ensure they can resolve any transactions they receive
The receiver node downloads the attachment immediately, and not when it first opens the attachment
N/A
The attachmentContentCacheSizeMegaBytes node configuration option is optional and specifies how much memory should be used to cache attachment contents in memory. It defaults to 10MB
The attachment is stored in the node's database as a blob when it is first uploaded
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.
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.