Skip to content

Commit

Permalink
Implement target time in getHistory tx
Browse files Browse the repository at this point in the history
  • Loading branch information
bandreghetti committed Jun 7, 2021
1 parent 97b54f9 commit 33c1e25
Showing 1 changed file with 55 additions and 18 deletions.
73 changes: 55 additions & 18 deletions transactions/readAssetHistory.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,17 @@ var ReadAssetHistory = Transaction{
DataType: "@key",
Required: true,
},
{
Tag: "timeTarget",
Description: "Optional parameter to retrieve specific version of the asset.",
DataType: "datetime",
},
},
ReadOnly: true,
Routine: func(stub shim.ChaincodeStubInterface, req map[string]interface{}) ([]byte, errors.ICCError) {
// This is safe to do because validation is done before calling routine
key := req["key"].(assets.Key)
timeTarget := req["timeTarget"]

// Get asset's history from blockchain
historyIterator, err := stub.GetHistoryForKey(key.Key())
Expand All @@ -44,33 +50,64 @@ var ReadAssetHistory = Transaction{
return nil, errors.NewCCError("history not found", 404)
}

response := make([]map[string]interface{}, 0)
if timeTarget == nil {
response := make([]map[string]interface{}, 0)
for historyIterator.HasNext() {
queryResponse, err := historyIterator.Next()
if err != nil {
return nil, errors.WrapError(err, "error iterating response")
}

data := make(map[string]interface{})

for historyIterator.HasNext() {
queryResponse, err := historyIterator.Next()
if queryResponse.IsDelete {
data["_isDelete"] = queryResponse.IsDelete
} else {
err = json.Unmarshal(queryResponse.Value, &data)
if err != nil {
return nil, errors.WrapError(err, "failed to unmarshal queryResponse's values")
}
}
data["_timestamp"] = time.Unix(queryResponse.Timestamp.Seconds, int64(queryResponse.Timestamp.Nanos)).Format(time.RFC3339)
response = append(response, data)
}
responseJSON, err := json.Marshal(response)
if err != nil {
return nil, errors.WrapError(err, "error iterating response")
return nil, errors.WrapError(err, "error marshaling response")
}

data := make(map[string]interface{})
return responseJSON, nil
} else {
response := make(map[string]interface{})
target := timeTarget.(time.Time)
closestTime := time.Time{}

if queryResponse.IsDelete {
data["_isDelete"] = queryResponse.IsDelete
} else {
err = json.Unmarshal(queryResponse.Value, &data)
for historyIterator.HasNext() {
queryResponse, err := historyIterator.Next()
if err != nil {
return nil, errors.WrapError(err, "failed to unmarshal queryResponse's values")
return nil, errors.WrapError(err, "error iterating response")
}

timestamp := queryResponse.Timestamp.AsTime()
if timestamp.Before(target) && timestamp.After(closestTime) {
closestTime = timestamp
if !queryResponse.IsDelete {
err = json.Unmarshal(queryResponse.Value, &response)
if err != nil {
return nil, errors.WrapError(err, "failed to unmarshal queryResponse's values")
}
}
response["_isDelete"] = queryResponse.IsDelete
response["_timestamp"] = timestamp.Format(time.RFC3339)
}
}
data["_timestamp"] = time.Unix(queryResponse.Timestamp.Seconds, int64(queryResponse.Timestamp.Nanos)).Format(time.RFC3339)
response = append(response, data)
}

responseJSON, err := json.Marshal(response)
if err != nil {
return nil, errors.WrapError(err, "error marshaling response")
}
responseJSON, err := json.Marshal(response)
if err != nil {
return nil, errors.WrapError(err, "error marshaling response")
}

return responseJSON, nil
return responseJSON, nil
}
},
}

0 comments on commit 33c1e25

Please sign in to comment.