Monday bug fixing

This commit is contained in:
2023-06-27 00:26:56 +01:00
parent fea2209083
commit bf7766931f
6 changed files with 159 additions and 121 deletions

View File

@@ -15,6 +15,7 @@ package blockchain
import (
"encoding/binary"
"errors"
"fmt"
"math"
)
@@ -24,8 +25,8 @@ type BlockRecordProfile struct {
Data []byte // Data
}
// decodeBlockRecordProfile decodes only profile records. Other records are ignored.
func decodeBlockRecordProfile(recordsRaw []BlockRecordRaw) (fields []BlockRecordProfile, err error) {
// DecodeBlockRecordProfile decodes only profile records. Other records are ignored.
func DecodeBlockRecordProfile(recordsRaw []BlockRecordRaw) (fields []BlockRecordProfile, err error) {
fieldMap := make(map[uint16][]byte)
for _, record := range recordsRaw {
@@ -38,10 +39,14 @@ func decodeBlockRecordProfile(recordsRaw []BlockRecordRaw) (fields []BlockRecord
}
fieldType := binary.LittleEndian.Uint16(record.Data[0:2])
fmt.Println(record.Data[0:2])
fmt.Println(fieldType)
fieldMap[fieldType] = record.Data[2:]
}
for fieldType, fieldData := range fieldMap {
fmt.Println("type value added")
fmt.Println(fieldType)
fields = append(fields, BlockRecordProfile{Type: fieldType, Data: fieldData})
}

View File

@@ -45,7 +45,7 @@ func decodeBlockRecords(block *Block) (decoded *BlockDecoded, err error) {
decoded.RecordsDecoded = append(decoded.RecordsDecoded, file)
}
if profileFields, err := decodeBlockRecordProfile(block.RecordsRaw); err != nil {
if profileFields, err := DecodeBlockRecordProfile(block.RecordsRaw); err != nil {
return nil, err
} else if len(profileFields) > 0 {
decoded.RecordsDecoded = append(decoded.RecordsDecoded, profileFields)

View File

@@ -6,12 +6,14 @@ Author: Peter Kleissner
package blockchain
import "fmt"
// ProfileReadField reads the specified profile field. See ProfileX for the list of recognized fields. The encoding depends on the field type. Status is StatusX.
func (blockchain *Blockchain) ProfileReadField(index uint16) (data []byte, status int) {
found := false
status = blockchain.Iterate(func(block *Block) (statusI int) {
fields, err := decodeBlockRecordProfile(block.RecordsRaw)
fields, err := DecodeBlockRecordProfile(block.RecordsRaw)
if err != nil {
return StatusCorruptBlockRecord
} else if len(fields) == 0 {
@@ -42,8 +44,10 @@ func (blockchain *Blockchain) ProfileReadField(index uint16) (data []byte, statu
func (blockchain *Blockchain) ProfileList() (fields []BlockRecordProfile, status int) {
uniqueFields := make(map[uint16][]byte)
fmt.Println(blockchain.height)
status = blockchain.Iterate(func(block *Block) (statusI int) {
fields, err := decodeBlockRecordProfile(block.RecordsRaw)
fields, err := DecodeBlockRecordProfile(block.RecordsRaw)
if err != nil {
return StatusCorruptBlockRecord
}
@@ -103,7 +107,7 @@ func (blockchain *Blockchain) ProfileDelete(fields []uint16) (newHeight, newVers
return 0 // no action
}
existingFields, err := decodeBlockRecordProfile([]BlockRecordRaw{*record})
existingFields, err := DecodeBlockRecordProfile([]BlockRecordRaw{*record})
if err != nil || len(existingFields) != 1 {
return 3 // error blockchain corrupt
}

View File

@@ -43,13 +43,13 @@ type apiFile struct {
Date time.Time `json:"date"` // Date shared
NodeID []byte `json:"nodeid"` // Node ID, owner of the file. Read only.
Metadata []apiFileMetadata `json:"metadata"` // Additional metadata.
Username []byte `json:"username"` // Username of the user who uploaded the file
Username string `json:"username"` // Username of the user who uploaded the file
}
// --- conversion from core to API data ---
func blockRecordFileToAPI(input blockchain.BlockRecordFile) (output apiFile) {
output = apiFile{ID: input.ID, Hash: input.Hash, NodeID: input.NodeID, Type: input.Type, Format: input.Format, Size: input.Size, Username: []byte(input.Username), Metadata: []apiFileMetadata{}}
output = apiFile{ID: input.ID, Hash: input.Hash, NodeID: input.NodeID, Type: input.Type, Format: input.Format, Size: input.Size, Username: input.Username, Metadata: []apiFileMetadata{}}
for _, tag := range input.Tags {
if tag.Type == blockchain.TagSharedByCount && tag.Number() == 0 {

View File

@@ -7,26 +7,27 @@ Author: Peter Kleissner
package webapi
import (
"bytes"
"net/http"
"strconv"
"bytes"
"fmt"
"net/http"
"strconv"
"github.com/PeernetOfficial/core/blockchain"
"github.com/PeernetOfficial/core/blockchain"
)
// apiProfileData contains profile metadata stored on the blockchain. Any data is treated as untrusted and unverified by default.
type apiProfileData struct {
Fields []apiBlockRecordProfile `json:"fields"` // All fields
Status int `json:"status"` // Status of the operation, only used when this structure is returned from the API. See blockchain.StatusX.
Fields []apiBlockRecordProfile `json:"fields"` // All fields
Status int `json:"status"` // Status of the operation, only used when this structure is returned from the API. See blockchain.StatusX.
}
// apiBlockRecordProfile provides information about the end user. Note that all profile data is arbitrary and shall be considered untrusted and unverified.
// To establish trust, the user must load Certificates into the blockchain that validate certain data.
type apiBlockRecordProfile struct {
Type uint16 `json:"type"` // See ProfileX constants.
// Depending on the exact type, one of the below fields is used for proper encoding:
Text string `json:"text"` // Text value. UTF-8 encoding.
Blob []byte `json:"blob"` // Binary data
Type uint16 `json:"type"` // See ProfileX constants.
// Depending on the exact type, one of the below fields is used for proper encoding:
Text string `json:"text"` // Text value. UTF-8 encoding.
Blob []byte `json:"blob"` // Binary data
}
/*
@@ -37,46 +38,72 @@ Response: 200 with JSON structure apiProfileData
*/
func (api *WebapiInstance) apiProfileList(w http.ResponseWriter, r *http.Request) {
NodeID, valid := DecodeBlake3Hash(r.URL.Query().Get("node"))
NodeID, valid := DecodeBlake3Hash(r.URL.Query().Get("node"))
var fields []blockchain.BlockRecordProfile
var status int
var fields []blockchain.BlockRecordProfile
var status int
result := apiProfileData{Status: status}
result := apiProfileData{Status: status}
if valid && !bytes.Equal(NodeID, api.Backend.SelfNodeID()) {
_, node, _ := api.Backend.FindNode(NodeID, 100)
fmt.Println(valid)
fmt.Println(NodeID)
fmt.Println(api.Backend.SelfNodeID())
// First iteration of the entire blockchain to search for the profile
// image and Username of the user
for blockN1 := node.BlockchainHeight - 1; blockN1 > 0; blockN1-- {
blockDecoded, _, found, _ := node.Backend.ReadBlock(node.PublicKey, node.BlockchainVersion, blockN1)
if !found {
continue
}
// Adding profile image and Username to the output
for raw := range blockDecoded.Block.RecordsRaw {
if blockDecoded.Block.RecordsRaw[raw].Type == blockchain.ProfileName {
result.Status = 0
result.Fields = append(result.Fields, blockRecordProfileToAPI(blockchain.BlockRecordProfile{Type: uint16(blockDecoded.Block.RecordsRaw[raw].Type), Data: blockDecoded.Block.RecordsRaw[raw].Data[:]}))
}
if blockDecoded.Block.RecordsRaw[raw].Type == blockchain.ProfilePicture {
result.Status = 0
result.Fields = append(result.Fields, blockRecordProfileToAPI(blockchain.BlockRecordProfile{Type: uint16(blockDecoded.Block.RecordsRaw[raw].Type), Data: blockDecoded.Block.RecordsRaw[raw].Data[:]}))
}
}
}
if valid && !bytes.Equal(NodeID, api.Backend.SelfNodeID()) {
//_, node, _ := api.Backend.FindNode(NodeID, 100)
fields, status = node.Backend.UserBlockchain.ProfileList()
} else {
fields, status = api.Backend.UserBlockchain.ProfileList()
result.Status = status
for n := range fields {
result.Fields = append(result.Fields, blockRecordProfileToAPI(fields[n]))
}
}
fmt.Println("we are in the if condition")
EncodeJSON(api.Backend, w, r, result)
peers := api.Backend.PeerlistGet()
for i, _ := range peers {
fmt.Println("in the loop")
if bytes.Equal(peers[i].NodeID, NodeID) {
// First iteration of the entire blockchain to search for the profile
// image and Username of the user
fmt.Println("Peer found")
fmt.Println(peers[i])
//fields, status = peers[i].Backend.UserBlockchain.ProfileList()
//
//for j, _ := range fields {
// result.Fields = append(result.Fields, blockRecordProfileToAPI(blockchain.BlockRecordProfile{Type: fields[j].Type, Data: fields[j].Data}))
//}
for blockN1 := peers[i].BlockchainHeight - 1; blockN1 > 0; blockN1-- {
blockDecoded, _, found, _ := peers[i].Backend.ReadBlock(peers[i].PublicKey, peers[i].BlockchainVersion, blockN1)
if !found {
continue
}
profile, _ := blockchain.DecodeBlockRecordProfile(blockDecoded.Block.RecordsRaw)
// Adding profile image and Username to the output
for raw, _ := range profile {
if profile[raw].Type == blockchain.ProfileName {
result.Fields = append(result.Fields, blockRecordProfileToAPI(blockchain.BlockRecordProfile{Type: profile[raw].Type, Data: profile[raw].Data[:]}))
}
if profile[raw].Type == blockchain.ProfilePicture {
result.Status = 0
result.Fields = append(result.Fields, blockRecordProfileToAPI(blockchain.BlockRecordProfile{Type: profile[raw].Type, Data: profile[raw].Data[:]}))
}
}
}
}
}
} else {
fmt.Println("why are you here")
fields, status = api.Backend.UserBlockchain.ProfileList()
result.Status = status
for n := range fields {
result.Fields = append(result.Fields, blockRecordProfileToAPI(fields[n]))
}
}
EncodeJSON(api.Backend, w, r, result)
}
/*
@@ -86,32 +113,32 @@ Request: GET /profile/read?field=[index]&node=[nodeid]
Response: 200 with JSON structure apiProfileData
*/
func (api *WebapiInstance) apiProfileRead(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
fieldN, err1 := strconv.Atoi(r.URL.Query().Get("field"))
NodeID, valid := DecodeBlake3Hash(r.URL.Query().Get("node"))
r.ParseForm()
fieldN, err1 := strconv.Atoi(r.URL.Query().Get("field"))
NodeID, valid := DecodeBlake3Hash(r.URL.Query().Get("node"))
if err1 != nil || fieldN < 0 {
http.Error(w, "", http.StatusBadRequest)
return
}
if err1 != nil || fieldN < 0 {
http.Error(w, "", http.StatusBadRequest)
return
}
var result apiProfileData
var data []byte
var result apiProfileData
var data []byte
if !valid {
_, node, _ := api.Backend.FindNode(NodeID, 100)
if data, result.Status = node.Backend.UserBlockchain.ProfileReadField(uint16(fieldN)); result.Status == blockchain.StatusOK {
result.Fields = append(result.Fields, blockRecordProfileToAPI(blockchain.BlockRecordProfile{Type: uint16(fieldN), Data: data}))
}
} else {
if api.Backend.NodelistLookup(NodeID) != nil {
if data, result.Status = api.Backend.NodelistLookup(NodeID).Backend.UserBlockchain.ProfileReadField(uint16(fieldN)); result.Status == blockchain.StatusOK {
result.Fields = append(result.Fields, blockRecordProfileToAPI(blockchain.BlockRecordProfile{Type: uint16(fieldN), Data: data}))
}
}
}
if !valid {
_, node, _ := api.Backend.FindNode(NodeID, 100)
if data, result.Status = node.Backend.UserBlockchain.ProfileReadField(uint16(fieldN)); result.Status == blockchain.StatusOK {
result.Fields = append(result.Fields, blockRecordProfileToAPI(blockchain.BlockRecordProfile{Type: uint16(fieldN), Data: data}))
}
} else {
if api.Backend.NodelistLookup(NodeID) != nil {
if data, result.Status = api.Backend.NodelistLookup(NodeID).Backend.UserBlockchain.ProfileReadField(uint16(fieldN)); result.Status == blockchain.StatusOK {
result.Fields = append(result.Fields, blockRecordProfileToAPI(blockchain.BlockRecordProfile{Type: uint16(fieldN), Data: data}))
}
}
}
EncodeJSON(api.Backend, w, r, result)
EncodeJSON(api.Backend, w, r, result)
}
/*
@@ -121,20 +148,24 @@ Request: POST /profile/write with JSON structure apiProfileData
Response: 200 with JSON structure apiBlockchainBlockStatus
*/
func (api *WebapiInstance) apiProfileWrite(w http.ResponseWriter, r *http.Request) {
var input apiProfileData
if err := DecodeJSON(w, r, &input); err != nil {
return
}
var input apiProfileData
if err := DecodeJSON(w, r, &input); err != nil {
return
}
var fields []blockchain.BlockRecordProfile
for _, field := range input.Fields {
api.Backend.LogError("apiProfileWrite(", "Upload type: %v\n", field.Type)
}
for n := range input.Fields {
fields = append(fields, blockRecordProfileFromAPI(input.Fields[n]))
}
var fields []blockchain.BlockRecordProfile
newHeight, newVersion, status := api.Backend.UserBlockchain.ProfileWrite(fields)
for n := range input.Fields {
fields = append(fields, blockRecordProfileFromAPI(input.Fields[n]))
}
EncodeJSON(api.Backend, w, r, apiBlockchainBlockStatus{Status: status, Height: newHeight, Version: newVersion})
newHeight, newVersion, status := api.Backend.UserBlockchain.ProfileWrite(fields)
EncodeJSON(api.Backend, w, r, apiBlockchainBlockStatus{Status: status, Height: newHeight, Version: newVersion})
}
/*
@@ -144,54 +175,54 @@ Request: POST /profile/delete with JSON structure apiProfileData
Response: 200 with JSON structure apiBlockchainBlockStatus
*/
func (api *WebapiInstance) apiProfileDelete(w http.ResponseWriter, r *http.Request) {
var input apiProfileData
if err := DecodeJSON(w, r, &input); err != nil {
return
}
var input apiProfileData
if err := DecodeJSON(w, r, &input); err != nil {
return
}
var fields []uint16
var fields []uint16
for n := range input.Fields {
fields = append(fields, input.Fields[n].Type)
}
for n := range input.Fields {
fields = append(fields, input.Fields[n].Type)
}
newHeight, newVersion, status := api.Backend.UserBlockchain.ProfileDelete(fields)
newHeight, newVersion, status := api.Backend.UserBlockchain.ProfileDelete(fields)
EncodeJSON(api.Backend, w, r, apiBlockchainBlockStatus{Status: status, Height: newHeight, Version: newVersion})
EncodeJSON(api.Backend, w, r, apiBlockchainBlockStatus{Status: status, Height: newHeight, Version: newVersion})
}
// --- conversion from core to API data ---
func blockRecordProfileToAPI(input blockchain.BlockRecordProfile) (output apiBlockRecordProfile) {
output.Type = input.Type
output.Type = input.Type
switch input.Type {
case blockchain.ProfileName, blockchain.ProfileEmail, blockchain.ProfileWebsite, blockchain.ProfileTwitter, blockchain.ProfileYouTube, blockchain.ProfileAddress:
output.Text = input.Text()
switch input.Type {
case blockchain.ProfileName, blockchain.ProfileEmail, blockchain.ProfileWebsite, blockchain.ProfileTwitter, blockchain.ProfileYouTube, blockchain.ProfileAddress:
output.Text = input.Text()
case blockchain.ProfilePicture:
output.Blob = input.Data
case blockchain.ProfilePicture:
output.Blob = input.Data
default:
output.Blob = input.Data
}
default:
output.Blob = input.Data
}
return output
return output
}
func blockRecordProfileFromAPI(input apiBlockRecordProfile) (output blockchain.BlockRecordProfile) {
output.Type = input.Type
output.Type = input.Type
switch input.Type {
case blockchain.ProfileName, blockchain.ProfileEmail, blockchain.ProfileWebsite, blockchain.ProfileTwitter, blockchain.ProfileYouTube, blockchain.ProfileAddress:
output.Data = []byte(input.Text)
switch input.Type {
case blockchain.ProfileName, blockchain.ProfileEmail, blockchain.ProfileWebsite, blockchain.ProfileTwitter, blockchain.ProfileYouTube, blockchain.ProfileAddress:
output.Data = []byte(input.Text)
case blockchain.ProfilePicture:
output.Data = input.Blob
case blockchain.ProfilePicture:
output.Data = input.Blob
default:
output.Data = input.Blob
}
default:
output.Data = input.Blob
}
return output
return output
}

View File

@@ -36,7 +36,6 @@ type SearchRequest struct {
FileFormat int `json:"fileformat"` // File format such as PDF, Word, Ebook, etc. See core.FormatX. -1 = not used.
SizeMin int `json:"sizemin"` // Min file size in bytes. -1 = not used.
SizeMax int `json:"sizemax"` // Max file size in bytes. -1 = not used.
NodeID string `json:"node"` // Filter based on the NodeID provided
}
// Sort orders
@@ -157,9 +156,9 @@ func (api *WebapiInstance) apiSearchResult(w http.ResponseWriter, r *http.Reques
sort, _ := strconv.Atoi(r.Form.Get("sort"))
sizeMin, _ := strconv.Atoi(r.Form.Get("sizemin"))
sizeMax, _ := strconv.Atoi(r.Form.Get("sizemax"))
nodeID, _ := DecodeBlake3Hash(r.Form.Get("node"))
//nodeID, _ := DecodeBlake3Hash(r.Form.Get("node"))
filter := inputToSearchFilter(sort, fileType, fileFormat, dateFrom, dateTo, sizeMin, sizeMax, nodeID)
filter := inputToSearchFilter(sort, fileType, fileFormat, dateFrom, dateTo, sizeMin, sizeMax)
job.RuntimeFilter(filter)
}
@@ -420,17 +419,16 @@ func (input *SearchRequest) Parse() (Timeout time.Duration) {
// ToSearchFilter converts the user input to a valid search filter
func (input *SearchRequest) ToSearchFilter() (output SearchFilter) {
hash, _ := DecodeBlake3Hash(input.NodeID)
return inputToSearchFilter(input.Sort, input.FileType, input.FileFormat, input.DateFrom, input.DateTo, input.SizeMin, input.SizeMax, hash)
//hash, _ := DecodeBlake3Hash(input.NodeID)
return inputToSearchFilter(input.Sort, input.FileType, input.FileFormat, input.DateFrom, input.DateTo, input.SizeMin, input.SizeMax)
}
func inputToSearchFilter(Sort, FileType, FileFormat int, DateFrom, DateTo string, SizeMin, SizeMax int, NodeID []byte) (output SearchFilter) {
func inputToSearchFilter(Sort, FileType, FileFormat int, DateFrom, DateTo string, SizeMin, SizeMax int) (output SearchFilter) {
output.Sort = Sort
output.FileType = FileType
output.FileFormat = FileFormat
output.SizeMin = SizeMin
output.SizeMax = SizeMax
output.NodeID = NodeID
dateFrom, errFrom := time.Parse(apiDateFormat, DateFrom)
dateTo, errTo := time.Parse(apiDateFormat, DateTo)