]> Cypherpunks.ru repositories - nncp.git/commitdiff
Sequential MTH optimization
authorSergey Matveev <stargrave@stargrave.org>
Thu, 8 Jul 2021 16:52:26 +0000 (19:52 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Thu, 8 Jul 2021 17:14:42 +0000 (20:14 +0300)
doc/news.ru.texi
doc/news.texi
src/check.go
src/cmd/nncp-hash/main.go
src/mth.go
src/mth_test.go
src/sp.go

index 4f87e6407e92eeb7c795f6b42735f5cf1aff66c4..eeaca1ec4101f1603f1f7f527d6fde044753e93b 100644 (file)
 Не отправлять multicast пакет оригинатору сообщения, очевидно точно
 видящего свой собственный пакет.
 
 Не отправлять multicast пакет оригинатору сообщения, очевидно точно
 видящего свой собственный пакет.
 
+@item
+Намного меньшее потребление памяти во время MTH хэширования когда
+смещение равно нулю: когда пакет не является докачиванием, а например
+проверяется @command{nncp-check} командой.
+
 @end itemize
 
 @node Релиз 7.1.1
 @end itemize
 
 @node Релиз 7.1.1
index ba822d2b08c58209b0f93522c21b8baa01f565bb..adf538b1d8c4079d29dd6f000901a21f8249e289 100644 (file)
@@ -18,6 +18,11 @@ route, then do not ignore, but use it.
 Do not relay multicast packet to area message's originator, that
 obviously has seen its own packet.
 
 Do not relay multicast packet to area message's originator, that
 obviously has seen its own packet.
 
+@item
+Much less memory usage during MTH hashing when offset is zero: when
+packet is not resumed, but for example checked with @command{nncp-check}
+command.
+
 @end itemize
 
 @node Release 7_1_1
 @end itemize
 
 @node Release 7_1_1
index 4f0a081479c9e12b3e6a56beae33028ac12c7155..7a3d5b8041a42a11059b763a5a2ac3e285c54646 100644 (file)
@@ -79,7 +79,7 @@ func (ctx *Ctx) Check(nodeId *NodeId) bool {
        return !(ctx.checkXxIsBad(nodeId, TRx) || ctx.checkXxIsBad(nodeId, TTx))
 }
 
        return !(ctx.checkXxIsBad(nodeId, TRx) || ctx.checkXxIsBad(nodeId, TTx))
 }
 
