Any terrible thing will happen if change Chaincode state in invokeChaincode? - blockchain

Let's say I have two chaincode in Hyperledger Fabric, ChaincodeA and ChaincodeB.
Some events in ChaincodeA will have to change state in ChaincodeB, for example, change its balance. If invokeChaincode() used in ChaincodeA to invoke some logic in ChaincodeB, which calls putState() to change ChaincodeB's state, any race condition could happen when getting consensus? What's the best practices on handling this?

While invoking a chaincode you do not change the state you only simulate transaction execution based on the current state. Only once transaction placed into the block by ordering service and reaches the peer where it has to pass VSCC and MVCC checks it gonna be eventually committed. MVCC will take care of possible race condition. Transaction execution works as following:
Client sends transaction proposal to the peer
Peer simulates transaction sign the results and put them into signed transaction proposal
Client has to repeat step #2 based on expected endorsement policies
Once client collected enough endorsements he send them to the ordering service
Ordering service cuts the block and order all transaction
Block delivered to the peers
Peer validates and eventually commits the block

As I understated two chaincode deployed on two different channels. chaincodeA want to call method of chaincodeB. As per specification its possible but only for read operation.
https://godoc.org/github.com/hyperledger/fabric/core/chaincode/shim#ChaincodeStub.InvokeChaincode
can you please share code how you are calling another chaincodeB from chaincodeA?

Related

Hyperledger Sawtooth Unmet Dependencies Transactions

Sawtooth Transaction headers have a dependencies field and which is an array of transaction headers that need to be added to the ledger before this transaction is processed.
Where are transactions with unmet dependencies stored? Are they stored in the node that first received them or stored in every node in the network?
The Validator stores incoming transactions in the pending queue. The Validator consumes the transaction from the pending queue for execution. Execution of the Transaction is done either when a Block is created or Block is validated. Addition of a Transaction to the Block is triggered by the consensus engine action.
A Transaction is broadcasted to other Validators part of that network as and when they arrive. It is removed from the pending queue if either the Transaction is evaluated, either failed or successful. If a Transaction is successful it should be either during the Block creation or the Block validation. If the created Block fails to be committed because of the consensus process, these Transactions are added back to the pending queue. There was nothing wrong with the Transaction as such, it just happened to be not part of the Block that is committed. A Transaction in other terms completely removed from the pending queue in successful case when it is committed to a Block.
When I say Transaction is pended at the Validator, of-course what is received is a Batch. Dependency check is done by the Validator when it considers a Transaction be added to the Block.
Hope this answers the question. Please add specific question if you're facing any issue or want to know in detail.

Hyperledger Network Roles

I'm going through the documentation on Hyperledger Fabric, and there's a portion in the introduction that writes:
"Hyperledger Fabric assigns network roles by node type. To provide concurrency and parallelism to the network, transaction execution is separated from transaction ordering and commitment. Executing transactions prior to ordering them enables each peer node to process multiple transactions simultaneously."
Maybe this is some fundamental misunderstanding on my part about the structure of the network and the different functions and mechanics of nodes, but how can one execute a transaction prior to ordering one?
Within a Hyperledger Fabric network, transactions start out with client applications sending transaction proposals, or, in other words, proposing a transaction to endorsing peers.
Each endorsing peer simulates the proposed transaction, without updating the ledger. The endorsing peers will capture the set of Read and Written data, called RW Sets.
These RW sets are then signed by the endorsing peer, and returned to the client application to be used in future steps of the transaction flow. Endorsing peers must hold smart contracts in order to simulate the transaction proposals.
The application then submits the endorsed transaction and the RW sets to the ordering service. Ordering happens across the network, in parallel with endorsed transactions and RW sets submitted by other applications.
The ordering service takes the endorsed transactions and RW sets, orders this information into a block, and delivers the block to all committing peers.
The committing peer validates the transaction by checking to make sure that the RW sets still match the current world state.
Committing peers are responsible for adding blocks of transactions to the shared ledger and updating the world state.
Here, you have the roles that there are in Hyperledger Fabric:
Endorser Peers: they receive a transaction. Then, they execute the transaction against the Smart Contrat and they sign the result. They send the transaction signed to the peer that has sent it.
Committer Peers: the Peers get the Blocks (with the validates transactions) and commit them to its ledger.
Orderes: nodes that sort the transactions and generate the blocks.
I take this info from an answer that I write for a question.

