]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Misc improvements
authorMatt Joiner <anacrolix@gmail.com>
Fri, 1 Mar 2024 12:40:05 +0000 (23:40 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Sat, 2 Mar 2024 02:02:56 +0000 (13:02 +1100)
cmd/torrent2/main.go
merkle/hash.go
metainfo/file-tree.go
metainfo/fileinfo.go
metainfo/info.go
metainfo/piece.go
segments/segments.go
spec.go
torrent.go

index 0d57f0133bbd7149f52d08c9e802692c92e609a6..6017464ff2ba95e4a38f83426a3981884269e985 100644 (file)
@@ -4,6 +4,7 @@
 package main
 
 import (
+       "fmt"
        "os"
 
        "github.com/anacrolix/torrent/metainfo"
@@ -39,6 +40,26 @@ func main() {
                                        err = metainfo.ValidatePieceLayers(mi.PieceLayers, &info.FileTree, info.PieceLength)
                                        assertOk(err)
                                },
+                               "pprint": func() {
+                                       mi, err := metainfo.LoadFromFile(args[2])
+                                       assertOk(err)
+                                       info, err := mi.UnmarshalInfo()
+                                       assertOk(err)
+                                       files := info.UpvertedFiles()
+                                       pieceIndex := 0
+                                       for _, f := range files {
+                                               numPieces := int((f.Length + info.PieceLength - 1) / info.PieceLength)
+                                               endIndex := pieceIndex + numPieces
+                                               fmt.Printf(
+                                                       "%x: %q: pieces (%v-%v)\n",
+                                                       f.PiecesRoot.Unwrap(),
+                                                       f.BestPath(),
+                                                       pieceIndex,
+                                                       endIndex-1,
+                                               )
+                                               pieceIndex = endIndex
+                                       }
+                               },
                        }[args[1]]()
                },
        }[args[0]]()
