@cryptotaxi247 / kubo / commits / 79efd424d

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 +}