-
Notifications
You must be signed in to change notification settings - Fork 972
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
871 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package eds | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/celestiaorg/celestia-node/share/sharetest" | ||
) | ||
|
||
func TestExtendAxisHalf(t *testing.T) { | ||
shares := sharetest.RandShares(t, 16) | ||
|
||
original := AxisHalf{ | ||
Shares: shares, | ||
IsParity: false, | ||
} | ||
|
||
extended, err := original.Extended() | ||
require.NoError(t, err) | ||
require.Len(t, extended, len(shares)*2) | ||
|
||
parity := AxisHalf{ | ||
Shares: extended[len(shares):], | ||
IsParity: true, | ||
} | ||
|
||
parityExtended, err := parity.Extended() | ||
require.NoError(t, err) | ||
|
||
require.Equal(t, extended, parityExtended) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package file | ||
|
||
import ( | ||
"sync" | ||
|
||
"github.com/klauspost/reedsolomon" | ||
) | ||
|
||
var codec Codec | ||
|
||
func init() { | ||
codec = NewCodec() | ||
} | ||
|
||
type Codec interface { | ||
Encoder(len int) (reedsolomon.Encoder, error) | ||
} | ||
|
||
type codecCache struct { | ||
cache sync.Map | ||
} | ||
|
||
func NewCodec() Codec { | ||
return &codecCache{} | ||
} | ||
|
||
func (l *codecCache) Encoder(len int) (reedsolomon.Encoder, error) { | ||
enc, ok := l.cache.Load(len) | ||
if !ok { | ||
var err error | ||
enc, err = reedsolomon.New(len/2, len/2, reedsolomon.WithLeopardGF(true)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
l.cache.Store(len, enc) | ||
} | ||
return enc.(reedsolomon.Encoder), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package file | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/klauspost/reedsolomon" | ||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/celestiaorg/celestia-node/share/sharetest" | ||
) | ||
|
||
func BenchmarkCodec(b *testing.B) { | ||
minSize, maxSize := 32, 128 | ||
|
||
for size := minSize; size <= maxSize; size *= 2 { | ||
// BenchmarkCodec/Leopard/size:32-10 409194 2793 ns/op | ||
// BenchmarkCodec/Leopard/size:64-10 190969 6170 ns/op | ||
// BenchmarkCodec/Leopard/size:128-10 82821 14287 ns/op | ||
b.Run(fmt.Sprintf("Leopard/size:%v", size), func(b *testing.B) { | ||
enc, err := reedsolomon.New(size/2, size/2, reedsolomon.WithLeopardGF(true)) | ||
require.NoError(b, err) | ||
|
||
shards := newShards(b, size, true) | ||
|
||
b.ResetTimer() | ||
for i := 0; i < b.N; i++ { | ||
err = enc.Encode(shards) | ||
require.NoError(b, err) | ||
} | ||
}) | ||
|
||
// BenchmarkCodec/default/size:32-10 222153 5364 ns/op | ||
// BenchmarkCodec/default/size:64-10 58831 20349 ns/op | ||
// BenchmarkCodec/default/size:128-10 14940 80471 ns/op | ||
b.Run(fmt.Sprintf("default/size:%v", size), func(b *testing.B) { | ||
enc, err := reedsolomon.New(size/2, size/2, reedsolomon.WithLeopardGF(false)) | ||
require.NoError(b, err) | ||
|
||
shards := newShards(b, size, true) | ||
|
||
b.ResetTimer() | ||
for i := 0; i < b.N; i++ { | ||
err = enc.Encode(shards) | ||
require.NoError(b, err) | ||
} | ||
}) | ||
|
||
// BenchmarkCodec/default-reconstructSome/size:32-10 1263585 954.4 ns/op | ||
// BenchmarkCodec/default-reconstructSome/size:64-10 762273 1554 ns/op | ||
// BenchmarkCodec/default-reconstructSome/size:128-10 429268 2974 ns/op | ||
b.Run(fmt.Sprintf("default-reconstructSome/size:%v", size), func(b *testing.B) { | ||
enc, err := reedsolomon.New(size/2, size/2, reedsolomon.WithLeopardGF(false)) | ||
require.NoError(b, err) | ||
|
||
shards := newShards(b, size, false) | ||
targets := make([]bool, size) | ||
target := size - 2 | ||
targets[target] = true | ||
|
||
b.ResetTimer() | ||
for i := 0; i < b.N; i++ { | ||
err = enc.ReconstructSome(shards, targets) | ||
require.NoError(b, err) | ||
shards[target] = nil | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func newShards(b require.TestingT, size int, fillParity bool) [][]byte { | ||
shards := make([][]byte, size) | ||
original := sharetest.RandShares(b, size/2) | ||
copy(shards, original) | ||
|
||
if fillParity { | ||
// fill with parity empty Shares | ||
for j := len(original); j < len(shards); j++ { | ||
shards[j] = make([]byte, len(original[0])) | ||
} | ||
} | ||
return shards | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package file | ||
|
||
import ( | ||
"bytes" | ||
"encoding/binary" | ||
"fmt" | ||
"io" | ||
|
||
"github.com/celestiaorg/celestia-node/share" | ||
) | ||
|
||
const headerSize = 64 | ||
|
||
type header struct { | ||
version fileVersion | ||
fileType fileType | ||
|
||
// Taken directly from EDS | ||
shareSize uint16 | ||
squareSize uint16 | ||
|
||
datahash share.DataHash | ||
} | ||
|
||
type fileVersion uint8 | ||
|
||
const ( | ||
fileV0 fileVersion = iota | ||
) | ||
|
||
type fileType uint8 | ||
|
||
const ( | ||
ods fileType = iota | ||
q1q4 | ||
) | ||
|
||
func (h *header) WriteTo(w io.Writer) (int64, error) { | ||
b := bytes.NewBuffer(make([]byte, 0, headerSize)) | ||
_ = b.WriteByte(byte(h.version)) | ||
_ = b.WriteByte(byte(h.fileType)) | ||
_ = binary.Write(b, binary.LittleEndian, h.shareSize) | ||
_ = binary.Write(b, binary.LittleEndian, h.squareSize) | ||
_, _ = b.Write(h.datahash) | ||
// write padding | ||
_, _ = b.Write(make([]byte, headerSize-b.Len()-1)) | ||
return writeLenEncoded(w, b.Bytes()) | ||
} | ||
|
||
func readHeader(r io.Reader) (*header, error) { | ||
bytesHeader, err := readLenEncoded(r) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if len(bytesHeader) != headerSize-1 { | ||
return nil, fmt.Errorf("readHeader: read %d bytes, expected %d", len(bytesHeader), headerSize) | ||
} | ||
h := &header{ | ||
version: fileVersion(bytesHeader[0]), | ||
fileType: fileType(bytesHeader[1]), | ||
shareSize: binary.LittleEndian.Uint16(bytesHeader[2:4]), | ||
squareSize: binary.LittleEndian.Uint16(bytesHeader[4:6]), | ||
datahash: make([]byte, 32), | ||
} | ||
|
||
copy(h.datahash, bytesHeader[6:6+32]) | ||
return h, err | ||
} | ||
|
||
func writeLenEncoded(w io.Writer, data []byte) (int64, error) { | ||
_, err := w.Write([]byte{byte(len(data))}) | ||
if err != nil { | ||
return 0, err | ||
} | ||
return io.Copy(w, bytes.NewBuffer(data)) | ||
} | ||
|
||
func readLenEncoded(r io.Reader) ([]byte, error) { | ||
lenBuf := make([]byte, 1) | ||
_, err := io.ReadFull(r, lenBuf) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
data := make([]byte, lenBuf[0]) | ||
n, err := io.ReadFull(r, data) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if n != len(data) { | ||
return nil, fmt.Errorf("readLenEncoded: read %d bytes, expected %d", n, len(data)) | ||
} | ||
return data, nil | ||
} |
Oops, something went wrong.