Is Corda support state deletion scenario? - corda

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.

Related

Locking transactions (SQL Server + EF5)

I am trying to debug a performance issue in an ASP.NET application using .NET 4.5, EF5 (with a 2nd level cache and lazy loaded navigation properties) and SQL Server 2014. We are experiencing a number of wait locks in the SQL server. When I look at the locking transactions, they contain a very quick UPDATE, and then a very large SELECT. The UPDATE is ostensibly a necessary one, but I am confused as to why the SELECT is being run in the same transaction (and why anything is being selected at all). The fundamental issue is that the table referenced in the UPDATE statement is locked for the duration of the SELECT statement.
We use repository pattern for getting data from the db, and DbContext.SaveChanges() for committing changes. I cannot figure out how it is possible that EF produces a transaction where there is both a write and a read, and I am not getting relevant results when I try to search Google.
We have a number of interfaces into the system, and a couple of console applications working on the database as well, but they all go through the same setup/versions of .NET and EF.
I figure that it must be through SaveChanges, since this is (AFAIK) the only time that things are written to the database.
Does anyone here have a hint as to how these locking transactions might be produced?
The fundamental issue is that the table referenced in the UPDATE
statement is locked for the duration of the SELECT statement.
The answer is in your question:
the SELECT is being run in the same transaction
X lock is always held until the end of the transaction, i.e. until it commits or rolls back. So if after your quick update there is a long select, all that update locked in your table remains locked until your select ends.
You can separate your update and select if your business rules permit, you can add an appropriate index on the updated table to lock only some rows and not the whole table, or you can optimize your select to execute faster.

How backup/restore corda node?

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.

Can I create Corda Custom Data Tables?

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.

How to create Corda Custom Data Tables

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.

How Are Objects Synced in a Shared Realm in Swift

After scouring the documentation, I recently learned that a shared realm (globally available to all users of my app) can only be queried with Realm.asyncOpen. For example, I have a /shared realm that has read-only access to any user. I tried querying it in the usual way, but it returned zero objects. But if I query it like this, it works:
Realm.asyncOpen(configuration: sharedConfig) { realm, error in
if let realm = realm {
// Realm successfully opened
self.announcements = realm.objects(Announcement.self)
print(self.announcements)
self.tableView.reloadData()
} else if let error = error {
print(error)
}
}
This method is visibly slower than a usual realm query since it appears to be fetching the data from the server instead of a local, already-synced realm.
Does this mean that the objects pulled down are never stored in the local copy of the realm, but are queried from the ROS each time I access them?
In other words, are shared realms pulled and not synced?
a shared realm (globally available to all users of my app) can only be queried with Realm.asyncOpen
This is incorrect. If a user only has read-only access to a Realm, it must be obtained with Realm.asyncOpen. That's explicitly what the documentation you linked to states.
This method is visibly slower than a usual realm query since it appears to be fetching the data from the server instead of a local, already-synced realm.
Almost correct. Yes data is fetched from the server, but not the whole Realm from scratch. Only the new data since the last time the Realm was synced with your local copy.
Does this mean that the objects pulled down are never stored in the local copy of the realm, but are queried from the ROS each time I access them?
This synced Realm is persisted locally and will be preserved across application launches.
In other words, are shared realms pulled and not synced?
No.
Taking a step back, let's explain what's happening here.
The reason why you get a "permission denied" error if you attempt to open a read-only synced Realm synchronously is that upon initialization, a local Realm file will be created, performing write operations to write the Realm's schema (i.e. create db tables, columns & metadata) immediately. However, since the user does not have write access to the Realm, the Realm Object Server (ROS) rejects the changes and triggers your global error handler notifying you that an illegal attempt to modify the file was made by your user.
The reason why this doesn't happen with asyncOpen is that it's an asynchronous operation and therefore doesn't need to give you a valid Realm immediately, so it doesn't need to "bootstrap" it by writing the schema to it. Instead, it requests the latest state of the Realm from ROS and vends it back to you once it's fully available in its latest state at the point in time at which the call was started.
That being said, if the local copy of the Realm already has its schema initialized (i.e. after a successful asyncOpen call), and the in-memory schema defined by either the default schema or the custom object types specified in Realm.Configuration hasn't changed, then no schema will be attempted to be written to the file.
This means that any time after a successful asyncOpen call, the Realm could be accessed synchronously without going through asyncOpen as long as you're ok with potentially not having the most up to date data from ROS.
So in your case, it appears as though you only want to use asyncOpen for the very first access to the Realm, so you could persist that state (using another Realm, or NSUserDefaults) and check for it to determine whether or not to open the Realm the asynchronously or synchronously.

Resources