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.
Related
I am new to Corda. My question is not about any particular implementation, but more of an architectural question.
What happens during back chain validation if one of the nodes involved permanently dies and fails to respond? How is that transaction validated?
I have seen this issue that only talks about how of transaction volume could slow down validation. Does validation come to a grinding halt if one of the nodes fails permanently?
As per Corda webinar on Consensus, in the example that is 5 minutes into the video, the back chain is Charlie -> Dan -> Alice -> Bob. In this, if either Charlie or Dan are unavailable, the proposed transaction cannot be validated. The same webinar further says that this is not a problem in other blockchains such as Ethereum.
Applications that can foresee the need for a highly-available record keeper, can surely accommodate such a node during the design phase, as suggested by Adel Rustum.
However, a privacy-conscious application reluctant to leak information that is deployed globally, could suffer from many transaction-validation failures due to the vagaries of a wide-area network. Thoughts?
The short answer is, transaction verification will fail (if that node was the only node that had that transaction); and that's the point of using a DLT (or a blockchain). If you can't go back in the history of a certain block of data until genesis, then you can't verify how that block and its ancestors were created.
As for the issue that you referenced in your question; Corda Enterprise 4.4 introduced a new feature called bulk back-chain fetching, which allows modifying the way the transactions that are needed to verify a certain transaction are fetched. Previously it was depth first, now you can change that to breadth first and specify how many transactions you want to fetch in one call. More details in this video.
The back chain validation doesn't depend on the nodes who were part of the transaction in the past. The validation of the back chain is only done by those nodes who are part of the current ongoing transaction. The other nodes who were part of a past transaction that involves the evolution of a state in question don't need to be contacted (or stay online) while the back chain is validated.
Back chain validation only involves checking that all transaction which happened in the past on a particular state used as input in the current transaction is valid. The validity is checked by running the contracts again for those previous transactions. There is no real need to reach to the parties of a previous transaction.
However, you need to make sure that the parties involved in the current transaction are online and responding since you would need signatures from them to successfully complete the transaction.
How the receiver verify a proposed transaction before accepting to make sure its a valid proposal, ie how do they check the transaction chain to make sure the same.
If its going through all the previous transactions it going going be costly and affect the TPS.
Is it possible for the receiver to goto the notary and get it verified, by any chance?
Please clarify.
At the receiver end, the transaction is being validated in the
related responder flow. Example can be found here:
https://github.com/corda/samples/blob/release-V4/blacklist/src/main/kotlin/net/corda/examples/attachments/flow/ReachAgreementFlow.kt#L42
Speaking of the verification for the entire transaction chain, it is not handled by the receiver anyway. It is handled by the Notary (When you turn the validation feature on). More details can be found: https://docs.corda.net/key-concepts-notaries.html
The Corda introduction to consensus says "uniqueness consensus is provided by notaries."
Are we saying that without a notary that it would be possible for A to convince B to commit a transaction to its ledger involving a state X as an input and at the same time, or later, convince C to commit a different transaction involving X to its ledger?
In this situation the ledger of A would be inconsistent with that of C (or B or both depending on what transaction, if any, it chooses to commit) and A would have created a situation that is inconsistent now and can never become consistent between A, B and C.
Presumably, the Corda framework tries to prevent this kind of thing as far as possible, so is this all about honesty? I.e. we're talking about the situation where A completely subverts its own infrastructure, i.e. doesn't use Corda as intended, and lies in all the messages it sends other parties?
Update: this question was initially asked due to my mistaken belief that notaries were an optional element of a Corda system. They are not, but their involvement may be optional for particular transactions, e.g. ones that involve no input states (and therefore by their nature have no double-spend issue).
The important thing that #joel makes clear in his answer is that the double-spend issue can also be a problem even if all parties trust each other, i.e. no malicious behavior is expected.
Once a party in Corda determines that validity consensus has been reached for a transaction it can immediately commit the transaction to its own ledger, i.e. it does not first try to reach some kind of additional BFT style consensus with the other parties that they can and will definitely commit the transaction to their respective ledgers as well.
So in the above scenario A could honestly/mistakenly propose two different transactions to B and C. B and C would both reach validity consensus on their respective transactions and commit them to their own ledgers with A only being confronted with the double-spend issue when it afterwards tried to commit the second of the two transactions to its own ledger.
The notary avoids such situations (whether the result of malicious intent or not).
There are two reasons you need a notary:
Malicious nodes: A node purposefully extracts a consumed state from its vault, consumes it in another transaction, and sends the transaction to a counterparty who didn't see the original transaction
Race conditions: Two nodes simultaneously propose transactions consuming the same state
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.