fix bug where a file containing duplicate blocks would fail to be read properly
Jeromy committed
Dec 14, 2014 at 23:55 UTC
79efd424d1725f2124d75048a7297a0b91db7758
2 files changed
+85
merkledag/merkledag.go
+7
@@ -332,6 +332,13 @@ func (ds *dagService) GetDAG(ctx context.Context, root *Node) <-chan *Node {
332
break
333
}
334
nodes[i] = nd
335
+ for { //Check for duplicate links
336
+ ni, err := FindLink(root, blk.Key(), nodes)
337
+ if err != nil {
338
+ break
339
+ }
340
+ nodes[ni] = nd
341
+ }
342
343
if next == i {
344
sig <- nd
merkledag/merkledag_test.go
+78
@@ -75,6 +75,25 @@ func makeTestDag(t *testing.T) *Node {
75
return root
76
}
77
78
+type devZero struct{}
79
+
80
+func (_ devZero) Read(b []byte) (int, error) {
81
+ for i, _ := range b {
82
+ b[i] = 0
83
+ }
84
+ return len(b), nil
85
+}
86
+
87
+func makeZeroDag(t *testing.T) *Node {
88
+ read := io.LimitReader(devZero{}, 1024*32)
89
+ spl := &chunk.SizeSplitter{512}
90
+ root, err := imp.NewDagFromReaderWithSplitter(read, spl)
91
+ if err != nil {
92
+ t.Fatal(err)
93
+ }
94
+ return root
95
+}
96
+
97
func TestBatchFetch(t *testing.T) {
98
var dagservs []DAGService
99
for _, bsi := range blockservice.Mocks(t, 5) {
@@ -133,3 +152,62 @@ func TestBatchFetch(t *testing.T) {
152
<-done
153
}
154
}
155
+
156
+func TestBatchFetchDupBlock(t *testing.T) {
157
+ var dagservs []DAGService
158
+ for _, bsi := range blockservice.Mocks(t, 5) {
159
+ dagservs = append(dagservs, NewDAGService(bsi))
160
+ }
161
+ t.Log("finished setup.")
162
+
163
+ root := makeZeroDag(t)
164
+ read, err := uio.NewDagReader(root, nil)
165
+ if err != nil {
166
+ t.Fatal(err)
167
+ }
168
+ expected, err := ioutil.ReadAll(read)
169
+ if err != nil {
170
+ t.Fatal(err)
171
+ }
172
+
173
+ err = dagservs[0].AddRecursive(root)
174
+ if err != nil {
175
+ t.Fatal(err)
176
+ }
177
+
178
+ t.Log("Added file to first node.")
179
+
180
+ k, err := root.Key()
181
+ if err != nil {
182
+ t.Fatal(err)
183
+ }
184
+
185
+ done := make(chan struct{})
186
+ for i := 1; i < len(dagservs); i++ {
187
+ go func(i int) {
188
+ first, err := dagservs[i].Get(k)
189
+ if err != nil {
190
+ t.Fatal(err)
191
+ }
192
+ fmt.Println("Got first node back.")
193
+
194
+ read, err := uio.NewDagReader(first, dagservs[i])
195
+ if err != nil {
196
+ t.Fatal(err)
197
+ }
198
+ datagot, err := ioutil.ReadAll(read)
199
+ if err != nil {
200
+ t.Fatal(err)
201
+ }
202
+
203
+ if !bytes.Equal(datagot, expected) {
204
+ t.Fatal("Got bad data back!")
205
+ }
206
+ done <- struct{}{}
207
+ }(i)
208
+ }
209
+
210
+ for i := 1; i < len(dagservs); i++ {
211
+ <-done
212
+ }
213
+}