From bf7766931f74619809ae56118cc52737c055e3f8 Mon Sep 17 00:00:00 2001 From: Akilan Date: Tue, 27 Jun 2023 00:26:56 +0100 Subject: [PATCH] Monday bug fixing --- blockchain/Block Record Profile.go | 9 +- blockchain/Block Record.go | 2 +- blockchain/Profile.go | 10 +- webapi/File.go | 4 +- webapi/Profile.go | 243 ++++++++++++++++------------- webapi/Search.go | 12 +- 6 files changed, 159 insertions(+), 121 deletions(-) diff --git a/blockchain/Block Record Profile.go b/blockchain/Block Record Profile.go index 1ff65ba..c40bab6 100644 --- a/blockchain/Block Record Profile.go +++ b/blockchain/Block Record Profile.go @@ -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}) } diff --git a/blockchain/Block Record.go b/blockchain/Block Record.go index 90c3dfd..606d177 100644 --- a/blockchain/Block Record.go +++ b/blockchain/Block Record.go @@ -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) diff --git a/blockchain/Profile.go b/blockchain/Profile.go index 0ea557d..5b80b74 100644 --- a/blockchain/Profile.go +++ b/blockchain/Profile.go @@ -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 } diff --git a/webapi/File.go b/webapi/File.go index fe8013d..f50b86f 100644 --- a/webapi/File.go +++ b/webapi/File.go @@ -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 { diff --git a/webapi/Profile.go b/webapi/Profile.go index c2bf9ef..d6a6a0d 100644 --- a/webapi/Profile.go +++ b/webapi/Profile.go @@ -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 } diff --git a/webapi/Search.go b/webapi/Search.go index d6401f6..209f71e 100644 --- a/webapi/Search.go +++ b/webapi/Search.go @@ -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)