diff --git a/da.go b/da.go index 175406c..63b821a 100644 --- a/da.go +++ b/da.go @@ -6,27 +6,19 @@ type DA interface { // // Error should be returned if ID is not formatted properly, there is no Blob for given ID or any other client-level // error occurred (dropped connection, timeout, etc). - Get(id ID) (Blob, error) + Get(ids []ID) ([]Blob, error) // Commit creates a Commitment for the given Blob. - Commit(blob Blob) (Commitment, error) + Commit(blobs []Blob) ([]Commitment, error) // Submit submits a Blob to Data Availability layer. // // This method is synchronous. Upon successful submission to Data Availability layer, it returns ID identifying blob // in DA and Proof of inclusion. - Submit(blob Blob) (ID, Proof, error) + Submit(blobs []Blob) ([]ID, []Proof, error) // Validate validates Commitment against Proof. This should be possible without retrieving Blob. - Validate(commit Commitment, proof Proof) (bool, error) -} - -// BatchDA is a batched version of DA interface. -type BatchDA interface { - Get(ids []ID) ([]Blob, error) - Commit(blobs []Blob) ([]Commitment, error) - Submit(blobs []Blob) ([]ID, []Proof, error) - Validate(commits []Commitment, proofs []Proof) ([]bool, error) + Validate(commits []ID, proofs []Proof) ([]bool, error) } // Blob is the data submitted/received from DA interface. diff --git a/da_test.go b/da_test.go index f24e1a5..ff0d3f6 100644 --- a/da_test.go +++ b/da_test.go @@ -18,21 +18,25 @@ func TestDummyDA(t *testing.T) { }) } +// TODO(tzdybal): how to get rid of this?! +type Blob = da.Blob +type ID = da.ID + func ExecuteDATest(t *testing.T, da da.DA) { msg1 := []byte("message 1") msg2 := []byte("message 2") - id1, proof1, err := da.Submit(msg1) + id1, proof1, err := da.Submit([]Blob{msg1}) assert.NoError(t, err) assert.NotEmpty(t, id1) assert.NotEmpty(t, proof1) - id2, proof2, err := da.Submit(msg2) + id2, proof2, err := da.Submit([]Blob{msg2}) assert.NoError(t, err) assert.NotEmpty(t, id2) assert.NotEmpty(t, proof2) - id3, proof3, err := da.Submit(msg1) + id3, proof3, err := da.Submit([]Blob{msg1}) assert.NoError(t, err) assert.NotEmpty(t, id3) assert.NotEmpty(t, proof3) @@ -42,31 +46,40 @@ func ExecuteDATest(t *testing.T, da da.DA) { ret, err := da.Get(id1) assert.NoError(t, err) - assert.Equal(t, msg1, ret) + assert.Equal(t, []Blob{msg1}, ret) - commitment1, err := da.Commit(msg1) + commitment1, err := da.Commit([]Blob{msg1}) assert.NoError(t, err) assert.NotEmpty(t, commitment1) - commitment2, err := da.Commit(msg2) + commitment2, err := da.Commit([]Blob{msg2}) assert.NoError(t, err) assert.NotEmpty(t, commitment2) - ok, err := da.Validate(commitment1, proof1) + oks, err := da.Validate(commitment1, proof1) assert.NoError(t, err) - assert.True(t, ok) + assert.NotEmpty(t, oks) + for _, ok := range oks { + assert.True(t, ok) + } - ok, err = da.Validate(commitment1, proof2) + oks, err = da.Validate(commitment1, proof2) assert.NoError(t, err) - assert.False(t, ok) + assert.NotEmpty(t, oks) + for _, ok := range oks { + assert.False(t, ok) + } - ok, err = da.Validate(commitment2, proof1) + oks, err = da.Validate(commitment2, proof1) assert.NoError(t, err) - assert.False(t, ok) + assert.NotEmpty(t, oks) + for _, ok := range oks { + assert.False(t, ok) + } } func CheckErrors(t *testing.T, da da.DA) { - blob, err := da.Get([]byte("invalid")) + blob, err := da.Get([]ID{[]byte("invalid")}) assert.Error(t, err) assert.Empty(t, blob) } diff --git a/dummy_test.go b/dummy_test.go index 4e4bb64..3a6bb2d 100644 --- a/dummy_test.go +++ b/dummy_test.go @@ -30,28 +30,51 @@ func NewDummyDA() *DummyDA { return da } -func (d *DummyDA) Get(id da.ID) (da.Blob, error) { - blob, ok := d.data[string(id)] - if !ok { - return nil, errors.New("no blob for given ID") +var _ da.DA = &DummyDA{} + +func (d *DummyDA) Get(ids []da.ID) ([]da.Blob, error) { + blobs := make([]da.Blob, len(ids)) + for i, id := range ids { + blob, ok := d.data[string(id)] + if !ok { + return nil, errors.New("no blob for given ID") + } + blobs[i] = blob } - return blob, nil + return blobs, nil } -func (d *DummyDA) Commit(blob da.Blob) (da.Commitment, error) { - return d.getHash(blob), nil +func (d *DummyDA) Commit(blobs []da.Blob) ([]da.Commitment, error) { + commits := make([]da.Commitment, len(blobs)) + for i, blob := range blobs { + commits[i] = d.getHash(blob) + } + return commits, nil } -func (d *DummyDA) Submit(blob da.Blob) (da.ID, da.Proof, error) { - id := d.nextID() - proof := d.getProof(id, blob) +func (d *DummyDA) Submit(blobs []da.Blob) ([]da.ID, []da.Proof, error) { + ids := make([]da.ID, len(blobs)) + proofs := make([]da.Proof, len(blobs)) + for i, blob := range blobs { + id := d.nextID() + ids[i] = id + proofs[i] = d.getProof(id, blob) + + d.data[string(id)] = blob + } - d.data[string(id)] = blob - return id, proof, nil + return ids, proofs, nil } -func (d *DummyDA) Validate(commit da.Commitment, proof da.Proof) (bool, error) { - return ed25519.Verify(d.pubKey, commit, proof), nil +func (d *DummyDA) Validate(ids []da.ID, proofs []da.Proof) ([]bool, error) { + if len(ids) != len(proofs) { + return nil, errors.New("number of IDs doesn't equal to number of proofs") + } + results := make([]bool, len(ids)) + for i := 0; i < len(ids); i++ { + results[i] = ed25519.Verify(d.pubKey, ids[i], proofs[i]) + } + return results, nil } func (d *DummyDA) nextID() []byte {