I would like to get some data from a chaincode transaction (too complex for a query), but, as I see from the code, transactions return promises that don't resolve to values. In addition, chaincode has access to the current user's identity, and I don't know how to implement this in a query.
The Util class contains both invokeChainCode and queryChainCode methods, but the BusinessNetworkConnection class has only the submitTransaction transaction method that uses invokeChainCode and doesn't return any value.
What is the correct way of getting data from the chaincode, apart from copying and modifying the code for submitTransaction?
As far as I can understand your question, you wish to return some values from a transaction.
Assuming that the transaction is of Invoke Type (not query) then whatever you are returning from the chain code (for example shim.Success(someData);, it will be part of your transaction payload.)
So, in order to get that transaction payload from the transaction, you have to make sure its committed to the peer's ledger.
To be sure, just before you submit the transaction, you can subscribe to the transaction event using the given transaction id)
Ref:
https://github.com/hyperledger/fabric-samples/blob/release/balance-transfer/app/invoke-transaction.js#L90
EventHub : https://fabric-sdk-node.github.io/EventHub.html
Once you receive this event you can be sure that your transaction is successfully committed in the peer.
You can use the same transaction ID you can query a peer for the transaction block.
Ref : https://github.com/hyperledger/fabric-samples/blob/release/balance-transfer/app/query.js#L95
Channel.queryTransaction : https://fabric-sdk-node.github.io/Channel.html#queryTransaction__anchor
Once you get the transaction payload in JSON you can dig into the JSON and find the return value in proposal response part of the JSON payload.
[P.S. Assuming you are using Node JS SDK]
EDIT 1:
Hyperledger Fabric supports only 2 types of transactions on a broader level.
Invoke - If you send the proposal response to the orderer then your values (if any) are written to the state otherwise, any queried value are returned as a part of the proposal response payload.
Deploy - In case of Chaincode deployment transactions where the payload is just a chaincode binary.
So, in case you have read only transaction then you could just submit the transaction and get the proposal response payload from the peer(s). The proposal response itself is the result of your query invocation.
Related
so I am looking into the postmates API and I have been able to create a delivery. This was great, I also setup a webhook url with ngrok to test the response from postmates but I am totally stumped as to how to determine when the pickup was actually completed and the dropoff/delivery was actually completed.
I saved all of the responses in a database and each time I did the test delivery, I received exactly 70 calls from the webhook endpoint. And each time 47 of them were in regards to the 'kind': 'event.delivery_status'. Here are the stats:
THIS IS ALL IN TEST MODE WITH THE SANDBOX...
11 of those are 'status':'pickup_complete'
14 of those are 'status':'pickup'
11 of those are 'status':'dropoff'
11 of those are 'status':'delivered'
all of the webhook responses for status=delivered have a 'data.courier_imminent':false value.
I went to the webpage for the 'data.tracking_url' and when the webpage showed that the delivery was complete, I immediately updated the database to see how many records that I had saved and I was only at 32 total records. this means that the webhook was continuing to send me updates after it was supposedly complete.
Lastly, all of these statuses are not in order, they are totally random, in fact the 6th to last record that was received was a pickup_complete status..
The real question:
how will I know what is actually a picked=completed, delivered=complete etc..
You'll receive a webhook of type event.delivery_status. One of the field within the body of the payload will be {status: "delivered"}. This has been accurate so far. Postmates doesn't return adelivered_at` timestamp, but you could create your own timestamp and store it along with the delivery for reporting.
As for the number of webhooks, Postmates has a delivery robot (called robo) that moves as if it was a real postmate. You'll receive a lot of webhooks of type event.courier_update with the updated location.
I'm wondering if there any way to find transaction by input/output address.
In REST API Reference GET /state/{address} is mentioned, but I don't understand what I get in response:
{
"data": "oXiAODM1OGFjYzgyY2FmYmY1ZjUzZmNjNDcwMzE0YTMzYjk1N2ViMzE0ZmI1OWU3MmVkNDVkNjNhMTZjZDAxMjc5NTg1OTliY2Q3ZDQ0ZmI4NWUxZDBmZGY5ZmJmYTU3N2FhZjgyYWNlNzBkMDVmZDJmYWIzMzNhMTYzMDM5Y2U3NDZ2MjAxOC0wOS0xOSBhdCAxMzoxMTo0OQ==",
"head": "22972511836daa61bef7b9b987760579bcc249809a6f2ff59b3050e989bc2ace116d5c4c1cea10fba0aad25f200bb117e6958765be1047a67493590c07b2603c",
"link": "http://xxx.xxx.xxx.xxx:8080/state/4536b54af36b6dbad85af2bf228500aaa7f89d11cf0bac0f3290a5977bae443d74d692?head=22972511836daa61bef7b9b987760579bcc249809a6f2ff59b3050e989bc2ace116d5c4c1cea10fba0aad25f200bb117e6958765be1047a67493590c07b2603c"
}
I've tried to decode data from response, figured out that it is Base64 encoded and that it contains only payload of transaction.
Is there any way to get the ID of transaction?
You can fetch a Sawtooth transaction with the REST API using
GET /transactions/{transaction_id}
You need to know the transaction ID. The client submits and creates the transaction ID and would know it.
The transaction ID is also listed in the transaction header for each transaction in a blockchain.
You can also list all transactions with GET /transactions
Yes, the data is base64-encoded. After decoding, you need to deserialize. The deserializing method is up to the Transaction Processor that processes the transaction. Common serialization methods are Protobuf and CBOR.
I am trying to build a cursor based pagination API on top of a spanner dataset. To do this I'm am using the read timestamp from the initial request to retrieve data and then encoding this into a cursor which can then be used to do an "Exact staleness" (https://cloud.google.com/spanner/docs/timestamp-bounds) read in subsequent paging requests.
For example, the processing of a request for the first page looks something like:
Transaction tx = spanner.singleUseReadOnlyTransaction();
tx.executeQuery(statement); // result set containing the first page of data
tx.getReadTimestamp(); // read timestamp that gets returned in a cursor
And for subsequent requests:
Transaction tx = spanner.singleUseReadOnlyTransaction(TimestampBound.ofReadTimestamp(cursorTs));
I'd also like to return a message to the user when the cursor timestamp has expired (the documentation linked to above states they are valid for roughly an hour) and to do this I have the following code:
try {
// process spanner result set
} catch (SpannerException e) {
if (ErrorCode.FAILED_PRECONDITION.equals(e.getErrorCode)) {
// cursor has expired, return appropriate error message
}
}
This works fine when manually testing against a long running spanner database. However, in my test code I create a spanner database and then tear it down once the test is complete and in these tests the spanner exception is only thrown intermittently when I use a read timestamp that should definitely be expired (say over a year old). In the cases where no exception is thrown, I get an empty resultset. If I make multiple requests to spanner in my test with this expired read timestamp, eventually the database seems to consistently throw the "failed precondition" error.
Is this behaviour expected for a newly provisioned spanner database?
I believe the reason for this behavior is because you are using Read-only Transactions. As explained in the documentation, Read-only transactions always observe a consistent state of the database and the transaction commit history at a chosen point. In your case, the database is created and torn down before and after your test is completed. Hence, no transaction commit history to be observed except after a number of attempts.
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?
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.