Peers and Orderers: Phase 3 Of Ledger Update Process in Hyperledger Fabric - hyperledger-fabric

I was going through https://hyperledger-fabric.readthedocs.io/en/latest/peers/peers.html link where 3 phases of ledger updates have been discussed. My question is with regard to phase 3.We have below text at the above link:
After a peer has successfully validated each individual transaction, it updates the ledger.Failed transactions are not applied to the ledger, but they are retained for audit purposes, as are successful transactions.
Where are these failed transactions retained, are these with peer's FileSystem?
Are Failed and Invalidated transactions the same?

They are appended to the block of the corresponding channel's chain, but they do not alter the channel's state.
With "failed" you probably refer to those transactions discarded by the chaincode's logic (those returning an HTTP 500 error on endorsement as launched by shim.Error).
With "invalidated" you probably refer to those transactions that do not fulfill the endorsement policy. For instance, individual endorsements return an HTTP 200 success code, but endorsements from different peers do not match. Another example: a MVCC_READ_CONFLICT error when trying to update the same writeset in the same block.

Related

What happen to invalid transactions in a block verified/created by orderer in hyperledger fabric?

In the transaction flow documentation
5. Transaction is validated and committed
The blocks of transactions are “delivered” to all peers on the channel. The transactions within the block are validated to ensure endorsement policy is fulfilled and to ensure that there have been no changes to ledger state for read set variables since the read set was generated by the transaction execution. Transactions in the block are tagged as being valid or invalid.
Does it means that a block holds invalid transaction also?
Yes - since blocks from the orderer are signed, the peer serializes the entire block with both valid and invalid transaction. It adds external metadata to the serialized blocks to mark invalid transactions. And of course the state changes for invalid transactions are not applied to the state database.
Even I was confused about it initially, and had to re-read the documentation for better understanding.
As we know - a Hyperledger Fabric Ledger consists of two parts - 1. World State and 2. Transaction Log. So, what happens is, after an orderer sends a block containing ordered transactions with policies and transactions verifications, it is received by an anchor peer which in turn broadcasts the block to all the other peers in the channel.
Once a peer receives the block, it goes through every transactions in the block and validates the transaction - i.e. Policies Check, and sanity check of transaction details against the world state data. If a transaction is found defective on any account (Policies/Data check), the peer marks the transaction invalid and does not commit the transaction on the world state. In contrast, if a transaction is valid, the peer would perform actions (Add/Update/Delete) on the world state based on the transaction's read/write set.
Once all the transactions are processed, the block would be appended to the transaction log (aka Block Chain). Which means, the block in the blockchain would contain both valid as well as invalid transactions and transactions would have markings stating whether it is valid or invalid one. A peer can rebuild the world state by going through the transaction log - in that scenario, only valid transactions would be considered for rebuilding the world state.
There is also another answer on the similar line - https://stackoverflow.com/a/50622463/2040522

How to refuse endorsing transactions as an organization

I always have a theoretical and general question in my mind: let's assume that there are two orgs: org1 and org2. And each org has one peer. If the endorsement policy is set to AND(org1, org2), which means that every transaction needs the endorsement from both org1 and org2's peer.
Let's assume a scenario: org1 and org2 have already endorsed 5 transactions. But some day, let's say, org1 doesn't want to endorse any transaction at all, which means that for every new incoming transaction(e.g. 6th transaction), org1 wants to say no, and refuses to endorse the new transaction. So my question is:
How can org1 refuse endorsing new incoming transaction? In more vivid words, as an org, how to say no? Thanks in advance.
You can actually pull this off with a little custom pluggable code which can be loaded at the startup of the peer.
What you need to do, is to create an authentication filter which will prevent endorsements and return errors instead of forwarding the request to the next authentication filter.
From the core.yaml file:
handlers:
authFilters:
-
name: DefaultAuth
-
name: ExpirationCheck # This filter checks identity x509 certificate expiration
These are the default built-in filters that exist in the peer. For example - the ExpirationCheck filter - checks for expiration of the identity of the client.
What you need to do, is to add another filter which simply refuses proposals from clients (let's name it - NopeFilter) and then compile it to a golang plugin, and add the following entry:
-
name: FilterOne
library: /opt/lib/filter.so
The content of the filter will be very similar to the DefaulAuth filter (which does nothing):
func (nf *NopeFilter) ProcessProposal(ctx context.Context, signedProp *peer.SignedProposal) (*peer.ProposalResponse, error) {
return nil, errors.New("nope")
}
At peer startup, the list of filters is read from the core.yaml section, and is then chained into a chain of filters which either reject the proposal, or pass it to the next filter.
The last filter is always the real endorser service in the peer, which actually performs the chaincode execution and endorsement (signing the results).
An endorsement is not an option, where a user chooses between yes and no. The transactions are executed in the peers having chaincode and when the peers, as specified by the endorsement policy, agree on the result then the transaction is said to be endorsed. The process of execution of a transaction may depend upon the ledgers of the peer. For example, all the peers have stored in the ledger that Ram has 50 value Ram:50, now the new transaction adds 20 value to Ram's account. This gets executed in the endorsing peers and the added result Ram:70 is agreed by all the peers. Now the transaction will be endorsed. But if the ledger of one peer is altered as Ram:40 and that peer needs to endorse the transaction, it will come up with a result of Ram:60 which won't match the result of rest of the peers and the transaction will not be endorsed.

What will happen to block if more than one transaction are changing same asset in same block in Hyperledger Fabric?

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.

Hyperledger transaction become failed when submit transaction in for loop

I successfully deployed my network file(.bna). Then I started a REST API using command composer-rest-server. I submit a single transaction using my front end Laravel application. When I try using for loop for submitting multiple transactions, I get an error in some time that MVCC_READ_CONFLICT. I decrease my network's bachtimeout. But the error continues. Please answer anyone if you have any idea about this issue.
Fabric vertion: 1.1.0
Composer : .19.16
Node :8.12
OS: Ubuntu 16.04
Well, MVCC_READ_CONFLICT means you are doing concurrent modification for some key in two different transactions, hence after transaction being ordered into block, whatever transaction gets in first committed while second one or subsequent transaction which works on same key marked invalid with MVCC_READ_CONFLICT.
To understand better the reason behind this status it's probably worth noting the transaction flow in fabric:
Client submit transaction proposal for endorsement sending it to endorsing peers
Endorsing peers executes simulation of chaincode where execution results are captured into Read-Write Set
Client collects endorsements and composes transaction, submitting it for ordering
Ordering service batches transactions into block employing total order of transactions
Block distributed between peers
Peer conducts validation to attest conformance with endorsement policy for each transaction
After that there is multi value concurrency control (MVCC), which checks for concurrent modifications, in fact validating keys version of RWSet and if concurrent modification detected tx invalidated with status MVCC_READ_CONFLICT
You can find more details in documentation "Transaction Flow".
lower the latency of the block creation so that blocks will be created more frequently and thus peers would be updated faster, for example, max_message_count=1 .but that may lead to some performance issue

When transaction is finalized in HLF v1?

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.

Resources