#fabric-questions #fabric #fabric-orderer #hyperledger-fabric #fabric-questions #fabric #fabric-orderer #hyperledger-fabric



We have set up hyperledger fabric infrastructure for 5 organizations on kubernetes platform where  each organization(2 peers) and orderers are in different namespace.

Currently we are working on to improve TPS and minimize latency. Our 1 user transaction is equal to 2 dlt transactions.So we send transaction from 1 organization and when another organization receives event related to that transaction. It starts another transaction. But we are getting major latency like 9s to 10s to receive events on any organization peer.

We are using fabric node sdk's contract.createTransaction and transaction.submit method  to invoke transaction and contract.addContractListener to listen block events.

Also we have have observed below logs when fabric node sdk sends transaction to orderer. As per the logs it shows 2-3 seconds time.

[[34m2020-11-03 05:59:49.438 UTC [comm.grpc.server] 1 -> INFO 38031^[[0m streaming call completed grpc.service=orderer.AtomicBroadcast grpc.method=Broadcast grpc.peer_address= grpc.peer_subject="CN=fabric-common" grpc.code=OK grpc.call_duration=3.116673186s

What is the meaning of above logs? Kindly help us reduce this latency. 


Mark Lewis

I am not familiar with that log message so maybe somebody else can help there.

On the latency, it's worth having a clear picture of the transaction flow and where latency will occur.

For the client submitting tx1:
  1. Client gets endorsements from peers for tx1, which involves the peers executing the transaction but not updating the ledger.
  2. Client assembles the proposal and endorsements into a transaction and sends to the orderer, then (by default) blocks waiting for the transaction to be committed on peers.
  3. Orderer waits for enough transactions to fill a block or for a block-cutting timeout (whichever comes first).
  4. Orderer commits a block and distributes to peers.
  5. Peers receive the block and update their copy of the ledger.
  6. Peers emit a block event (including the chaincode event for tx1).
  7. Client receive block events and unblocks the call to transaction.submit().

For the client submitting tx2, the contract event listener receives the contract event emitted by tx1 at the last step of the tx1 flow above. This triggers a new transaction submit, which duplicates the first flow.

There is distributed work on going in the flow so there is going to be some latency. Under low loads, the pause before the orderer commits a block is often the largest chunk of this end-to-end latency. You can tune the orderer configuration to minimise the delay. However, under load the block tend to be cut quicker as the orderer fills the blocks before reaching the block cutting timeout so, provided the system is not overloaded, both throughput and latency often improve under load.

A more fundamental question to consider is whether you really need the second separate transaction triggered by the contract event emitted from the first transaction. If the two things must always happen together, can you do all the work in a single transaction? Or at least do a chaincode-to-chaincode call as part of the first transaction so both transaction functions are executed and committed as one?