diff --git a/lib/protocol/bep_extensions.go b/lib/protocol/bep_extensions.go index f5add40ab..76797c676 100644 --- a/lib/protocol/bep_extensions.go +++ b/lib/protocol/bep_extensions.go @@ -276,9 +276,11 @@ func PermsEqual(a, b uint32) bool { // BlocksEqual returns true when the two files have identical block lists. func (f FileInfo) BlocksEqual(other FileInfo) bool { - // If both sides have blocks hashes then we can just compare those. - if len(f.BlocksHash) > 0 && len(other.BlocksHash) > 0 { - return bytes.Equal(f.BlocksHash, other.BlocksHash) + // If both sides have blocks hashes and they match, we are good. If they + // don't match still check individual block hashes to catch differences + // in weak hashes only (e.g. after switching weak hash algo). + if len(f.BlocksHash) > 0 && len(other.BlocksHash) > 0 && bytes.Equal(f.BlocksHash, other.BlocksHash) { + return true } // Actually compare the block lists in full. @@ -382,6 +384,7 @@ func BlocksHash(bs []BlockInfo) []byte { h := sha256.New() for _, b := range bs { _, _ = h.Write(b.Hash) + _ = binary.Write(h, binary.BigEndian, b.WeakHash) } return h.Sum(nil) } diff --git a/lib/protocol/protocol_test.go b/lib/protocol/protocol_test.go index 380dddb2a..8d7ca4ad5 100644 --- a/lib/protocol/protocol_test.go +++ b/lib/protocol/protocol_test.go @@ -887,7 +887,8 @@ func TestBlocksEqual(t *testing.T) { {blocksOne, nil, blocksOne, nil, true}, // blocks compared {blocksOne, nil, blocksTwo, nil, false}, // blocks compared {blocksOne, hashOne, blocksTwo, hashOne, true}, // hashes equal, blocks not looked at - {blocksOne, hashOne, blocksOne, hashTwo, false}, // hashes different, blocks not looked at + {blocksOne, hashOne, blocksOne, hashTwo, true}, // hashes different, blocks compared + {blocksOne, hashOne, blocksTwo, hashTwo, false}, // hashes different, blocks compared {blocksOne, hashOne, nil, nil, false}, // blocks is different from no blocks {blocksOne, nil, nil, nil, false}, // blocks is different from no blocks {nil, hashOne, nil, nil, true}, // nil blocks are equal, even of one side has a hash