Im trying to use a ticker in my chaincode to update the chaincode state periodically, based on some condition:
func (t *SimpleChaincode) Invoke(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {
ticker := time.NewTicker(time.Millisecond * 10000)
go func() {
for t := range ticker.C {
fmt.Println("Tick at", t)
a = a+5
err:= stub.PutState("a", []byte(strconv.Itoa(a)))
fmt.Println(err.Error())
}
}()
return nil, nil
}
I am sending the invoke transaction using the chaincode REST api for invoke :
POST http://<ip>:<port>/chaincode
{
"jsonrpc": "2.0",
"method": "invoke",
"params": {
"type": 1,
"chaincodeID":{
"name":"c7b3c82f1170423115dcfc2524189f96f156b30961e0a0e84426c425c22f3b4e8b6ecbf477b76e014bfce74b996dee476a2470cbddc14d390617192f00c22c38"
},
"ctorMsg": {
"function":"invoke",
"args":[]
},
"secureContext": "tom"
},
"id": 1
}
But PutState is failing with the following log:
2016/05/20 13:44:04 [8bcbe40e]Inside putstate, isTransaction = false
Tick at 2016-05-20 13:44:04.609079034 +0000 UTC
Cannot put state in query context
Tick at 2016-05-20 13:44:14.609093012 +0000 UTC
Cannot put state in query context
2016/05/20 13:44:14 [8bcbe40e]Inside putstate, isTransaction = false
Tick at 2016-05-20 13:44:24.609070317 +0000 UTC
Cannot put state in query context
Why is isTransaction = false , and why does it consider this context as a query context ?
The original invoke transaction has completed and returned. The PutState from goroutine continues outside the transaction context (becoming, as it were, "a transaction" initiated by the chaincode itself). This is not allowed. All interactions with the ledger have to be part of an external transaction.