index 1a8f67a92288a243a772892bf88813620e3bb261..5984547aab981982fbfbce19a49c03cf4420fbe6 100644 (file)
@@ -3,12 +3,14 @@ package merkle
 import (
        "crypto/sha256"
        "hash"
+       "unsafe"
 )
 
 func NewHash() *Hash {
-       return &Hash{
+       h := &Hash{
                nextBlock: sha256.New(),
        }
+       return h
 }
 
 type Hash struct {
@@ -41,7 +43,9 @@ func (h *Hash) Write(p []byte) (n int, err error) {
 }
 
 func (h *Hash) nextBlockSum() (sum [32]byte) {
-       h.nextBlock.Sum(sum[:0])
+       if unsafe.SliceData(h.nextBlock.Sum(sum[:0])) != unsafe.SliceData(sum[:]) {
+               panic("go sux")
+       }
        return
 }
 
@@ -57,6 +61,7 @@ func (h *Hash) Sum(b []byte) []byte {
 func (h *Hash) Reset() {
        h.blocks = h.blocks[:0]
        h.nextBlock.Reset()
+       h.written = 0
 }
 
 func (h *Hash) Size() int {
index bfb7229e9a8d1691f6d7edd9bf72ce31894397b2..0d7e1caf3b485610ca62a7646b08b1946651d97d 100644 (file)
@@ -64,23 +64,35 @@ func (ft *FileTree) orderedKeys() []string {
        return keys
 }
 
-func (ft *FileTree) UpvertedFiles(path []string, out func(fi FileInfo)) {
+func (ft *FileTree) upvertedFiles(pieceLength int64, out func(fi FileInfo)) {
+       var offset int64
+       ft.upvertedFilesInner(pieceLength, nil, &offset, out)
+}
+
+func (ft *FileTree) upvertedFilesInner(
+       pieceLength int64,
+       path []string,
+       offset *int64,
+       out func(fi FileInfo),
+) {
        if ft.IsDir() {
                for _, key := range ft.orderedKeys() {
                        if key == FileTreePropertiesKey {
                                continue
                        }
                        sub := g.MapMustGet(ft.Dir, key)
-                       sub.UpvertedFiles(append(path, key), out)
+                       sub.upvertedFilesInner(pieceLength, append(path, key), offset, out)
                }
        } else {
                out(FileInfo{
                        Length: ft.File.Length,
                        Path:   append([]string(nil), path...),
                        // BEP 52 requires paths be UTF-8 if possible.
-                       PathUtf8:   append([]string(nil), path...),
-                       PiecesRoot: ft.PiecesRootAsByteArray(),
+                       PathUtf8:      append([]string(nil), path...),
+                       PiecesRoot:    ft.PiecesRootAsByteArray(),
+                       TorrentOffset: *offset,
                })
+               *offset += (ft.File.Length + pieceLength - 1) / pieceLength * pieceLength
        }
 }
 
index 66ee2da8b808f66f6c8916de657b80c1a904b63a..25c262529b5b94aa13ecd41075c7244ada081cd6 100644 (file)
@@ -18,7 +18,8 @@ type FileInfo struct {
 
        // BEP 52. This isn't encoded in a v1 FileInfo, but is exposed here for APIs that expect to deal
        // v1 files.
-       PiecesRoot g.Option[[32]byte] `bencode:"-"`
+       PiecesRoot    g.Option[[32]byte] `bencode:"-"`
+       TorrentOffset int64              `bencode:"-"`
 }
 
 func (fi *FileInfo) DisplayPath(info *Info) string {
index d1b54d44d61a93e8087fe53641dd886a0b5739bb..8b8749c7c13219b257be72257464771d652cf167 100644 (file)
@@ -155,7 +155,7 @@ func (info *Info) IsDir() bool {
 // single and multi-file torrent infos.
 func (info *Info) UpvertedFiles() (files []FileInfo) {
        if info.HasV2() {
-               info.FileTree.UpvertedFiles(nil, func(fi FileInfo) {
+               info.FileTree.upvertedFiles(info.PieceLength, func(fi FileInfo) {
                        files = append(files, fi)
                })
                return
index c7377f5db643b9e372010c7e7f39043316495a24..4972e529267e4f2bb3901dbb5c41ecb49fac6b93 100644 (file)
@@ -13,7 +13,7 @@ func (p Piece) Length() int64 {
                pieceLength := p.Info.PieceLength
                lastFileEnd := int64(0)
                done := false
-               p.Info.FileTree.UpvertedFiles(nil, func(fi FileInfo) {
+               p.Info.FileTree.upvertedFiles(pieceLength, func(fi FileInfo) {
                        if done {
                                return
                        }
index 90e77ce0d7eb21d98cc4300f5fcfdde856971c29..3870042589446957782e141c958b6aaad7fb0ada 100644 (file)
@@ -4,16 +4,6 @@ type Int = int64
 
 type Length = Int
 
-func min(i Int, rest ...Int) Int {
-       ret := i
-       for _, i := range rest {
-               if i < ret {
-                       ret = i
-               }
-       }
-       return ret
-}
-
 type Extent struct {
        Start, Length Int
 }
@@ -23,10 +13,12 @@ func (e Extent) End() Int {
 }
 
 type (
-       Callback   = func(int, Extent) bool
+       Callback   = func(segmentIndex int, segmentBounds Extent) bool
        LengthIter = func() (Length, bool)
 )
 
+// Returns true if callback returns false early, or all segments in the haystack for the needle are
+// found.
 func Scan(haystack LengthIter, needle Extent, callback Callback) bool {
        i := 0
        for needle.Length != 0 {
diff --git a/spec.go b/spec.go
index 49a1104edec007bae6c1fc4562fdd04f30c42247..f54b325b5cee9708da43656aade5a21ffb5094dc 100644 (file)
--- a/spec.go
+++ b/spec.go
@@ -71,13 +71,13 @@ func TorrentSpecFromMetaInfoErr(mi *metainfo.MetaInfo) (*TorrentSpec, error) {
        if err != nil {
                err = fmt.Errorf("unmarshalling info: %w", err)
        }
-       v1Ih := mi.HashInfoBytes()
+       var v1Ih metainfo.Hash
+       if info.HasV1() {
+               v1Ih = mi.HashInfoBytes()
+       }
        var v2Infohash g.Option[infohash_v2.T]
        if info.HasV2() {
                v2Infohash.Set(infohash_v2.HashBytes(mi.InfoBytes))
-               if !info.HasV1() {
-                       v1Ih = *v2Infohash.Value.ToShort()
-               }
        }
 
        return &TorrentSpec{
index e7b579b3c0e89a38d4bc5fc72cf533b054c56f82..64e8066012ca015c50f32dc52e46c06035fc572b 100644 (file)
@@ -2489,11 +2489,15 @@ func (t *Torrent) dropBannedPeers() {
 
 func (t *Torrent) pieceHasher(index pieceIndex) {
        p := t.piece(index)
+       // Do we really need to spell out that it's a copy error? If it's a failure to hash the hash
+       // will just be wrong.
        correct, failedPeers, copyErr := t.hashPiece(index)
        switch copyErr {
        case nil, io.EOF:
        default:
-               log.Fmsg("piece %v (%s) hash failure copy error: %v", p, p.hash.HexString(), copyErr).Log(t.logger)
+               t.logger.Levelf(
+                       log.Warning,
+                       "error hashing piece %v: %v", index, copyErr)
        }
        t.storageLock.RUnlock()
        t.cl.lock()