From 794c1c69d2b5d5a7136b386173ac7754f94c297d Mon Sep 17 00:00:00 2001
From: Vlad <vlad@celestia.org>
Date: Fri, 5 Jan 2024 15:22:58 +0700
Subject: [PATCH] Allow reconstructSome to reconstruct parity shards

---
 leopard.go          |  2 +-
 leopard8.go         |  2 +-
 reedsolomon.go      | 18 +++++++++---------
 reedsolomon_test.go | 22 ++++++++++++++++++++--
 4 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/leopard.go b/leopard.go
index b55eddd5..8585e475 100644
--- a/leopard.go
+++ b/leopard.go
@@ -333,7 +333,7 @@ func (r *leopardFF16) Split(data []byte) ([][]byte, error) {
 }
 
 func (r *leopardFF16) ReconstructSome(shards [][]byte, required []bool) error {
-	return r.ReconstructData(shards)
+	return r.Reconstruct(shards)
 }
 
 func (r *leopardFF16) Reconstruct(shards [][]byte) error {
diff --git a/leopard8.go b/leopard8.go
index ae297672..5fead4de 100644
--- a/leopard8.go
+++ b/leopard8.go
@@ -369,7 +369,7 @@ func (r *leopardFF8) Split(data []byte) ([][]byte, error) {
 }
 
 func (r *leopardFF8) ReconstructSome(shards [][]byte, required []bool) error {
-	return r.ReconstructData(shards)
+	return r.Reconstruct(shards)
 }
 
 func (r *leopardFF8) Reconstruct(shards [][]byte) error {
diff --git a/reedsolomon.go b/reedsolomon.go
index bd82015f..f41b4d6b 100644
--- a/reedsolomon.go
+++ b/reedsolomon.go
@@ -65,7 +65,7 @@ type Encoder interface {
 	// Given a list of shards, some of which contain data, fills in the
 	// data shards that don't have data.
 	//
-	// The length of the array must be equal to Shards.
+	// The length of the array must be equal to TotalShards.
 	// You indicate that a shard is missing by setting it to nil or zero-length.
 	// If a shard is zero-length but has sufficient capacity, that memory will
 	// be used, otherwise a new []byte will be allocated.
@@ -77,11 +77,11 @@ type Encoder interface {
 	// calling the Verify function is likely to fail.
 	ReconstructData(shards [][]byte) error
 
-	// ReconstructSome will recreate only requested data shards, if possible.
+	// ReconstructSome will recreate only requested shards, if possible.
 	//
 	// Given a list of shards, some of which contain data, fills in the
-	// data shards indicated by true values in the "required" parameter.
-	// The length of "required" array must be equal to DataShards.
+	// shards indicated by true values in the "required" parameter.
+	// The length of "required" array must be equal to Shards.
 	//
 	// The length of "shards" array must be equal to Shards.
 	// You indicate that a shard is missing by setting it to nil or zero-length.
@@ -1402,11 +1402,11 @@ func (r *reedSolomon) ReconstructData(shards [][]byte) error {
 	return r.reconstruct(shards, true, nil)
 }
 
-// ReconstructSome will recreate only requested data shards, if possible.
+// ReconstructSome will recreate only requested shards, if possible.
 //
-// Given a list of shards, some of which contain data, fills in the
-// data shards indicated by true values in the "required" parameter.
-// The length of "required" array must be equal to dataShards.
+// Given a list of shards, fills in the shards
+// indicated by true values in the "required" parameter.
+// The length of "required" array must be equal to TotalShards.
 //
 // The length of "shards" array must be equal to shards.
 // You indicate that a shard is missing by setting it to nil or zero-length.
@@ -1419,7 +1419,7 @@ func (r *reedSolomon) ReconstructData(shards [][]byte) error {
 // As the reconstructed shard set may contain missing parity shards,
 // calling the Verify function is likely to fail.
 func (r *reedSolomon) ReconstructSome(shards [][]byte, required []bool) error {
-	return r.reconstruct(shards, true, required)
+	return r.reconstruct(shards, false, required)
 }
 
 // reconstruct will recreate the missing data totalShards, and unless
diff --git a/reedsolomon_test.go b/reedsolomon_test.go
index 2932787c..a1745a35 100644
--- a/reedsolomon_test.go
+++ b/reedsolomon_test.go
@@ -826,8 +826,26 @@ func testReconstructData(t *testing.T, o ...Option) {
 		t.Fatal(err)
 	}
 
-	// Reconstruct 3 shards with 3 data and 5 parity shards
+	// Reconstruct parity shards from data
 	shardsCopy := make([][]byte, 13)
+	for i := 0; i < 8; i++ {
+		shardsCopy[i] = shards[i]
+	}
+
+	shardsRequired := make([]bool, 13)
+	shardsRequired[10] = true
+
+	err = r.ReconstructSome(shardsCopy, shardsRequired)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if !bytes.Equal(shardsCopy[10], shards[10]) {
+		t.Fatal("ReconstructSome did not reconstruct required shards correctly")
+	}
+
+	// Reconstruct 3 shards with 3 data and 5 parity shards
+	shardsCopy = make([][]byte, 13)
 	copy(shardsCopy, shards)
 	shardsCopy[2] = nil
 	shardsCopy[3] = nil
@@ -835,7 +853,7 @@ func testReconstructData(t *testing.T, o ...Option) {
 	shardsCopy[5] = nil
 	shardsCopy[6] = nil
 
-	shardsRequired := make([]bool, 8)
+	shardsRequired = make([]bool, 8)
 	shardsRequired[3] = true
 	shardsRequired[4] = true
 	err = r.ReconstructSome(shardsCopy, shardsRequired)