Are blocks mined in HyperLedger Fabric?

I have been reading the documentation on how HyperLedger Fabric's project is implementing a open source BlockChain solution: https://github.com/hyperledger/fabric/blob/master/docs/protocol-spec.md
I have seen that PBFT consensus algorithm is used, but I do not understand how blocks are mined and shared among all Validating Peers in the BlockChain network.
Hyperledger Validating Peers (VPs) do not mine blocks and do not share the blocks between them. Here is how it works:
A transaction is send to one trusted VP.
The VP broadcasts the transaction to all other VPs.
All VPs reach consensus (using PBFT algorithm) on the order to follow to execute the transactions.
All VPs execute the transactions "on their own" following the total order and build a block (calculating hashes mainly) with the executed transactions.
All the blocks will be the same because: the transaction execution is deterministic (should be) and the number of tx in a block is fixed.
According to Hyperledger Fabric 1.X
User through Client SDK send the transaction proposal to Endorsing Peers.
Endorsing Peer check the transaction and make endorsement proposal of transaction(with read/write set (previous value/Changed value)) and send to again client SDK.
Client SDK wait for all endorsement, once it get all endorsement proposal it make one invocation request and send to Orderer.
Orderer verify invocation request rent by client SDK by checking Policies defined(Consensus), verify the transaction and add to the block.
According to configuration defined for block, after specified time or number of transaction it form a Hash of block by using transaction hash, metadata and previous block hash.
The blocks of transactions are “delivered” to all peers on the channel by the Orderer.
All committing peers verify the endorsing policy and ensure that there have been no changes to ledger state for read set variables since the read set was generated by the transaction execution. After this all the transactions in the block and update the ledger with new block and current state of asset.
Ledger Contains
1) Current state Database(Level BD or Couch DB)
2) Blockchain(Files)(Linked blocks)
Read the transaction flow of hyperledger fabric
Check image for reference
Hyperledger is an umbrella of blockchain technologies. Hyperledger Fabric, mentioned above, is one of them. Hyperledger Sawtooth also does not use mining and adds these consensus algorithms:
PoET Proof of Elapsed Time (optional Nakamoto-style consensus algorithm used for Sawtooth). PoET with SGX has BFT. PoET Simulator has CFT. Not CPU-intensive as with PoW-style algorithms, although it still can fork and have stale blocks . See PoET specification at https://sawtooth.hyperledger.org/docs/core/release s/latest/architecture/poet.html
RAFT Consensus algorithm that elects a leader for a term of arbitrary time. Leader replaced if it times-out. Raft is faster than PoET, but is not BFT (Raft is CFT). Also Raft does not fork.
With unpluggable consensus, another consensus algorithm can be changed without reinitializing the blockchain or even restarting the software.
For completeness, the original consensus algorithm with bitcoin (and does use mining) is:
PoW Proof of Work. Completing work (CPU-intensive Nakamoto-style consensus algorithm). Usually used in permissionless blockchains

Applying CQRS to charging credit Card (using AKKA)

Given that I am a bit confused with CQRS I would like to understand it further in the following scenario.
I have an Actor that charge Users' credit card. To do so it contact a bank external service that does the operation, get a confirmation result. I would like to know how can I apply this with CQRS.
The information that needs to be written here is that a specific user has been charge a certain amount. So the event generated is Charged (UserID, Card, Amount). Something like that.
The problem is that all the examples I have seen especially with AKKA, would only generate the event after a Command is validated, such that it is persisted in a journal, and used to update the state of the actor. The Journal could then be red on the other side, such that to create a Reading view here.
Also usually, in those examples, the update state function has a logic that somewhat execute the command, because the command correspond straightforwardly to a state update at the end of the day. This is the typical BasketShoping example: CreateOrder, AddLineItem. All Of this Command, are directly translated in Event, that correspond to a specific code of the Update state function.
However in this example, one needs to actually contact an external service, charge the user and then generate an event. Contacting the external service can't be done in the update state, or after reading the journal. It would not make sense.
How is that done, and where, and when exactly, in the spirit of CQRS?
I can think of 2 ways of doing this.
First is a simple way. The command is DoCharge(UserId, Card, Amount). Upon reception of this command, you call the external payment service. If this has been successfully completed, you generate an event, Charged(UserId, Card, Amount, TransactionId) and store it in the journal.
Now, of course, it's not completely safe way, because your Actor can crash after it has sent the request to payment service, but before it has received and persisted the confirmation of the successful completion. Then you risk of charging the user twice. To overcome this risk, you have to make your payment operation idempotent. Here's how to do it. This example is based on the classic "RESTify Day trader" article. I'll summarize it here.
You need to split the payment operation in 2 phases. In first one, payment service creates a transaction token. It just identifies the transaction, and no financial operations are performed yet. Upon the creation, the identifier is received by your service and persisted in the journal.
In next phase you perform a payment associated with the identifier from phase one. If your actor now fails in the middle, while operation is performed successfully on the payment service side, the transaction token will already be marked as processed by the payment service, and it won't let you charge the customer twice. Now, if you restart the failed Actor, and it tries to run the payment associated with the existing transaction token, the payment service should return result like "Already executed" or such. Of course, at the end you also persist the result of the operation in the journal.

