2869 lines
83 KiB
Go
2869 lines
83 KiB
Go
|
|
// badgerDatabase provides functions to read and write to the Badger database.
|
|
// This database is used to store profiles, messages, reviews, reports, and more.
|
|
|
|
package badgerDatabase
|
|
|
|
// Below are the kinds of information being stored, and the format in which they are stored.
|
|
|
|
// Mate Profiles
|
|
// -Key = Prefix + Profile hash
|
|
// -Value = Mate profile bytes
|
|
|
|
// Host Profiles
|
|
// -Key = Prefix + Profile hash
|
|
// -Value = Host profile bytes
|
|
|
|
// Moderator Profiles
|
|
// -Key = Prefix + Profile hash
|
|
// -Value = Moderator profile bytes
|
|
|
|
// Messages
|
|
// -Key = Prefix + Message Hash
|
|
// -Value = Message bytes
|
|
|
|
// Reviews
|
|
// -Key = Prefix + Review hash
|
|
// -Value = Review bytes
|
|
|
|
// Reports
|
|
// -Key = Prefix + Report Hash
|
|
// -Value = Report bytes
|
|
|
|
// Profile Metadata
|
|
// -Key: Prefix + Profile Hash
|
|
// -Value: Messagepack encoded profile metadata. Described in contentMetadata.go
|
|
|
|
// Message Metadata
|
|
// -Key: Prefix + Message Hash
|
|
// -Value: Messagepack encoded message metadata. Described in contentMetadata.go
|
|
|
|
// The rest of the described database entries do not store data, but rather store information about the data
|
|
// These will make it faster to retrieve profiles, messages, reviews, and reports
|
|
// For example, review and report lists make it faster to find reviews/reports of a particular message/identity/profile/attribute
|
|
|
|
// Attribute Profiles List
|
|
// -Key = Prefix + Attribute Hash
|
|
// -Value = Comma separated list of all profile hashes which contain this attribute
|
|
|
|
// Mate Identity Profiles List:
|
|
// -Key = Prefix + Identity hash
|
|
// -Value = Comma separated list of the Mate identity's profile hashes
|
|
|
|
// Host Identity Profiles List:
|
|
// -Key = Prefix + Identity Hash
|
|
// -Value = Comma separated list of the Host identity's profile hashes
|
|
|
|
// Moderator Identity Profiles List:
|
|
// -Key = Prefix + Identity Hash
|
|
// -Value = Comma separated list of the Moderator identity's profile hashes
|
|
|
|
// Inbox Messages List:
|
|
// -Key = Prefix + Inbox
|
|
// -Value = Comma separated list of message hashes of messages in a particular inbox
|
|
|
|
// Reviewer Identity Reviews List
|
|
// -Key = Prefix + Reviewer Identity Hash
|
|
// -Value = Comma separated list of all review hashes of identity reviews authored by a reviewer (moderator)
|
|
|
|
// Reviewer Profile Reviews List
|
|
// -Key = Prefix + Reviewer Identity Hash
|
|
// -Value = Comma separated list of all review hashes of profile reviews authored by a reviewer (moderator)
|
|
|
|
// Reviewer Attribute Reviews List
|
|
// -Key = Prefix + Reviewer Identity Hash
|
|
// -Value = Comma separated list of all review hashes of attribute reviews authored by a reviewer (moderator)
|
|
|
|
// Reviewer Message Reviews List
|
|
// -Key = Prefix + Reviewer Identity Hash
|
|
// -Value = Comma separated list of all review hashes of message reviews authored by a reviewer (moderator)
|
|
|
|
// Identity Reviews List
|
|
// -Key = Prefix + Reviewed Identity Hash
|
|
// -Value = Comma separated list of all review hashes for reviews of a particular identity.
|
|
// These are the identities of the users who are being reviewed, not the identities of the moderators who created the reviews
|
|
|
|
// Profile Reviews List:
|
|
// -Key = Prefix + Reviewed Profile Hash
|
|
// -Value = Comma separated list of all review hashes for reviews of a particular profile hash
|
|
|
|
// Attribute Reviews List:
|
|
// -Key = Prefix + Reviewed Profile Attribute Hash
|
|
// -Value = Comma separated list of all review hashes for reviews of a particular profile attribute
|
|
|
|
// Message Reviews List:
|
|
// -Key = Prefix + Reviewed Message hash
|
|
// -Value = Comma separated list of all reviews hashes for reviews of a particular message
|
|
|
|
|
|
// Identity Reports List
|
|
// -Key = Prefix + Reported Identity Hash
|
|
// -Value = Comma separated list of all report hashes for reports of a particular identity.
|
|
|
|
// Profile Reports List:
|
|
// -Key = Prefix + Reported Profile Hash
|
|
// -Value = Comma separated list of all report hashes for reports of a particular profile
|
|
|
|
// Attribute Reports List:
|
|
// -Key = Prefix + Reported Profile Attribute Hash
|
|
// -Value = Comma separated list of all report hashes for reports of a particular profile attribute
|
|
|
|
// Message Reports List:
|
|
// -Key = Prefix + Reported Message Hash
|
|
// -Value = Comma separated list of all report hashes for reports of a particular message
|
|
|
|
//TODO: Be aware that we cannot prune the attributeProfilesList until all of the attribute's profiles are expired (if mate), or if the attribute's author identity is no longer funded
|
|
// We need to do this so we can keep track of which attribute reviews can be pruned
|
|
// We can only prune an attribute review once the profile is expired (if mate), or the author identity is no longer funded
|
|
// We use the attributeProfilesList to keep track of which profile(s) the attribute belongs to
|
|
// We will delete profiles that are banned, so keeping track of the attribute's profiles is necessary
|
|
// Each profile's author information is stored in contentMetadata
|
|
|
|
import "seekia/internal/encoding"
|
|
import "seekia/internal/helpers"
|
|
import "seekia/internal/identity"
|
|
import "seekia/internal/localFilesystem"
|
|
import "seekia/internal/moderation/readReports"
|
|
import "seekia/internal/moderation/readReviews"
|
|
import "seekia/internal/profiles/readProfiles"
|
|
|
|
import badger "github.com/dgraph-io/badger/v4"
|
|
|
|
import goFilepath "path/filepath"
|
|
|
|
import "slices"
|
|
import "bytes"
|
|
import "sync"
|
|
import "errors"
|
|
|
|
const mateProfilesPrefix byte = 1
|
|
const hostProfilesPrefix byte = 2
|
|
const moderatorProfilesPrefix byte = 3
|
|
|
|
const messagesPrefix byte = 4
|
|
const reviewsPrefix byte = 5
|
|
const reportsPrefix byte = 6
|
|
|
|
const profileMetadataPrefix byte = 7
|
|
const messageMetadataPrefix byte = 8
|
|
const attributeProfilesListPrefix byte = 9
|
|
|
|
const mateIdentityProfilesListPrefix byte = 10
|
|
const hostIdentityProfilesListPrefix byte = 11
|
|
const moderatorIdentityProfilesListPrefix byte = 12
|
|
|
|
const inboxMessagesListPrefix byte = 13
|
|
|
|
const reviewerIdentityReviewsListPrefix byte = 14
|
|
const reviewerProfileReviewsListPrefix byte = 15
|
|
const reviewerAttributeReviewsListPrefix byte = 16
|
|
const reviewerMessageReviewsListPrefix byte = 17
|
|
|
|
const identityReviewsListPrefix byte = 18
|
|
const profileReviewsListPrefix byte = 19
|
|
const attributeReviewsListPrefix byte = 20
|
|
const messageReviewsListPrefix byte = 21
|
|
|
|
const identityReportsListPrefix byte = 22
|
|
const profileReportsListPrefix byte = 23
|
|
const attributeReportsListPrefix byte = 24
|
|
const messageReportsListPrefix byte = 25
|
|
|
|
|
|
// We use a lock for for database entries which contain comma separated values
|
|
// This is because badger will return a ErrConflict if we do a txn.Get and txn.Set in the same operation
|
|
// List entries contain values which need to be read and edited before being committed
|
|
// For example, we need to read the exiting value "1,2,3" and append "4", so result is "1,2,3,4"
|
|
// Entries such as profiles only need to be set or deleted, so we don't need to use a Mutex
|
|
|
|
var editingAttributeProfilesListMutex sync.Mutex
|
|
|
|
var editingMateIdentityProfilesListMutex sync.Mutex
|
|
var editingHostIdentityProfilesListMutex sync.Mutex
|
|
var editingModeratorIdentityProfilesListMutex sync.Mutex
|
|
|
|
var editingInboxMessagesListMutex sync.Mutex
|
|
|
|
var editingReviewerIdentityReviewsListMutex sync.Mutex
|
|
var editingReviewerProfileReviewsListMutex sync.Mutex
|
|
var editingReviewerAttributeReviewsListMutex sync.Mutex
|
|
var editingReviewerMessageReviewsListMutex sync.Mutex
|
|
|
|
var editingIdentityReviewsListMutex sync.Mutex
|
|
var editingProfileReviewsListMutex sync.Mutex
|
|
var editingAttributeReviewsListMutex sync.Mutex
|
|
var editingMessageReviewsListMutex sync.Mutex
|
|
|
|
var editingIdentityReportsListMutex sync.Mutex
|
|
var editingProfileReportsListMutex sync.Mutex
|
|
var editingAttributeReportsListMutex sync.Mutex
|
|
var editingMessageReportsListMutex sync.Mutex
|
|
|
|
var myDatabase *badger.DB
|
|
|
|
// We use this when establishing and reading from the myDatabase object
|
|
var databaseMutex sync.RWMutex
|
|
|
|
func startDatabase()error{
|
|
|
|
databaseMutex.RLock()
|
|
|
|
if (myDatabase != nil) {
|
|
if (myDatabase.IsClosed() == false){
|
|
databaseMutex.RUnlock()
|
|
return nil
|
|
}
|
|
}
|
|
databaseMutex.RUnlock()
|
|
|
|
databaseDirectory, err := localFilesystem.GetAppDatabaseFolderPath()
|
|
if (err != nil) { return err }
|
|
|
|
_, err = localFilesystem.CreateFolder(databaseDirectory)
|
|
if (err != nil) { return err }
|
|
|
|
// We put the badger database into its own folder
|
|
// We will need to keep multiple databases and migrate data to new versions when they are released
|
|
// This also makes it easier to switch from using Badger to a different database if needed.
|
|
|
|
databaseFolderpath := goFilepath.Join(databaseDirectory, "BadgerDatabaseVersion4")
|
|
|
|
_, err = localFilesystem.CreateFolder(databaseFolderpath)
|
|
if (err != nil) { return err }
|
|
|
|
databaseOptions := badger.DefaultOptions(databaseFolderpath)
|
|
|
|
newDatabase, err := badger.Open(databaseOptions)
|
|
if (err != nil) { return err }
|
|
|
|
databaseMutex.Lock()
|
|
myDatabase = newDatabase
|
|
databaseMutex.Unlock()
|
|
|
|
return nil
|
|
}
|
|
|
|
|
|
func StopDatabase(){
|
|
|
|
if (myDatabase != nil) {
|
|
myDatabase.Close()
|
|
}
|
|
}
|
|
|
|
func AddUserProfile(profileType string, profileHash [28]byte, profileBytes []byte)error{
|
|
|
|
hashIsValid, err := readProfiles.VerifyProfileHash(profileHash, true, profileType, false, false)
|
|
if (err != nil) {
|
|
return errors.New("AddUserProfile called with invalid profileType: " + profileType)
|
|
}
|
|
if (hashIsValid == false){
|
|
profileHashHex := encoding.EncodeBytesToHexString(profileHash[:])
|
|
return errors.New("AddUserProfile called with invalid profileHash: " + profileHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
getKeyPrefix := func()(byte, error){
|
|
|
|
if (profileType == "Mate"){
|
|
return mateProfilesPrefix, nil
|
|
|
|
} else if (profileType == "Host"){
|
|
return hostProfilesPrefix, nil
|
|
|
|
} else if (profileType == "Moderator"){
|
|
return moderatorProfilesPrefix, nil
|
|
}
|
|
|
|
return 0, errors.New("VerifyProfileHash not verifying profileType: " + profileType)
|
|
}
|
|
|
|
keyPrefix, err := getKeyPrefix()
|
|
if (err != nil) { return err }
|
|
|
|
key := []byte{keyPrefix}
|
|
key = append(key, profileHash[:]...)
|
|
|
|
err = setDatabaseEntry(key, profileBytes)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
//Outputs
|
|
// -bool: Profile exists
|
|
// -[]byte: User profile bytes
|
|
// -error
|
|
func GetUserProfile(profileType string, profileHash [28]byte)(bool, []byte, error){
|
|
|
|
hashIsValid, err := readProfiles.VerifyProfileHash(profileHash, true, profileType, false, false)
|
|
if (err != nil) {
|
|
return false, nil, errors.New("GetUserProfile called with invalid profileType: " + profileType)
|
|
}
|
|
if (hashIsValid == false){
|
|
profileHashHex := encoding.EncodeBytesToHexString(profileHash[:])
|
|
return false, nil, errors.New("GetUserProfile called with invalid profileHash: " + profileHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
getKeyPrefix := func()(byte, error){
|
|
|
|
if (profileType == "Mate"){
|
|
return mateProfilesPrefix, nil
|
|
|
|
} else if (profileType == "Host"){
|
|
return hostProfilesPrefix, nil
|
|
|
|
} else if (profileType == "Moderator"){
|
|
return moderatorProfilesPrefix, nil
|
|
}
|
|
|
|
return 0, errors.New("VerifyProfileHash not verifying profileType: " + profileType)
|
|
}
|
|
|
|
keyPrefix, err := getKeyPrefix()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
key := []byte{keyPrefix}
|
|
key = append(key, profileHash[:]...)
|
|
|
|
exists, profileData, err := getDatabaseValue(key)
|
|
if (err != nil) { return false, nil, err }
|
|
if (exists == false) {
|
|
return false, nil, nil
|
|
}
|
|
|
|
return true, profileData, nil
|
|
}
|
|
|
|
|
|
func DeleteUserProfile(profileType string, profileHash [28]byte)error{
|
|
|
|
hashIsValid, err := readProfiles.VerifyProfileHash(profileHash, true, profileType, false, false)
|
|
if (err != nil) {
|
|
return errors.New("DeleteUserProfile called with invalid profileType: " + profileType)
|
|
}
|
|
if (hashIsValid == false){
|
|
profileHashHex := encoding.EncodeBytesToHexString(profileHash[:])
|
|
return errors.New("DeleteUserProfile called with invalid profileHash: " + profileHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
getKeyPrefix := func()(byte, error){
|
|
|
|
if (profileType == "Mate"){
|
|
return mateProfilesPrefix, nil
|
|
|
|
} else if (profileType == "Host"){
|
|
return hostProfilesPrefix, nil
|
|
|
|
} else if (profileType == "Moderator"){
|
|
return moderatorProfilesPrefix, nil
|
|
}
|
|
|
|
return 0, errors.New("VerifyProfileHash not verifying profileType: " + profileType)
|
|
}
|
|
|
|
keyPrefix, err := getKeyPrefix()
|
|
if (err != nil) { return err }
|
|
|
|
key := []byte{keyPrefix}
|
|
key = append(key, profileHash[:]...)
|
|
|
|
err = deleteDatabaseEntry(key)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetNumberOfUserProfiles()(int64, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return 0, err }
|
|
|
|
numberOfMateProfiles, err := GetNumberOfProfiles("Mate")
|
|
if (err != nil) { return 0, err }
|
|
|
|
numberOfHostProfiles, err := GetNumberOfProfiles("Host")
|
|
if (err != nil) { return 0, err }
|
|
|
|
GetNumberOfModeratorProfiles, err := GetNumberOfProfiles("Moderator")
|
|
if (err != nil) { return 0, err }
|
|
|
|
result := numberOfMateProfiles + numberOfHostProfiles + GetNumberOfModeratorProfiles
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func GetNumberOfProfiles(profileType string)(int64, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return 0, err }
|
|
|
|
getKeyPrefix := func()(byte, error){
|
|
|
|
if (profileType == "Mate"){
|
|
return mateProfilesPrefix, nil
|
|
|
|
} else if (profileType == "Host"){
|
|
return hostProfilesPrefix, nil
|
|
|
|
} else if (profileType == "Moderator"){
|
|
return moderatorProfilesPrefix, nil
|
|
}
|
|
|
|
return 0, errors.New("GetNumberOfProfiles called with invalid profileType: " + profileType)
|
|
}
|
|
|
|
keyPrefix, err := getKeyPrefix()
|
|
if (err != nil) { return 0, err }
|
|
|
|
numberOfProfiles, err := getNumberOfKeysInDatabaseWithPrefix(keyPrefix)
|
|
if (err != nil) { return 0, err }
|
|
|
|
return numberOfProfiles, nil
|
|
}
|
|
|
|
func GetAllProfileHashes(profileType string)([][28]byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return nil, err }
|
|
|
|
getKeyPrefix := func()(byte, error){
|
|
|
|
if (profileType == "Mate"){
|
|
return mateProfilesPrefix, nil
|
|
|
|
} else if (profileType == "Host"){
|
|
return hostProfilesPrefix, nil
|
|
|
|
} else if (profileType == "Moderator"){
|
|
return moderatorProfilesPrefix, nil
|
|
}
|
|
|
|
return 0, errors.New("GetAllProfileHashes called with invalid profileType: " + profileType)
|
|
}
|
|
|
|
keyPrefix, err := getKeyPrefix()
|
|
if (err != nil) { return nil, err }
|
|
|
|
profileHashesBytesList, err := getAllKeysInDatabaseWithPrefix(keyPrefix, true)
|
|
if (err != nil) { return nil, err }
|
|
|
|
profileHashesList := make([][28]byte, 0, len(profileHashesBytesList))
|
|
|
|
for _, profileHash := range profileHashesBytesList{
|
|
|
|
if (len(profileHash) != 28){
|
|
return nil, errors.New("profileHashesBytesList contains invalid length profile hash.")
|
|
}
|
|
|
|
profileHashArray := [28]byte(profileHash)
|
|
|
|
profileHashesList = append(profileHashesList, profileHashArray)
|
|
}
|
|
|
|
return profileHashesList, nil
|
|
}
|
|
|
|
|
|
func AddChatMessage(messageHash [26]byte, messageBytes []byte)error{
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
key := []byte{messagesPrefix}
|
|
key = append(key, messageHash[:]...)
|
|
|
|
err = setDatabaseEntry(key, messageBytes)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
|
|
func GetChatMessage(messageHash [26]byte)(bool, []byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
key := []byte{messagesPrefix}
|
|
key = append(key, messageHash[:]...)
|
|
|
|
exists, messageBytes, err := getDatabaseValue(key)
|
|
if (err != nil) { return false, nil, err }
|
|
if (exists == false) {
|
|
return false, nil, nil
|
|
}
|
|
|
|
return true, messageBytes, nil
|
|
}
|
|
|
|
func DeleteChatMessage(messageHash [26]byte)error{
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
key := []byte{messagesPrefix}
|
|
key = append(key, messageHash[:]...)
|
|
|
|
err = deleteDatabaseEntry(key)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetNumberOfChatMessages()(int64, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return 0, err }
|
|
|
|
numberOfMessages, err := getNumberOfKeysInDatabaseWithPrefix(messagesPrefix)
|
|
if (err != nil) { return 0, err }
|
|
|
|
return numberOfMessages, nil
|
|
}
|
|
|
|
func GetAllChatMessageHashes()([][26]byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return nil, err }
|
|
|
|
messageHashesBytesList, err := getAllKeysInDatabaseWithPrefix(messagesPrefix, true)
|
|
if (err != nil) { return nil, err }
|
|
|
|
messageHashesList := make([][26]byte, 0, len(messageHashesBytesList))
|
|
|
|
for _, messageHashBytes := range messageHashesBytesList{
|
|
|
|
if (len(messageHashBytes) != 26){
|
|
return nil, errors.New("messageHashesBytesList contains invalid length messageHash")
|
|
}
|
|
|
|
messageHashArray := [26]byte(messageHashBytes)
|
|
|
|
messageHashesList = append(messageHashesList, messageHashArray)
|
|
}
|
|
|
|
return messageHashesList, nil
|
|
}
|
|
|
|
|
|
func AddReview(reviewHash [29]byte, reviewBytes []byte)error{
|
|
|
|
isValid, err := readReviews.VerifyReviewHash(reviewHash, false, "")
|
|
if (err != nil) { return err }
|
|
if (isValid == false){
|
|
reviewHashHex := encoding.EncodeBytesToHexString(reviewHash[:])
|
|
return errors.New("AddReview called with invalid reviewHash: " + reviewHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
key := []byte{reviewsPrefix}
|
|
key = append(key, reviewHash[:]...)
|
|
|
|
err = setDatabaseEntry(key, reviewBytes)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
|
|
func GetReview(reviewHash [29]byte)(bool, []byte, error){
|
|
|
|
isValid, err := readReviews.VerifyReviewHash(reviewHash, false, "")
|
|
if (err != nil) { return false, nil, err }
|
|
if (isValid == false){
|
|
reviewHashHex := encoding.EncodeBytesToHexString(reviewHash[:])
|
|
return false, nil, errors.New("GetReview called with invalid reviewHash: " + reviewHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
key := []byte{reviewsPrefix}
|
|
key = append(key, reviewHash[:]...)
|
|
|
|
exists, reviewBytes, err := getDatabaseValue(key)
|
|
if (err != nil) { return false, nil, err }
|
|
if (exists == false) {
|
|
return false, nil, nil
|
|
}
|
|
|
|
return true, reviewBytes, nil
|
|
}
|
|
|
|
func DeleteReview(reviewHash [29]byte)error{
|
|
|
|
isValid, err := readReviews.VerifyReviewHash(reviewHash, false, "")
|
|
if (err != nil) { return err }
|
|
if (isValid == false){
|
|
reviewHashHex := encoding.EncodeBytesToHexString(reviewHash[:])
|
|
return errors.New("DeleteReview called with invalid reviewHash: " + reviewHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
key := []byte{reviewsPrefix}
|
|
key = append(key, reviewHash[:]...)
|
|
|
|
err = deleteDatabaseEntry(key)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetNumberOfReviews()(int64, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return 0, err }
|
|
|
|
numberOfReviews, err := getNumberOfKeysInDatabaseWithPrefix(reviewsPrefix)
|
|
if (err != nil) { return 0, err }
|
|
|
|
return numberOfReviews, nil
|
|
}
|
|
|
|
|
|
func AddReport(reportHash [30]byte, reportBytes []byte)error{
|
|
|
|
isValid, err := readReports.VerifyReportHash(reportHash, false, "")
|
|
if (err != nil) { return err }
|
|
if (isValid == false){
|
|
reportHashHex := encoding.EncodeBytesToHexString(reportHash[:])
|
|
return errors.New("AddReport called with invalid reportHash: " + reportHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
key := []byte{reportsPrefix}
|
|
key = append(key, reportHash[:]...)
|
|
|
|
err = setDatabaseEntry(key, reportBytes)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
|
|
func GetReport(reportHash [30]byte)(bool, []byte, error){
|
|
|
|
isValid, err := readReports.VerifyReportHash(reportHash, false, "")
|
|
if (err != nil) { return false, nil, err }
|
|
if (isValid == false){
|
|
reportHashHex := encoding.EncodeBytesToHexString(reportHash[:])
|
|
return false, nil, errors.New("GetReport called with invalid reportHash: " + reportHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
key := []byte{reportsPrefix}
|
|
key = append(key, reportHash[:]...)
|
|
|
|
exists, reportBytes, err := getDatabaseValue(key)
|
|
if (err != nil) { return false, nil, err }
|
|
if (exists == false) {
|
|
return false, nil, nil
|
|
}
|
|
|
|
return true, reportBytes, nil
|
|
}
|
|
|
|
func DeleteReport(reportHash [30]byte)error{
|
|
|
|
isValid, err := readReports.VerifyReportHash(reportHash, false, "")
|
|
if (err != nil) { return err }
|
|
if (isValid == false){
|
|
reportHashHex := encoding.EncodeBytesToHexString(reportHash[:])
|
|
return errors.New("DeleteReport called with invalid reportHash: " + reportHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
key := []byte{reportsPrefix}
|
|
key = append(key, reportHash[:]...)
|
|
|
|
err = deleteDatabaseEntry(key)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetNumberOfReports()(int64, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return 0, err }
|
|
|
|
numberOfReports, err := getNumberOfKeysInDatabaseWithPrefix(reportsPrefix)
|
|
if (err != nil) { return 0, err }
|
|
|
|
return numberOfReports, nil
|
|
}
|
|
|
|
|
|
func AddProfileMetadata(profileHash [28]byte, profileMetadata []byte)error{
|
|
|
|
isValid, err := readProfiles.VerifyProfileHash(profileHash, false, "", false, false)
|
|
if (err != nil) { return err }
|
|
if (isValid == false){
|
|
profileHashHex := encoding.EncodeBytesToHexString(profileHash[:])
|
|
return errors.New("AddProfileMetadata called with invalid profileHash: " + profileHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
entryKey := []byte{profileMetadataPrefix}
|
|
entryKey = append(entryKey, profileHash[:]...)
|
|
|
|
err = setDatabaseEntry(entryKey, profileMetadata)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
//Outputs:
|
|
// -bool: Metadata found
|
|
// -[]byte: Profile Metadata
|
|
// -error
|
|
func GetProfileMetadata(profileHash [28]byte)(bool, []byte, error){
|
|
|
|
isValid, err := readProfiles.VerifyProfileHash(profileHash, false, "", false, false)
|
|
if (err != nil) { return false, nil, err }
|
|
if (isValid == false){
|
|
profileHashHex := encoding.EncodeBytesToHexString(profileHash[:])
|
|
return false, nil, errors.New("GetProfileMetadata called with invalid profileHash: " + profileHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
entryKey := []byte{profileMetadataPrefix}
|
|
entryKey = append(entryKey, profileHash[:]...)
|
|
|
|
exists, entryValue, err := getDatabaseValue(entryKey)
|
|
if (err != nil) { return false, nil, err }
|
|
if (exists == false){
|
|
return false, nil, nil
|
|
}
|
|
|
|
return true, entryValue, nil
|
|
}
|
|
|
|
func DeleteProfileMetadata(profileHash [28]byte)error{
|
|
|
|
isValid, err := readProfiles.VerifyProfileHash(profileHash, false, "", false, false)
|
|
if (err != nil) { return err }
|
|
if (isValid == false){
|
|
profileHashHex := encoding.EncodeBytesToHexString(profileHash[:])
|
|
return errors.New("DeleteProfileMetadata called with invalid profileHash: " + profileHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
entryKey := []byte{profileMetadataPrefix}
|
|
entryKey = append(entryKey, profileHash[:]...)
|
|
|
|
err = deleteDatabaseEntry(entryKey)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetAllProfileHashesWithMetadata()([][28]byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return nil, err }
|
|
|
|
profileHashesBytesList, err := getAllKeysInDatabaseWithPrefix(profileMetadataPrefix, true)
|
|
if (err != nil) { return nil, err }
|
|
|
|
profileHashesList := make([][28]byte, 0, len(profileHashesBytesList))
|
|
|
|
for _, profileHashBytes := range profileHashesBytesList{
|
|
|
|
if (len(profileHashBytes) != 28){
|
|
profileHashHex := encoding.EncodeBytesToHexString(profileHashBytes)
|
|
return nil, errors.New("profileHashesBytesList contains invalid length profileHash: " + profileHashHex)
|
|
}
|
|
|
|
profileHashArray := [28]byte(profileHashBytes)
|
|
|
|
profileHashesList = append(profileHashesList, profileHashArray)
|
|
}
|
|
|
|
return profileHashesList, nil
|
|
}
|
|
|
|
func AddMessageMetadata(messageHash [26]byte, messageMetadata []byte)error{
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
entryKey := []byte{messageMetadataPrefix}
|
|
entryKey = append(entryKey, messageHash[:]...)
|
|
|
|
err = setDatabaseEntry(entryKey, messageMetadata)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
//Outputs:
|
|
// -bool: Message metadata exists
|
|
// -[]byte: Message Metadata
|
|
// -error
|
|
func GetMessageMetadata(messageHash [26]byte)(bool, []byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
entryKey := []byte{messageMetadataPrefix}
|
|
entryKey = append(entryKey, messageHash[:]...)
|
|
|
|
exists, entryValue, err := getDatabaseValue(entryKey)
|
|
if (err != nil) { return false, nil, err }
|
|
if (exists == false){
|
|
return false, nil, nil
|
|
}
|
|
|
|
return true, entryValue, nil
|
|
}
|
|
|
|
func DeleteMessageMetadata(messageHash [26]byte)error{
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
entryKey := []byte{messageMetadataPrefix}
|
|
entryKey = append(entryKey, messageHash[:]...)
|
|
|
|
err = deleteDatabaseEntry(entryKey)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetAllMessageHashesWithMetadata()([][26]byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return nil, err }
|
|
|
|
messageHashesBytesList, err := getAllKeysInDatabaseWithPrefix(messageMetadataPrefix, true)
|
|
if (err != nil) { return nil, err }
|
|
|
|
messageHashesList := make([][26]byte, 0, len(messageHashesBytesList))
|
|
|
|
for _, messageHashBytes := range messageHashesBytesList{
|
|
|
|
if (len(messageHashBytes) != 26){
|
|
messageHashHex := encoding.EncodeBytesToHexString(messageHashBytes)
|
|
return nil, errors.New("messageHashesBytesList contains invalid length messageHash: " + messageHashHex)
|
|
}
|
|
|
|
messageHashArray := [26]byte(messageHashBytes)
|
|
|
|
messageHashesList = append(messageHashesList, messageHashArray)
|
|
}
|
|
|
|
return messageHashesList, nil
|
|
}
|
|
|
|
func AddAttributeProfile(attributeHash [27]byte, profileHash [28]byte)error{
|
|
|
|
attributeProfileType, _, err := readProfiles.ReadAttributeHashMetadata(attributeHash)
|
|
if (err != nil){
|
|
attributeHashHex := encoding.EncodeBytesToHexString(attributeHash[:])
|
|
return errors.New("AddAttributeProfile called with invalid attributeHash: " + attributeHashHex)
|
|
}
|
|
hashIsValid, err := readProfiles.VerifyProfileHash(profileHash, true, attributeProfileType, false, false)
|
|
if (err != nil) { return err }
|
|
if (hashIsValid == false){
|
|
profileHashHex := encoding.EncodeBytesToHexString(profileHash[:])
|
|
return errors.New("AddAttributeProfile called with invalid profileHash: " + profileHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingAttributeProfilesListMutex.Lock()
|
|
defer editingAttributeProfilesListMutex.Unlock()
|
|
|
|
entryKey := []byte{attributeProfilesListPrefix}
|
|
entryKey = append(entryKey, attributeHash[:]...)
|
|
|
|
err = addItemToEntryList(entryKey, 28, profileHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
|
|
func GetAttributeProfilesList(attributeHash [27]byte)(bool, [][28]byte, error){
|
|
|
|
hashIsValid, err := readProfiles.VerifyAttributeHash(attributeHash, false, "", false, false)
|
|
if (err != nil){ return false, nil, err }
|
|
if (hashIsValid == false){
|
|
attributeHashHex := encoding.EncodeBytesToHexString(attributeHash[:])
|
|
return false, nil, errors.New("GetAttributeProfilesList called with invalid attributeHash: " + attributeHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
entryKey := []byte{attributeProfilesListPrefix}
|
|
entryKey = append(entryKey, attributeHash[:]...)
|
|
|
|
exists, profileHashesBytesList, err := getEntryList(entryKey, 28)
|
|
if (err != nil) { return false, nil, err }
|
|
if (exists == false) {
|
|
return false, nil, nil
|
|
}
|
|
|
|
profileHashesList := make([][28]byte, 0, len(profileHashesBytesList))
|
|
|
|
for _, profileHashBytes := range profileHashesBytesList{
|
|
|
|
if (len(profileHashBytes) != 28){
|
|
return false, nil, errors.New("getEntryList returning invalid bytes length item.")
|
|
}
|
|
|
|
profileHashArray := [28]byte(profileHashBytes)
|
|
|
|
profileHashesList = append(profileHashesList, profileHashArray)
|
|
}
|
|
|
|
return true, profileHashesList, nil
|
|
}
|
|
|
|
func DeleteAttributeProfile(attributeHash [27]byte, profileHash [28]byte)error{
|
|
|
|
attributeProfileType, _, err := readProfiles.ReadAttributeHashMetadata(attributeHash)
|
|
if (err != nil) {
|
|
attributeHashHex := encoding.EncodeBytesToHexString(attributeHash[:])
|
|
return errors.New("DeleteAttributeHashProfile called with invalid attributeHash: " + attributeHashHex)
|
|
}
|
|
|
|
hashIsValid, err := readProfiles.VerifyProfileHash(profileHash, true, attributeProfileType, false, false)
|
|
if (err != nil) { return err }
|
|
if (hashIsValid == false){
|
|
profileHashHex := encoding.EncodeBytesToHexString(profileHash[:])
|
|
return errors.New("DeleteAttributeHashProfile called with invalid profileHash: " + profileHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingAttributeProfilesListMutex.Lock()
|
|
defer editingAttributeProfilesListMutex.Unlock()
|
|
|
|
entryKey := []byte{attributeProfilesListPrefix}
|
|
entryKey = append(entryKey, attributeHash[:]...)
|
|
|
|
err = deleteItemFromEntryList(entryKey, 28, profileHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetAllProfileAttributesHashes()([][27]byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return nil, err }
|
|
|
|
attributeHashesBytesList, err := getAllKeysInDatabaseWithPrefix(attributeProfilesListPrefix, true)
|
|
if (err != nil) { return nil, err }
|
|
|
|
attributeHashesList := make([][27]byte, 0, len(attributeHashesBytesList))
|
|
|
|
for _, attributeHashBytes := range attributeHashesBytesList{
|
|
|
|
if (len(attributeHashBytes) != 27){
|
|
attributeHashHex := encoding.EncodeBytesToHexString(attributeHashBytes)
|
|
return nil, errors.New("attributeHashesBytesList contains invalid length attribute hash: " + attributeHashHex)
|
|
}
|
|
|
|
attributeHashArray := [27]byte(attributeHashBytes)
|
|
|
|
attributeHashesList = append(attributeHashesList, attributeHashArray)
|
|
}
|
|
|
|
return attributeHashesList, nil
|
|
}
|
|
|
|
|
|
func AddIdentityProfileHash(identityHash [16]byte, profileHash [28]byte)error{
|
|
|
|
identityType, err := identity.GetIdentityTypeFromIdentityHash(identityHash)
|
|
if (err != nil){
|
|
identityHashHex := encoding.EncodeBytesToHexString(identityHash[:])
|
|
return errors.New("AddIdentityProfileHash called with invalid identity hash: " + identityHashHex)
|
|
}
|
|
|
|
hashIsValid, err := readProfiles.VerifyProfileHash(profileHash, true, identityType, false, false)
|
|
if (err != nil) { return err }
|
|
if (hashIsValid == false){
|
|
|
|
identityHashHex := encoding.EncodeBytesToHexString(identityHash[:])
|
|
profileHashHex := encoding.EncodeBytesToHexString(profileHash[:])
|
|
|
|
return errors.New("AddIdentityProfileHash called with invalid profile hash: " + profileHashHex + ". Identity hash: " + identityHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
if (identityType == "Mate"){
|
|
|
|
editingMateIdentityProfilesListMutex.Lock()
|
|
defer editingMateIdentityProfilesListMutex.Unlock()
|
|
|
|
} else if (identityType == "Host"){
|
|
|
|
editingHostIdentityProfilesListMutex.Lock()
|
|
defer editingHostIdentityProfilesListMutex.Unlock()
|
|
|
|
} else if (identityType == "Moderator"){
|
|
|
|
editingModeratorIdentityProfilesListMutex.Lock()
|
|
defer editingModeratorIdentityProfilesListMutex.Unlock()
|
|
} else {
|
|
return errors.New("GetIdentityTypeFromIdentityHash returning invalid identityType: " + identityType)
|
|
}
|
|
|
|
getEntryKeyPrefix := func()byte{
|
|
|
|
if (identityType == "Mate"){
|
|
return mateIdentityProfilesListPrefix
|
|
}
|
|
if (identityType == "Host"){
|
|
return hostIdentityProfilesListPrefix
|
|
}
|
|
// identityType == "Moderator"
|
|
return moderatorIdentityProfilesListPrefix
|
|
}
|
|
|
|
entryKeyPrefix := getEntryKeyPrefix()
|
|
|
|
entryKey := []byte{entryKeyPrefix}
|
|
entryKey = append(entryKey, identityHash[:]...)
|
|
|
|
err = addItemToEntryList(entryKey, 28, profileHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetIdentityProfileHashesList(identityHash [16]byte)(bool, [][28]byte, error){
|
|
|
|
identityType, err := identity.GetIdentityTypeFromIdentityHash(identityHash)
|
|
if (err != nil){
|
|
identityHashHex := encoding.EncodeBytesToHexString(identityHash[:])
|
|
return false, nil, errors.New("GetIdentityProfileHashesList called with invalid identity hash: " + identityHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
getEntryKeyPrefix := func()(byte, error){
|
|
|
|
if (identityType == "Mate"){
|
|
return mateIdentityProfilesListPrefix, nil
|
|
|
|
} else if (identityType == "Host"){
|
|
return hostIdentityProfilesListPrefix, nil
|
|
|
|
} else if (identityType == "Moderator"){
|
|
return moderatorIdentityProfilesListPrefix, nil
|
|
}
|
|
|
|
return 0, errors.New("GetIdentityTypeFromIdentityHash returning invalid identityType: " + identityType)
|
|
}
|
|
|
|
entryKeyPrefix, err := getEntryKeyPrefix()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
entryKey := []byte{entryKeyPrefix}
|
|
entryKey = append(entryKey, identityHash[:]...)
|
|
|
|
exists, profileHashesBytesList, err := getEntryList(entryKey, 28)
|
|
if (err != nil) { return false, nil, err }
|
|
if (exists == false){
|
|
return false, nil, nil
|
|
}
|
|
|
|
profileHashesList := make([][28]byte, 0, len(profileHashesBytesList))
|
|
|
|
for _, profileHashBytes := range profileHashesBytesList{
|
|
|
|
if (len(profileHashBytes) != 28){
|
|
|
|
profileHashHex := encoding.EncodeBytesToHexString(profileHashBytes)
|
|
return false, nil, errors.New("getEntryList returning invalid length item in list: " + profileHashHex)
|
|
}
|
|
|
|
profileHashArray := [28]byte(profileHashBytes)
|
|
|
|
profileHashesList = append(profileHashesList, profileHashArray)
|
|
}
|
|
|
|
return true, profileHashesList, nil
|
|
}
|
|
|
|
func DeleteIdentityProfileHash(identityHash [16]byte, profileHash [28]byte)error{
|
|
|
|
identityType, err := identity.GetIdentityTypeFromIdentityHash(identityHash)
|
|
if (err != nil){
|
|
identityHashHex := encoding.EncodeBytesToHexString(identityHash[:])
|
|
return errors.New("DeleteIdentityProfileHash called with invalid identity hash: " + identityHashHex)
|
|
}
|
|
|
|
hashIsValid, err := readProfiles.VerifyProfileHash(profileHash, true, identityType, false, false)
|
|
if (err != nil) { return err }
|
|
if (hashIsValid == false){
|
|
|
|
identityHashHex := encoding.EncodeBytesToHexString(identityHash[:])
|
|
profileHashHex := encoding.EncodeBytesToHexString(profileHash[:])
|
|
|
|
return errors.New("DeleteIdentityProfileHash called with invalid profile hash: " + profileHashHex + ". Identity hash: " + identityHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
if (identityType == "Mate"){
|
|
|
|
editingMateIdentityProfilesListMutex.Lock()
|
|
defer editingMateIdentityProfilesListMutex.Unlock()
|
|
|
|
} else if (identityType == "Host"){
|
|
|
|
editingHostIdentityProfilesListMutex.Lock()
|
|
defer editingHostIdentityProfilesListMutex.Unlock()
|
|
|
|
} else if (identityType == "Moderator"){
|
|
|
|
editingModeratorIdentityProfilesListMutex.Lock()
|
|
defer editingModeratorIdentityProfilesListMutex.Unlock()
|
|
}
|
|
|
|
getEntryKeyPrefix := func()(byte, error){
|
|
|
|
if (identityType == "Mate"){
|
|
return mateIdentityProfilesListPrefix, nil
|
|
|
|
} else if (identityType == "Host"){
|
|
return hostIdentityProfilesListPrefix, nil
|
|
|
|
} else if (identityType == "Moderator"){
|
|
return moderatorIdentityProfilesListPrefix, nil
|
|
}
|
|
|
|
return 0, errors.New("GetIdentityTypeFromIdentityHash returning invalid identityType: " + identityType)
|
|
}
|
|
|
|
entryKeyPrefix, err := getEntryKeyPrefix()
|
|
if (err != nil) { return err }
|
|
|
|
entryKey := []byte{entryKeyPrefix}
|
|
entryKey = append(entryKey, identityHash[:]...)
|
|
|
|
err = deleteItemFromEntryList(entryKey, 28, profileHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
|
|
// This only returns identity hashes that have been added to the profile identity lists
|
|
// This means these identities have had at least 1 profile added to the database
|
|
func GetAllProfileIdentityHashes(identityType string)([][16]byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return nil, err }
|
|
|
|
getEntryKeyPrefix := func()(byte, error){
|
|
|
|
if (identityType == "Mate"){
|
|
return mateIdentityProfilesListPrefix, nil
|
|
|
|
} else if (identityType == "Host"){
|
|
return hostIdentityProfilesListPrefix, nil
|
|
|
|
} else if (identityType == "Moderator"){
|
|
return moderatorIdentityProfilesListPrefix, nil
|
|
}
|
|
|
|
return 0, errors.New("GetAllProfileIdentityHashes called with invalid identityType: " + identityType)
|
|
}
|
|
|
|
entryKeyPrefix, err := getEntryKeyPrefix()
|
|
if (err != nil) { return nil, err }
|
|
|
|
identityHashesBytesList, err := getAllKeysInDatabaseWithPrefix(entryKeyPrefix, true)
|
|
if (err != nil) { return nil, err }
|
|
|
|
identityHashesList := make([][16]byte, 0, len(identityHashesBytesList))
|
|
|
|
for _, identityHashBytes := range identityHashesBytesList{
|
|
|
|
if (len(identityHashBytes) != 16){
|
|
identityHashHex := encoding.EncodeBytesToHexString(identityHashBytes)
|
|
return nil, errors.New("Database corrupt: Identity profiles list entry contains invalid identity hash in key: " + identityHashHex)
|
|
}
|
|
|
|
identityHashArray := [16]byte(identityHashBytes)
|
|
|
|
identityHashesList = append(identityHashesList, identityHashArray)
|
|
}
|
|
|
|
return identityHashesList, nil
|
|
}
|
|
|
|
|
|
func AddChatInboxMessage(recipientInbox [10]byte, messageHash [26]byte)error{
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingInboxMessagesListMutex.Lock()
|
|
defer editingInboxMessagesListMutex.Unlock()
|
|
|
|
entryKey := []byte{inboxMessagesListPrefix}
|
|
entryKey = append(entryKey, recipientInbox[:]...)
|
|
|
|
err = addItemToEntryList(entryKey, 26, messageHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetChatInboxMessageHashesList(recipientInbox [10]byte)(bool, [][26]byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
entryKey := []byte{inboxMessagesListPrefix}
|
|
entryKey = append(entryKey, recipientInbox[:]...)
|
|
|
|
exists, messageHashesBytesList, err := getEntryList(entryKey, 26)
|
|
if (err != nil) { return false, nil, err }
|
|
if (exists == false) {
|
|
return false, nil, nil
|
|
}
|
|
|
|
messageHashesList := make([][26]byte, 0, len(messageHashesBytesList))
|
|
|
|
for _, messageHashBytes := range messageHashesBytesList{
|
|
|
|
if (len(messageHashBytes) != 26){
|
|
return false, nil, errors.New("getEntryList returning invalid length message hash.")
|
|
}
|
|
|
|
messageHashArray := [26]byte(messageHashBytes)
|
|
|
|
messageHashesList = append(messageHashesList, messageHashArray)
|
|
}
|
|
|
|
return true, messageHashesList, nil
|
|
}
|
|
|
|
func DeleteChatInboxMessage(recipientInbox [10]byte, messageHash [26]byte)error{
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingInboxMessagesListMutex.Lock()
|
|
defer editingInboxMessagesListMutex.Unlock()
|
|
|
|
entryKey := []byte{inboxMessagesListPrefix}
|
|
entryKey = append(entryKey, recipientInbox[:]...)
|
|
|
|
err = deleteItemFromEntryList(entryKey, 26, messageHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
|
|
func GetAllMessageInboxes()([][10]byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return nil, err }
|
|
|
|
inboxesBytesList, err := getAllKeysInDatabaseWithPrefix(inboxMessagesListPrefix, true)
|
|
if (err != nil) { return nil, err }
|
|
|
|
inboxesList := make([][10]byte, 0, len(inboxesBytesList))
|
|
|
|
for _, inboxBytes := range inboxesBytesList{
|
|
|
|
if (len(inboxBytes) != 10){
|
|
return nil, errors.New("Database corrupt: Contains inbox entry with invalid inbox: Invalid length.")
|
|
}
|
|
|
|
inboxArray := [10]byte(inboxBytes)
|
|
|
|
inboxesList = append(inboxesList, inboxArray)
|
|
}
|
|
|
|
return inboxesList, nil
|
|
}
|
|
|
|
|
|
func AddReviewerReviewHash(reviewerIdentityHash [16]byte, reviewHash [29]byte)error{
|
|
|
|
identityIsValid, err := identity.VerifyIdentityHash(reviewerIdentityHash, true, "Moderator")
|
|
if (err != nil) { return err }
|
|
if (identityIsValid == false){
|
|
reviewerIdentityHashHex := encoding.EncodeBytesToHexString(reviewerIdentityHash[:])
|
|
return errors.New("AddReviewerReviewHash called with invalid reviewerIdentityHash: " + reviewerIdentityHashHex)
|
|
}
|
|
|
|
reviewType, err := readReviews.GetReviewTypeFromReviewHash(reviewHash)
|
|
if (err != nil){
|
|
reviewHashHex := encoding.EncodeBytesToHexString(reviewHash[:])
|
|
return errors.New("AddReviewerReviewHash called with invalid reviewHash: " + reviewHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
if (reviewType == "Identity"){
|
|
|
|
editingReviewerIdentityReviewsListMutex.Lock()
|
|
defer editingReviewerIdentityReviewsListMutex.Unlock()
|
|
|
|
} else if (reviewType == "Profile"){
|
|
|
|
editingReviewerProfileReviewsListMutex.Lock()
|
|
defer editingReviewerProfileReviewsListMutex.Unlock()
|
|
|
|
} else if (reviewType == "Attribute"){
|
|
|
|
editingReviewerAttributeReviewsListMutex.Lock()
|
|
defer editingReviewerAttributeReviewsListMutex.Unlock()
|
|
|
|
} else if (reviewType == "Message"){
|
|
|
|
editingReviewerMessageReviewsListMutex.Lock()
|
|
defer editingReviewerMessageReviewsListMutex.Unlock()
|
|
} else {
|
|
|
|
return errors.New("GetReviewTypeFromReviewHash returning invalid reviewType: " + reviewType)
|
|
}
|
|
|
|
getEntryKeyPrefix := func()byte{
|
|
|
|
if (reviewType == "Identity"){
|
|
return reviewerIdentityReviewsListPrefix
|
|
}
|
|
if (reviewType == "Profile"){
|
|
return reviewerProfileReviewsListPrefix
|
|
}
|
|
if (reviewType == "Attribute"){
|
|
return reviewerAttributeReviewsListPrefix
|
|
}
|
|
// reviewType == "Message"
|
|
return reviewerMessageReviewsListPrefix
|
|
}
|
|
|
|
entryKeyPrefix := getEntryKeyPrefix()
|
|
|
|
entryKey := []byte{entryKeyPrefix}
|
|
entryKey = append(entryKey, reviewerIdentityHash[:]...)
|
|
|
|
err = addItemToEntryList(entryKey, 29, reviewHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
// Returns all review hashes created by reviewer
|
|
func GetReviewerReviewHashesList(reviewerIdentityHash [16]byte, reviewType string)(bool, [][29]byte, error){
|
|
|
|
identityIsValid, err := identity.VerifyIdentityHash(reviewerIdentityHash, true, "Moderator")
|
|
if (err != nil) { return false, nil, err }
|
|
if (identityIsValid == false){
|
|
reviewerIdentityHashHex := encoding.EncodeBytesToHexString(reviewerIdentityHash[:])
|
|
return false, nil, errors.New("GetReviewerReviewHashesList called with invalid reviewerIdentityHash: " + reviewerIdentityHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
getEntryKeyPrefix := func()(byte, error){
|
|
|
|
if (reviewType == "Identity"){
|
|
return reviewerIdentityReviewsListPrefix, nil
|
|
}
|
|
if (reviewType == "Profile"){
|
|
return reviewerProfileReviewsListPrefix, nil
|
|
}
|
|
if (reviewType == "Attribute"){
|
|
return reviewerAttributeReviewsListPrefix, nil
|
|
}
|
|
if (reviewType == "Message"){
|
|
return reviewerMessageReviewsListPrefix, nil
|
|
}
|
|
return 0, errors.New("GetReviewerReviewHashesList called with invalid reviewType: " + reviewType)
|
|
}
|
|
|
|
entryKeyPrefix, err := getEntryKeyPrefix()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
entryKey := []byte{entryKeyPrefix}
|
|
entryKey = append(entryKey, reviewerIdentityHash[:]...)
|
|
|
|
exists, reviewHashesBytesList, err := getEntryList(entryKey, 29)
|
|
if (err != nil) { return false, nil, err }
|
|
if (exists == false){
|
|
return false, nil, nil
|
|
}
|
|
|
|
reviewHashesList := make([][29]byte, 0, len(reviewHashesBytesList))
|
|
|
|
for _, reviewHashBytes := range reviewHashesBytesList{
|
|
|
|
if (len(reviewHashBytes) != 29){
|
|
return false, nil, errors.New("getEntryList returning invalid length review hash.")
|
|
}
|
|
|
|
reviewHashArray := [29]byte(reviewHashBytes)
|
|
|
|
reviewHashesList = append(reviewHashesList, reviewHashArray)
|
|
}
|
|
|
|
return true, reviewHashesList, nil
|
|
}
|
|
|
|
func DeleteReviewerReviewHash(reviewerIdentityHash [16]byte, reviewHash [29]byte)error{
|
|
|
|
identityIsValid, err := identity.VerifyIdentityHash(reviewerIdentityHash, true, "Moderator")
|
|
if (err != nil) { return err }
|
|
if (identityIsValid == false){
|
|
reviewerIdentityHashHex := encoding.EncodeBytesToHexString(reviewerIdentityHash[:])
|
|
return errors.New("DeleteReviewerReviewHash called with invalid reviewerIdentityHash: " + reviewerIdentityHashHex)
|
|
}
|
|
|
|
reviewType, err := readReviews.GetReviewTypeFromReviewHash(reviewHash)
|
|
if (err != nil){
|
|
reviewHashHex := encoding.EncodeBytesToHexString(reviewHash[:])
|
|
return errors.New("DeleteReviewerReviewHash called with invalid reviewHash: " + reviewHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
if (reviewType == "Identity"){
|
|
|
|
editingReviewerIdentityReviewsListMutex.Lock()
|
|
defer editingReviewerIdentityReviewsListMutex.Unlock()
|
|
|
|
} else if (reviewType == "Profile"){
|
|
|
|
editingReviewerProfileReviewsListMutex.Lock()
|
|
defer editingReviewerProfileReviewsListMutex.Unlock()
|
|
|
|
} else if (reviewType == "Attribute"){
|
|
|
|
editingReviewerAttributeReviewsListMutex.Lock()
|
|
defer editingReviewerAttributeReviewsListMutex.Unlock()
|
|
|
|
} else if (reviewType == "Message"){
|
|
|
|
editingReviewerMessageReviewsListMutex.Lock()
|
|
defer editingReviewerMessageReviewsListMutex.Unlock()
|
|
} else {
|
|
|
|
return errors.New("GetReviewTypeFromReviewHash returning invalid reviewType: " + reviewType)
|
|
}
|
|
|
|
getEntryKeyPrefix := func()byte{
|
|
|
|
if (reviewType == "Identity"){
|
|
return reviewerIdentityReviewsListPrefix
|
|
}
|
|
if (reviewType == "Profile"){
|
|
return reviewerProfileReviewsListPrefix
|
|
}
|
|
if (reviewType == "Attribute"){
|
|
return reviewerAttributeReviewsListPrefix
|
|
}
|
|
// reviewType == "Message"
|
|
return reviewerMessageReviewsListPrefix
|
|
}
|
|
|
|
entryKeyPrefix := getEntryKeyPrefix()
|
|
|
|
entryKey := []byte{entryKeyPrefix}
|
|
entryKey = append(entryKey, reviewerIdentityHash[:]...)
|
|
|
|
err = deleteItemFromEntryList(entryKey, 29, reviewHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func AddIdentityReviewToList(identityHash [16]byte, reviewHash [29]byte)error{
|
|
|
|
identityIsValid, err := identity.VerifyIdentityHash(identityHash, false, "")
|
|
if (err != nil) { return err }
|
|
if (identityIsValid == false){
|
|
identityHashHex := encoding.EncodeBytesToHexString(identityHash[:])
|
|
return errors.New("AddIdentityReviewToList called with invalid identityHash: " + identityHashHex)
|
|
}
|
|
|
|
hashIsValid, err := readReviews.VerifyReviewHash(reviewHash, true, "Identity")
|
|
if (err != nil) { return err }
|
|
if (hashIsValid == false){
|
|
reviewHashHex := encoding.EncodeBytesToHexString(reviewHash[:])
|
|
return errors.New("AddIdentityReviewToList called with invalid reviewHash: " + reviewHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingIdentityReviewsListMutex.Lock()
|
|
defer editingIdentityReviewsListMutex.Unlock()
|
|
|
|
entryKey := []byte{identityReviewsListPrefix}
|
|
entryKey = append(entryKey, identityHash[:]...)
|
|
|
|
err = addItemToEntryList(entryKey, 29, reviewHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetIdentityReviewsList(identityHash [16]byte)(bool, [][29]byte, error){
|
|
|
|
identityIsValid, err := identity.VerifyIdentityHash(identityHash, false, "")
|
|
if (err != nil) { return false, nil, err }
|
|
if (identityIsValid == false){
|
|
identityHashHex := encoding.EncodeBytesToHexString(identityHash[:])
|
|
return false, nil, errors.New("GetIdentityReviewsList called with invalid identityHash: " + identityHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
entryKey := []byte{identityReviewsListPrefix}
|
|
entryKey = append(entryKey, identityHash[:]...)
|
|
|
|
exists, reviewHashesBytesList, err := getEntryList(entryKey, 29)
|
|
if (err != nil) { return false, nil, err }
|
|
if (exists == false) {
|
|
return false, nil, nil
|
|
}
|
|
|
|
reviewHashesList := make([][29]byte, 0, len(reviewHashesBytesList))
|
|
|
|
for _, reviewHashBytes := range reviewHashesBytesList{
|
|
|
|
if (len(reviewHashBytes) != 29){
|
|
return false, nil, errors.New("getEntryList returning invalid length review hash.")
|
|
}
|
|
|
|
reviewHashArray := [29]byte(reviewHashBytes)
|
|
|
|
reviewHashesList = append(reviewHashesList, reviewHashArray)
|
|
}
|
|
|
|
return true, reviewHashesList, nil
|
|
}
|
|
|
|
func DeleteIdentityReviewFromList(identityHash [16]byte, reviewHash [29]byte)error{
|
|
|
|
identityIsValid, err := identity.VerifyIdentityHash(identityHash, false, "")
|
|
if (err != nil) { return err }
|
|
if (identityIsValid == false){
|
|
identityHashHex := encoding.EncodeBytesToHexString(identityHash[:])
|
|
return errors.New("DeleteIdentityReviewFromList called with invalid identityHash: " + identityHashHex)
|
|
}
|
|
|
|
hashIsValid, err := readReviews.VerifyReviewHash(reviewHash, true, "Identity")
|
|
if (err != nil) { return err }
|
|
if (hashIsValid == false){
|
|
reviewHashHex := encoding.EncodeBytesToHexString(reviewHash[:])
|
|
return errors.New("DeleteIdentityReviewFromList called with invalid reviewHash: " + reviewHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingIdentityReviewsListMutex.Lock()
|
|
defer editingIdentityReviewsListMutex.Unlock()
|
|
|
|
entryKey := []byte{identityReviewsListPrefix}
|
|
entryKey = append(entryKey, identityHash[:]...)
|
|
|
|
err = deleteItemFromEntryList(entryKey, 29, reviewHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
// Returns all identity hashes that have been reviewed, both profiles and their identity
|
|
func GetAllReviewedIdentityHashes()([][16]byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return nil, err }
|
|
|
|
identityHashesBytesList, err := getAllKeysInDatabaseWithPrefix(identityReviewsListPrefix, true)
|
|
if (err != nil) { return nil, err }
|
|
|
|
identityHashesList := make([][16]byte, 0, len(identityHashesBytesList))
|
|
|
|
for _, identityHashBytes := range identityHashesBytesList{
|
|
|
|
if (len(identityHashBytes) != 16){
|
|
return nil, errors.New("Database corrupt: Identtity reviews list entry contains invalid identity hash.")
|
|
}
|
|
|
|
identityHashArray := [16]byte(identityHashBytes)
|
|
|
|
identityHashesList = append(identityHashesList, identityHashArray)
|
|
}
|
|
|
|
return identityHashesList, nil
|
|
}
|
|
|
|
|
|
func AddIdentityReportToList(identityHash [16]byte, reportHash [30]byte)error{
|
|
|
|
identityIsValid, err := identity.VerifyIdentityHash(identityHash, false, "")
|
|
if (err != nil) { return err }
|
|
if (identityIsValid == false){
|
|
identityHashHex := encoding.EncodeBytesToHexString(identityHash[:])
|
|
return errors.New("AddIdentityReportToList called with invalid identityHash: " + identityHashHex)
|
|
}
|
|
|
|
hashIsValid, err := readReports.VerifyReportHash(reportHash, true, "Identity")
|
|
if (err != nil) { return err }
|
|
if (hashIsValid == false){
|
|
reportHashHex := encoding.EncodeBytesToHexString(reportHash[:])
|
|
return errors.New("AddIdentityReportToList called with invalid reportHash: " + reportHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingIdentityReportsListMutex.Lock()
|
|
defer editingIdentityReportsListMutex.Unlock()
|
|
|
|
entryKey := []byte{identityReportsListPrefix}
|
|
entryKey = append(entryKey, identityHash[:]...)
|
|
|
|
err = addItemToEntryList(entryKey, 30, reportHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetIdentityReportsList(identityHash [16]byte)(bool, [][30]byte, error){
|
|
|
|
identityIsValid, err := identity.VerifyIdentityHash(identityHash, false, "")
|
|
if (err != nil) { return false, nil, err }
|
|
if (identityIsValid == false){
|
|
identityHashHex := encoding.EncodeBytesToHexString(identityHash[:])
|
|
return false, nil, errors.New("GetIdentityReportsList called with invalid identityHash: " + identityHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
entryKey := []byte{identityReportsListPrefix}
|
|
entryKey = append(entryKey, identityHash[:]...)
|
|
|
|
exists, reportHashesBytesList, err := getEntryList(entryKey, 30)
|
|
if (err != nil) { return false, nil, err }
|
|
if (exists == false) {
|
|
return false, nil, nil
|
|
}
|
|
|
|
reportHashesList := make([][30]byte, 0, len(reportHashesBytesList))
|
|
|
|
for _, reportHashBytes := range reportHashesBytesList{
|
|
|
|
if (len(reportHashBytes) != 30){
|
|
return false, nil, errors.New("getEntryList returning invalid length reportHash.")
|
|
}
|
|
|
|
reportHashArray := [30]byte(reportHashBytes)
|
|
|
|
reportHashesList = append(reportHashesList, reportHashArray)
|
|
}
|
|
|
|
return true, reportHashesList, nil
|
|
}
|
|
|
|
func DeleteIdentityReportFromList(identityHash [16]byte, reportHash [30]byte)error{
|
|
|
|
identityIsValid, err := identity.VerifyIdentityHash(identityHash, false, "")
|
|
if (err != nil) { return err }
|
|
if (identityIsValid == false){
|
|
identityHashHex := encoding.EncodeBytesToHexString(identityHash[:])
|
|
return errors.New("DeleteIdentityReportFromList called with invalid identityHash: " + identityHashHex)
|
|
}
|
|
|
|
hashIsValid, err := readReports.VerifyReportHash(reportHash, true, "Identity")
|
|
if (err != nil) { return err }
|
|
if (hashIsValid == false){
|
|
reportHashHex := encoding.EncodeBytesToHexString(reportHash[:])
|
|
return errors.New("DeleteIdentityReportFromList called with invalid reportHash: " + reportHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingIdentityReportsListMutex.Lock()
|
|
defer editingIdentityReportsListMutex.Unlock()
|
|
|
|
entryKey := []byte{identityReportsListPrefix}
|
|
entryKey = append(entryKey, identityHash[:]...)
|
|
|
|
err = deleteItemFromEntryList(entryKey, 30, reportHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetAllReportedIdentityHashes()([][16]byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return nil, err }
|
|
|
|
identityHashesBytesList, err := getAllKeysInDatabaseWithPrefix(identityReportsListPrefix, true)
|
|
if (err != nil) { return nil, err }
|
|
|
|
identityHashesList := make([][16]byte, 0, len(identityHashesBytesList))
|
|
|
|
for _, identityHashBytes := range identityHashesBytesList{
|
|
|
|
if (len(identityHashBytes) != 16){
|
|
return nil, errors.New("Database corrupt: identity reports list entry key contains invalid length identity hash.")
|
|
}
|
|
|
|
identityHashArray := [16]byte(identityHashBytes)
|
|
|
|
identityHashesList = append(identityHashesList, identityHashArray)
|
|
}
|
|
|
|
return identityHashesList, nil
|
|
}
|
|
|
|
func AddProfileReviewToList(profileHash [28]byte, reviewHash [29]byte)error{
|
|
|
|
profileHashIsValid, err := readProfiles.VerifyProfileHash(profileHash, false, "", false, false)
|
|
if (err != nil) { return err }
|
|
if (profileHashIsValid == false){
|
|
profileHashHex := encoding.EncodeBytesToHexString(profileHash[:])
|
|
return errors.New("AddProfileReviewToList called with invalid profileHash: " + profileHashHex)
|
|
}
|
|
|
|
reviewHashIsValid, err := readReviews.VerifyReviewHash(reviewHash, true, "Profile")
|
|
if (err != nil) { return err }
|
|
if (reviewHashIsValid == false){
|
|
reviewHashHex := encoding.EncodeBytesToHexString(reviewHash[:])
|
|
return errors.New("AddProfileReviewToList called with invalid reviewHash: " + reviewHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingProfileReviewsListMutex.Lock()
|
|
defer editingProfileReviewsListMutex.Unlock()
|
|
|
|
entryKey := []byte{profileReviewsListPrefix}
|
|
entryKey = append(entryKey, profileHash[:]...)
|
|
|
|
err = addItemToEntryList(entryKey, 29, reviewHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetProfileReviewsList(profileHash [28]byte)(bool, [][29]byte, error){
|
|
|
|
profileHashIsValid, err := readProfiles.VerifyProfileHash(profileHash, false, "", false, false)
|
|
if (err != nil) { return false, nil, err }
|
|
if (profileHashIsValid == false){
|
|
profileHashHex := encoding.EncodeBytesToHexString(profileHash[:])
|
|
return false, nil, errors.New("GetProfileReviewsList called with invalid profileHash: " + profileHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
entryKey := []byte{profileReviewsListPrefix}
|
|
entryKey = append(entryKey, profileHash[:]...)
|
|
|
|
exists, reviewHashesBytesList, err := getEntryList(entryKey, 29)
|
|
if (err != nil) { return false, nil, err }
|
|
if (exists == false) {
|
|
return false, nil, nil
|
|
}
|
|
|
|
reviewHashesList := make([][29]byte, 0, len(reviewHashesBytesList))
|
|
|
|
for _, reviewHashBytes := range reviewHashesBytesList{
|
|
|
|
if (len(reviewHashBytes) != 29){
|
|
return false, nil, errors.New("getEntryList returning invalid review hash.")
|
|
}
|
|
|
|
reviewHashArray := [29]byte(reviewHashBytes)
|
|
|
|
reviewHashesList = append(reviewHashesList, reviewHashArray)
|
|
}
|
|
|
|
return true, reviewHashesList, nil
|
|
}
|
|
|
|
func DeleteProfileReviewFromList(profileHash [28]byte, reviewHash [29]byte)error{
|
|
|
|
profileHashIsValid, err := readProfiles.VerifyProfileHash(profileHash, false, "", false, false)
|
|
if (err != nil) { return err }
|
|
if (profileHashIsValid == false){
|
|
profileHashHex := encoding.EncodeBytesToHexString(profileHash[:])
|
|
return errors.New("DeleteProfileReviewFromList called with invalid profileHash: " + profileHashHex)
|
|
}
|
|
|
|
reviewHashIsValid, err := readReviews.VerifyReviewHash(reviewHash, true, "Profile")
|
|
if (err != nil) { return err }
|
|
if (reviewHashIsValid == false){
|
|
reviewHashHex := encoding.EncodeBytesToHexString(reviewHash[:])
|
|
return errors.New("DeleteProfileReviewFromList called with invalid reviewHash: " + reviewHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingProfileReviewsListMutex.Lock()
|
|
defer editingProfileReviewsListMutex.Unlock()
|
|
|
|
entryKey := []byte{profileReviewsListPrefix}
|
|
entryKey = append(entryKey, profileHash[:]...)
|
|
|
|
err = deleteItemFromEntryList(entryKey, 29, reviewHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
// Returns all Profile hashes that have been reviewed
|
|
func GetAllReviewedProfileHashes()([][28]byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return nil, err }
|
|
|
|
profileHashesBytesList, err := getAllKeysInDatabaseWithPrefix(profileReviewsListPrefix, true)
|
|
if (err != nil) { return nil, err }
|
|
|
|
profileHashesList := make([][28]byte, 0, len(profileHashesBytesList))
|
|
|
|
for _, profileHashBytes := range profileHashesBytesList{
|
|
|
|
if (len(profileHashBytes) != 28){
|
|
return nil, errors.New("Database corrupt: Profile reviews list entry key contains invalid profile hash.")
|
|
}
|
|
|
|
profileHashArray := [28]byte(profileHashBytes)
|
|
|
|
profileHashesList = append(profileHashesList, profileHashArray)
|
|
}
|
|
|
|
return profileHashesList, nil
|
|
}
|
|
|
|
|
|
func AddProfileReportToList(profileHash [28]byte, reportHash [30]byte)error{
|
|
|
|
profileHashIsValid, err := readProfiles.VerifyProfileHash(profileHash, false, "", false, false)
|
|
if (err != nil) { return err }
|
|
if (profileHashIsValid == false){
|
|
profileHashHex := encoding.EncodeBytesToHexString(profileHash[:])
|
|
return errors.New("AddProfileReportToList called with invalid profileHash: " + profileHashHex)
|
|
}
|
|
|
|
reportHashIsValid, err := readReports.VerifyReportHash(reportHash, true, "Profile")
|
|
if (err != nil) { return err }
|
|
if (reportHashIsValid == false){
|
|
reportHashHex := encoding.EncodeBytesToHexString(reportHash[:])
|
|
return errors.New("AddProfileReportToList called with invalid reportHash: " + reportHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingProfileReportsListMutex.Lock()
|
|
defer editingProfileReportsListMutex.Unlock()
|
|
|
|
entryKey := []byte{profileReportsListPrefix}
|
|
entryKey = append(entryKey, profileHash[:]...)
|
|
|
|
err = addItemToEntryList(entryKey, 30, reportHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetProfileReportsList(profileHash [28]byte)(bool, [][30]byte, error){
|
|
|
|
profileHashIsValid, err := readProfiles.VerifyProfileHash(profileHash, false, "", false, false)
|
|
if (err != nil) { return false, nil, err }
|
|
if (profileHashIsValid == false){
|
|
profileHashHex := encoding.EncodeBytesToHexString(profileHash[:])
|
|
return false, nil, errors.New("GetProfileReportsList called with invalid profileHash: " + profileHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
entryKey := []byte{profileReportsListPrefix}
|
|
entryKey = append(entryKey, profileHash[:]...)
|
|
|
|
exists, reportHashesBytesList, err := getEntryList(entryKey, 30)
|
|
if (err != nil) { return false, nil, err }
|
|
if (exists == false) {
|
|
return false, nil, nil
|
|
}
|
|
|
|
reportHashesList := make([][30]byte, 0, len(reportHashesBytesList))
|
|
|
|
for _, reportHashBytes := range reportHashesBytesList{
|
|
|
|
if (len(reportHashBytes) != 30){
|
|
return false, nil, errors.New("getEntryList returning invalid length reportHash.")
|
|
}
|
|
|
|
reportHashArray := [30]byte(reportHashBytes)
|
|
|
|
reportHashesList = append(reportHashesList, reportHashArray)
|
|
}
|
|
|
|
return true, reportHashesList, nil
|
|
}
|
|
|
|
|
|
func DeleteProfileReportFromList(profileHash [28]byte, reportHash [30]byte)error{
|
|
|
|
profileHashIsValid, err := readProfiles.VerifyProfileHash(profileHash, false, "", false, false)
|
|
if (err != nil) { return err }
|
|
if (profileHashIsValid == false){
|
|
profileHashHex := encoding.EncodeBytesToHexString(profileHash[:])
|
|
return errors.New("DeleteProfileReportFromList called with invalid profileHash: " + profileHashHex)
|
|
}
|
|
|
|
reportHashIsValid, err := readReports.VerifyReportHash(reportHash, true, "Profile")
|
|
if (err != nil) { return err }
|
|
if (reportHashIsValid == false){
|
|
reportHashHex := encoding.EncodeBytesToHexString(reportHash[:])
|
|
return errors.New("DeleteProfileReportFromList called with invalid reportHash: " + reportHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingProfileReportsListMutex.Lock()
|
|
defer editingProfileReportsListMutex.Unlock()
|
|
|
|
entryKey := []byte{profileReportsListPrefix}
|
|
entryKey = append(entryKey, profileHash[:]...)
|
|
|
|
err = deleteItemFromEntryList(entryKey, 30, reportHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
// Returns all Profile hashes that have been reported
|
|
func GetAllReportedProfileHashes()([][28]byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return nil, err }
|
|
|
|
profileHashesBytesList, err := getAllKeysInDatabaseWithPrefix(profileReportsListPrefix, true)
|
|
if (err != nil) { return nil, err }
|
|
|
|
profileHashesList := make([][28]byte, 0, len(profileHashesBytesList))
|
|
|
|
for _, profileHashBytes := range profileHashesBytesList{
|
|
|
|
if (len(profileHashBytes) != 28){
|
|
return nil, errors.New("Database corrupt: Profile reports list entry contains invalid profileHash.")
|
|
}
|
|
|
|
profileHashArray := [28]byte(profileHashBytes)
|
|
|
|
profileHashesList = append(profileHashesList, profileHashArray)
|
|
}
|
|
|
|
return profileHashesList, nil
|
|
}
|
|
|
|
|
|
func AddProfileAttributeReviewToList(attributeHash [27]byte, reviewHash [29]byte)error{
|
|
|
|
attributeHashIsValid, err := readProfiles.VerifyAttributeHash(attributeHash, false, "", false, false)
|
|
if (err != nil) { return err }
|
|
if (attributeHashIsValid == false){
|
|
attributeHashHex := encoding.EncodeBytesToHexString(attributeHash[:])
|
|
return errors.New("AddProfileAttributeReviewToList called with invalid attributeHash: " + attributeHashHex)
|
|
}
|
|
reviewHashIsValid, err := readReviews.VerifyReviewHash(reviewHash, true, "Attribute")
|
|
if (err != nil) { return err }
|
|
if (reviewHashIsValid == false){
|
|
reviewHashHex := encoding.EncodeBytesToHexString(reviewHash[:])
|
|
return errors.New("AddProfileAttributeReviewToList called with invalid reviewHash: " + reviewHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingAttributeReviewsListMutex.Lock()
|
|
defer editingAttributeReviewsListMutex.Unlock()
|
|
|
|
entryKey := []byte{attributeReviewsListPrefix}
|
|
entryKey = append(entryKey, attributeHash[:]...)
|
|
|
|
err = addItemToEntryList(entryKey, 29, reviewHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetProfileAttributeReviewsList(attributeHash [27]byte)(bool, [][29]byte, error){
|
|
|
|
attributeHashIsValid, err := readProfiles.VerifyAttributeHash(attributeHash, false, "", false, false)
|
|
if (err != nil) { return false, nil, err }
|
|
if (attributeHashIsValid == false){
|
|
attributeHashHex := encoding.EncodeBytesToHexString(attributeHash[:])
|
|
return false, nil, errors.New("GetProfileAttributeReviewsList called with invalid attributeHash: " + attributeHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
entryKey := []byte{attributeReviewsListPrefix}
|
|
entryKey = append(entryKey, attributeHash[:]...)
|
|
|
|
exists, reviewHashesBytesList, err := getEntryList(entryKey, 29)
|
|
if (err != nil) { return false, nil, err }
|
|
if (exists == false) {
|
|
return false, nil, nil
|
|
}
|
|
|
|
reviewHashesList := make([][29]byte, 0, len(reviewHashesBytesList))
|
|
|
|
for _, reviewHashBytes := range reviewHashesBytesList{
|
|
|
|
if (len(reviewHashBytes) != 29){
|
|
return false, nil, errors.New("getEntryList returning invalid length review hash.")
|
|
}
|
|
|
|
reviewHashArray := [29]byte(reviewHashBytes)
|
|
|
|
reviewHashesList = append(reviewHashesList, reviewHashArray)
|
|
}
|
|
|
|
return true, reviewHashesList, nil
|
|
}
|
|
|
|
func DeleteProfileAttributeReviewFromList(attributeHash [27]byte, reviewHash [29]byte)error{
|
|
|
|
attributeHashIsValid, err := readProfiles.VerifyAttributeHash(attributeHash, false, "", false, false)
|
|
if (err != nil) { return err }
|
|
if (attributeHashIsValid == false){
|
|
attributeHashHex := encoding.EncodeBytesToHexString(attributeHash[:])
|
|
return errors.New("DeleteProfileAttributeReviewFromList called with invalid attributeHash: " + attributeHashHex)
|
|
}
|
|
|
|
reviewHashIsValid, err := readReviews.VerifyReviewHash(reviewHash, true, "Attribute")
|
|
if (err != nil) { return err }
|
|
if (reviewHashIsValid == false){
|
|
reviewHashHex := encoding.EncodeBytesToHexString(reviewHash[:])
|
|
return errors.New("DeleteProfileAttributeReviewFromList called with invalid reviewHash: " + reviewHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingAttributeReviewsListMutex.Lock()
|
|
defer editingAttributeReviewsListMutex.Unlock()
|
|
|
|
entryKey := []byte{attributeReviewsListPrefix}
|
|
entryKey = append(entryKey, attributeHash[:]...)
|
|
|
|
err = deleteItemFromEntryList(entryKey, 29, reviewHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
// Returns all attribute hashes that have been reviewed
|
|
func GetAllReviewedProfileAttributeHashes()([][27]byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return nil, err }
|
|
|
|
attributeHashesBytesList, err := getAllKeysInDatabaseWithPrefix(attributeReviewsListPrefix, true)
|
|
if (err != nil) { return nil, err }
|
|
|
|
attributeHashesList := make([][27]byte, 0, len(attributeHashesBytesList))
|
|
|
|
for _, attributeHashBytes := range attributeHashesBytesList{
|
|
|
|
if (len(attributeHashBytes) != 27){
|
|
return nil, errors.New("Database corrupt: Attribute reviews list entry key contains invalid length attribute hash.")
|
|
}
|
|
|
|
attributeHashArray := [27]byte(attributeHashBytes)
|
|
|
|
attributeHashesList = append(attributeHashesList, attributeHashArray)
|
|
}
|
|
|
|
return attributeHashesList, nil
|
|
}
|
|
|
|
func AddProfileAttributeReportToList(attributeHash [27]byte, reportHash [30]byte)error{
|
|
|
|
attributeHashIsValid, err := readProfiles.VerifyAttributeHash(attributeHash, false, "", false, false)
|
|
if (err != nil) { return err }
|
|
if (attributeHashIsValid == false){
|
|
attributeHashHex := encoding.EncodeBytesToHexString(attributeHash[:])
|
|
return errors.New("AddProfileAttributeReportToList called with invalid attributeHash: " + attributeHashHex)
|
|
}
|
|
reportHashIsValid, err := readReports.VerifyReportHash(reportHash, true, "Attribute")
|
|
if (err != nil) { return err }
|
|
if (reportHashIsValid == false){
|
|
reportHashHex := encoding.EncodeBytesToHexString(reportHash[:])
|
|
return errors.New("AddProfileAttributeReportToList called with invalid reportHash: " + reportHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingAttributeReportsListMutex.Lock()
|
|
defer editingAttributeReportsListMutex.Unlock()
|
|
|
|
entryKey := []byte{attributeReportsListPrefix}
|
|
entryKey = append(entryKey, attributeHash[:]...)
|
|
|
|
err = addItemToEntryList(entryKey, 30, reportHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
|
|
func GetProfileAttributeReportsList(attributeHash [27]byte)(bool, [][30]byte, error){
|
|
|
|
attributeHashIsValid, err := readProfiles.VerifyAttributeHash(attributeHash, false, "", false, false)
|
|
if (err != nil) { return false, nil, err }
|
|
if (attributeHashIsValid == false){
|
|
attributeHashHex := encoding.EncodeBytesToHexString(attributeHash[:])
|
|
return false, nil, errors.New("GetProfileAttributeReportsList called with invalid attributeHash: " + attributeHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
entryKey := []byte{attributeReportsListPrefix}
|
|
entryKey = append(entryKey, attributeHash[:]...)
|
|
|
|
exists, reportHashesBytesList, err := getEntryList(entryKey, 30)
|
|
if (err != nil) { return false, nil, err }
|
|
if (exists == false) {
|
|
return false, nil, nil
|
|
}
|
|
|
|
reportHashesList := make([][30]byte, 0, len(reportHashesBytesList))
|
|
|
|
for _, reportHashBytes := range reportHashesBytesList{
|
|
|
|
if (len(reportHashBytes) != 30){
|
|
return false, nil, errors.New("getEntryList returning invalid length report hash.")
|
|
}
|
|
|
|
reportHashArray := [30]byte(reportHashBytes)
|
|
|
|
reportHashesList = append(reportHashesList, reportHashArray)
|
|
}
|
|
|
|
return true, reportHashesList, nil
|
|
}
|
|
|
|
func DeleteProfileAttributeReportFromList(attributeHash [27]byte, reportHash [30]byte)error{
|
|
|
|
attributeHashIsValid, err := readProfiles.VerifyAttributeHash(attributeHash, false, "", false, false)
|
|
if (err != nil){ return err }
|
|
if (attributeHashIsValid == false){
|
|
attributeHashHex := encoding.EncodeBytesToHexString(attributeHash[:])
|
|
return errors.New("DeleteProfileAttributeReportFromList called with invalid attributeHash: " + attributeHashHex)
|
|
}
|
|
reportHashIsValid, err := readReports.VerifyReportHash(reportHash, true, "Attribute")
|
|
if (err != nil){ return err }
|
|
if (reportHashIsValid == false){
|
|
reportHashHex := encoding.EncodeBytesToHexString(reportHash[:])
|
|
return errors.New("DeleteProfileAttributeReportFromList called with invalid reportHash: " + reportHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingAttributeReportsListMutex.Lock()
|
|
defer editingAttributeReportsListMutex.Unlock()
|
|
|
|
entryKey := []byte{attributeReportsListPrefix}
|
|
entryKey = append(entryKey, attributeHash[:]...)
|
|
|
|
err = deleteItemFromEntryList(entryKey, 30, reportHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
|
|
// Returns all profile attribute hashes that have been reported
|
|
func GetAllReportedProfileAttributeHashes()([][27]byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return nil, err }
|
|
|
|
attributeHashesBytesList, err := getAllKeysInDatabaseWithPrefix(attributeReportsListPrefix, true)
|
|
if (err != nil) { return nil, err }
|
|
|
|
attributeHashesList := make([][27]byte, 0, len(attributeHashesBytesList))
|
|
|
|
for _, attributeHashBytes := range attributeHashesBytesList{
|
|
|
|
if (len(attributeHashBytes) != 27){
|
|
return nil, errors.New("Database corrupt: Attribute reports list entry key contains invalid attribute hash")
|
|
}
|
|
|
|
attributeHashArray := [27]byte(attributeHashBytes)
|
|
|
|
attributeHashesList = append(attributeHashesList, attributeHashArray)
|
|
}
|
|
|
|
return attributeHashesList, nil
|
|
}
|
|
|
|
|
|
func AddMessageReviewToList(messageHash [26]byte, reviewHash [29]byte)error{
|
|
|
|
reviewHashIsValid, err := readReviews.VerifyReviewHash(reviewHash, true, "Message")
|
|
if (err != nil) { return err }
|
|
if (reviewHashIsValid == false){
|
|
reviewHashHex := encoding.EncodeBytesToHexString(reviewHash[:])
|
|
return errors.New("AddMessageReviewToList called with invalid reviewHash: " + reviewHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingMessageReviewsListMutex.Lock()
|
|
defer editingMessageReviewsListMutex.Unlock()
|
|
|
|
entryKey := []byte{messageReviewsListPrefix}
|
|
entryKey = append(entryKey, messageHash[:]...)
|
|
|
|
err = addItemToEntryList(entryKey, 29, reviewHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetMessageReviewsList(messageHash [26]byte)(bool, [][29]byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
entryKey := []byte{messageReviewsListPrefix}
|
|
entryKey = append(entryKey, messageHash[:]...)
|
|
|
|
exists, reviewHashesBytesList, err := getEntryList(entryKey, 29)
|
|
if (err != nil) { return false, nil, err }
|
|
if (exists == false) {
|
|
return false, nil, nil
|
|
}
|
|
|
|
reviewHashesList := make([][29]byte, 0, len(reviewHashesBytesList))
|
|
|
|
for _, reviewHashBytes := range reviewHashesBytesList{
|
|
|
|
if (len(reviewHashBytes) != 29){
|
|
return false, nil, errors.New("getEntryList returning invalid length reviewHash.")
|
|
}
|
|
|
|
reviewHashArray := [29]byte(reviewHashBytes)
|
|
|
|
reviewHashesList = append(reviewHashesList, reviewHashArray)
|
|
}
|
|
|
|
return true, reviewHashesList, nil
|
|
}
|
|
|
|
|
|
func DeleteMessageReviewFromList(messageHash [26]byte, reviewHash [29]byte)error{
|
|
|
|
reviewHashIsValid, err := readReviews.VerifyReviewHash(reviewHash, true, "Message")
|
|
if (err != nil){ return err }
|
|
if (reviewHashIsValid == false){
|
|
reviewHashHex := encoding.EncodeBytesToHexString(reviewHash[:])
|
|
return errors.New("DeleteMessageReviewFromList called with invalid reviewHash: " + reviewHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingMessageReviewsListMutex.Lock()
|
|
defer editingMessageReviewsListMutex.Unlock()
|
|
|
|
entryKey := []byte{messageReviewsListPrefix}
|
|
entryKey = append(entryKey, messageHash[:]...)
|
|
|
|
err = deleteItemFromEntryList(entryKey, 29, reviewHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
// Returns all message hashes that have been reviewed
|
|
func GetAllReviewedMessageHashes()([][26]byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return nil, err }
|
|
|
|
messageHashesBytesList, err := getAllKeysInDatabaseWithPrefix(messageReviewsListPrefix, true)
|
|
if (err != nil) { return nil, err }
|
|
|
|
messageHashesList := make([][26]byte, 0, len(messageHashesBytesList))
|
|
|
|
for _, messageHashBytes := range messageHashesBytesList{
|
|
|
|
if (len(messageHashBytes) != 26){
|
|
return nil, errors.New("Database corrupt: Contains invalid message reviews list entry key message hash.")
|
|
}
|
|
|
|
messageHashArray := [26]byte(messageHashBytes)
|
|
|
|
messageHashesList = append(messageHashesList, messageHashArray)
|
|
}
|
|
|
|
return messageHashesList, nil
|
|
}
|
|
|
|
|
|
func AddMessageReportToList(messageHash [26]byte, reportHash [30]byte)error{
|
|
|
|
reportHashIsValid, err := readReports.VerifyReportHash(reportHash, true, "Message")
|
|
if (err != nil) { return err }
|
|
if (reportHashIsValid == false){
|
|
reportHashHex := encoding.EncodeBytesToHexString(reportHash[:])
|
|
return errors.New("AddMessageReportToList called with invalid reportHash: " + reportHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingMessageReportsListMutex.Lock()
|
|
defer editingMessageReportsListMutex.Unlock()
|
|
|
|
entryKey := []byte{messageReportsListPrefix}
|
|
entryKey = append(entryKey, messageHash[:]...)
|
|
|
|
err = addItemToEntryList(entryKey, 30, reportHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetMessageReportsList(messageHash [26]byte)(bool, [][30]byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
entryKey := []byte{messageReportsListPrefix}
|
|
entryKey = append(entryKey, messageHash[:]...)
|
|
|
|
exists, reportHashesBytesList, err := getEntryList(entryKey, 30)
|
|
if (err != nil) { return false, nil, err }
|
|
if (exists == false) {
|
|
return false, nil, nil
|
|
}
|
|
|
|
reportHashesList := make([][30]byte, 0, len(reportHashesBytesList))
|
|
|
|
for _, reportHashBytes := range reportHashesBytesList{
|
|
|
|
if (len(reportHashBytes) != 30){
|
|
return false, nil, errors.New("getEntryList returning invalid length report hash.")
|
|
}
|
|
|
|
reportHashArray := [30]byte(reportHashBytes)
|
|
|
|
reportHashesList = append(reportHashesList, reportHashArray)
|
|
}
|
|
|
|
return true, reportHashesList, nil
|
|
}
|
|
|
|
func DeleteMessageReportFromList(messageHash [26]byte, reportHash [30]byte)error{
|
|
|
|
reportHashIsValid, err := readReports.VerifyReportHash(reportHash, true, "Message")
|
|
if (err != nil) { return err }
|
|
if (reportHashIsValid == false){
|
|
reportHashHex := encoding.EncodeBytesToHexString(reportHash[:])
|
|
return errors.New("DeleteMessageReportFromList called with invalid reportHash: " + reportHashHex)
|
|
}
|
|
|
|
err = startDatabase()
|
|
if (err != nil) { return err }
|
|
|
|
editingMessageReportsListMutex.Lock()
|
|
defer editingMessageReportsListMutex.Unlock()
|
|
|
|
entryKey := []byte{messageReportsListPrefix}
|
|
entryKey = append(entryKey, messageHash[:]...)
|
|
|
|
err = deleteItemFromEntryList(entryKey, 30, reportHash[:])
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
// Returns all message hashes that have been reported
|
|
func GetAllReportedMessageHashes()([][26]byte, error){
|
|
|
|
err := startDatabase()
|
|
if (err != nil) { return nil, err }
|
|
|
|
messageHashesBytesList, err := getAllKeysInDatabaseWithPrefix(messageReportsListPrefix, true)
|
|
if (err != nil) { return nil, err }
|
|
|
|
messageHashesList := make([][26]byte, 0, len(messageHashesBytesList))
|
|
|
|
for _, messageHashBytes := range messageHashesBytesList{
|
|
|
|
if (len(messageHashBytes) != 26){
|
|
return nil, errors.New("Database corrupt: Contains message reports list entry with invalid message hash.")
|
|
}
|
|
|
|
messageHashArray := [26]byte(messageHashBytes)
|
|
|
|
messageHashesList = append(messageHashesList, messageHashArray)
|
|
}
|
|
|
|
return messageHashesList, nil
|
|
}
|
|
|
|
//Ouputs:
|
|
// -bool: Entry exists
|
|
// -[][]byte: Items list
|
|
// -error
|
|
func getEntryList(entryKey []byte, lengthOfEachItem int)(bool, [][]byte, error){
|
|
|
|
exists, entryValue, err := getDatabaseValue(entryKey)
|
|
if (err != nil) { return false, nil, err }
|
|
if (exists == false){
|
|
return false, nil, nil
|
|
}
|
|
|
|
itemsList, err := splitByteSliceIntoEqualParts(entryValue, lengthOfEachItem)
|
|
if (err != nil){
|
|
entryKeyHex := encoding.EncodeBytesToHexString(entryKey)
|
|
return false, nil, errors.New("Database entry list is invalid for entry key: " + entryKeyHex)
|
|
}
|
|
|
|
return true, itemsList, nil
|
|
}
|
|
|
|
// This adds an item to an entry whose value is a list of equal-length byte slices
|
|
// Duplicates items will be avoided
|
|
func addItemToEntryList(entryKey []byte, lengthOfEachItem int, itemToAdd []byte)error{
|
|
|
|
if (len(itemToAdd) != lengthOfEachItem){
|
|
lengthString := helpers.ConvertIntToString(lengthOfEachItem)
|
|
return errors.New("addItemToEntryList called with invalid length itemToAdd: Not " + lengthString)
|
|
}
|
|
|
|
//Outputs:
|
|
// -bool: Update needed
|
|
// -bool: New value exists (false = delete entry value)
|
|
// -[]byte: New value
|
|
// -error
|
|
updateValueFunction := func(existingValueExists bool, existingValue []byte)(bool, bool, []byte, error){
|
|
|
|
if (existingValueExists == false){
|
|
return true, true, itemToAdd, nil
|
|
}
|
|
|
|
//TODO: Do we need to copy existingValue? because we use it as an input to slices.Concat()
|
|
|
|
currentList, err := splitByteSliceIntoEqualParts(existingValue, lengthOfEachItem)
|
|
if (err != nil) { return false, false, nil, err }
|
|
|
|
for _, element := range currentList{
|
|
|
|
areEqual := bytes.Equal(itemToAdd, element)
|
|
if (areEqual == true){
|
|
// The item to add already exists.
|
|
// No update is needed.
|
|
return false, false, nil, nil
|
|
}
|
|
}
|
|
|
|
newValue := slices.Concat(existingValue, itemToAdd)
|
|
|
|
return true, true, newValue, nil
|
|
}
|
|
|
|
err := updateDatabaseEntry(entryKey, updateValueFunction)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
// This deletes a value from an entry whose value is a list of equal-length byte slices
|
|
// All byte slices are concatenated
|
|
func deleteItemFromEntryList(entryKey []byte, lengthOfEachItem int, itemToDelete []byte)error{
|
|
|
|
//Outputs:
|
|
// -bool: Update needed
|
|
// -bool: New value exists (false == delete entry)
|
|
// -[]byte: New value
|
|
// -error
|
|
updateValueFunction := func(existingValueExists bool, existingValue []byte)(bool, bool, []byte, error){
|
|
|
|
if (existingValueExists == false){
|
|
// Nothing to delete
|
|
return false, false, nil, nil
|
|
}
|
|
|
|
currentList, err := splitByteSliceIntoEqualParts(existingValue, lengthOfEachItem)
|
|
if (err != nil) { return false, false, nil, err }
|
|
|
|
newValue := make([]byte, 0)
|
|
|
|
deletedAny := false
|
|
|
|
for _, element := range currentList{
|
|
|
|
areEqual := bytes.Equal(element, itemToDelete)
|
|
if (areEqual == true){
|
|
// We are deleting this element
|
|
deletedAny = true
|
|
continue
|
|
}
|
|
|
|
newValue = append(newValue, element...)
|
|
}
|
|
|
|
if (deletedAny == false){
|
|
// Nothing to delete
|
|
return false, false, nil, nil
|
|
}
|
|
|
|
if (len(newValue) == 0){
|
|
// New value is empty
|
|
return true, false, nil, nil
|
|
}
|
|
|
|
return true, true, newValue, nil
|
|
}
|
|
|
|
err := updateDatabaseEntry(entryKey, updateValueFunction)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func setDatabaseEntry(key []byte, value []byte)error{
|
|
|
|
if (myDatabase == nil) {
|
|
return errors.New("setDatabaseEntry called when database not started.")
|
|
}
|
|
|
|
//TODO: Do we need to copy value?
|
|
// Copy is never needed for key because it will always be passed in as an array
|
|
|
|
valueCopy := slices.Clone(value)
|
|
|
|
updateValueFunction := func(txn *badger.Txn) error {
|
|
err := txn.Set(key, valueCopy)
|
|
return err
|
|
}
|
|
|
|
databaseMutex.RLock()
|
|
defer databaseMutex.RUnlock()
|
|
|
|
err := myDatabase.Update(updateValueFunction)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func getDatabaseValue(key []byte)(bool, []byte, error){
|
|
|
|
if (myDatabase == nil) {
|
|
return false, nil, errors.New("getDatabaseValue called when database is not started.")
|
|
}
|
|
|
|
valueFound := false
|
|
var valueBytes []byte
|
|
|
|
getEntryValueFunction := func(txn *badger.Txn)error{
|
|
|
|
item, err := txn.Get(key)
|
|
if (err != nil) {
|
|
if (err == badger.ErrKeyNotFound){
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
|
|
valueFound = true
|
|
valueBytes, err = item.ValueCopy(nil)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
databaseMutex.RLock()
|
|
defer databaseMutex.RUnlock()
|
|
|
|
err := myDatabase.View(getEntryValueFunction)
|
|
if (err != nil){ return false, nil, err }
|
|
|
|
if (valueFound == false){
|
|
return false, nil, nil
|
|
}
|
|
|
|
return true, valueBytes, nil
|
|
}
|
|
|
|
|
|
func deleteDatabaseEntry(key []byte)error{
|
|
|
|
if (myDatabase == nil) {
|
|
return errors.New("deleteDatabaseEntry called when database is not started.")
|
|
}
|
|
|
|
deleteFunction := func(txn *badger.Txn) error {
|
|
err := txn.Delete(key)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
databaseMutex.RLock()
|
|
defer databaseMutex.RUnlock()
|
|
|
|
err := myDatabase.Update(deleteFunction)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
// This function will get the database entry and replace the value, conditional on what the existing value is
|
|
//
|
|
//Inputs:
|
|
// -[]byte: The key we are editing
|
|
// -func(currentValueExists bool, currentValue []byte)(bool, bool, []byte, error)
|
|
// -Outputs:
|
|
// -bool: Change to key value is needed
|
|
// -bool: New value exists (false = delete key value)
|
|
// -[]byte: New value for key entry
|
|
// -error
|
|
// Outputs:
|
|
// -error
|
|
func updateDatabaseEntry(key []byte, updateEntryValueFunction func(bool, []byte)(bool, bool, []byte, error))error{
|
|
|
|
updateFunction := func(txn *badger.Txn)error{
|
|
|
|
//Outputs:
|
|
// -bool: Existing value exists
|
|
// -string: Existing value
|
|
// -error
|
|
getExistingValue := func()(bool, []byte, error){
|
|
|
|
item, err := txn.Get(key)
|
|
if (err != nil) {
|
|
if (err == badger.ErrKeyNotFound){
|
|
return false, nil, nil
|
|
}
|
|
return false, nil, err
|
|
}
|
|
|
|
existingValue, err := item.ValueCopy(nil)
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
return true, existingValue, nil
|
|
}
|
|
|
|
existingValueExists, existingValue, err := getExistingValue()
|
|
if (err != nil){ return err }
|
|
|
|
needsUpdate, newValueExists, newValue, err := updateEntryValueFunction(existingValueExists, existingValue)
|
|
if (err != nil){ return err }
|
|
if (needsUpdate == false){
|
|
return nil
|
|
}
|
|
if (newValueExists == false){
|
|
err := txn.Delete(key)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
err = txn.Set(key, newValue)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
databaseMutex.RLock()
|
|
defer databaseMutex.RUnlock()
|
|
|
|
err := myDatabase.Update(updateFunction)
|
|
if (err != nil){ return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
|
|
func getNumberOfKeysInDatabaseWithPrefix(prefixToCheck byte)(int64, error){
|
|
|
|
if (myDatabase == nil) {
|
|
return 0, errors.New("getNumberOfKeysInDatabaseWithPrefix called when database is not started.")
|
|
}
|
|
|
|
counter := int64(0)
|
|
|
|
getNumberOfKeysFunction := func(txn *badger.Txn) error {
|
|
|
|
options := badger.DefaultIteratorOptions
|
|
options.PrefetchValues = false
|
|
iterator := txn.NewIterator(options)
|
|
|
|
for iterator.Rewind(); iterator.Valid(); iterator.Next() {
|
|
|
|
item := iterator.Item()
|
|
entryKey := item.KeyCopy(nil)
|
|
|
|
if (len(entryKey) == 0){
|
|
return errors.New("Database corrupt: Contains empty entry key.")
|
|
}
|
|
|
|
if (entryKey[0] == prefixToCheck){
|
|
counter += 1
|
|
}
|
|
}
|
|
|
|
iterator.Close()
|
|
return nil
|
|
}
|
|
|
|
databaseMutex.RLock()
|
|
defer databaseMutex.RUnlock()
|
|
|
|
err := myDatabase.View(getNumberOfKeysFunction)
|
|
if (err != nil) { return 0, err }
|
|
|
|
return counter, nil
|
|
}
|
|
|
|
|
|
func getAllKeysInDatabaseWithPrefix(prefixToCheck byte, trimPrefix bool)([][]byte, error){
|
|
|
|
if (myDatabase == nil) {
|
|
return nil, errors.New("getAllKeysInDatabaseWithPrefix called when database is not started.")
|
|
}
|
|
|
|
keysList := make([][]byte, 0)
|
|
|
|
getAllKeysFunction := func(txn *badger.Txn) error {
|
|
options := badger.DefaultIteratorOptions
|
|
options.PrefetchValues = false
|
|
iterator := txn.NewIterator(options)
|
|
|
|
for iterator.Rewind(); iterator.Valid(); iterator.Next() {
|
|
item := iterator.Item()
|
|
|
|
entryKey := item.KeyCopy(nil)
|
|
|
|
if (len(entryKey) < 2){
|
|
return errors.New("Database corrupt: Contains entry key less than 2 bytes in length.")
|
|
}
|
|
|
|
if (entryKey[0] == prefixToCheck){
|
|
|
|
if (trimPrefix == false){
|
|
keysList = append(keysList, entryKey)
|
|
|
|
} else {
|
|
|
|
keyWithoutPrefix := entryKey[1:]
|
|
keysList = append(keysList, keyWithoutPrefix)
|
|
}
|
|
}
|
|
}
|
|
|
|
iterator.Close()
|
|
return nil
|
|
}
|
|
|
|
databaseMutex.RLock()
|
|
defer databaseMutex.RUnlock()
|
|
|
|
err := myDatabase.View(getAllKeysFunction)
|
|
if (err != nil) { return nil, err }
|
|
|
|
return keysList, nil
|
|
}
|
|
|
|
|
|
func splitByteSliceIntoEqualParts(inputSlice []byte, lengthOfEachSubslice int)([][]byte, error){
|
|
|
|
inputLength := len(inputSlice)
|
|
|
|
if (inputLength % lengthOfEachSubslice != 0){
|
|
// The input slice should be a list of uniform-length byte arrays appended together
|
|
inputSliceHex := encoding.EncodeBytesToHexString(inputSlice)
|
|
return nil, errors.New("splitByteSliceIntoEqualParts called with invalid inputSlice: " + inputSliceHex)
|
|
}
|
|
|
|
numberOfSubslices := inputLength/lengthOfEachSubslice
|
|
|
|
subslicesList := make([][]byte, 0)
|
|
|
|
for i := 0; i < numberOfSubslices; i++{
|
|
|
|
index := i * lengthOfEachSubslice
|
|
|
|
subsliceBytes := inputSlice[index:index+lengthOfEachSubslice]
|
|
|
|
subslicesList = append(subslicesList, subsliceBytes)
|
|
}
|
|
|
|
return subslicesList, nil
|
|
}
|
|
|
|
|
|
|