Since the data is stored in RDBMS it could be accessed and changed later at any point by any party.
And any reference to the changed data could be a problem.
Does the notaries storage (which can't be queried) or the Merkle trees play the role?
Immutability is handled in Corda through the use of digital signatures.
You are correct in saying that Corda transactions are backed by RDBS, however, you wouldn't be able to change 'data' without invalidating the signatures that have been applied to them.
The Notary doesn't act as secondary storage, the Notary (or rather Notaries as they always operate in clusters) is responsible for preventing double spends.
A simple example might be, I create a transaction where I send you 3 tokens, we both sign this transaction to make it valid (according to some contract rules we've defined). If you were to then change the 'data' backing this transaction to instead reflect 4 tokens, you would invalidate the signatures.
You could recreate your own signature, but you wouldn't be able to recreate mine. If you now tried to spend this state reflecting 4 tokens, it would be rejected by the new receiving party.
Related
I've been working on some ideas to determine the initiator of a transaction in Corda. It's quite hard to prove since transactions can be signed by one (trivial to prove), or more (hard to prove) parties.
However I'm now wondering if there's something inherent to the transaction itself that can be used to trivially determine who initiated a transaction.
When a transaction that requires multiple signatures is created, we call the CollectSignaturesFlow to obtain counter-party signatures, however if we do this before signing the transaction ourselves, we get the following exception:
The Initiator of CollectSignaturesFlow must have signed the transaction.
Therefore I could assume that the first signature in the transaction must have some from the initiator. Is it safe to assume that SignedTransaction.sigs[0] is the transaction initiator?
Footnote 1: The code that throws the above exception is implemented as such:
require(partiallySignedTx.sigs.any { it.by in myKeys }) {
"The Initiator of CollectSignaturesFlow must have signed the transaction."
}
This would suggest that one (or specifically more) signatures applied to the transaction will belong to the initiator.
Footnote 2: Would transaction storage (serialization/deserialization) have any impact on the ordering of the sigs list? - If it's order isn't deterministic, then we cannot rely on sigs[0] being the initiator.
Phoned a friend from r3, from Alex Koller
I looked at the question and it's not very clear to me what is Matthew trying to achieve. AFAIK corda doesn't record who initiated a transaction and trying to devise that from the order of the signatures on the tx is probably prone to error now or in the future. A possibility would be to look at the notary and see who requested the notarisation. But that may be suitable in minority of use cases. If the holder of the tx should need to know who initiated it then it may have to be recorded in one of the states. But you obviously cannot prove the correctness of the value in the state from the tx contracts, so it would have to be atested to by the other signers on the tx (in the collect signature responding flow, before the counterparties sign). I think we would need to know more about what he's doing to be able to advise. He should get in touch with Professional Services.
At the risk of sounding naive, I ask myself "Is a validating notary necessary?", given all the issues with it - transaction and dependencies leak, exposure of state model, to name a few.
The answer I hear has something to do with the potential attack where a dishonest node tries to steal someone else's asset. For example, in a legitimate transaction, partyA sold partyB some asset S subject to a Move contract. Immediately afterwards, partyA creates a self-signed transaction that transfers S back to himself subject to a dummy contract in a bogus flow that does not even run the ledger transaction verify(). But when he calls FinaltyFlow to satisfy the simple notary to commit the transaction on the ledger, it will fail the verifyContracts() because S appoints to the Move contract which should say owner partyB must sign the bogus transaction.
So that does not convince me of the need for a validating notary.
Apparently, I must have missed something. Can someone enlighten me?
Thanks.
\Sean
As you say, the advantage of the validating notary is that it prevents a malicious party from "wedging" a state - that is, creating an invalid transaction that consumes an unconsumed state that they are aware of. Although the transaction is invalid, the non-validating notary would not be aware of this, and would mark the state as spent.
You're correct that this invalid transaction would fail the FinalityFlow's call to verifyContracts(). However, we cannot force a malicious node to use FinalityFlow to send something to the notary. If the malicious node was sufficiently motivated, they could build the invalid transaction hash by hand and send that to the notary directly, for example.
However, note that in the non-validating notary case, there are still multiple layers of protection against wedging:
The malicious party has to be aware of the state(s) they want to wedge. Since information in Corda is only distributed on a need-to-know basis, the node would only be aware of a small subset of unconsumed states
If the state is wedged by accident, the node can show the invalid transaction to the notary. Upon seeing that the transaction is invalid, the notary will mark the re-mark the state as unconsumed
As Corda is a permissioned network, the notary can keep a record of the legal identity of everyone who submits a transaction. If a malicious node is submitting invalid transactions to consume states, their identity will be known, and the dispute can be resolved outside of the platform, based on the agreements governing participation in the network
On the other hand, SGX addresses the data leak issue associated with validating notaries. If the validation of the transaction occurs within an SGX enclave, the validating notary gains no information about the contents of the transaction they are validating.
Ultimately, the choice between validating and non-validating notaries comes down to the threat model associated with a given deployment. If you are using Corda in a setting where you are sure the participants won't deliberately change their node's code or act maliciously, then a validating notary is not needed.
But if you assume somebody WILL try to cheat and would be willing to write their own code to do so, then a validating notary provides an extra layer of protection.
So Corda provides choices:
Choose to reveal more to a notary cluster if you trust the participants relatively less...
Choose to reveal less to a notary cluster if you consider the risk of revealing too much to the notaries to be the bigger problem
(and use SGX if you're paranoid about everybody!)
I've been trying to understand the concepts of Consensus and Notaries, there are some questions:
do all nodes/participants require to do the verification consensus in order to assure the transaction inputs, outputs are valid? Does it somehow resemble verifying the Bitcoin input transactions?
uniqueness consensus is a must when involving unique successor of a state (aka preventing double spending) and by using uniqueness consensus, notary service is involved?
(this one confused me) in notary services, containing verifying and non-verifying notaries, does the verifying notary do the same way as the verifying consensus to validate all transactions (going back to the very beginning of each state to check the signatures & correctness), that’s why it is called verifying notary service?
Do both notary services will store the map locally for checking consumed state of the proposed transactions? If yes, how can I see the details of the map?
Thanks and cheers,
No. Only the participants involved in a given transaction, plus the transaction's notary, verify a given transaction. This is core to Corda's privacy-first approach, where transaction information is only distributed on a need-to-know basis.
Yes, each transaction is assigned to a specific notary service (there may be several on the network), and the notary ensures that there are no double-spends.
That's correct. The non-verifying notary simply checks that the transaction's inputs haven't already been spent. The verifying notary also "walks the chain" to ensure that the transaction is valid. You have a choice between using a non-verifying and a verifying notary for each transaction, depending on how much information you wish to disclose.
Both types of notaries store the information about which states have been spent locally. Only the notary itself can see the details of this map, by checking the NODE_NOTARY_COMMIT_LOG in its H2 database.
How can I access vault in Smart Contract?
I want to do below business validation in Smart Contract
- New Data and attachment which I have entered, already exists in vault or not
You cannot access the vault, or any other source of outside information, from within the contract. This is because contract execution must be deterministic. If a contract's view of the validity of a ledger update depended on the current contents of your vault, disagreements could arise between different nodes (or even within the same node at different points in time) on whether a given ledger update was valid. This would destroy the integrity of the ledger - there would be no consensus on which updates were valid.
In your case, it might be best to impose the additional constraints you want to impose within the flow. For example, within the flow you could check the contents of the proposed transaction against the contents of the vault, and sign or not sign the transaction accordingly.
It's important to keep in mind - just because a transaction is contractually valid, does not mean you have to sign it!
In riak documentation, there are often examples that you could model your e-commerce datastore in certain way. But here is written:
In a production Riak cluster being hit by lots and lots of concurrent writes,
value conflicts are inevitable, and Riak Data Types
are not perfect, particularly in that they do not guarantee strong
consistency and in that you cannot specify the rules yourself.
From http://docs.basho.com/riak/latest/theory/concepts/crdts/#Riak-Data-Types-Under-the-Hood, last paragraph.
So, is it safe enough to user Riak as primary datastore in e-commerce app, or its better to use another database with stronger consistency?
Riak out of the box
In my opinion out of the box Riak is not safe enough to use as the primary datastore in an e-commerce app. This is because of the eventual consistency nature of Riak (and a lot of the NoSQL solutions).
In the CAP Theorem distributed datastores (Riak being one of them) can only guarentee at most 2 of:
Consistency (all nodes see the same data at the same time)
Availability (a guarantee that every request receives a response
about whether it succeeded or failed)
Partition tolerance (the system
continues to operate despite arbitrary partitioning due to network
failures)
Riak specifically errs on the side of Availability and Partition tolerance by having eventual consistency of data held in its datastore
What Riak can do for an e-commerce app
Using Riak out of the box, it would be a good source for the content about the items being sold in your e-commerce app (content that is generally written once and read lots is a great use case for Riak), however maintaining:
count of how many items left
money in a users' account
Need to be carefully handled in a distributed datastore.
Implementing consistency in an eventually consistent datastore
There are several methods you can use, they include:
Implement a serialization method when writing updates to values that you need to be consistent (ie: go through a single/controlled service that guarantees that it will only update a single item sequentially), this would need to be done outside of Riak in your API layer
Change the replication properties of your consistent buckets so that you can 'guarantee' you never retrieve out of date data
At the bucket level, you can choose how many copies of data you want
to store in your cluster (N, or n_val), how many copies you wish to
read from at one time (R, or r), and how many copies must be written
to be considered a success (W, or w).
The above method is similar to using the strong consistency model available in the latest versions of Riak.
Important note: In all of these data store systems (distributed or not) you in general will do:
Read the current data
Make a decision based on the current value
Change the data (decrement the Item count)
If all three of the above actions cannot be done in atomic way (either by locking or failing the 3rd if the value was changed by something else) an e-commerce app is open to abuse. This issue exists in traditional SQL storage solutions (which is why you have SQL Transactions).