To my knowledge, there isn't a way to do timed transaction in Hyperledger Fabric.
Consider the use case using the marbles example. Say I want to transfer a marble 600 seconds after I received it. Does the Fabric SDK provide anyway for me to get the unix timestamp of the event when I received my marble then send another transaction to a queue that will happen exactly 600 seconds later by calculating the timestamp + 600?
As you are talking about the time when the Marbles are actually received, then in my opinion you have to write some code on both sides. i.e, both at client and the chaincode sides.
I am not sure how to do the same with only SDK/Client side code.
If you are willing to write something in your transaction processing logic, there is a method ChaincodeStubInterface.GetTxTimestamp() in the github.com/hyperledger/fabric/core/chaincode/shim package to get the time when the transaction is processed by the Fabric.
You could return the same to your SDK, and then to your external calling program. And then compute the +600 seconds and send the next transaction.
No, there is no way to automate a timed transaction from within the chaincode and it would be bad practice to try handle it there. If you try to create a timestamp from within the chaincode, it is guaranteed that all peers processing the transaction proposal will return different values as they do not all being processing the proposal at the same exact instance. Since the results sets will return non-deterministic, the transaction will always fail when it enters the validation phase. If you try to use stub.GetTxTimestamp() you will only be returning the timestamp that the client itself sent up, as per the docs.
The best way to do this is with pure sdk code. After acquiring requisite transaction proposals and sending the transaction for ordering, listen for a transaction commitment event.
Upon receiving notification of transaction commitment, you can queue up another transaction to be sent endorsement and commitment 600 seconds later. The specifics of how will differ from sdk to sdk, but all sdk's support notification of transaction commitment.
Related
Running the Fabric test network with a very basic asset based chaincode.
Using the Java SDK to submit batches of assets. All works fine until I've submitted about 75,000 transactions. At this point, the following exception starts to occur every insert. It does however appear to successfully add assets.
org.hyperledger.fabric.gateway.ContractException: Commit strategy failed
Looking at the ContractException, the proposalResponse for each peer appears to have the ChaincodeResponseStatus set to SUCCESS, and indeed the hashes of the payload responses match. There seems to be nothing within the exception to indicate something has gone wrong (apart from the presence of the exception itself).
A restart of the Java app using the SDK seems to resolve this until 75k or so inserts. No errors appear in the logs of the peers (or indeed the chaincode containers). If I add debug output to the CC, no adverse output is generated.
The steps in the submit flow at the client end are:
Send transaction proposal to peers for endorsement.
Send endorsed transaction to the orderer.
Listen for block events from peers, and look through each block for the submitted transaction ID.
The way the block events are handled depends on which commit strategy is selected, but the default behaviour is:
If an unsuccessful validation code is observed from any peer, the transaction failed validation at the peer, the ledger was not updated, and you get an exception to indicate that.
If a timeout period is reached before a result (either successful validation or connection failure) is received for all org peers, a TimeoutException occurs.
Once a successful transaction validation code has been received or a connection failure has occurred for all org peers:
If at least one successful validation code is observed, you're good.
If the block eventing connection to all peers fails without the transaction being observed, you get the "Commit strategy failed" message.
So this message is received after the transaction has been successfully endorsed and sent to the orderer, but then the block eventing connection to all peers failed and the client does not know whether or not the transaction was successful. It might have committed successfully. It might have failed. It might not have been committed at all yet.
The block eventing connections should retry and reestablish connectivity, but I have seen some cases where something in the network path is black-holing traffic for some reason. Since it seems to happen consistently for you after a certain number of transactions, it's just possible there is some issue in the client that is causing a failure over time, like a memory leak. It's worth doing some investigation.
In general, if you do have a transaction in this indeterminate state, a good approach can be to resubmit the transaction with the same transaction ID to the orderer again until you can observe the commit status and know for sure whether the transaction was successful or failed. Using the same transaction ID is important as it avoids the possibility of double-spend since Fabric will reject a transaction at validation time if that transaction ID has previously been committed, either successfully or unsuccessfully.
As currently, I'm working on fabric SDKs. I want to get all the past transactions of fabric on the client-side.
Example: I already have 1 installed chain code. On fabric, I called delete_user and edit_user methods. I want those all transaction on client side without storing in offchain DB.
Can anyone suggest Node SDK method for the same?
Have each transaction function emit a suitably named chaincode event (such as "deleteUser" and "editUser"). The chaincode event gets emitted be peers only when the transaction is successfully committed and updates the ledger. Your client application can listen for those chaincode events and take action on each chaincode event.
You can start listening for chaincode events from a specific block number to replay historic events. You may also want to use a "checkpointer" (or roll-your-own) mechanism for persisting the block number and transaction ID your listener last successfully processed so you can resume listening from exactly the same point after an application restart. This would allow you to process each chaincode event exactly once, with no duplication or missed events.
See these Fabric samples for examples:
https://github.com/hyperledger/fabric-samples/tree/main/asset-transfer-events
https://github.com/hyperledger/fabric-samples/tree/main/off_chain_data
I am using web3 to perform ethereum transactions. I have been able to perform the transaction, but I want to notify the user if the transaction is successful and has been mined. How would i do this in node.js?
I have tried to find ways to use a webhook on the reciever ethereum wallet in order to notify the server if a transaction on the blockchain has been mined. After that i would be able to notify the user.
My last option is to create a multi threaded loop on my server that checks if the transaction hash has been mined.
I am unsure if I should provide any code, as I don’t know if it will help.
You can use the web3.eth.getTransactionReceipt method to get a receipt for a transaction, or wait for an event generated by a smart contract when your transaction is being executed.
However, you should take into mind that public Ethereum may have forks and you should wait 5-6 blocks to make sure that the transaction will not be dropped along with the "side" fork.
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
I have a conceptual question. I'm performing async requests to Composer REST and I'm getting message: 'error trying invoke chaincode. Error: Peer has rejected transaction \'552b42fa4d2cfd366ff1b7d01371878f53f7553b44f141187c6db86b75f68906\' with cdoe MVCC_READ_CONFLICT',. I got the same problem when using node-sdk. What is the reason for that? Shouldn't it be possible to submit multiple transactions asynchronously?
Hyperledger Fabric uses lock-free optimistic concurrency, with rollback in case of dirty read/writes. You need to avoid key collisions as far as possible and may need to write retry logic on the client side.
The BatchTimeout setting for Fabric can be used to decrease latency (minimise the chance of collisions) at the expense of throughout:
https://github.com/hyperledger/fabric/blob/release/sampleconfig/configtx.yaml#L144
When you submit a transaction, the peer generates a read and write set. This read/write set is then used when the transaction is committed to the ledger. It contains the name of the variables to be read/written and their version when they were read. If, during the time between set creation and committing, a different transaction was committed and changed the version of the variable, the original transaction will be rejected during committal because the version when read is not the current version.
To address this, you will have to create data and transaction structures which avoid concurrently editing the same key. A sample way to do this is provided in fabric-samples here:
https://github.com/hyperledger/fabric-samples/tree/release/high-throughput