func (self *Store) Op_hash(operation *operations.Hash) (ret bucket.BucketReturn) { opGet := operations.Get{ BucketId: operation.BucketId, Key: operation.Key, } ret = self.Op_get(&opGet) if !ret.GetCode().IsOk() { // Error return } if ret.GetCode() == retcode.OkNotFound { // Not found, so we cannot hash it return } // Ok, something we can hash returnGet := ret.(*operations.GetReturn) value := returnGet.Value hasher := hasher.NewHasher(value) hashreturn := new(operations.HashReturn) hashreturn.FirstElementSha256Hash = hasher.FirstElement() hashreturn.AllElementsSha256Hash = hasher.AllElements() hashreturn.Status = retcode.NewStatusOk() return hashreturn }
func fillMissingHashesAccordingToConfig(returnConfig *operations.ReturnConfig, value types.Array, hashes *hashes.Hashes) { // Can only return hashes if value is available if returnConfig.HashReturn && value != nil { // Ok, need hashes if hashes.AllElementsSha256Hash == nil || hashes.FirstElementSha256Hash == nil { // Ok, hash is missing hasher := hasher.NewHasher(value) hashes.FirstElementSha256Hash = hasher.FirstElement() hashes.AllElementsSha256Hash = hasher.AllElements() } } }
func (self *hasherInstance) op_put(operation *operations.Put, state *minos.OperationState) (ret bucket.BucketReturn) { if operation.Value == nil { // Removes are ignored return &bucket.ReturnGeneric{retcode.NewStatus(retcode.ErrorOperationNotSupported)} } var firstElementHashBytes []byte if operation.Hashes.FirstElementSha256Hash == nil { theHasher := syshasher.NewHasher(operation.Value) firstElementHashBytes = theHasher.FirstElement() //TODO: Also forward alle elements hash } firstElementHash := hashes.FirstElementSha256Hash(firstElementHashBytes) // Always forward a put with the generated hash as value, even if already exists //TODO: Security problem if someone listens for such things? putForward := operations.Put{ Key: operation.Key, Value: types.Array{firstElementHashBytes}, Hashes: hashes.Hashes{ FirstElementSha256Hash: firstElementHash, }, } state.PutForwarder.ForwardIfOk(&putForward) // Check if already exists existsOperation := operations.Exists{ BucketId: self.backendId, Key: types.Key{firstElementHashBytes}, } apiExists := state.Dispatcher.Perform(state.Context, &existsOperation) if apiExists.GetCode() == retcode.Ok { // Already exists, end here return &operations.PutReturn{retcode.NewStatus(retcode.OkAlreadyExists)} } if !apiExists.GetCode().IsOk() { return &bucket.ReturnGeneric{retcode.NewStatusError( apiExists.GetCode(), errors.New("Unable to check if the entry already exists"))} } originalValue := operation.Value var valueToSupply []byte if len(originalValue) > 0 { valueToSupply = originalValue[0] } else { // If there's no value, take empty bytes valueToSupply = []byte{} } newPutOperation := operations.Put{ BucketId: self.backendId, Key: types.Key{firstElementHashBytes}, // Only the first element survives Value: types.Array{valueToSupply}, } apiPerformRet := state.Dispatcher.Perform(state.Context, &newPutOperation) if !apiPerformRet.GetCode().IsOk() { return &bucket.ReturnGeneric{retcode.NewStatusError( apiPerformRet.GetCode(), errors.New("Unable to transfer the data to the backend bucket"))} } return &bucket.ReturnGeneric{retcode.NewStatusOk()} }