-func (ctx *Ctx) CheckNoCK(nodeId *NodeId, hshValue *[MTHSize]byte, mth *MTH) (int64, error) {
+func (ctx *Ctx) CheckNoCK(nodeId *NodeId, hshValue *[MTHSize]byte, mth MTH) (int64, error) {
        dirToSync := filepath.Join(ctx.Spool, nodeId.String(), string(TRx))
        pktName := Base32Codec.EncodeToString(hshValue[:])
        pktPath := filepath.Join(dirToSync, pktName)
        dirToSync := filepath.Join(ctx.Spool, nodeId.String(), string(TRx))
        pktName := Base32Codec.EncodeToString(hshValue[:])
        pktPath := filepath.Join(dirToSync, pktName)
@@ -103,7 +103,7 @@ func (ctx *Ctx) CheckNoCK(nodeId *NodeId, hshValue *[MTHSize]byte, mth *MTH) (in
        if mth == nil {
                gut, err = Check(fd, size, hshValue[:], les, ctx.ShowPrgrs)
        } else {
        if mth == nil {
                gut, err = Check(fd, size, hshValue[:], les, ctx.ShowPrgrs)
        } else {
-               mth.PktName = pktName
+               mth.SetPktName(pktName)
                if _, err = mth.PrependFrom(bufio.NewReaderSize(fd, MTHSize)); err != nil {
                        return 0, err
                }
                if _, err = mth.PrependFrom(bufio.NewReaderSize(fd, MTHSize)); err != nil {
                        return 0, err
                }
index ba0723221bc856e2f2a8822e46aa484ebb8c9a74..8b90ab9c0cc5eda0dbf6e1b3bcf309f96fc6c4f7 100644 (file)
@@ -42,6 +42,7 @@ func main() {
        var (
                fn        = flag.String("file", "", "Read the file instead of stdin")
                seek      = flag.Uint64("seek", 0, "Seek the file, hash, rewind, hash remaining")
        var (
                fn        = flag.String("file", "", "Read the file instead of stdin")
                seek      = flag.Uint64("seek", 0, "Seek the file, hash, rewind, hash remaining")
+               forceFat  = flag.Bool("force-fat", false, "Force MTHFat implementation usage")
                showPrgrs = flag.Bool("progress", false, "Progress showing")
                debug     = flag.Bool("debug", false, "Print MTH steps calculations")
                version   = flag.Bool("version", false, "Print version information")
                showPrgrs = flag.Bool("progress", false, "Progress showing")
                debug     = flag.Bool("debug", false, "Print MTH steps calculations")
                version   = flag.Bool("version", false, "Print version information")
@@ -75,15 +76,20 @@ func main() {
                }
                size = fi.Size()
        }
                }
                size = fi.Size()
        }
-       mth := nncp.MTHNew(size, int64(*seek))
+       var mth nncp.MTH
+       if *forceFat {
+               mth = nncp.MTHFatNew(size, int64(*seek))
+       } else {
+               mth = nncp.MTHNew(size, int64(*seek))
+       }
        var debugger sync.WaitGroup
        if *debug {
                fmt.Println("Leaf BLAKE3 key:", hex.EncodeToString(nncp.MTHLeafKey[:]))
                fmt.Println("Node BLAKE3 key:", hex.EncodeToString(nncp.MTHNodeKey[:]))
        var debugger sync.WaitGroup
        if *debug {
                fmt.Println("Leaf BLAKE3 key:", hex.EncodeToString(nncp.MTHLeafKey[:]))
                fmt.Println("Node BLAKE3 key:", hex.EncodeToString(nncp.MTHNodeKey[:]))
-               mth.Events = make(chan nncp.MTHEvent)
+               events := mth.Events()
                debugger.Add(1)
                go func() {
                debugger.Add(1)
                go func() {
-                       for e := range mth.Events {
+                       for e := range events {
                                var t string
                                switch e.Type {
                                case nncp.MTHEventAppend:
                                var t string
                                switch e.Type {
                                case nncp.MTHEventAppend:
@@ -121,7 +127,7 @@ func main() {
                        log.Fatalln(err)
                }
                if *showPrgrs {
                        log.Fatalln(err)
                }
                if *showPrgrs {
-                       mth.PktName = *fn
+                       mth.SetPktName(*fn)
                }
                if _, err = mth.PrependFrom(bufio.NewReaderSize(fd, nncp.MTHBlockSize)); err != nil {
                        log.Fatalln(err)
                }
                if _, err = mth.PrependFrom(bufio.NewReaderSize(fd, nncp.MTHBlockSize)); err != nil {
                        log.Fatalln(err)
index 6cb1f3640b6f180fa363f6b8c9b7664f4ff0787a..a766925cee3b6e9b3db90a679486bc97d5fc3103 100644 (file)
@@ -20,6 +20,7 @@ package nncp
 import (
        "bytes"
        "errors"
 import (
        "bytes"
        "errors"
+       "hash"
        "io"
 
        "lukechampine.com/blake3"
        "io"
 
        "lukechampine.com/blake3"
@@ -50,21 +51,29 @@ type MTHEvent struct {
        Hsh   []byte
 }
 
        Hsh   []byte
 }
 
-type MTH struct {
+type MTH interface {
+       hash.Hash
+       PrependFrom(r io.Reader) (int, error)
+       SetPktName(n string)
+       PrependSize() int64
+       Events() chan MTHEvent
+}
+
+type MTHFat struct {
        size        int64
        size        int64
-       PrependSize int64
+       prependSize int64
        skip        int64
        skipped     bool
        hasher      *blake3.Hasher
        hashes      [][MTHSize]byte
        buf         *bytes.Buffer
        finished    bool
        skip        int64
        skipped     bool
        hasher      *blake3.Hasher
        hashes      [][MTHSize]byte
        buf         *bytes.Buffer
        finished    bool
-       Events      chan MTHEvent
-       PktName     string
+       events      chan MTHEvent
+       pktName     string
 }
 
 }
 
-func MTHNew(size, offset int64) *MTH {
-       mth := MTH{
+func MTHFatNew(size, offset int64) MTH {
+       mth := MTHFat{
                hasher: blake3.New(MTHSize, MTHLeafKey[:]),
                buf:    bytes.NewBuffer(make([]byte, 0, 2*MTHBlockSize)),
        }
                hasher: blake3.New(MTHSize, MTHLeafKey[:]),
                buf:    bytes.NewBuffer(make([]byte, 0, 2*MTHBlockSize)),
        }
@@ -86,19 +95,28 @@ func MTHNew(size, offset int64) *MTH {
                skip = size - offset
        }
        mth.size = size
                skip = size - offset
        }
        mth.size = size
-       mth.PrependSize = prependSize
+       mth.prependSize = prependSize
        mth.skip = skip
        mth.hashes = make([][MTHSize]byte, prepends, 1+size/MTHBlockSize)
        return &mth
 }
 
        mth.skip = skip
        mth.hashes = make([][MTHSize]byte, prepends, 1+size/MTHBlockSize)
        return &mth
 }
 
-func (mth *MTH) Reset() { panic("not implemented") }
+func (mth *MTHFat) Events() chan MTHEvent {
+       mth.events = make(chan MTHEvent)
+       return mth.events
+}
+
+func (mth *MTHFat) SetPktName(pktName string) { mth.pktName = pktName }
+
+func (mth *MTHFat) PrependSize() int64 { return mth.prependSize }
 
 
-func (mth *MTH) Size() int { return MTHSize }
+func (mth *MTHFat) Reset() { panic("not implemented") }
 
 
-func (mth *MTH) BlockSize() int { return MTHBlockSize }
+func (mth *MTHFat) Size() int { return MTHSize }
 
 
-func (mth *MTH) Write(data []byte) (int, error) {
+func (mth *MTHFat) BlockSize() int { return MTHBlockSize }
+
+func (mth *MTHFat) Write(data []byte) (int, error) {
        if mth.finished {
                return 0, errors.New("already Sum()ed")
        }
        if mth.finished {
                return 0, errors.New("already Sum()ed")
        }
@@ -118,8 +136,8 @@ func (mth *MTH) Write(data []byte) (int, error) {
                mth.hasher.Sum(h[:0])
                mth.hasher.Reset()
                mth.hashes = append(mth.hashes, *h)
                mth.hasher.Sum(h[:0])
                mth.hasher.Reset()
                mth.hashes = append(mth.hashes, *h)
-               if mth.Events != nil {
-                       mth.Events <- MTHEvent{
+               if mth.events != nil {
+                       mth.events <- MTHEvent{
                                MTHEventAppend,
                                0, len(mth.hashes) - 1,
                                mth.hashes[len(mth.hashes)-1][:],
                                MTHEventAppend,
                                0, len(mth.hashes) - 1,
                                mth.hashes[len(mth.hashes)-1][:],
@@ -129,19 +147,19 @@ func (mth *MTH) Write(data []byte) (int, error) {
        return n, err
 }
 
        return n, err
 }
 
-func (mth *MTH) PrependFrom(r io.Reader) (int, error) {
+func (mth *MTHFat) PrependFrom(r io.Reader) (int, error) {
        if mth.finished {
                return 0, errors.New("already Sum()ed")
        }
        var err error
        buf := make([]byte, MTHBlockSize)
        var i, n, read int
        if mth.finished {
                return 0, errors.New("already Sum()ed")
        }
        var err error
        buf := make([]byte, MTHBlockSize)
        var i, n, read int
-       fullsize := mth.PrependSize
-       les := LEs{{"Pkt", mth.PktName}, {"FullSize", fullsize}, {"Size", 0}}
-       for mth.PrependSize >= MTHBlockSize {
+       fullsize := mth.prependSize
+       les := LEs{{"Pkt", mth.pktName}, {"FullSize", fullsize}, {"Size", 0}}
+       for mth.prependSize >= MTHBlockSize {
                n, err = io.ReadFull(r, buf)
                read += n
                n, err = io.ReadFull(r, buf)
                read += n
-               mth.PrependSize -= MTHBlockSize
+               mth.prependSize -= MTHBlockSize
                if err != nil {
                        return read, err
                }
                if err != nil {
                        return read, err
                }
@@ -150,30 +168,30 @@ func (mth *MTH) PrependFrom(r io.Reader) (int, error) {
                }
                mth.hasher.Sum(mth.hashes[i][:0])
                mth.hasher.Reset()
                }
                mth.hasher.Sum(mth.hashes[i][:0])
                mth.hasher.Reset()
-               if mth.Events != nil {
-                       mth.Events <- MTHEvent{MTHEventPrepend, 0, i, mth.hashes[i][:]}
+               if mth.events != nil {
+                       mth.events <- MTHEvent{MTHEventPrepend, 0, i, mth.hashes[i][:]}
                }
                }
-               if mth.PktName != "" {
+               if mth.pktName != "" {
                        les[len(les)-1].V = int64(read)
                        Progress("check", les)
                }
                i++
        }
                        les[len(les)-1].V = int64(read)
                        Progress("check", les)
                }
                i++
        }
-       if mth.PrependSize > 0 {
-               n, err = io.ReadFull(r, buf[:mth.PrependSize])
+       if mth.prependSize > 0 {
+               n, err = io.ReadFull(r, buf[:mth.prependSize])
                read += n
                if err != nil {
                        return read, err
                }
                read += n
                if err != nil {
                        return read, err
                }
-               if _, err = mth.hasher.Write(buf[:mth.PrependSize]); err != nil {
+               if _, err = mth.hasher.Write(buf[:mth.prependSize]); err != nil {
                        panic(err)
                }
                mth.hasher.Sum(mth.hashes[i][:0])
                mth.hasher.Reset()
                        panic(err)
                }
                mth.hasher.Sum(mth.hashes[i][:0])
                mth.hasher.Reset()
-               if mth.Events != nil {
-                       mth.Events <- MTHEvent{MTHEventPrepend, 0, i, mth.hashes[i][:]}
+               if mth.events != nil {
+                       mth.events <- MTHEvent{MTHEventPrepend, 0, i, mth.hashes[i][:]}
                }
                }
-               if mth.PktName != "" {
+               if mth.pktName != "" {
                        les[len(les)-1].V = fullsize
                        Progress("check", les)
                }
                        les[len(les)-1].V = fullsize
                        Progress("check", les)
                }
@@ -181,7 +199,7 @@ func (mth *MTH) PrependFrom(r io.Reader) (int, error) {
        return read, nil
 }
 
        return read, nil
 }
 
-func (mth *MTH) Sum(b []byte) []byte {
+func (mth *MTHFat) Sum(b []byte) []byte {
        if mth.finished {
                return append(b, mth.hashes[0][:]...)
        }
        if mth.finished {
                return append(b, mth.hashes[0][:]...)
        }
@@ -194,8 +212,8 @@ func (mth *MTH) Sum(b []byte) []byte {
                mth.hasher.Sum(h[:0])
                mth.hasher.Reset()
                mth.hashes = append(mth.hashes, *h)
                mth.hasher.Sum(h[:0])
                mth.hasher.Reset()
                mth.hashes = append(mth.hashes, *h)
-               if mth.Events != nil {
-                       mth.Events <- MTHEvent{
+               if mth.events != nil {
+                       mth.events <- MTHEvent{
                                MTHEventAppend,
                                0, len(mth.hashes) - 1,
                                mth.hashes[len(mth.hashes)-1][:],
                                MTHEventAppend,
                                0, len(mth.hashes) - 1,
                                mth.hashes[len(mth.hashes)-1][:],
@@ -211,14 +229,14 @@ func (mth *MTH) Sum(b []byte) []byte {
                mth.hasher.Sum(h[:0])
                mth.hasher.Reset()
                mth.hashes = append(mth.hashes, *h)
                mth.hasher.Sum(h[:0])
                mth.hasher.Reset()
                mth.hashes = append(mth.hashes, *h)
-               if mth.Events != nil {
-                       mth.Events <- MTHEvent{MTHEventAppend, 0, 0, mth.hashes[0][:]}
+               if mth.events != nil {
+                       mth.events <- MTHEvent{MTHEventAppend, 0, 0, mth.hashes[0][:]}
                }
                fallthrough
        case 1:
                mth.hashes = append(mth.hashes, mth.hashes[0])
                }
                fallthrough
        case 1:
                mth.hashes = append(mth.hashes, mth.hashes[0])
-               if mth.Events != nil {
-                       mth.Events <- MTHEvent{MTHEventAppend, 0, 1, mth.hashes[1][:]}
+               if mth.events != nil {
+                       mth.events <- MTHEvent{MTHEventAppend, 0, 1, mth.hashes[1][:]}
                }
        }
        mth.hasher = blake3.New(MTHSize, MTHNodeKey[:])
                }
        }
        mth.hasher = blake3.New(MTHSize, MTHNodeKey[:])
@@ -237,8 +255,8 @@ func (mth *MTH) Sum(b []byte) []byte {
                        mth.hasher.Sum(h[:0])
                        mth.hasher.Reset()
                        hashesUp = append(hashesUp, *h)
                        mth.hasher.Sum(h[:0])
                        mth.hasher.Reset()
                        hashesUp = append(hashesUp, *h)
-                       if mth.Events != nil {
-                               mth.Events <- MTHEvent{
+                       if mth.events != nil {
+                               mth.events <- MTHEvent{
                                        MTHEventFold,
                                        level, len(hashesUp) - 1,
                                        hashesUp[len(hashesUp)-1][:],
                                        MTHEventFold,
                                        level, len(hashesUp) - 1,
                                        hashesUp[len(hashesUp)-1][:],
@@ -247,8 +265,8 @@ func (mth *MTH) Sum(b []byte) []byte {
                }
                if len(mth.hashes)%2 == 1 {
                        hashesUp = append(hashesUp, mth.hashes[len(mth.hashes)-1])
                }
                if len(mth.hashes)%2 == 1 {
                        hashesUp = append(hashesUp, mth.hashes[len(mth.hashes)-1])
-                       if mth.Events != nil {
-                               mth.Events <- MTHEvent{
+                       if mth.events != nil {
+                               mth.events <- MTHEvent{
                                        MTHEventAppend,
                                        level, len(hashesUp) - 1,
                                        hashesUp[len(hashesUp)-1][:],
                                        MTHEventAppend,
                                        level, len(hashesUp) - 1,
                                        hashesUp[len(hashesUp)-1][:],
@@ -259,8 +277,170 @@ func (mth *MTH) Sum(b []byte) []byte {
                level++
        }
        mth.finished = true
                level++
        }
        mth.finished = true
-       if mth.Events != nil {
-               close(mth.Events)
+       if mth.events != nil {
+               close(mth.events)
        }
        return append(b, mth.hashes[0][:]...)
 }
        }
        return append(b, mth.hashes[0][:]...)
 }
+
+type MTHSeqEnt struct {
+       l int
+       h [MTHSize]byte
+}
+
+type MTHSeq struct {
+       hasherLeaf *blake3.Hasher
+       hasherNode *blake3.Hasher
+       hashes     []MTHSeqEnt
+       buf        *bytes.Buffer
+       events     chan MTHEvent
+       ctrs       []int
+       finished   bool
+}
+
+func MTHSeqNew() *MTHSeq {
+       mth := MTHSeq{
+               hasherLeaf: blake3.New(MTHSize, MTHLeafKey[:]),
+               hasherNode: blake3.New(MTHSize, MTHNodeKey[:]),
+               buf:        bytes.NewBuffer(make([]byte, 0, 2*MTHBlockSize)),
+               ctrs:       make([]int, 1, 2),
+       }
+       return &mth
+}
+
+func (mth *MTHSeq) Reset() { panic("not implemented") }
+
+func (mth *MTHSeq) Size() int { return MTHSize }
+
+func (mth *MTHSeq) BlockSize() int { return MTHBlockSize }
+
+func (mth *MTHSeq) PrependFrom(r io.Reader) (int, error) {
+       panic("must not reach that code")
+}
+
+func (mth *MTHSeq) Events() chan MTHEvent {
+       mth.events = make(chan MTHEvent)
+       return mth.events
+}
+
+func (mth *MTHSeq) SetPktName(pktName string) {}
+
+func (mth *MTHSeq) PrependSize() int64 { return 0 }
+
+func (mth *MTHSeq) leafAdd() {
+       ent := MTHSeqEnt{l: 0}
+       mth.hasherLeaf.Sum(ent.h[:0])
+       mth.hasherLeaf.Reset()
+       mth.hashes = append(mth.hashes, ent)
+       if mth.events != nil {
+               mth.events <- MTHEvent{
+                       MTHEventAppend, 0, mth.ctrs[0],
+                       mth.hashes[len(mth.hashes)-1].h[:],
+               }
+       }
+       mth.ctrs[0]++
+}
+
+func (mth *MTHSeq) incr(l int) {
+       if len(mth.ctrs) <= l {
+               mth.ctrs = append(mth.ctrs, 0)
+       } else {
+               mth.ctrs[l]++
+       }
+}
+
+func (mth *MTHSeq) fold() {
+       for len(mth.hashes) >= 2 {
+               if mth.hashes[len(mth.hashes)-2].l != mth.hashes[len(mth.hashes)-1].l {
+                       break
+               }
+               if _, err := mth.hasherNode.Write(mth.hashes[len(mth.hashes)-2].h[:]); err != nil {
+                       panic(err)
+               }
+               if _, err := mth.hasherNode.Write(mth.hashes[len(mth.hashes)-1].h[:]); err != nil {
+                       panic(err)
+               }
+               mth.hashes = mth.hashes[:len(mth.hashes)-1]
+               end := &mth.hashes[len(mth.hashes)-1]
+               end.l++
+               mth.incr(end.l)
+               mth.hasherNode.Sum(end.h[:0])
+               mth.hasherNode.Reset()
+               if mth.events != nil {
+                       mth.events <- MTHEvent{MTHEventFold, end.l, mth.ctrs[end.l], end.h[:]}
+               }
+       }
+}
+
+func (mth *MTHSeq) Write(data []byte) (int, error) {
+       if mth.finished {
+               return 0, errors.New("already Sum()ed")
+       }
+       n, err := mth.buf.Write(data)
+       if err != nil {
+               return n, err
+       }
+       for mth.buf.Len() >= MTHBlockSize {
+               if _, err = mth.hasherLeaf.Write(mth.buf.Next(MTHBlockSize)); err != nil {
+                       return n, err
+               }
+               mth.leafAdd()
+               mth.fold()
+       }
+       return n, err
+}
+
+func (mth *MTHSeq) Sum(b []byte) []byte {
+       if mth.finished {
+               return append(b, mth.hashes[0].h[:]...)
+       }
+       if mth.buf.Len() > 0 {
+               if _, err := mth.hasherLeaf.Write(mth.buf.Next(MTHBlockSize)); err != nil {
+                       panic(err)
+               }
+               mth.leafAdd()
+               mth.fold()
+       }
+       switch mth.ctrs[0] {
+       case 0:
+               if _, err := mth.hasherLeaf.Write(nil); err != nil {
+                       panic(err)
+               }
+               mth.leafAdd()
+               fallthrough
+       case 1:
+               mth.hashes = append(mth.hashes, mth.hashes[0])
+               mth.ctrs[0]++
+               if mth.events != nil {
+                       mth.events <- MTHEvent{
+                               MTHEventAppend, 0, mth.ctrs[0],
+                               mth.hashes[len(mth.hashes)-1].h[:],
+                       }
+               }
+               mth.fold()
+       }
+       for len(mth.hashes) >= 2 {
+               l := mth.hashes[len(mth.hashes)-2].l
+               mth.incr(l)
+               mth.hashes[len(mth.hashes)-1].l = l
+               if mth.events != nil {
+                       mth.events <- MTHEvent{
+                               MTHEventAppend, l, mth.ctrs[l],
+                               mth.hashes[len(mth.hashes)-1].h[:],
+                       }
+               }
+               mth.fold()
+       }
+       mth.finished = true
+       if mth.events != nil {
+               close(mth.events)
+       }
+       return append(b, mth.hashes[0].h[:]...)
+}
+
+func MTHNew(size, offset int64) MTH {
+       if offset == 0 {
+               return MTHSeqNew()
+       }
+       return MTHFatNew(size, offset)
+}
index 2d36f07a95067eb8f3eb9b52cf0cc50d3ce34acd..a4737c09d7efbf6399420ecefc25d04eed074703 100644 (file)
@@ -26,7 +26,7 @@ import (
        "lukechampine.com/blake3"
 )
 
        "lukechampine.com/blake3"
 )
 
-func TestMTHSymmetric(t *testing.T) {
+func TestMTHFatSymmetric(t *testing.T) {
        xof := blake3.New(32, nil).XOF()
        f := func(size uint32, offset uint32) bool {
                size %= 2 * 1024 * 1024
        xof := blake3.New(32, nil).XOF()
        f := func(size uint32, offset uint32) bool {
                size %= 2 * 1024 * 1024
@@ -36,13 +36,13 @@ func TestMTHSymmetric(t *testing.T) {
                }
                offset = offset % size
 
                }
                offset = offset % size
 
-               mth := MTHNew(int64(size), 0)
+               mth := MTHFatNew(int64(size), 0)
                if _, err := io.Copy(mth, bytes.NewReader(data)); err != nil {
                        panic(err)
                }
                hsh0 := mth.Sum(nil)
 
                if _, err := io.Copy(mth, bytes.NewReader(data)); err != nil {
                        panic(err)
                }
                hsh0 := mth.Sum(nil)
 
-               mth = MTHNew(int64(size), int64(offset))
+               mth = MTHFatNew(int64(size), int64(offset))
                if _, err := io.Copy(mth, bytes.NewReader(data[int(offset):])); err != nil {
                        panic(err)
                }
                if _, err := io.Copy(mth, bytes.NewReader(data[int(offset):])); err != nil {
                        panic(err)
                }
@@ -53,14 +53,14 @@ func TestMTHSymmetric(t *testing.T) {
                        return false
                }
 
                        return false
                }
 
-               mth = MTHNew(0, 0)
+               mth = MTHFatNew(0, 0)
                mth.Write(data)
                if bytes.Compare(hsh0, mth.Sum(nil)) != 0 {
                        return false
                }
 
                data = append(data, 0)
                mth.Write(data)
                if bytes.Compare(hsh0, mth.Sum(nil)) != 0 {
                        return false
                }
 
                data = append(data, 0)
-               mth = MTHNew(int64(size)+1, 0)
+               mth = MTHFatNew(int64(size)+1, 0)
                if _, err := io.Copy(mth, bytes.NewReader(data)); err != nil {
                        panic(err)
                }
                if _, err := io.Copy(mth, bytes.NewReader(data)); err != nil {
                        panic(err)
                }
@@ -69,7 +69,7 @@ func TestMTHSymmetric(t *testing.T) {
                        return false
                }
 
                        return false
                }
 
-               mth = MTHNew(int64(size)+1, int64(offset))
+               mth = MTHFatNew(int64(size)+1, int64(offset))
                if _, err := io.Copy(mth, bytes.NewReader(data[int(offset):])); err != nil {
                        panic(err)
                }
                if _, err := io.Copy(mth, bytes.NewReader(data[int(offset):])); err != nil {
                        panic(err)
                }
@@ -80,7 +80,7 @@ func TestMTHSymmetric(t *testing.T) {
                        return false
                }
 
                        return false
                }
 
-               mth = MTHNew(0, 0)
+               mth = MTHFatNew(0, 0)
                mth.Write(data)
                if bytes.Compare(hsh00, mth.Sum(nil)) != 0 {
                        return false
                mth.Write(data)
                if bytes.Compare(hsh00, mth.Sum(nil)) != 0 {
                        return false
@@ -93,10 +93,42 @@ func TestMTHSymmetric(t *testing.T) {
        }
 }
 
        }
 }
 
+func TestMTHSeqAndFatEqual(t *testing.T) {
+       xof := blake3.New(32, nil).XOF()
+       f := func(size uint32, offset uint32) bool {
+               size %= 10 * 1024 * 1024
+               data := make([]byte, int(size), int(size)+1)
+               if _, err := io.ReadFull(xof, data); err != nil {
+                       panic(err)
+               }
+               fat := MTHFatNew(int64(size), 0)
+               if _, err := io.Copy(fat, bytes.NewReader(data)); err != nil {
+                       panic(err)
+               }
+               hshFat := fat.Sum(nil)
+               seq := MTHSeqNew()
+               if _, err := io.Copy(seq, bytes.NewReader(data)); err != nil {
+                       panic(err)
+               }
+               return bytes.Compare(hshFat, seq.Sum(nil)) == 0
+       }
+       if err := quick.Check(f, nil); err != nil {
+               t.Error(err)
+       }
+}
+
 func TestMTHNull(t *testing.T) {
 func TestMTHNull(t *testing.T) {
-       mth := MTHNew(0, 0)
-       if _, err := mth.Write(nil); err != nil {
+       fat := MTHFatNew(0, 0)
+       if _, err := fat.Write(nil); err != nil {
                t.Error(err)
        }
                t.Error(err)
        }
-       mth.Sum(nil)
+       hshFat := fat.Sum(nil)
+
+       seq := MTHSeqNew()
+       if _, err := seq.Write(nil); err != nil {
+               t.Error(err)
+       }
+       if bytes.Compare(hshFat, seq.Sum(nil)) != 0 {
+               t.FailNow()
+       }
 }
 }
index a1f51ebf80276b143675159248c97514ba621494..1bb8f75d6e628b4b294f0b931dbdaf6d7af6b33c 100644 (file)
--- a/src/sp.go
+++ b/src/sp.go
@@ -41,14 +41,14 @@ const (
 )
 
 type MTHAndOffset struct {
 )
 
 type MTHAndOffset struct {
-       mth    *MTH
+       mth    MTH
        offset uint64
 }
 
 type SPCheckerTask struct {
        nodeId *NodeId
        hsh    *[MTHSize]byte
        offset uint64
 }
 
 type SPCheckerTask struct {
        nodeId *NodeId
        hsh    *[MTHSize]byte
-       mth    *MTH
+       mth    MTH
        done   chan []byte
 }
 
        done   chan []byte
 }
 
@@ -1439,7 +1439,7 @@ func (state *SPState) ProcessSP(payload []byte) ([][]byte, error) {
                        }
                        if hasherAndOffset != nil {
                                delete(state.fileHashers, filePath)
                        }
                        if hasherAndOffset != nil {
                                delete(state.fileHashers, filePath)
-                               if hasherAndOffset.mth.PrependSize == 0 {
+                               if hasherAndOffset.mth.PrependSize() == 0 {
                                        if bytes.Compare(hasherAndOffset.mth.Sum(nil), file.Hash[:]) != 0 {
                                                state.Ctx.LogE(
                                                        "sp-file-bad-checksum", lesp,
                                        if bytes.Compare(hasherAndOffset.mth.Sum(nil), file.Hash[:]) != 0 {
                                                state.Ctx.LogE(
                                                        "sp-file-bad-checksum", lesp,