diff --git a/pkg/castor/client.go b/pkg/castor/client.go index 00551ba6..313686b8 100644 --- a/pkg/castor/client.go +++ b/pkg/castor/client.go @@ -9,21 +9,21 @@ package castor import ( - "encoding/json" "errors" "fmt" - "github.com/google/uuid" "io/ioutil" "net/http" "net/url" "strconv" + "github.com/google/uuid" + "github.com/asaskevich/govalidator" ) // AbstractClient is an interface for castor tuple client. type AbstractClient interface { - GetTuples(tupleCount int32, tupleType TupleType, requestID uuid.UUID) (*TupleList, error) + GetTuples(tupleCount int32, tupleType TupleType, requestID uuid.UUID) ([]byte, error) } // NewClient returns a new Castor client for the given endpoint @@ -48,7 +48,7 @@ const countParam = "count" const reservationIDParam = "reservationId" // GetTuples retrieves a list of tuples matching the given criteria from Castor -func (c *Client) GetTuples(count int32, tt TupleType, requestID uuid.UUID) (*TupleList, error) { +func (c *Client) GetTuples(count int32, tt TupleType, requestID uuid.UUID) ([]byte, error) { values := url.Values{} values.Add(tupleTypeParam, tt.Name) values.Add(countParam, strconv.Itoa(int(count))) @@ -66,17 +66,16 @@ func (c *Client) GetTuples(count int32, tt TupleType, requestID uuid.UUID) (*Tup if err != nil { return nil, fmt.Errorf("communication with castor failed: %s", err) } + bodyBytes, err := ioutil.ReadAll(resp.Body) if resp.StatusCode != http.StatusOK { - bodyBytes, err := ioutil.ReadAll(resp.Body) + if err != nil { return nil, err } return nil, fmt.Errorf("getting tuples failed for \"%s\" with response code #%d: %s", req.URL, resp.StatusCode, string(bodyBytes)) } - tuples := &TupleList{} - err = json.NewDecoder(resp.Body).Decode(tuples) if err != nil { return nil, fmt.Errorf("castor has returned an invalid response body: %s", err) } - return tuples, nil + return bodyBytes, nil } diff --git a/pkg/castor/client_test.go b/pkg/castor/client_test.go index 601ab655..1067f280 100644 --- a/pkg/castor/client_test.go +++ b/pkg/castor/client_test.go @@ -58,13 +58,14 @@ var _ = Describe("Castor", func() { }) Context("when the path is correct", func() { It("returns tuples", func() { - mockedRT := MockedRoundTripper{ExpectedPath: "/intra-vcp/tuples", ReturnJSON: jsn, ExpectedResponseCode: http.StatusOK} + tbytelist := []byte{1, 2, 1, 2} + mockedRT := MockedRoundTripper{ExpectedPath: "/intra-vcp/tuples", ReturnJSON: tbytelist, ExpectedResponseCode: http.StatusOK} httpClient := &http.Client{Transport: &mockedRT} client := Client{URL: myURL, HTTPClient: httpClient} - tuples, err := client.GetTuples(0, BitGfp, uuid.MustParse("acc23dc8-7855-4a2f-bc89-494ba30a74d2")) + tuples, err := client.GetTuples(2, BitGfp, uuid.MustParse("acc23dc8-7855-4a2f-bc89-494ba30a74d2")) - Expect(tuples).To(Equal(tupleList)) + Expect(tuples).To(Equal(tbytelist)) Expect(err).NotTo(HaveOccurred()) }) }) @@ -90,18 +91,6 @@ var _ = Describe("Castor", func() { Expect(checkHTTPError(err.Error(), "communication with castor failed")).To(BeTrue()) }) }) - Context("when castor returns invalid json body", func() { - It("returns an error", func() { - jsn = []byte("invalid JSON String") - mockedRT := MockedRoundTripper{ExpectedPath: "/intra-vcp/tuples", ReturnJSON: jsn, ExpectedResponseCode: http.StatusOK} - httpClient := &http.Client{Transport: &mockedRT} - - client := Client{URL: myURL, HTTPClient: httpClient} - _, err := client.GetTuples(0, BitGfp, uuid.MustParse("acc23dc8-7855-4a2f-bc89-494ba30a74d2")) - - Expect(checkHTTPError(err.Error(), "castor has returned an invalid response body")).To(BeTrue()) - }) - }) }) diff --git a/pkg/ephemeral/io/tuple_streamer.go b/pkg/ephemeral/io/tuple_streamer.go index 9abf43f5..01a6c85b 100644 --- a/pkg/ephemeral/io/tuple_streamer.go +++ b/pkg/ephemeral/io/tuple_streamer.go @@ -8,7 +8,6 @@ package io import ( - "encoding/base64" "encoding/binary" "errors" "fmt" @@ -273,15 +272,11 @@ func (ts *CastorTupleStreamer) bufferData(terminateCh chan struct{}, streamerErr func (ts *CastorTupleStreamer) getTupleData() ([]byte, error) { requestID := uuid.NewMD5(ts.baseRequestID, []byte(strconv.Itoa(ts.requestCycle))) ts.requestCycle++ - tupleList, err := ts.castorClient.GetTuples(ts.stockSize, ts.tupleType, requestID) + tupleData, err := ts.castorClient.GetTuples(ts.stockSize, ts.tupleType, requestID) if err != nil { return nil, err } ts.logger.Debugw("Fetched new tuples from Castor", "RequestID", requestID) - tupleData, err := ts.tupleListToByteArray(tupleList) - if err != nil { - return nil, fmt.Errorf("error parsing received tuple list: %v", err) - } return tupleData, nil } @@ -328,26 +323,6 @@ func (ts *CastorTupleStreamer) writeDataToPipe(terminateCh chan struct{}, doneCh } } -// tupleListToByteArray converts a given list of tuple to a byte array -func (ts *CastorTupleStreamer) tupleListToByteArray(tl *castor.TupleList) ([]byte, error) { - var result []byte - for _, tuple := range tl.Tuples { - for _, share := range tuple.Shares { - decodeString, err := base64.StdEncoding.DecodeString(share.Value) - if err != nil { - return []byte{}, err - } - result = append(result, decodeString...) - decodeString, err = base64.StdEncoding.DecodeString(share.Mac) - if err != nil { - return []byte{}, err - } - result = append(result, decodeString...) - } - } - return result, nil -} - // generateHeader returns the file header for the given protocol and spdz runtime configuration func generateHeader(sp castor.SPDZProtocol, conf *SPDZEngineTypedConfig) ([]byte, error) { switch sp { diff --git a/pkg/ephemeral/io/tuple_streamer_test.go b/pkg/ephemeral/io/tuple_streamer_test.go index 7ec5ab9b..63147ac7 100644 --- a/pkg/ephemeral/io/tuple_streamer_test.go +++ b/pkg/ephemeral/io/tuple_streamer_test.go @@ -105,49 +105,6 @@ var _ = Describe("Tuple Streamer", func() { Expect(<-errCh).NotTo(BeNil()) }) }) - Context("when castor client returns illegal data", func() { - Context("when share value is invalid", func() { - It("writes error to error channel and stops", func() { - invalidShareValue := "value" - share := castor.Share{Value: invalidShareValue} - shares := make([]castor.Share, 1) - shares[0] = share - tuples := make([]castor.Tuple, 1) - tuples[0] = castor.Tuple{Shares: shares} - cc.TupleList = &castor.TupleList{Tuples: tuples} - wg.Add(1) - ts.StartStreamTuples(terminate, errCh, wg) - wg.Wait() - close(terminate) - close(errCh) - Expect(fcpw.isClosed).To(BeTrue()) - err := <-errCh - Expect(err).To(HaveOccurred()) - Expect(err).To(Equal(errors.New("error parsing received tuple list: illegal base64 data at input byte 4"))) - }) - }) - Context("when share value is invalid", func() { - It("writes error to error channel and stops", func() { - validShareValue := base64.StdEncoding.EncodeToString([]byte("value")) - invalidShareMac := "value" - share := castor.Share{Value: validShareValue, Mac: invalidShareMac} - shares := make([]castor.Share, 1) - shares[0] = share - tuples := make([]castor.Tuple, 1) - tuples[0] = castor.Tuple{Shares: shares} - cc.TupleList = &castor.TupleList{Tuples: tuples} - wg.Add(1) - ts.StartStreamTuples(terminate, errCh, wg) - wg.Wait() - close(terminate) - close(errCh) - Expect(fcpw.isClosed).To(BeTrue()) - err := <-errCh - Expect(err).To(HaveOccurred()) - Expect(err).To(Equal(errors.New("error parsing received tuple list: illegal base64 data at input byte 4"))) - }) - }) - }) Context("when tuples fetched successfully", func() { shareValue := "value" shareMac := "value" @@ -161,7 +118,7 @@ var _ = Describe("Tuple Streamer", func() { tuples[0] = castor.Tuple{Shares: shares} initialStreamData := []byte(shareValue + shareMac) BeforeEach(func() { - cc.TupleList = &castor.TupleList{Tuples: tuples} + cc.TupleData = initialStreamData }) Context("when writing data to pipe fails with broken pipe", func() { var expectedError = syscall.EPIPE @@ -551,19 +508,19 @@ func (fpcfpw *FakePartialConsumingFailSecondCallPipeWriter) Close() error { } type FakeCastorClient struct { - TupleList *castor.TupleList + TupleData []byte } -func (fcc *FakeCastorClient) GetTuples(int32, castor.TupleType, uuid.UUID) (*castor.TupleList, error) { - tl := fcc.TupleList +func (fcc *FakeCastorClient) GetTuples(int32, castor.TupleType, uuid.UUID) ([]byte, error) { + tl := fcc.TupleData if tl == nil { - tl = &castor.TupleList{} + tl = []byte{} } return tl, nil } type BrokenDownloadCastorClient struct{} -func (fcc *BrokenDownloadCastorClient) GetTuples(int32, castor.TupleType, uuid.UUID) (*castor.TupleList, error) { - return &castor.TupleList{}, errors.New("fetching tuples failed") +func (fcc *BrokenDownloadCastorClient) GetTuples(int32, castor.TupleType, uuid.UUID) ([]byte, error) { + return []byte{}, errors.New("fetching tuples failed") }