mirror of
https://github.com/PeernetOfficial/Cmd.git
synced 2026-07-17 02:47:52 +01:00
New command: get block
This commit is contained in:
119
Block Transfer.go
Normal file
119
Block Transfer.go
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
File Name: Block Transfer.go
|
||||
Copyright: 2021 Peernet Foundation s.r.o.
|
||||
Author: Peter Kleissner
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"github.com/PeernetOfficial/core"
|
||||
"github.com/PeernetOfficial/core/blockchain"
|
||||
"github.com/PeernetOfficial/core/protocol"
|
||||
)
|
||||
|
||||
const maxBlockSize = 1 * 1024 * 1024
|
||||
|
||||
func blockTransfer(peer *core.PeerInfo, blockNumber uint64) {
|
||||
conn, _, err := peer.BlockTransferRequest(peer.PublicKey, 1, maxBlockSize, []protocol.BlockRange{{Offset: uint64(blockNumber), Limit: 1}})
|
||||
if err != nil {
|
||||
fmt.Printf("Error starting block transfer: %s\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
data, targetBlock, blockSize, availability, err := protocol.BlockTransferReadBlock(conn, maxBlockSize)
|
||||
conn.Close()
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("Error reading block (indicated block size %d) from remote: %s\n", blockSize, err.Error())
|
||||
return
|
||||
} else if targetBlock.Limit != 1 || targetBlock.Offset != blockNumber {
|
||||
fmt.Printf("Error mismatch requested block %d with returned block %d (count %d)\n", blockNumber, targetBlock.Offset, targetBlock.Limit)
|
||||
return
|
||||
} else if availability == protocol.GetBlockStatusNotAvailable { // Block range not available
|
||||
fmt.Printf("Error requested block %d not available\n", blockNumber)
|
||||
return
|
||||
} else if availability == protocol.GetBlockStatusSizeExceed { // Block range exceeds size limit
|
||||
fmt.Printf("Error block %d reported by remote as exceeding size %d (limit %d)\n", blockNumber, blockSize, maxBlockSize)
|
||||
return
|
||||
} else if availability != protocol.GetBlockStatusAvailable {
|
||||
fmt.Printf("Error requested block %d unknown availability indicator %d\n", blockNumber, availability)
|
||||
return
|
||||
}
|
||||
|
||||
decoded, status, err := blockchain.DecodeBlockRaw(data)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("Error decoding block: %s\n", err.Error())
|
||||
return
|
||||
} else if status != blockchain.StatusOK {
|
||||
fmt.Printf("Error decoding block status is %d\n", status)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("Block %d from %s: version %d, number %d, block size %d, decoded %d records\n", blockNumber, hex.EncodeToString(peer.PublicKey.SerializeCompressed()), decoded.BlockchainVersion, decoded.Number, len(data), len(decoded.RecordsDecoded))
|
||||
|
||||
for _, decodedR := range decoded.RecordsDecoded {
|
||||
if file, ok := decodedR.(blockchain.BlockRecordFile); ok {
|
||||
blockPrintFile(file)
|
||||
} else if recordsProfile, ok := decodedR.([]blockchain.BlockRecordProfile); ok {
|
||||
for _, recordP := range recordsProfile {
|
||||
blockPrintProfileField(recordP)
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("* Unknown record.\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func blockPrintFile(file blockchain.BlockRecordFile) {
|
||||
fmt.Printf("* File %s\n", file.ID.String())
|
||||
fmt.Printf(" Size %d\n", file.Size)
|
||||
fmt.Printf(" Type %d\n", file.Type)
|
||||
fmt.Printf(" Format %d\n", file.Format)
|
||||
fmt.Printf(" Hash %s\n", hex.EncodeToString(file.Hash))
|
||||
fmt.Printf(" Merkle Root Hash %s\n", hex.EncodeToString(file.MerkleRootHash))
|
||||
fmt.Printf(" Fragment Size %d\n", file.FragmentSize)
|
||||
|
||||
for _, tag := range file.Tags {
|
||||
switch tag.Type {
|
||||
case blockchain.TagName:
|
||||
fmt.Printf(" Name %s\n", tag.Text())
|
||||
case blockchain.TagFolder:
|
||||
fmt.Printf(" Folder %s\n", tag.Text())
|
||||
case blockchain.TagDescription:
|
||||
fmt.Printf(" Description %s\n", tag.Text())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func blockPrintProfileField(field blockchain.BlockRecordProfile) {
|
||||
switch field.Type {
|
||||
case blockchain.ProfileName:
|
||||
fmt.Printf("* Profile Name = %s\n", string(field.Data))
|
||||
|
||||
case blockchain.ProfileEmail:
|
||||
fmt.Printf("* Profile Email = %s\n", string(field.Data))
|
||||
|
||||
case blockchain.ProfileWebsite:
|
||||
fmt.Printf("* Profile Website = %s\n", string(field.Data))
|
||||
|
||||
case blockchain.ProfileTwitter:
|
||||
fmt.Printf("* Profile Twitter = %s\n", string(field.Data))
|
||||
|
||||
case blockchain.ProfileYouTube:
|
||||
fmt.Printf("* Profile YouTube = %s\n", string(field.Data))
|
||||
|
||||
case blockchain.ProfileAddress:
|
||||
fmt.Printf("* Profile Address = %s\n", string(field.Data))
|
||||
|
||||
case blockchain.ProfilePicture:
|
||||
fmt.Printf("* Profile Picture. Size %d\n", len(field.Data))
|
||||
|
||||
default:
|
||||
fmt.Printf("* Field %d = %s\n", field.Type, hex.EncodeToString(field.Data))
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,7 @@ func showHelp(output io.Writer) {
|
||||
"warehouse store Store data into local warehouse\n"+
|
||||
"dht get Get data via DHT by hash\n"+
|
||||
"dht store Store data into DHT\n"+
|
||||
"get block Get block from remote peer\n"+
|
||||
"log error Set error log output\n"+
|
||||
"\n")
|
||||
}
|
||||
@@ -400,6 +401,45 @@ func userCommands(input io.Reader, output io.Writer, terminateSignal chan struct
|
||||
}
|
||||
|
||||
go transferCompareFile(peer, fileHash)
|
||||
|
||||
case "get block":
|
||||
fmt.Fprintf(output, "Enter peer ID or node ID:\n")
|
||||
nodeIDA, _, terminate := getUserOptionString(reader, terminateSignal)
|
||||
if terminate {
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(output, "Enter block number:\n")
|
||||
blockNumber, _, terminate := getUserOptionInt(reader, terminateSignal)
|
||||
if terminate {
|
||||
return
|
||||
}
|
||||
|
||||
nodeID, valid2 := webapi.DecodeBlake3Hash(nodeIDA)
|
||||
publicKey, err3 := core.PublicKeyFromPeerID(nodeIDA)
|
||||
|
||||
if !valid2 && err3 != nil {
|
||||
fmt.Fprintf(output, "Invalid peer ID or node ID.\n")
|
||||
break
|
||||
} else if blockNumber < 0 {
|
||||
fmt.Fprintf(output, "Invalid block number.\n")
|
||||
}
|
||||
|
||||
var peer *core.PeerInfo
|
||||
var err error
|
||||
timeout := time.Second * 10
|
||||
|
||||
if valid2 {
|
||||
peer, err = webapi.PeerConnectNode(nodeID, timeout)
|
||||
} else if err3 == nil {
|
||||
peer, err = webapi.PeerConnectPublicKey(publicKey, timeout)
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Fprintf(output, "Could not connect to peer: %s\n", err.Error())
|
||||
break
|
||||
}
|
||||
|
||||
go blockTransfer(peer, uint64(blockNumber))
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
2
go.mod
2
go.mod
@@ -3,7 +3,7 @@ module github.com/PeernetOfficial/Cmd
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/PeernetOfficial/core v0.0.0-20211130025319-68d8c1187273
|
||||
github.com/PeernetOfficial/core v0.0.0-20211204025234-34e48c09df12
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gorilla/websocket v1.4.3-0.20210424162022-e8629af678b7
|
||||
)
|
||||
|
||||
4
go.sum
4
go.sum
@@ -1,5 +1,5 @@
|
||||
github.com/PeernetOfficial/core v0.0.0-20211130025319-68d8c1187273 h1:WZKBtdXfNBxy06Dyf+aPXsA+0fIBwNNGD7O5FnmiIVo=
|
||||
github.com/PeernetOfficial/core v0.0.0-20211130025319-68d8c1187273/go.mod h1:0D/jIDYdV0WXg5WACS+fR5keafLhYB89WUs6ZEE8t4Y=
|
||||
github.com/PeernetOfficial/core v0.0.0-20211204025234-34e48c09df12 h1:mOz4+1+2P5cJoRYUDesXnNvKX3qp0TUeX81oYjn3alQ=
|
||||
github.com/PeernetOfficial/core v0.0.0-20211204025234-34e48c09df12/go.mod h1:0D/jIDYdV0WXg5WACS+fR5keafLhYB89WUs6ZEE8t4Y=
|
||||
github.com/akrylysov/pogreb v0.10.1 h1:FqlR8VR7uCbJdfUob916tPM+idpKgeESDXOA1K0DK4w=
|
||||
github.com/akrylysov/pogreb v0.10.1/go.mod h1:pNs6QmpQ1UlTJKDezuRWmaqkgUE2TuU0YTWyqJZ7+lI=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
|
||||
Reference in New Issue
Block a user