Architecture for robust payment processing

Imagine 3 system components:
1. External ecommerce web service to process credit card transactions
2. Local Database to store processing results
3. Local UI (or win service) to perform payment processing of the customer order document
The external web service is obviously not transactional, so how to guarantee:
1. results to be eventually persisted to database when received from web service even in case the database is not accessible at that moment(network issue, db timeout)
2. prevent clients from processing the customer order while payment initiated by other client but results not successfully persisted to database yet(and waiting in some kind of recovery queue)
The aim is to do processing having non transactional system components and guarantee the transaction won't be repeated by other process in case of failure.
(please look at it in the context of post sell payment processing, where multiple operators might attempt manual payment processing; not web checkout application)
Ask the payment processor whether they can detect duplicate transactions based on an order ID you supply. Then if you are unable to store the response due to a database failure, you can safely resubmit the request without fear of double-charging (at least one PSP I've used returned the same response/auth code in this scenario, along with a flag to say that this was a duplicate).
Alternatively, just set a flag on your order immediately before attempting payment, and don't attempt payment if the flag was already set. If an error then occurs during payment, you can investigate and fix the data at your leisure.
I'd be reluctant to go down the route of trying to automatically cancel the order and resubmitting, as this just gets confusing (e.g. what if cancelling fails - should you retry or not?). Best to keep the logic simple so when something goes wrong you know exactly where you stand.
In any system like this, you need robust error handling and error reporting. This is doubly true when it comes to dealing with payments, where you absolutely do not want to accidentaly take someone's money and not deliver the goods.
Because you're outsourcing your payment handling to a 3rd party, you're ultimately very reliant on the gateway having robust error handling and reporting systems.
In general then, you hand off control to the payment gateway and start a task that waits for a response from the gateway, which is either 'payment accepted' or 'payment declined'. When you get that response you move onto the next step in your process and everything is good.
When you don't get a response at all (time out), or the response is invalid, then how you proceed very much depends on the payment gateway:
If the gateway supports it send a 'cancel payment' style request. If the payment cancels successfully then you probably want to send the user to a 'sorry, please try again' style page.
If the gateway doesn't support canceling, or you have no communications to the gateway then you will need to manually (in person, such as telephone) contact the 3rd party to discover what went wrong and how to proceed. To aid this you need to dump as much detail as you have to error logs, such as date/time, customer id, transaction value, product ids etc.
Once you're back on your site (and payment is accepted) then you're much more in control of errors, but in brief if you cant complete the order, then you should either dump the details to disk (such as csv file for manual handling) or contact the gateway to cancel the payment.
Its also worth having a system in place to track errors as they occur, and if an excessive number occur then consider what should happen. If its a high traffic site for example you may want to temporarily prevent further customers from placing orders whilst the issue is investigated.
Distributed messaging.
When your payment gateway returns submit a message to a durable queue that guarantees a handler will eventually get it and process it. The handler would update the database. Should failure occur at that point the handler can leave the message in the queue or repost it to the queue, or post an alternate message.
Should something occur later that invalidates the transaction, another message could be queued to "undo" the change.
There's a fair amount of buzz lately about eventual consistency and distribute messaging. NServiceBus is the new component hotness. I suggest looking into this, I know we are.