According to the docs, a leading peer node communicates with orderer nodes on behalf of a member. This means, as I understood, two functions of orderers, which are <broadcast> and <deliver>, should be invoked by a leading peer. However, some parts of docs seems to say a submitting-client (a.k.a application with SDK) can invoke <broadcast> of Orderers directly and, at the same time, a submitting-client should have at least one peer to participate in the blockchain network.
So, does it means that a submitting client invoke <broadcast> function of Orderers through a leading peer? Or does a submitting-client can directly invoke <broadcast> function of orderers without passing through any peer node?
Submitting client do able to directly invoke the broadcast API of ordering service, one of the most obvious examples as the channel creation, where client has to submit configuration transaction (using broadcast) to the ordering service and get the genesis block (using deliver). Of course you need to make sure client has valid permissions to do it.
Related
In Hyperledger Fabric, what is the expected behavior of peer when all orderer nodes are down.
Should peer also down, or stop serving request from client, or continue to serve query request?
In our test, after orderers are stopped, the peer keeps writing "failed to create connection to orderer" log. When we query a key by calling chaincode the value is returned.
Can you help clarify if this is expected behavior. Thank you.
I am working on a distributed hyperledger fabric network. I would recommend the Orderer Raft Consensus https://hyperledger-fabric.readthedocs.io/en/release-2.2/orderer/ordering_service.html#ordering-service-implementations.
I have solved this in such a way that in my case I have three orderers that run independently on different environments.
If I crash all these orderers, the peer containers will continue to run on the other participants of the network. As you said, they cannot make any transactions.
If one of my orderers crashes it is not so bad after the raft consensus, the containers keep running. If another one fails, no transactions can be made. In this case I let the peers continue and check if the orderers are available again.
The behaviour you described I would put down to the fact that the peer requests the value from his ledger, he doesn't need an orderer for that. https://hyperledger.github.io/fabric-chaincode-node/master/api/fabric-shim.ChaincodeStub.html#getState
Have a read of this: https://github.com/hyperledger/fabric/blob/master/docs/source/peers/peers.md This is the best documentation for how the system works I've found and there's more in the docs directory on the repo for orderers, etc.
My understanding is: The peers are there to sign (endorse) transaction proposals. The orderer exists to order, validate, package and distribute transactions to peers. The peers can also distribute their knowledge of validated transactions via the gossip channel.
If all orderers go down, the transactions will not be validated/packaged/distributed so the blockchain will be out of action until the orderers are restored.
When we query a key by calling chaincode the value is returned.
Peers will still remain up and ready to sign/endorse transaction proposals, and querying the blockchain held at the peers will still work. Chaincodes are hosted by the peers. Orderers do not host chaincode.
Also see here https://github.com/hyperledger/fabric/blob/master/docs/source/orderer/ordering_service.md#ordering-service-implementations for the various modes the orderer can be run in: Raft mode, Kafka ordering, Solo ordering.
I think the current observerd behavour is expected and in my view it is just fine.
Let's check the purpose of orderer?
Order the transactions
Cut the block and distribute the block amongst the orgs when the criteria is met ( min txn/size or time).
This also means, orderer is needed when your Fabric network is processing those transactions which intend to write data into the ledger, isnt it? And Query is not a transaction which writes into the ledger. So it doesn't need the orderer. For query, it will pick up the data from the peer's local database.
So I think what could be done is, to send out an alert to the production support when your application detect orderer node down ( with some health check ? ). And your application displays a dimnished capacity/limited operations message while work on bringing up the orderer network, the system can still serve the search queries.
From my view, its just fantastic. But its finally upto you. Cheers!!
I've been studying Hyperledger Fabric for about 1 year.
But I still can't tell how a chaincode works and is dealt with exactly, especially in terms of its implementation and process.
This is how I understand a chaincode below.
A chaincode is running and is isolated from peers, as one of docker containers for its integrity in the network. The chaincode is a program which defines how functions in transactions(e.g., AddTwoIntegerValues()) should update the ledger
Also, endorsing peers access the chaincode for executing functions in the transaction proposals from clients or other peers to respond with endorsement.(This process is not clear)
In that case, I'd like to ask you how those endorsing peers can execute or access the chaincode container in parallel? I heard 'chaincode execution' means simulation of the chaincode logic computation. But I can't get that.
In other words, my question is how can they execute or access that at the same time? Do they have copies of that chaincode? How do peers know the chaincode logic? Could you please correct me or explain chaincode process if I'm wrong?
Please tell me if you have any idea about my question. I'm looking forward to your answer!
Each peer has its own chaincode container for each version of a given chaincode code.
When the chaincode is installed on a peer, the code package of the chaincode's code is written to the file system.
Later on, when the peer receives a request to invoke a function on the chaincode (Init() or Invoke(), when Init() runs on instantiate), the peer checks to see if the chaincode is already running, and if not, it:
Spins a container to compile the chaincode code package to produce the chaincode shim binary and afterwards destroys it
Spins a container that would actually run the chaincode shim binary.
The chaincode shim binary:
Connects to the peer via gRPC and registers itself to be the name it is installed with.
Runs an endless loop in which it waits for commands to simulate transactions from the peer.
Whenever the peer receives a proposal from a client, it:
Locates the chaincode container gRPC stream and forwards the proposal from the client to the chaincode
Prepares a map of key reads and writes that the chaincode shim would ask the peer during its execution, which is called a Read-Write set.
Then, the chaincode shim, running inside the container - extracts the arguments from the proposal and starts running the chaincode logic (part of its binary).
If the chaincode logic contains data access operations such as GetState or PutState, it sends a request to the peer down the same gRPC stream it is connected to the peer, and then the peer does the following:
If the data operation is a read operation, it adds to the read-write set the key and the version read from the key, and sends back the key and the value to the chaincode shim container over the gRPC stream.
If the data operation is a write operation, it adds to the read-write set the key and the value and the version, and then sends back an "OK" to the chaincode shim(*).
(*) I personally think this step is not necessary... it just prolongs the execution time
After the chaincode shim finished computing the transaction, it sends back the result (i.e "OK") to the peer, along with a marker that denotes that the transaction finished executing.
Since the values that are written, are not really written to the DB but just added to an in-memory map, this is called a "transaction simulation".
The peer then proceeds to sign the transaction simulation's results (the read-write set map and the result from the chaincode shim) and then returns the signed transaction simulation (also called an "endorsement") back to the client as a response.
In that case, I'd like to ask you how those endorsing peers can execute or access the chaincode container in parallel?
You can do that in parallel because when the chaincode shim invokes the transaction, it does so on a separate goroutine.
I'm aware that read query is a chaincode invocation which reads the ledger current state but does not write to the ledger.
The client app can choose to submit the read-only transaction for ordering, validation, and commit (for auditing purpose)
Question:
Is it possible to read the ledger db without going via the chaincode ?
What prevents someone on channel from directly reading CouchDB (assuming that is the underlying DB used) without using contracts and avoiding recording of reads
Fundamentally, we use an async communication in fabric. The node initiating transaction talks only with the peers synchronously and after that ordering service is initiated which will commit the txn to ledger after all verification check..
Is the following possible ?
node A submits a data to the ledger request for an operation -> which needs to be done by node B.
Is this possible for node A to notify B to check ledger and perform operation and B upon completion notify A to check the updated ledger ?
Is it possible to read the ledger db without going via the chaincode ?
What prevents someone on channel from directly reading CouchDB
(assuming that is the underlying DB used) without using contracts and
avoiding recording of reads
Nothing prevents you from doing it, if you have access to the database itself.
However, the clients usually don't have access to the database and thus the peer (through the chaincode) may enforce selective logic on which clients and what data can be read.
Think of an application server, a servlet container, etc.
The user that browses from the browser doesn't have access to the database the application server uses, right?
A similar thing takes place here.
Fundamentally, we use an async communication in fabric. The node
initiating transaction talks only with the peers synchronously and
after that ordering service is initiated which will commit the txn to
ledger after all verification check..
Strictly speaking, the ordering service does not commit the txn to the ledger, as the ordering service has no ledger. It packages transactions into blocks, then sends the blocks to peers. It is the peers that then validate and commit the block to their own ledgers.
Is this possible for node A to notify B to check ledger and perform
operation and B upon completion notify A to check the updated ledger ?
You need the client SDK to orchestrate all of these. User Chaincodes only run in the context of a client's request.
So, you can have a client perform an operation that submits a transaction, and then the client sends another transaction in which the chaincode checks the current ledger, etc.
I would really like to understand how endorsments work in Hyperledger Fabric in order to help me in designing a solution to a problem.
let's assume I am an endorser and a transaction proposal has just arrived. I would randomly select a participant within my organization, use its identity to perform the validations, checking for replay attacks etc then sign an endorsement with that participant's private key. Assuming I used an admin's credentials, the admin(person) may not be aware that I used its identities to validate and endorse a transaction proposal. Is this example correct?
Initial discussions here makes me feel like the more I look into it, the more confused I become. Could anyone help?
Just to start with, the endorser is the peer that capable to handle incoming invocation, maintain and run the chaincode. The flow works as following, support you have a client (C) and the endorsing peer (P), which runs a chaincode (CC).
Client forms transaction proposal request which includes parameters for chaincode invocation.
In order to get an endorsement for this proposal he sends it the endorsing peer.
Endorsing peer opens a transaction proposal and forwards requests to the required chaincode along the way it passes all parameters.
Chaincode get invoked which produces a RWset (set of keys and values read of changed during the invocation)
Peer collects RWset and forms proposal response and signs it
Client gets the proposal response, signs it as well and send it to the ordering service
Ordering service collects proposal responses and cuts the block which got distributed to the peers in the network.
Upon arrival peers opens a block and validates all transactions, one of the validation is to check whenever transaction conforms the endorsement policy, where basically it checks whenever transaction has enough signatures which satisfies the policy.
Back to your question, please note that at each step everyone uses its own key and certificate to sign, no one randomly selects participants to use they identities for signatures or whatever else.
PS. Note that process above a bit simplified and lack a lot of technical details.
PPS. There is a new course on Coursera which covers pretty well many technical aspects of Hyperledger Fabric architecture and the interaction between different components, I would urge you to consider taking this course.
I have following fabric network topology: two orgs with two peers and two orderers per organisation (along with required kafka/zookeepers).
Q: How to setup the node fabric-client to protect my app against failure of the single orderer?
The documentation says that I can add multiple orderers to the list using channel.addOrderer(orderer), but it also says that
"SDK uses only first orderer from the list"
so, my understanding is that failure of the first orderer from the list will prevent the processing of the subsequent transactions - am I right?
You are correct although you can easily rectify this situation. If you get a failure from sendTransaction which is related to that orderer node being down (e.g. SERVICE_UNAVAILABLE), you can use the removeOrderer method remove the orderer and then call sendTransaction again (as it will now use whatever the next orderer in the list was). You can also use addOrderer to add the orderer you removed back to the end of the list as well.
The version v1.2.0 of Node SDK, already includes this feature where the channel may have multiple orderers, and the sendTransaction API should try the first one and then the next and so on until it succeeds in sending the transaction.