From c2f110169ac92e76b1dc59c1ac6d960f4f2cae92 Mon Sep 17 00:00:00 2001 From: Kleissner Date: Wed, 13 Oct 2021 06:00:40 +0200 Subject: [PATCH] Automatically delete files from Warehouse in case there are no other references when deleting files from the blockchain via /blockchain/self/delete/file. New function blockchain.FileExists. blockchain.DeleteFiles now returns list of deleted files. --- blockchain/Blockchain.go | 28 ++++++++++++++++++++++++++-- blockchain/Test_test.go | 2 +- webapi/Blockchain.go | 4 ++-- webapi/File.go | 12 +++++++++++- webapi/readme.md | 4 +++- 5 files changed, 43 insertions(+), 7 deletions(-) diff --git a/blockchain/Blockchain.go b/blockchain/Blockchain.go index e644c68..313b4e8 100644 --- a/blockchain/Blockchain.go +++ b/blockchain/Blockchain.go @@ -18,6 +18,7 @@ Offset Size Info package blockchain import ( + "bytes" "encoding/binary" "errors" "sync" @@ -361,6 +362,26 @@ func (blockchain *Blockchain) ListFiles() (files []BlockRecordFile, status int) return files, status } +// FileExists checks if the file (identified via its hash) exists. +// If there is a corruption in the blockchain it will stop reading but return the files found so far. +func (blockchain *Blockchain) FileExists(hash []byte) (files []BlockRecordFile, status int) { + status = blockchain.Iterate(func(block *Block) (statusI int) { + filesD, err := decodeBlockRecordFiles(block.RecordsRaw, block.NodeID) + if err != nil { + return BlockchainStatusCorruptBlockRecord + } + for _, file := range filesD { + if bytes.Equal(file.Hash, hash) { + files = append(files, file) + } + } + + return BlockchainStatusOK + }) + + return files, status +} + // ProfileReadField reads the specified profile field. See ProfileX for the list of recognized fields. The encoding depends on the field type. Status is BlockchainStatusX. func (blockchain *Blockchain) ProfileReadField(index uint16) (data []byte, status int) { found := false @@ -450,8 +471,8 @@ func (blockchain *Blockchain) ProfileDelete(fields []uint16) (newHeight, newVers } // DeleteFiles deletes files from the blockchain. Status is BlockchainStatusX. -func (blockchain *Blockchain) DeleteFiles(IDs []uuid.UUID) (newHeight, newVersion uint64, status int) { - return blockchain.IterateDeleteRecord(func(record *BlockRecordRaw) (deleteAction int) { +func (blockchain *Blockchain) DeleteFiles(IDs []uuid.UUID) (newHeight, newVersion uint64, deletedFiles []BlockRecordFile, status int) { + newHeight, newVersion, status = blockchain.IterateDeleteRecord(func(record *BlockRecordRaw) (deleteAction int) { if record.Type != RecordTypeFile { return 0 // no action on record } @@ -463,10 +484,13 @@ func (blockchain *Blockchain) DeleteFiles(IDs []uuid.UUID) (newHeight, newVersio for _, id := range IDs { if id == filesDecoded[0].ID { // found a file ID to delete? + deletedFiles = append(deletedFiles, filesDecoded[0]) return 1 // delete record } } return 0 // no action on record }) + + return } diff --git a/blockchain/Test_test.go b/blockchain/Test_test.go index f23c0b3..f0435ff 100644 --- a/blockchain/Test_test.go +++ b/blockchain/Test_test.go @@ -193,7 +193,7 @@ func TestBlockchainDelete(t *testing.T) { fmt.Printf("----------------\n") // delete the file - newHeight, newVersion, status = blockchain.DeleteFiles([]uuid.UUID{file1.ID}) + newHeight, newVersion, _, status = blockchain.DeleteFiles([]uuid.UUID{file1.ID}) fmt.Printf("Deleted file: Status %d height %d version %d\n", status, newHeight, newVersion) // list all files diff --git a/webapi/Blockchain.go b/webapi/Blockchain.go index 4a2a192..1c6e1ea 100644 --- a/webapi/Blockchain.go +++ b/webapi/Blockchain.go @@ -44,7 +44,7 @@ type apiBlockchainBlockRaw struct { } type apiBlockchainBlockStatus struct { - Status int `json:"status"` // See BlockchainStatusX. + Status int `json:"status"` // See blockchain.StatusX. Height uint64 `json:"height"` // Height of the blockchain (number of blocks). Version uint64 `json:"version"` // Version of the blockchain. } @@ -74,7 +74,7 @@ func apiBlockchainSelfAppend(w http.ResponseWriter, r *http.Request) { } type apiBlockchainBlock struct { - Status int `json:"status"` // Status: 0 = Success, 1 = Error block not found, 2 = Error block encoding (indicates that the blockchain is corrupt) + Status int `json:"status"` // See blockchain.StatusX. PeerID string `json:"peerid"` // Peer ID hex encoded. LastBlockHash []byte `json:"lastblockhash"` // Hash of the last block. Blake3. BlockchainVersion uint64 `json:"blockchainversion"` // Blockchain version diff --git a/webapi/File.go b/webapi/File.go index be1b7bb..e817a40 100644 --- a/webapi/File.go +++ b/webapi/File.go @@ -184,6 +184,7 @@ func apiBlockchainSelfListFile(w http.ResponseWriter, r *http.Request) { /* apiBlockchainSelfDeleteFile deletes files with the provided IDs. Other fields are ignored. +It will automatically delete the file in the Warehouse if there are no other references. Request: POST /blockchain/self/delete/file with JSON structure apiBlockAddFiles Response: 200 with JSON structure apiBlockchainBlockStatus @@ -200,7 +201,16 @@ func apiBlockchainSelfDeleteFile(w http.ResponseWriter, r *http.Request) { deleteIDs = append(deleteIDs, input.Files[n].ID) } - newHeight, newVersion, status := core.UserBlockchain.DeleteFiles(deleteIDs) + newHeight, newVersion, deletedFiles, status := core.UserBlockchain.DeleteFiles(deleteIDs) + + // If successfully deleted from the blockchain, delete from the Warehouse in case there are no other references. + if status == blockchain.BlockchainStatusOK { + for n := range deletedFiles { + if files, status := core.UserBlockchain.FileExists(deletedFiles[n].Hash); status == blockchain.BlockchainStatusOK && len(files) == 0 { + core.UserWarehouse.DeleteFile(deletedFiles[n].Hash) + } + } + } EncodeJSON(w, r, apiBlockchainBlockStatus{Status: status, Height: newHeight, Version: newVersion}) } diff --git a/webapi/readme.md b/webapi/readme.md index c762130..2ff1170 100644 --- a/webapi/readme.md +++ b/webapi/readme.md @@ -345,6 +345,8 @@ Example response: This deletes files from the blockchain with the provided IDs. The blockchain will be refactored, which means it is recalculated without the specified files. The blockchains version number might be increased. +It will automatically delete the file in the Warehouse if there are no other references. + ``` Request: POST /blockchain/self/delete/file with JSON structure apiBlockAddFiles Response: 200 with JSON structure apiBlockchainBlockStatus @@ -360,7 +362,7 @@ Example POST request to `http://127.0.0.1:112/blockchain/self/delete/file`: } ``` -Example response: +Example response indicating success: ```json {