mirror of
https://github.com/PeernetOfficial/core.git
synced 2026-07-17 02:47:51 +01:00
Refactor blockchain code into separate files (no code changes).
This commit is contained in:
85
blockchain/Blockchain File.go
Normal file
85
blockchain/Blockchain File.go
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
File Name: Blockchain File.go
|
||||
Copyright: 2021 Peernet s.r.o.
|
||||
Author: Peter Kleissner
|
||||
*/
|
||||
|
||||
package blockchain
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// AddFiles adds files to the blockchain. Status is BlockchainStatusX.
|
||||
// It makes sense to group all files in the same directory into one call, since only one directory record will be created per unique directory per block.
|
||||
func (blockchain *Blockchain) AddFiles(files []BlockRecordFile) (newHeight, newVersion uint64, status int) {
|
||||
encoded, err := encodeBlockRecordFiles(files)
|
||||
if err != nil {
|
||||
return 0, 0, BlockchainStatusCorruptBlockRecord
|
||||
}
|
||||
|
||||
return blockchain.Append(encoded)
|
||||
}
|
||||
|
||||
// ListFiles returns a list of all files. Status is BlockchainStatusX.
|
||||
// If there is a corruption in the blockchain it will stop reading but return the files parsed so far.
|
||||
func (blockchain *Blockchain) ListFiles() (files []BlockRecordFile, status int) {
|
||||
status = blockchain.Iterate(func(block *Block) (statusI int) {
|
||||
filesMore, err := decodeBlockRecordFiles(block.RecordsRaw, block.NodeID)
|
||||
if err != nil {
|
||||
return BlockchainStatusCorruptBlockRecord
|
||||
}
|
||||
files = append(files, filesMore...)
|
||||
|
||||
return BlockchainStatusOK
|
||||
})
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// DeleteFiles deletes files from the blockchain. Status is BlockchainStatusX.
|
||||
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
|
||||
}
|
||||
|
||||
filesDecoded, err := decodeBlockRecordFiles([]BlockRecordRaw{*record}, nil)
|
||||
if err != nil || len(filesDecoded) != 1 {
|
||||
return 3 // error blockchain corrupt
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
95
blockchain/Blockchain Profile.go
Normal file
95
blockchain/Blockchain Profile.go
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
File Name: Blockchain Profile.go
|
||||
Copyright: 2021 Peernet s.r.o.
|
||||
Author: Peter Kleissner
|
||||
*/
|
||||
|
||||
package blockchain
|
||||
|
||||
// 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
|
||||
|
||||
status = blockchain.Iterate(func(block *Block) (statusI int) {
|
||||
fields, err := decodeBlockRecordProfile(block.RecordsRaw)
|
||||
if err != nil {
|
||||
return BlockchainStatusCorruptBlockRecord
|
||||
} else if len(fields) == 0 {
|
||||
return BlockchainStatusOK
|
||||
}
|
||||
|
||||
// Check if the field is available in the profile record. If there are multiple records, only return the latest one.
|
||||
for n := range fields {
|
||||
if fields[n].Type == index {
|
||||
data = fields[n].Data
|
||||
found = true
|
||||
}
|
||||
}
|
||||
|
||||
return BlockchainStatusOK
|
||||
})
|
||||
|
||||
if status != BlockchainStatusOK {
|
||||
return nil, status
|
||||
} else if !found {
|
||||
return nil, BlockchainStatusDataNotFound
|
||||
}
|
||||
|
||||
return data, BlockchainStatusOK
|
||||
}
|
||||
|
||||
// ProfileList lists all profile fields. Status is BlockchainStatusX.
|
||||
func (blockchain *Blockchain) ProfileList() (fields []BlockRecordProfile, status int) {
|
||||
uniqueFields := make(map[uint16][]byte)
|
||||
|
||||
status = blockchain.Iterate(func(block *Block) (statusI int) {
|
||||
fields, err := decodeBlockRecordProfile(block.RecordsRaw)
|
||||
if err != nil {
|
||||
return BlockchainStatusCorruptBlockRecord
|
||||
}
|
||||
|
||||
for n := range fields {
|
||||
uniqueFields[fields[n].Type] = fields[n].Data
|
||||
}
|
||||
|
||||
return BlockchainStatusOK
|
||||
})
|
||||
|
||||
for key, value := range uniqueFields {
|
||||
fields = append(fields, BlockRecordProfile{Type: key, Data: value})
|
||||
}
|
||||
|
||||
return fields, status
|
||||
}
|
||||
|
||||
// ProfileWrite writes profile fields and blobs to the blockchain. Status is BlockchainStatusX.
|
||||
func (blockchain *Blockchain) ProfileWrite(fields []BlockRecordProfile) (newHeight, newVersion uint64, status int) {
|
||||
encoded, err := encodeBlockRecordProfile(fields)
|
||||
if err != nil {
|
||||
return 0, 0, BlockchainStatusCorruptBlockRecord
|
||||
}
|
||||
|
||||
return blockchain.Append(encoded)
|
||||
}
|
||||
|
||||
// ProfileDelete deletes fields and blobs from the blockchain. Status is BlockchainStatusX.
|
||||
func (blockchain *Blockchain) ProfileDelete(fields []uint16) (newHeight, newVersion uint64, status int) {
|
||||
return blockchain.IterateDeleteRecord(func(record *BlockRecordRaw) (deleteAction int) {
|
||||
if record.Type != RecordTypeProfile {
|
||||
return 0 // no action
|
||||
}
|
||||
|
||||
existingFields, err := decodeBlockRecordProfile([]BlockRecordRaw{*record})
|
||||
if err != nil || len(existingFields) != 1 {
|
||||
return 3 // error blockchain corrupt
|
||||
}
|
||||
|
||||
for _, i := range fields {
|
||||
if i == existingFields[0].Type { // found a file ID to delete?
|
||||
return 1 // delete record
|
||||
}
|
||||
}
|
||||
|
||||
return 0 // no action on record
|
||||
})
|
||||
}
|
||||
@@ -18,14 +18,12 @@ Offset Size Info
|
||||
package blockchain
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"sync"
|
||||
|
||||
"github.com/PeernetOfficial/core/store"
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// Blockchain stores the blockchain's header in memory. Any changes must be synced to disk!
|
||||
@@ -334,163 +332,3 @@ func (blockchain *Blockchain) Read(number uint64) (decoded *BlockDecoded, status
|
||||
|
||||
return decoded, BlockchainStatusOK, nil
|
||||
}
|
||||
|
||||
// AddFiles adds files to the blockchain. Status is BlockchainStatusX.
|
||||
// It makes sense to group all files in the same directory into one call, since only one directory record will be created per unique directory per block.
|
||||
func (blockchain *Blockchain) AddFiles(files []BlockRecordFile) (newHeight, newVersion uint64, status int) {
|
||||
encoded, err := encodeBlockRecordFiles(files)
|
||||
if err != nil {
|
||||
return 0, 0, BlockchainStatusCorruptBlockRecord
|
||||
}
|
||||
|
||||
return blockchain.Append(encoded)
|
||||
}
|
||||
|
||||
// ListFiles returns a list of all files. Status is BlockchainStatusX.
|
||||
// If there is a corruption in the blockchain it will stop reading but return the files parsed so far.
|
||||
func (blockchain *Blockchain) ListFiles() (files []BlockRecordFile, status int) {
|
||||
status = blockchain.Iterate(func(block *Block) (statusI int) {
|
||||
filesMore, err := decodeBlockRecordFiles(block.RecordsRaw, block.NodeID)
|
||||
if err != nil {
|
||||
return BlockchainStatusCorruptBlockRecord
|
||||
}
|
||||
files = append(files, filesMore...)
|
||||
|
||||
return BlockchainStatusOK
|
||||
})
|
||||
|
||||
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
|
||||
|
||||
status = blockchain.Iterate(func(block *Block) (statusI int) {
|
||||
fields, err := decodeBlockRecordProfile(block.RecordsRaw)
|
||||
if err != nil {
|
||||
return BlockchainStatusCorruptBlockRecord
|
||||
} else if len(fields) == 0 {
|
||||
return BlockchainStatusOK
|
||||
}
|
||||
|
||||
// Check if the field is available in the profile record. If there are multiple records, only return the latest one.
|
||||
for n := range fields {
|
||||
if fields[n].Type == index {
|
||||
data = fields[n].Data
|
||||
found = true
|
||||
}
|
||||
}
|
||||
|
||||
return BlockchainStatusOK
|
||||
})
|
||||
|
||||
if status != BlockchainStatusOK {
|
||||
return nil, status
|
||||
} else if !found {
|
||||
return nil, BlockchainStatusDataNotFound
|
||||
}
|
||||
|
||||
return data, BlockchainStatusOK
|
||||
}
|
||||
|
||||
// ProfileList lists all profile fields. Status is BlockchainStatusX.
|
||||
func (blockchain *Blockchain) ProfileList() (fields []BlockRecordProfile, status int) {
|
||||
uniqueFields := make(map[uint16][]byte)
|
||||
|
||||
status = blockchain.Iterate(func(block *Block) (statusI int) {
|
||||
fields, err := decodeBlockRecordProfile(block.RecordsRaw)
|
||||
if err != nil {
|
||||
return BlockchainStatusCorruptBlockRecord
|
||||
}
|
||||
|
||||
for n := range fields {
|
||||
uniqueFields[fields[n].Type] = fields[n].Data
|
||||
}
|
||||
|
||||
return BlockchainStatusOK
|
||||
})
|
||||
|
||||
for key, value := range uniqueFields {
|
||||
fields = append(fields, BlockRecordProfile{Type: key, Data: value})
|
||||
}
|
||||
|
||||
return fields, status
|
||||
}
|
||||
|
||||
// ProfileWrite writes profile fields and blobs to the blockchain. Status is BlockchainStatusX.
|
||||
func (blockchain *Blockchain) ProfileWrite(fields []BlockRecordProfile) (newHeight, newVersion uint64, status int) {
|
||||
encoded, err := encodeBlockRecordProfile(fields)
|
||||
if err != nil {
|
||||
return 0, 0, BlockchainStatusCorruptBlockRecord
|
||||
}
|
||||
|
||||
return blockchain.Append(encoded)
|
||||
}
|
||||
|
||||
// ProfileDelete deletes fields and blobs from the blockchain. Status is BlockchainStatusX.
|
||||
func (blockchain *Blockchain) ProfileDelete(fields []uint16) (newHeight, newVersion uint64, status int) {
|
||||
return blockchain.IterateDeleteRecord(func(record *BlockRecordRaw) (deleteAction int) {
|
||||
if record.Type != RecordTypeProfile {
|
||||
return 0 // no action
|
||||
}
|
||||
|
||||
existingFields, err := decodeBlockRecordProfile([]BlockRecordRaw{*record})
|
||||
if err != nil || len(existingFields) != 1 {
|
||||
return 3 // error blockchain corrupt
|
||||
}
|
||||
|
||||
for _, i := range fields {
|
||||
if i == existingFields[0].Type { // found a file ID to delete?
|
||||
return 1 // delete record
|
||||
}
|
||||
}
|
||||
|
||||
return 0 // no action on record
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteFiles deletes files from the blockchain. Status is BlockchainStatusX.
|
||||
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
|
||||
}
|
||||
|
||||
filesDecoded, err := decodeBlockRecordFiles([]BlockRecordRaw{*record}, nil)
|
||||
if err != nil || len(filesDecoded) != 1 {
|
||||
return 3 // error blockchain corrupt
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user