Reading the Fabric ordering service documentation on peer validation and commit it's stated that "Each peer will validate distributed blocks independently, but in a deterministic fashion, ensuring that ledgers remain consistent."
My question is, how can block validation be simultaneously independent and deterministic? It seems circular that because validation is deterministic the ledger is consistent, how can we be absolutely certain that each peer ledger is up-to-date at the time of validation?
"Each peer will validate distributed blocks independently..."
This means that the peers don't depend of each other to validate the new block, so a peer can commit the block and have a state ahead of others.
"...but in a deterministic fashion..."
Even the time of commit of each peer is different the result is deterministic(the same result) for all the peers
how can block validation be simultaneously independent and deterministic?
As said earlier, the validation on commit time don't need to happen simultaneously for all peer, Fabric ensure determinism of the content of transaction by checking the signatures of Endorsers and order of transaction by checking the Orderer signature.
The peers still need to fallow the block order since it's a blockchain :)
If its still not clear comment this question and I will edit to fulfill your doubt.
Related
I tried to find about how committing peer works in hyperledger fabric technically in producing new block but I couldn't seem to find resources that explain to me in a very detail manner(such as sign using private key, how transaction is validated technically, etc). My question is after committing peer validate the transaction which they got from ordering service node, who will create the new block exactly? If it's the committing peer, committing peer is not one node but usually it has multiple committing peer node(which represents number of company participating in the network), so how do the system decide which committing peer will produce the new block?
Any reference link about this will be highly appreciated.
Please refer to the Transaction Flow in the documentation. Furthermore, Please check out the Key Concept Section too (Both Ledger and Ordering Service for you to understand the flow and also what is inside a block).
Committing peers do not create new blocks, they execute, validate and commit the block created by orderer to their ledger. The signing is done by Endorsing Peers using private key with ECDSA-SHA256 signing. Then of course, verification uses ECDSA-SHA256 too.
Validation is basically executing the read write set and check if the output is deterministic (and thus the result should be same with all other nodes).
I am over simplifying here tho.
I am bit confused to understand following use case:
Lets assume, We have more than one transactions in same block which are changing state of same asset, then what will happen in consensus cycle of Hyperledger Fabric?
Block will be rejected
First transaction in block will be successful, but rest of them will be failed
Kindly help me to understand this corner case.
Consensus in Fabric involves multiple pieces:
Invoking chaincode functions and obtaining enough endorsements
(typically signatures) to meet the endorsement policy by invoking
the chaincode and receiving responses from the correct number of
peers
Submitting the transactions to the ordering service node(s) which reach consensus on the order of transactions and then package them into blocks
Ordering node(s) broadcast the transactions to the peer nodes which then validate the transactions and commit state changes for valid transactions
Peers validate transactions by checking to make sure each transaction meets the endorsement policy for the chaincode invoked and then checks the read set of each transaction to make sure that the version of each key which was read in the chaincode has not changed. If it has changed, the transaction is marked invalid and it's write set (state changes) is not processed. The transaction still remains in the block but the block is annotated with metadata indicating the status of each transaction in the block. The validation and commit logic is deterministic.
You should read through the Transaction Flow and Read-Write set semantics in the documentation for the lower level details.
I am having difficulty understanding how Hyperledger Fabrics' execute-order-validate work. Can someone provide a specific examples and compare/contrast that against an order-execute architecture?
https://www.ibm.com/blogs/research/2018/02/architecture-hyperledger-fabric/
order-execute architecture
Order: Transactions are added to the ledger in some order and disseminated to all peers.
Execute: Transactions are sequentially executed (e.g. using smart contract code) on all peers.
execute-order-validate architecture
Execute: Transactions are executed (using chaincode) in any order, possibly even in parallel.
Order: When enough peers agree on the results of a transaction, it’s added to the ledger and disseminated to all peers. This step is where the transactions are first given an ordering — until transactions are added to the ledger, there’s no concept of one transaction happening before or after another.
Validate: Each peer validates and applies the ledger’s transactions in sequence. Now that the transactions have an ordering, the peers can check whether a later transaction was invalidated by an earlier transaction. For example, this prevents one item from being sold two times (called double-spending).
https://medium.com/kokster/hyperledger-fabric-endorsing-transactions-3c1b7251a709
In bitcoin and Ethereum, all peers execute the transactions in a block, after the transactions have been ordered in a block.
Thus, they operate in a "Order-Execute-Validate" blockchain.
In Fabric - you only need to execute the transaction in a subset of the nodes and not on all of them, and the transaction is executed speculatively and sent to ordering.
I am wondering that how your data is safe when an admin can change the latest state in Couchdb using Fauxton or cURL provided by Couchdb directly.
According to my understanding Hyperledger Fabric provides immutable data feature and is best for fraud prevention(Blockchain feature).
The issue is :- I can easily change the data in couchdb and when I query from my chaincode it shows the changed data. But when I query ledger by using GetHistoryForKey() it does not shows that change I made to couchdb. Is there any way I can prevent such fraud? Because user will see the latest state always i.e data from couchdb not from ledger
Any answer would be appreciated.
Thanks
You should not expose the CouchDB port beyond the peer's network to avoid the data getting tampered. Only the peer's administrator should be able to access CouchDB, and the administrator has no incentive to tamper their own data. Let me explain further...
The Hyperledger Fabric state database is similar to the bitcoin unspent transaction database, in that if a peer administrator tampers with their own peer’s database, the peer will not be able to convince other peers that transactions coming from it are valid. In both cases, the database can be viewed as a cache of current blockchain state. And in both cases, if the database becomes corrupt or tampered, it can be rebuilt on the peer from the blockchain. In the case of bitcoin, this is done with the -reindex flag. In the case of Fabric, this is done by dropping the state database and restarting the peer.
In Fabric, peers from different orgs as specified in the endorsement policy must return the same chaincode execution results for transactions to be validated. If ledger state data had been altered or corrupted (in CouchDB or LevelDB file system) on a peer, then the chaincode execution results would be inconsistent across endorsing peers, the 'bad’ peer/org will be found out, and the application client should throw out the results from the bad peer/org before submitting the transaction for ordering/commit. If a client application tries to submit a transaction with inconsistent endorsement results regardless, this will be detected on all the peers at validation time and the transaction will be invalidated.
You must secure your couchdb from modification by processes other than the peer, just as you must generally protect your filesystem or memory.
If you make your filesystem world writable, other users could overwrite ledger contents. Similarly, if you do not put access control on couchdb writes, then you lose the immutability properties.
In Hyperledger Fabric v1.2, each peer has its own CouchDB. So even if you change the data directly from CouchDB of one peer. The endorsement would fail. If the endorsement fails, your data will not be written neither in world state nor in the current state.
That's the beauty of a decentralized distributed system. Even if you or someone else changes the state of your database/ledger it will not match with the state of others in the network, neither will it match the transaction block hash rendering any transactions invalid by the endorsers unless you can restore the actual agreed upon state of the ledger from the network participants or the orderer.
To take advantage of the immutability of ledger you must query the ledger. Querying the database does not utilize the power of blockchain and hence must be protected in fashion similar to how access to any other database is protected.
You need to understand 2 things here
Although the data of a couchdb of a peer maybe tampered, you should setup your endorsement policy in such a way that it must be endorsed by all the peers.
You cannot expose your couchdb to be altered, I recommend to see Cilium
As explained by others - endorsements/consensus is the key. Despite the fact that ledger state of an endorsing peer can be modified externally - in that event all transactions endorsed by that peer would get discarded, because other endorsing peers would be sending correct transactions (assuming other's world state was also not tampered with) and consensus would play the key role here to help select the correct transaction.
Worst case scenario all transactions would fail.
Hyperledger fabric's world state (Ledger state) can be regenerated from the blockchain (Transactions Log) anytime. And, in the event of peer failure this regeneration happens automatically. With some careful configuration, one can build a self-healing network where a peer at fault would automatically rise from ashes (pun intended).
The key point to consider here is the Gossip Data dissemination protocol which can be considered as the mystical healer. All peers within the network continuously connect, and exchange data with other peers within the network.
To quote the documentation -
Peers affected by delays, network partitions, or other causes resulting in missed blocks will eventually be synced up to the current ledger state by contacting peers in possession of these missing blocks.
and ...
Any peer with data that is out of sync with the rest of the channel identifies the missing blocks and syncs itself by copying the correct data.
That's why it is always recommended to have more and more of endorsing peers within the network and organizations. The bigger the network - harder it would be beat with malicious intent.
I hope, I could be of some help. Ref Link: https://hyperledger-fabric.readthedocs.io/en/release-1.4/gossip.html
Even though this is plausible, the endorsement policy is the general means by which you protect yourself (the system) from the effects of such an act.
"a state reconciliation process synchronizes world state across peers on each channel. Each peer continually pulls blocks from other peers on the channel, in order to repair its own state if discrepancies are identified."
According to architecture explained (http://hyperledger-fabric.readthedocs.io/en/latest/arch-deep-dive.html), ordering service collects transactions (RWSets) into block for distribution to committing peers. Then, committing peer validates endorsement policy and RWsets then apply the transaction to ledger.
To verify the transaction was succeeded, should client application wait until all committing peers returned "Success" event ? Or just need to verify only one "Success" event ?
To verify the transaction was succeeded, should client application
wait until all committing peers returned "Success" event ? Or just
need to verify only one "Success" event ?
Tanaka, that's a very good question!
The short answer is No.
The reason is that in contrast to existing popular blockchains, HLF has a unique transaction lifecycle which does:
A transaction is simulated on some endorser or a few endorsers
It is sent to the ordering service and is cut into some block
The block is sent to peers, and they all execute the same validation code and all validation code for a specific transaction is guaranteed to reach the same conclusion in all peers, because they run it in the same order across all of them.
Therefore, if a transaction is validated on some peer - when other peers will receive the block the transaction resides in - they will too consider it as valid.
However - a very important aspect you should consider is data availability and synchronization.
For example, if you have an application that uses 10 peers and only 1 peer got the event and the rest didn't, and you invoke another transaction on the other peers, it might be that the endorsements that the other peers will compute will be turned into an invalid transaction, because they will simulate on old data (the fact that they didn't get the event yet proves that they have not processed the block for that transaction), so you need to keep that in mind.