diff --git a/block/da_speed_test.go b/block/da_speed_test.go index 3c63fb4e07..fb4d07e9b5 100644 --- a/block/da_speed_test.go +++ b/block/da_speed_test.go @@ -47,16 +47,16 @@ func TestDASpeed(t *testing.T) { manager, mockDAClient := setupManagerForTest(t, daHeight) var receivedBlockCount atomic.Uint64 - ids, namespace := []coreda.ID{[]byte("dummy-id")}, []byte("placeholder") + ids := []coreda.ID{[]byte("dummy-id")} mockDAClient. - On("GetIDs", mock.Anything, mock.Anything, namespace). - Return(func(ctx context.Context, height uint64, namespace []byte) (*coreda.GetIDsResult, error) { + On("GetIDs", mock.Anything, mock.Anything). + Return(func(ctx context.Context, height uint64) (*coreda.GetIDsResult, error) { return &coreda.GetIDsResult{IDs: ids, Timestamp: time.Now()}, nil }) mockDAClient. - On("Get", mock.Anything, ids, namespace). - Return(func(ctx context.Context, ids []coreda.ID, namespace []byte) ([]coreda.Blob, error) { + On("Get", mock.Anything, ids). + Return(func(ctx context.Context, ids []coreda.ID) ([]coreda.Blob, error) { time.Sleep(spec.daDelay) // unique headers for cache misses n := receivedBlockCount.Add(1) diff --git a/block/retriever_test.go b/block/retriever_test.go index 84a279b43e..35bbeb5a60 100644 --- a/block/retriever_test.go +++ b/block/retriever_test.go @@ -135,11 +135,11 @@ func TestProcessNextDAHeader_Success_SingleHeaderAndData(t *testing.T) { blockDataBytes, err := signedData.MarshalBinary() require.NoError(t, err) // ----------------------------------------------------------- - mockDAClient.On("GetIDs", mock.Anything, daHeight, []byte("placeholder")).Return(&coreda.GetIDsResult{ + mockDAClient.On("GetIDs", mock.Anything, daHeight).Return(&coreda.GetIDsResult{ IDs: []coreda.ID{[]byte("dummy-id")}, Timestamp: time.Now(), }, nil).Once() - mockDAClient.On("Get", mock.Anything, []coreda.ID{[]byte("dummy-id")}, []byte("placeholder")).Return( + mockDAClient.On("Get", mock.Anything, []coreda.ID{[]byte("dummy-id")}).Return( []coreda.Blob{headerBytes, blockDataBytes}, nil, ).Once() @@ -247,11 +247,11 @@ func TestProcessNextDAHeader_MultipleHeadersAndData(t *testing.T) { // Add a few more invalid blobs at the end blobs = append(blobs, invalidBlob, []byte{}) - mockDAClient.On("GetIDs", mock.Anything, daHeight, []byte("placeholder")).Return(&coreda.GetIDsResult{ + mockDAClient.On("GetIDs", mock.Anything, daHeight).Return(&coreda.GetIDsResult{ IDs: []coreda.ID{[]byte("dummy-id")}, Timestamp: time.Now(), }, nil).Once() - mockDAClient.On("Get", mock.Anything, []coreda.ID{[]byte("dummy-id")}, []byte("placeholder")).Return( + mockDAClient.On("Get", mock.Anything, []coreda.ID{[]byte("dummy-id")}).Return( blobs, nil, ).Once() @@ -311,11 +311,11 @@ func TestProcessNextDAHeaderAndData_NotFound(t *testing.T) { defer cancel() // Mock GetIDs to return empty IDs to simulate "not found" scenario - mockDAClient.On("GetIDs", mock.Anything, daHeight, []byte("placeholder")).Return(&coreda.GetIDsResult{ - IDs: []coreda.ID{}, // Empty IDs array + // Example updates needed for one instance: + mockDAClient.On("GetIDs", mock.Anything, daHeight).Return(&coreda.GetIDsResult{ + IDs: []coreda.ID{}, Timestamp: time.Now(), }, coreda.ErrBlobNotFound).Once() - ctx := context.Background() err := manager.processNextDAHeaderAndData(ctx) require.NoError(t, err) @@ -345,13 +345,13 @@ func TestProcessNextDAHeaderAndData_UnmarshalHeaderError(t *testing.T) { invalidBytes := []byte("this is not a valid protobuf message") // Mock GetIDs to return success with dummy ID - mockDAClient.On("GetIDs", mock.Anything, daHeight, []byte("placeholder")).Return(&coreda.GetIDsResult{ + mockDAClient.On("GetIDs", mock.Anything, daHeight).Return(&coreda.GetIDsResult{ IDs: []coreda.ID{[]byte("dummy-id")}, Timestamp: time.Now(), }, nil).Once() // Mock Get to return invalid bytes - mockDAClient.On("Get", mock.Anything, []coreda.ID{[]byte("dummy-id")}, []byte("placeholder")).Return( + mockDAClient.On("Get", mock.Anything, []coreda.ID{[]byte("dummy-id")}).Return( []coreda.Blob{invalidBytes}, nil, ).Once() @@ -404,13 +404,13 @@ func TestProcessNextDAHeader_UnexpectedSequencer(t *testing.T) { require.NoError(t, err) // Mock GetIDs to return success with dummy ID - mockDAClient.On("GetIDs", mock.Anything, daHeight, []byte("placeholder")).Return(&coreda.GetIDsResult{ + mockDAClient.On("GetIDs", mock.Anything, daHeight).Return(&coreda.GetIDsResult{ IDs: []coreda.ID{[]byte("dummy-id")}, Timestamp: time.Now(), }, nil).Once() // Mock Get to return header bytes - mockDAClient.On("Get", mock.Anything, []coreda.ID{[]byte("dummy-id")}, []byte("placeholder")).Return( + mockDAClient.On("Get", mock.Anything, []coreda.ID{[]byte("dummy-id")}).Return( []coreda.Blob{headerBytes}, nil, ).Once() @@ -448,7 +448,7 @@ func TestProcessNextDAHeader_FetchError_RetryFailure(t *testing.T) { fetchErr := errors.New("persistent DA connection error") // Mock GetIDs to return error for all retries - mockDAClient.On("GetIDs", mock.Anything, daHeight, []byte("placeholder")).Return( + mockDAClient.On("GetIDs", mock.Anything, daHeight).Return( nil, fetchErr, ).Times(dAFetcherRetries) @@ -538,7 +538,7 @@ func TestProcessNextDAHeader_HeaderAndDataAlreadySeen(t *testing.T) { Timestamp: time.Now(), }, nil).Once() - mockDAClient.On("Get", mock.Anything, []coreda.ID{[]byte("dummy-id")}, mock.Anything).Return( + mockDAClient.On("Get", mock.Anything, []coreda.ID{[]byte("dummy-id")}).Return( []coreda.Blob{headerBytes, blockDataBytes}, nil, ).Once() @@ -576,12 +576,12 @@ func TestRetrieveLoop_ProcessError_HeightFromFuture(t *testing.T) { futureErr := fmt.Errorf("some error wrapping: %w", ErrHeightFromFutureStr) // Mock GetIDs to return future error for all retries - mockDAClient.On("GetIDs", mock.Anything, startDAHeight, []byte("placeholder")).Return( + mockDAClient.On("GetIDs", mock.Anything, startDAHeight).Return( nil, futureErr, ).Once() // Optional: Mock for the next height if needed - mockDAClient.On("GetIDs", mock.Anything, startDAHeight+1, []byte("placeholder")).Return( + mockDAClient.On("GetIDs", mock.Anything, startDAHeight+1).Return( &coreda.GetIDsResult{IDs: []coreda.ID{}}, coreda.ErrBlobNotFound, ).Maybe() @@ -624,7 +624,7 @@ func TestRetrieveLoop_ProcessError_Other(t *testing.T) { otherErr := errors.New("some other DA error") // Mock GetIDs to return error for all retries - mockDAClient.On("GetIDs", mock.Anything, startDAHeight, []byte("placeholder")).Return( + mockDAClient.On("GetIDs", mock.Anything, startDAHeight).Return( nil, otherErr, ).Times(dAFetcherRetries) @@ -708,11 +708,11 @@ func TestProcessNextDAHeader_WithNoTxs(t *testing.T) { emptyDataBytes, err := emptySignedData.MarshalBinary() require.NoError(t, err) - mockDAClient.On("GetIDs", mock.Anything, daHeight, []byte("placeholder")).Return(&coreda.GetIDsResult{ + mockDAClient.On("GetIDs", mock.Anything, daHeight).Return(&coreda.GetIDsResult{ IDs: []coreda.ID{[]byte("dummy-id")}, Timestamp: time.Now(), }, nil).Once() - mockDAClient.On("Get", mock.Anything, []coreda.ID{[]byte("dummy-id")}, []byte("placeholder")).Return( + mockDAClient.On("Get", mock.Anything, []coreda.ID{[]byte("dummy-id")}).Return( []coreda.Blob{headerBytes, emptyDataBytes}, nil, ).Once() @@ -761,23 +761,23 @@ func TestRetrieveLoop_DAHeightIncrementsOnlyOnSuccess(t *testing.T) { require.NoError(t, err) // 1. First call: success (header) - mockDAClient.On("GetIDs", mock.Anything, startDAHeight, []byte("placeholder")).Return(&coreda.GetIDsResult{ + mockDAClient.On("GetIDs", mock.Anything, startDAHeight).Return(&coreda.GetIDsResult{ IDs: []coreda.ID{[]byte("dummy-id")}, Timestamp: time.Now(), }, nil).Once() - mockDAClient.On("Get", mock.Anything, []coreda.ID{[]byte("dummy-id")}, []byte("placeholder")).Return( + mockDAClient.On("Get", mock.Anything, []coreda.ID{[]byte("dummy-id")}).Return( []coreda.Blob{headerBytes}, nil, ).Once() // 2. Second call: NotFound - mockDAClient.On("GetIDs", mock.Anything, startDAHeight+1, []byte("placeholder")).Return(&coreda.GetIDsResult{ + mockDAClient.On("GetIDs", mock.Anything, startDAHeight+1).Return(&coreda.GetIDsResult{ IDs: nil, Timestamp: time.Now(), }, nil).Once() // 3. Third call: Error errDA := errors.New("some DA error") - mockDAClient.On("GetIDs", mock.Anything, startDAHeight+2, []byte("placeholder")).Return( + mockDAClient.On("GetIDs", mock.Anything, startDAHeight+2).Return( &coreda.GetIDsResult{ IDs: nil, Timestamp: time.Now(), diff --git a/block/submitter_test.go b/block/submitter_test.go index 1bc7b2f7ac..8cd5ac149d 100644 --- a/block/submitter_test.go +++ b/block/submitter_test.go @@ -50,7 +50,7 @@ func TestSubmitDataToDA_Success(t *testing.T) { // Simulate DA success da.On("GasMultiplier", mock.Anything).Return(2.0, nil) - da.On("SubmitWithOptions", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + da.On("Submit", mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return([]coreda.ID{[]byte("id")}, nil) pubKey, err := m.signer.GetPublic() @@ -102,7 +102,7 @@ func TestSubmitDataToDA_Failure(t *testing.T) { var gasPriceHistory []float64 da.ExpectedCalls = nil da.On("GasMultiplier", mock.Anything).Return(2.0, nil) - da.On("SubmitWithOptions", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + da.On("Submit", mock.Anything, mock.Anything, mock.Anything, mock.Anything). Run(func(args mock.Arguments) { gasPriceHistory = append(gasPriceHistory, args.Get(2).(float64)) }). //save the gas price to verify it later Return(nil, tc.daError) @@ -157,7 +157,7 @@ func TestSubmitHeadersToDA_Success(t *testing.T) { fillWithBlockData(context.Background(), t, m.pendingHeaders, "Test Submitting Headers") // Simulate DA layer successfully accepting the header submission - da.On("SubmitWithOptions", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + da.On("Submit", mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return([]coreda.ID{[]byte("id")}, nil) // Call submitHeadersToDA and expect no error @@ -189,7 +189,7 @@ func TestSubmitHeadersToDA_Failure(t *testing.T) { da.ExpectedCalls = nil // Simulate DA layer returning a specific error var gasPriceHistory []float64 - da.On("SubmitWithOptions", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + da.On("Submit", mock.Anything, mock.Anything, mock.Anything, mock.Anything). Run(func(args mock.Arguments) { gasPriceHistory = append(gasPriceHistory, args.Get(2).(float64)) }). //save the gas price to verify it later Return(nil, tc.daError) @@ -226,7 +226,7 @@ func TestSubmitHeadersToDA_WithMetricsRecorder(t *testing.T) { fillWithBlockData(context.Background(), t, m.pendingHeaders, "Test Submitting Headers") // Simulate DA layer successfully accepting the header submission - da.On("SubmitWithOptions", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + da.On("Submit", mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return([]coreda.ID{[]byte("id")}, nil) // Expect RecordMetrics to be called with the correct parameters @@ -262,7 +262,7 @@ func TestSubmitDataToDA_WithMetricsRecorder(t *testing.T) { // Simulate DA success da.On("GasMultiplier", mock.Anything).Return(2.0, nil) - da.On("SubmitWithOptions", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + da.On("Submit", mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return([]coreda.ID{[]byte("id")}, nil) // Expect RecordMetrics to be called with the correct parameters diff --git a/core/da/da.go b/core/da/da.go index a3effde2dc..00649d5f62 100644 --- a/core/da/da.go +++ b/core/da/da.go @@ -13,28 +13,25 @@ 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(ctx context.Context, ids []ID, namespace []byte) ([]Blob, error) + Get(ctx context.Context, ids []ID) ([]Blob, error) // GetIDs returns IDs of all Blobs located in DA at given height. - GetIDs(ctx context.Context, height uint64, namespace []byte) (*GetIDsResult, error) + GetIDs(ctx context.Context, height uint64) (*GetIDsResult, error) // GetProofs returns inclusion Proofs for Blobs specified by their IDs. - GetProofs(ctx context.Context, ids []ID, namespace []byte) ([]Proof, error) + GetProofs(ctx context.Context, ids []ID) ([]Proof, error) // Commit creates a Commitment for each given Blob. - Commit(ctx context.Context, blobs []Blob, namespace []byte) ([]Commitment, error) + Commit(ctx context.Context, blobs []Blob) ([]Commitment, error) - // Submit submits the Blobs to Data Availability layer. + // Submit submits the Blobs to Data Availability layer with additional options. // // This method is synchronous. Upon successful submission to Data Availability layer, it returns the IDs identifying blobs // in DA. - Submit(ctx context.Context, blobs []Blob, gasPrice float64, namespace []byte) ([]ID, error) - - // SubmitWithOptions submits the Blobs to Data Availability layer with additional options. - SubmitWithOptions(ctx context.Context, blobs []Blob, gasPrice float64, namespace []byte, options []byte) ([]ID, error) + Submit(ctx context.Context, blobs []Blob, gasPrice float64, options []byte) ([]ID, error) // Validate validates Commitments against the corresponding Proofs. This should be possible without retrieving the Blobs. - Validate(ctx context.Context, ids []ID, proofs []Proof, namespace []byte) ([]bool, error) + Validate(ctx context.Context, ids []ID, proofs []Proof) ([]bool, error) // GasPrice returns the gas price for the DA layer. GasPrice(ctx context.Context) (float64, error) diff --git a/core/da/dummy.go b/core/da/dummy.go index f575cf67ed..88fb0e0b25 100644 --- a/core/da/dummy.go +++ b/core/da/dummy.go @@ -20,11 +20,9 @@ type DummyDA struct { maxBlobSize uint64 gasPrice float64 gasMultiplier float64 - - // DA height simulation - currentHeight uint64 - blockTime time.Duration - stopCh chan struct{} + height uint64 + blockTime time.Duration + stopCh chan struct{} } var ErrHeightFromFutureStr = fmt.Errorf("given height is from the future") @@ -40,9 +38,9 @@ func NewDummyDA(maxBlobSize uint64, gasPrice float64, gasMultiplier float64, blo maxBlobSize: maxBlobSize, gasPrice: gasPrice, gasMultiplier: gasMultiplier, + height: 1, blockTime: blockTime, stopCh: make(chan struct{}), - currentHeight: 0, } } @@ -55,7 +53,7 @@ func (d *DummyDA) StartHeightTicker() { select { case <-ticker.C: d.mu.Lock() - d.currentHeight++ + d.height++ d.mu.Unlock() case <-d.stopCh: return @@ -85,7 +83,7 @@ func (d *DummyDA) GasMultiplier(ctx context.Context) (float64, error) { } // Get returns blobs for the given IDs. -func (d *DummyDA) Get(ctx context.Context, ids []ID, namespace []byte) ([]Blob, error) { +func (d *DummyDA) Get(ctx context.Context, ids []ID) ([]Blob, error) { d.mu.RLock() defer d.mu.RUnlock() @@ -101,12 +99,12 @@ func (d *DummyDA) Get(ctx context.Context, ids []ID, namespace []byte) ([]Blob, } // GetIDs returns IDs of all blobs at the given height. -func (d *DummyDA) GetIDs(ctx context.Context, height uint64, namespace []byte) (*GetIDsResult, error) { +func (d *DummyDA) GetIDs(ctx context.Context, height uint64) (*GetIDsResult, error) { d.mu.RLock() defer d.mu.RUnlock() - if height > d.currentHeight { - return nil, fmt.Errorf("%w: requested %d, current %d", ErrHeightFromFutureStr, height, d.currentHeight) + if height > d.height { + return nil, fmt.Errorf("%w: requested %d, current %d", ErrHeightFromFutureStr, height, d.height) } ids, exists := d.blobsByHeight[height] @@ -124,7 +122,7 @@ func (d *DummyDA) GetIDs(ctx context.Context, height uint64, namespace []byte) ( } // GetProofs returns proofs for the given IDs. -func (d *DummyDA) GetProofs(ctx context.Context, ids []ID, namespace []byte) ([]Proof, error) { +func (d *DummyDA) GetProofs(ctx context.Context, ids []ID) ([]Proof, error) { d.mu.RLock() defer d.mu.RUnlock() @@ -140,7 +138,7 @@ func (d *DummyDA) GetProofs(ctx context.Context, ids []ID, namespace []byte) ([] } // Commit creates commitments for the given blobs. -func (d *DummyDA) Commit(ctx context.Context, blobs []Blob, namespace []byte) ([]Commitment, error) { +func (d *DummyDA) Commit(ctx context.Context, blobs []Blob) ([]Commitment, error) { d.mu.Lock() defer d.mu.Unlock() @@ -153,17 +151,14 @@ func (d *DummyDA) Commit(ctx context.Context, blobs []Blob, namespace []byte) ([ return commitments, nil } -// Submit submits blobs to the DA layer. -func (d *DummyDA) Submit(ctx context.Context, blobs []Blob, gasPrice float64, namespace []byte) ([]ID, error) { - return d.SubmitWithOptions(ctx, blobs, gasPrice, namespace, nil) -} - // SubmitWithOptions submits blobs to the DA layer with additional options. -func (d *DummyDA) SubmitWithOptions(ctx context.Context, blobs []Blob, gasPrice float64, namespace []byte, options []byte) ([]ID, error) { +func (d *DummyDA) Submit(ctx context.Context, blobs []Blob, gasPrice float64, options []byte) ([]ID, error) { d.mu.Lock() defer d.mu.Unlock() - height := d.currentHeight + 1 + batchHeight := d.height + d.height++ + ids := make([]ID, 0, len(blobs)) var currentSize uint64 @@ -192,7 +187,7 @@ func (d *DummyDA) SubmitWithOptions(ctx context.Context, blobs []Blob, gasPrice commitment := bz[:] // Create ID from height and commitment - id := makeID(height, commitment) + id := makeID(batchHeight, commitment) idStr := string(id) d.blobs[idStr] = blob @@ -202,19 +197,14 @@ func (d *DummyDA) SubmitWithOptions(ctx context.Context, blobs []Blob, gasPrice ids = append(ids, id) } - // Add the IDs to the blobsByHeight map if they don't already exist - if existingIDs, exists := d.blobsByHeight[height]; exists { - d.blobsByHeight[height] = append(existingIDs, ids...) - } else { - d.blobsByHeight[height] = ids - } - d.timestampsByHeight[height] = time.Now() + d.blobsByHeight[batchHeight] = ids + d.timestampsByHeight[batchHeight] = time.Now() return ids, nil } // Validate validates commitments against proofs. -func (d *DummyDA) Validate(ctx context.Context, ids []ID, proofs []Proof, namespace []byte) ([]bool, error) { +func (d *DummyDA) Validate(ctx context.Context, ids []ID, proofs []Proof) ([]bool, error) { d.mu.RLock() defer d.mu.RUnlock() diff --git a/core/da/dummy_test.go b/core/da/dummy_test.go index cf3e686dd8..34fe31bdaa 100644 --- a/core/da/dummy_test.go +++ b/core/da/dummy_test.go @@ -30,7 +30,7 @@ func TestDummyDA(t *testing.T) { []byte("test blob 1"), []byte("test blob 2"), } - ids, err := dummyDA.Submit(ctx, blobs, 0, nil) + ids, err := dummyDA.Submit(ctx, blobs, 0, []byte("ns")) if err != nil { t.Fatalf("Submit failed: %v", err) } @@ -43,7 +43,7 @@ func TestDummyDA(t *testing.T) { } // Test Get - retrievedBlobs, err := dummyDA.Get(ctx, ids, nil) + retrievedBlobs, err := dummyDA.Get(ctx, ids) if err != nil { t.Fatalf("Get failed: %v", err) } @@ -57,7 +57,7 @@ func TestDummyDA(t *testing.T) { } // Test GetIDs - result, err := dummyDA.GetIDs(ctx, 1, nil) + result, err := dummyDA.GetIDs(ctx, 1) if err != nil { t.Fatalf("GetIDs failed: %v", err) } @@ -66,7 +66,7 @@ func TestDummyDA(t *testing.T) { } // Test Commit - commitments, err := dummyDA.Commit(ctx, blobs, nil) + commitments, err := dummyDA.Commit(ctx, blobs) if err != nil { t.Fatalf("Commit failed: %v", err) } @@ -75,7 +75,7 @@ func TestDummyDA(t *testing.T) { } // Test GetProofs - proofs, err := dummyDA.GetProofs(ctx, ids, nil) + proofs, err := dummyDA.GetProofs(ctx, ids) if err != nil { t.Fatalf("GetProofs failed: %v", err) } @@ -84,7 +84,7 @@ func TestDummyDA(t *testing.T) { } // Test Validate - validations, err := dummyDA.Validate(ctx, ids, proofs, nil) + validations, err := dummyDA.Validate(ctx, ids, proofs) if err != nil { t.Fatalf("Validate failed: %v", err) } @@ -113,7 +113,7 @@ func waitForFirstDAHeight(ctx context.Context, da *DummyDA) error { func waitForAtLeastDAHeight(ctx context.Context, da *DummyDA, targetHeight uint64) error { // Read current height at the start da.mu.RLock() - current := da.currentHeight + current := da.height da.mu.RUnlock() if current >= targetHeight { @@ -129,7 +129,7 @@ func waitForAtLeastDAHeight(ctx context.Context, da *DummyDA, targetHeight uint6 deadline := time.Now().Add(timeout) for { da.mu.RLock() - current = da.currentHeight + current = da.height da.mu.RUnlock() if current >= targetHeight { return nil diff --git a/da/cmd/local-da/local.go b/da/cmd/local-da/local.go index d1242f1cd2..b806f73bd5 100644 --- a/da/cmd/local-da/local.go +++ b/da/cmd/local-da/local.go @@ -77,7 +77,7 @@ func (d *LocalDA) GasPrice(ctx context.Context) (float64, error) { } // Get returns Blobs for given IDs. -func (d *LocalDA) Get(ctx context.Context, ids []coreda.ID, _ []byte) ([]coreda.Blob, error) { +func (d *LocalDA) Get(ctx context.Context, ids []coreda.ID) ([]coreda.Blob, error) { d.logger.Debug("Get called", "ids", ids) d.mu.Lock() defer d.mu.Unlock() @@ -105,7 +105,7 @@ func (d *LocalDA) Get(ctx context.Context, ids []coreda.ID, _ []byte) ([]coreda. } // GetIDs returns IDs of Blobs at given DA height. -func (d *LocalDA) GetIDs(ctx context.Context, height uint64, _ []byte) (*coreda.GetIDsResult, error) { +func (d *LocalDA) GetIDs(ctx context.Context, height uint64) (*coreda.GetIDsResult, error) { d.logger.Debug("GetIDs called", "height", height) d.mu.Lock() defer d.mu.Unlock() @@ -130,9 +130,9 @@ func (d *LocalDA) GetIDs(ctx context.Context, height uint64, _ []byte) (*coreda. } // GetProofs returns inclusion Proofs for all Blobs located in DA at given height. -func (d *LocalDA) GetProofs(ctx context.Context, ids []coreda.ID, _ []byte) ([]coreda.Proof, error) { +func (d *LocalDA) GetProofs(ctx context.Context, ids []coreda.ID) ([]coreda.Proof, error) { d.logger.Debug("GetProofs called", "ids", ids) - blobs, err := d.Get(ctx, ids, nil) + blobs, err := d.Get(ctx, ids) if err != nil { d.logger.Error("GetProofs: failed to get blobs", "error", err) return nil, err @@ -149,7 +149,7 @@ func (d *LocalDA) GetProofs(ctx context.Context, ids []coreda.ID, _ []byte) ([]c } // Commit returns cryptographic Commitments for given blobs. -func (d *LocalDA) Commit(ctx context.Context, blobs []coreda.Blob, _ []byte) ([]coreda.Commitment, error) { +func (d *LocalDA) Commit(ctx context.Context, blobs []coreda.Blob) ([]coreda.Commitment, error) { d.logger.Debug("Commit called", "numBlobs", len(blobs)) commits := make([]coreda.Commitment, len(blobs)) for i, blob := range blobs { @@ -160,23 +160,6 @@ func (d *LocalDA) Commit(ctx context.Context, blobs []coreda.Blob, _ []byte) ([] } // SubmitWithOptions stores blobs in DA layer (options are ignored). -func (d *LocalDA) SubmitWithOptions(ctx context.Context, blobs []coreda.Blob, gasPrice float64, _ []byte, _ []byte) ([]coreda.ID, error) { - d.logger.Info("SubmitWithOptions called", "numBlobs", len(blobs), "gasPrice", gasPrice) - d.mu.Lock() - defer d.mu.Unlock() - ids := make([]coreda.ID, len(blobs)) - d.height += 1 - d.timestamps[d.height] = time.Now() - for i, blob := range blobs { - ids[i] = append(d.nextID(), d.getHash(blob)...) - - d.data[d.height] = append(d.data[d.height], kvp{ids[i], blob}) - } - d.logger.Info("SubmitWithOptions successful", "newHeight", d.height, "count", len(ids)) - return ids, nil -} - -// Submit stores blobs in DA layer (options are ignored). func (d *LocalDA) Submit(ctx context.Context, blobs []coreda.Blob, gasPrice float64, _ []byte) ([]coreda.ID, error) { d.logger.Info("Submit called", "numBlobs", len(blobs), "gasPrice", gasPrice) d.mu.Lock() @@ -194,7 +177,7 @@ func (d *LocalDA) Submit(ctx context.Context, blobs []coreda.Blob, gasPrice floa } // Validate checks the Proofs for given IDs. -func (d *LocalDA) Validate(ctx context.Context, ids []coreda.ID, proofs []coreda.Proof, _ []byte) ([]bool, error) { +func (d *LocalDA) Validate(ctx context.Context, ids []coreda.ID, proofs []coreda.Proof) ([]bool, error) { d.logger.Debug("Validate called", "numIDs", len(ids), "numProofs", len(proofs)) if len(ids) != len(proofs) { d.logger.Error("Validate: id/proof count mismatch", "ids", len(ids), "proofs", len(proofs)) diff --git a/da/internal/mocks/da.go b/da/internal/mocks/da.go index af123609c1..9fd281ae0b 100644 --- a/da/internal/mocks/da.go +++ b/da/internal/mocks/da.go @@ -14,9 +14,9 @@ type DA struct { mock.Mock } -// Commit provides a mock function with given fields: ctx, blobs, namespace -func (_m *DA) Commit(ctx context.Context, blobs [][]byte, namespace []byte) ([][]byte, error) { - ret := _m.Called(ctx, blobs, namespace) +// Commit provides a mock function with given fields: ctx, blobs +func (_m *DA) Commit(ctx context.Context, blobs [][]byte) ([][]byte, error) { + ret := _m.Called(ctx, blobs) if len(ret) == 0 { panic("no return value specified for Commit") @@ -24,19 +24,19 @@ func (_m *DA) Commit(ctx context.Context, blobs [][]byte, namespace []byte) ([][ var r0 [][]byte var r1 error - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, []byte) ([][]byte, error)); ok { - return rf(ctx, blobs, namespace) + if rf, ok := ret.Get(0).(func(context.Context, [][]byte) ([][]byte, error)); ok { + return rf(ctx, blobs) } - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, []byte) [][]byte); ok { - r0 = rf(ctx, blobs, namespace) + if rf, ok := ret.Get(0).(func(context.Context, [][]byte) [][]byte); ok { + r0 = rf(ctx, blobs) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([][]byte) } } - if rf, ok := ret.Get(1).(func(context.Context, [][]byte, []byte) error); ok { - r1 = rf(ctx, blobs, namespace) + if rf, ok := ret.Get(1).(func(context.Context, [][]byte) error); ok { + r1 = rf(ctx, blobs) } else { r1 = ret.Error(1) } @@ -100,9 +100,9 @@ func (_m *DA) GasPrice(ctx context.Context) (float64, error) { return r0, r1 } -// Get provides a mock function with given fields: ctx, ids, namespace -func (_m *DA) Get(ctx context.Context, ids [][]byte, namespace []byte) ([][]byte, error) { - ret := _m.Called(ctx, ids, namespace) +// Get provides a mock function with given fields: ctx, ids +func (_m *DA) Get(ctx context.Context, ids [][]byte) ([][]byte, error) { + ret := _m.Called(ctx, ids) if len(ret) == 0 { panic("no return value specified for Get") @@ -110,19 +110,19 @@ func (_m *DA) Get(ctx context.Context, ids [][]byte, namespace []byte) ([][]byte var r0 [][]byte var r1 error - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, []byte) ([][]byte, error)); ok { - return rf(ctx, ids, namespace) + if rf, ok := ret.Get(0).(func(context.Context, [][]byte) ([][]byte, error)); ok { + return rf(ctx, ids) } - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, []byte) [][]byte); ok { - r0 = rf(ctx, ids, namespace) + if rf, ok := ret.Get(0).(func(context.Context, [][]byte) [][]byte); ok { + r0 = rf(ctx, ids) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([][]byte) } } - if rf, ok := ret.Get(1).(func(context.Context, [][]byte, []byte) error); ok { - r1 = rf(ctx, ids, namespace) + if rf, ok := ret.Get(1).(func(context.Context, [][]byte) error); ok { + r1 = rf(ctx, ids) } else { r1 = ret.Error(1) } @@ -130,9 +130,9 @@ func (_m *DA) Get(ctx context.Context, ids [][]byte, namespace []byte) ([][]byte return r0, r1 } -// GetIDs provides a mock function with given fields: ctx, height, namespace -func (_m *DA) GetIDs(ctx context.Context, height uint64, namespace []byte) (*da.GetIDsResult, error) { - ret := _m.Called(ctx, height, namespace) +// GetIDs provides a mock function with given fields: ctx, height +func (_m *DA) GetIDs(ctx context.Context, height uint64) (*da.GetIDsResult, error) { + ret := _m.Called(ctx, height) if len(ret) == 0 { panic("no return value specified for GetIDs") @@ -140,19 +140,19 @@ func (_m *DA) GetIDs(ctx context.Context, height uint64, namespace []byte) (*da. var r0 *da.GetIDsResult var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uint64, []byte) (*da.GetIDsResult, error)); ok { - return rf(ctx, height, namespace) + if rf, ok := ret.Get(0).(func(context.Context, uint64) (*da.GetIDsResult, error)); ok { + return rf(ctx, height) } - if rf, ok := ret.Get(0).(func(context.Context, uint64, []byte) *da.GetIDsResult); ok { - r0 = rf(ctx, height, namespace) + if rf, ok := ret.Get(0).(func(context.Context, uint64) *da.GetIDsResult); ok { + r0 = rf(ctx, height) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*da.GetIDsResult) } } - if rf, ok := ret.Get(1).(func(context.Context, uint64, []byte) error); ok { - r1 = rf(ctx, height, namespace) + if rf, ok := ret.Get(1).(func(context.Context, uint64) error); ok { + r1 = rf(ctx, height) } else { r1 = ret.Error(1) } @@ -160,9 +160,9 @@ func (_m *DA) GetIDs(ctx context.Context, height uint64, namespace []byte) (*da. return r0, r1 } -// GetProofs provides a mock function with given fields: ctx, ids, namespace -func (_m *DA) GetProofs(ctx context.Context, ids [][]byte, namespace []byte) ([][]byte, error) { - ret := _m.Called(ctx, ids, namespace) +// GetProofs provides a mock function with given fields: ctx, ids +func (_m *DA) GetProofs(ctx context.Context, ids [][]byte) ([][]byte, error) { + ret := _m.Called(ctx, ids) if len(ret) == 0 { panic("no return value specified for GetProofs") @@ -170,19 +170,19 @@ func (_m *DA) GetProofs(ctx context.Context, ids [][]byte, namespace []byte) ([] var r0 [][]byte var r1 error - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, []byte) ([][]byte, error)); ok { - return rf(ctx, ids, namespace) + if rf, ok := ret.Get(0).(func(context.Context, [][]byte) ([][]byte, error)); ok { + return rf(ctx, ids) } - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, []byte) [][]byte); ok { - r0 = rf(ctx, ids, namespace) + if rf, ok := ret.Get(0).(func(context.Context, [][]byte) [][]byte); ok { + r0 = rf(ctx, ids) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([][]byte) } } - if rf, ok := ret.Get(1).(func(context.Context, [][]byte, []byte) error); ok { - r1 = rf(ctx, ids, namespace) + if rf, ok := ret.Get(1).(func(context.Context, [][]byte) error); ok { + r1 = rf(ctx, ids) } else { r1 = ret.Error(1) } @@ -190,37 +190,9 @@ func (_m *DA) GetProofs(ctx context.Context, ids [][]byte, namespace []byte) ([] return r0, r1 } -// MaxBlobSize provides a mock function with given fields: ctx -func (_m *DA) MaxBlobSize(ctx context.Context) (uint64, error) { - ret := _m.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for MaxBlobSize") - } - - var r0 uint64 - var r1 error - if rf, ok := ret.Get(0).(func(context.Context) (uint64, error)); ok { - return rf(ctx) - } - if rf, ok := ret.Get(0).(func(context.Context) uint64); ok { - r0 = rf(ctx) - } else { - r0 = ret.Get(0).(uint64) - } - - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(ctx) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Submit provides a mock function with given fields: ctx, blobs, gasPrice, namespace -func (_m *DA) Submit(ctx context.Context, blobs [][]byte, gasPrice float64, namespace []byte) ([][]byte, error) { - ret := _m.Called(ctx, blobs, gasPrice, namespace) +// Submit provides a mock function with given fields: ctx, blobs, gasPrice, options +func (_m *DA) Submit(ctx context.Context, blobs [][]byte, gasPrice float64, options []byte) ([][]byte, error) { + ret := _m.Called(ctx, blobs, gasPrice, options) if len(ret) == 0 { panic("no return value specified for Submit") @@ -229,10 +201,10 @@ func (_m *DA) Submit(ctx context.Context, blobs [][]byte, gasPrice float64, name var r0 [][]byte var r1 error if rf, ok := ret.Get(0).(func(context.Context, [][]byte, float64, []byte) ([][]byte, error)); ok { - return rf(ctx, blobs, gasPrice, namespace) + return rf(ctx, blobs, gasPrice, options) } if rf, ok := ret.Get(0).(func(context.Context, [][]byte, float64, []byte) [][]byte); ok { - r0 = rf(ctx, blobs, gasPrice, namespace) + r0 = rf(ctx, blobs, gasPrice, options) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([][]byte) @@ -240,37 +212,7 @@ func (_m *DA) Submit(ctx context.Context, blobs [][]byte, gasPrice float64, name } if rf, ok := ret.Get(1).(func(context.Context, [][]byte, float64, []byte) error); ok { - r1 = rf(ctx, blobs, gasPrice, namespace) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// SubmitWithOptions provides a mock function with given fields: ctx, blobs, gasPrice, namespace, options -func (_m *DA) SubmitWithOptions(ctx context.Context, blobs [][]byte, gasPrice float64, namespace []byte, options []byte) ([][]byte, error) { - ret := _m.Called(ctx, blobs, gasPrice, namespace, options) - - if len(ret) == 0 { - panic("no return value specified for SubmitWithOptions") - } - - var r0 [][]byte - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, float64, []byte, []byte) ([][]byte, error)); ok { - return rf(ctx, blobs, gasPrice, namespace, options) - } - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, float64, []byte, []byte) [][]byte); ok { - r0 = rf(ctx, blobs, gasPrice, namespace, options) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([][]byte) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, [][]byte, float64, []byte, []byte) error); ok { - r1 = rf(ctx, blobs, gasPrice, namespace, options) + r1 = rf(ctx, blobs, gasPrice, options) } else { r1 = ret.Error(1) } @@ -278,9 +220,9 @@ func (_m *DA) SubmitWithOptions(ctx context.Context, blobs [][]byte, gasPrice fl return r0, r1 } -// Validate provides a mock function with given fields: ctx, ids, proofs, namespace -func (_m *DA) Validate(ctx context.Context, ids [][]byte, proofs [][]byte, namespace []byte) ([]bool, error) { - ret := _m.Called(ctx, ids, proofs, namespace) +// Validate provides a mock function with given fields: ctx, ids, proofs +func (_m *DA) Validate(ctx context.Context, ids [][]byte, proofs [][]byte) ([]bool, error) { + ret := _m.Called(ctx, ids, proofs) if len(ret) == 0 { panic("no return value specified for Validate") @@ -288,19 +230,19 @@ func (_m *DA) Validate(ctx context.Context, ids [][]byte, proofs [][]byte, names var r0 []bool var r1 error - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, [][]byte, []byte) ([]bool, error)); ok { - return rf(ctx, ids, proofs, namespace) + if rf, ok := ret.Get(0).(func(context.Context, [][]byte, [][]byte) ([]bool, error)); ok { + return rf(ctx, ids, proofs) } - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, [][]byte, []byte) []bool); ok { - r0 = rf(ctx, ids, proofs, namespace) + if rf, ok := ret.Get(0).(func(context.Context, [][]byte, [][]byte) []bool); ok { + r0 = rf(ctx, ids, proofs) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]bool) } } - if rf, ok := ret.Get(1).(func(context.Context, [][]byte, [][]byte, []byte) error); ok { - r1 = rf(ctx, ids, proofs, namespace) + if rf, ok := ret.Get(1).(func(context.Context, [][]byte, [][]byte) error); ok { + r1 = rf(ctx, ids, proofs) } else { r1 = ret.Error(1) } diff --git a/da/jsonrpc/client.go b/da/jsonrpc/client.go index 593501b2f0..a0fbf1ac51 100644 --- a/da/jsonrpc/client.go +++ b/da/jsonrpc/client.go @@ -25,20 +25,19 @@ type API struct { Namespace []byte MaxBlobSize uint64 Internal struct { - Get func(ctx context.Context, ids []da.ID, ns []byte) ([]da.Blob, error) `perm:"read"` - GetIDs func(ctx context.Context, height uint64, ns []byte) (*da.GetIDsResult, error) `perm:"read"` - GetProofs func(ctx context.Context, ids []da.ID, ns []byte) ([]da.Proof, error) `perm:"read"` - Commit func(ctx context.Context, blobs []da.Blob, ns []byte) ([]da.Commitment, error) `perm:"read"` - Validate func(context.Context, []da.ID, []da.Proof, []byte) ([]bool, error) `perm:"read"` - Submit func(context.Context, []da.Blob, float64, []byte) ([]da.ID, error) `perm:"write"` - SubmitWithOptions func(context.Context, []da.Blob, float64, []byte, []byte) ([]da.ID, error) `perm:"write"` - GasMultiplier func(context.Context) (float64, error) `perm:"read"` - GasPrice func(context.Context) (float64, error) `perm:"read"` + Get func(ctx context.Context, ids []da.ID, ns []byte) ([]da.Blob, error) `perm:"read"` + GetIDs func(ctx context.Context, height uint64, ns []byte) (*da.GetIDsResult, error) `perm:"read"` + GetProofs func(ctx context.Context, ids []da.ID, ns []byte) ([]da.Proof, error) `perm:"read"` + Commit func(ctx context.Context, blobs []da.Blob, ns []byte) ([]da.Commitment, error) `perm:"read"` + Validate func(context.Context, []da.ID, []da.Proof, []byte) ([]bool, error) `perm:"read"` + Submit func(context.Context, []da.Blob, float64, []byte, []byte) ([]da.ID, error) `perm:"write"` + GasMultiplier func(context.Context) (float64, error) `perm:"read"` + GasPrice func(context.Context) (float64, error) `perm:"read"` } } // Get returns Blob for each given ID, or an error. -func (api *API) Get(ctx context.Context, ids []da.ID, _ []byte) ([]da.Blob, error) { +func (api *API) Get(ctx context.Context, ids []da.ID) ([]da.Blob, error) { api.Logger.Debug("Making RPC call", "method", "Get", "num_ids", len(ids), "namespace", string(api.Namespace)) res, err := api.Internal.Get(ctx, ids, api.Namespace) if err != nil { @@ -55,7 +54,7 @@ func (api *API) Get(ctx context.Context, ids []da.ID, _ []byte) ([]da.Blob, erro } // GetIDs returns IDs of all Blobs located in DA at given height. -func (api *API) GetIDs(ctx context.Context, height uint64, _ []byte) (*da.GetIDsResult, error) { +func (api *API) GetIDs(ctx context.Context, height uint64) (*da.GetIDsResult, error) { api.Logger.Debug("Making RPC call", "method", "GetIDs", "height", height, "namespace", string(api.Namespace)) res, err := api.Internal.GetIDs(ctx, height, api.Namespace) if err != nil { @@ -88,7 +87,7 @@ func (api *API) GetIDs(ctx context.Context, height uint64, _ []byte) (*da.GetIDs } // GetProofs returns inclusion Proofs for Blobs specified by their IDs. -func (api *API) GetProofs(ctx context.Context, ids []da.ID, _ []byte) ([]da.Proof, error) { +func (api *API) GetProofs(ctx context.Context, ids []da.ID) ([]da.Proof, error) { api.Logger.Debug("Making RPC call", "method", "GetProofs", "num_ids", len(ids), "namespace", string(api.Namespace)) res, err := api.Internal.GetProofs(ctx, ids, api.Namespace) if err != nil { @@ -100,7 +99,7 @@ func (api *API) GetProofs(ctx context.Context, ids []da.ID, _ []byte) ([]da.Proo } // Commit creates a Commitment for each given Blob. -func (api *API) Commit(ctx context.Context, blobs []da.Blob, _ []byte) ([]da.Commitment, error) { +func (api *API) Commit(ctx context.Context, blobs []da.Blob) ([]da.Commitment, error) { api.Logger.Debug("Making RPC call", "method", "Commit", "num_blobs", len(blobs), "namespace", string(api.Namespace)) res, err := api.Internal.Commit(ctx, blobs, api.Namespace) if err != nil { @@ -112,7 +111,7 @@ func (api *API) Commit(ctx context.Context, blobs []da.Blob, _ []byte) ([]da.Com } // Validate validates Commitments against the corresponding Proofs. This should be possible without retrieving the Blobs. -func (api *API) Validate(ctx context.Context, ids []da.ID, proofs []da.Proof, _ []byte) ([]bool, error) { +func (api *API) Validate(ctx context.Context, ids []da.ID, proofs []da.Proof) ([]bool, error) { api.Logger.Debug("Making RPC call", "method", "Validate", "num_ids", len(ids), "num_proofs", len(proofs), "namespace", string(api.Namespace)) res, err := api.Internal.Validate(ctx, ids, proofs, api.Namespace) if err != nil { @@ -123,29 +122,13 @@ func (api *API) Validate(ctx context.Context, ids []da.ID, proofs []da.Proof, _ return res, err } -// Submit submits the Blobs to Data Availability layer. -func (api *API) Submit(ctx context.Context, blobs []da.Blob, gasPrice float64, _ []byte) ([]da.ID, error) { - api.Logger.Debug("Making RPC call", "method", "Submit", "num_blobs", len(blobs), "gas_price", gasPrice, "namespace", string(api.Namespace)) - res, err := api.Internal.Submit(ctx, blobs, gasPrice, api.Namespace) - if err != nil { - if strings.Contains(err.Error(), context.Canceled.Error()) { - api.Logger.Debug("RPC call canceled due to context cancellation", "method", "Submit") - return res, context.Canceled - } - api.Logger.Error("RPC call failed", "method", "Submit", "error", err) - } else { - api.Logger.Debug("RPC call successful", "method", "Submit", "num_ids_returned", len(res)) - } - return res, err -} - -// SubmitWithOptions submits the Blobs to Data Availability layer with additional options. +// Submit submits the Blobs to Data Availability layer with additional options. // It checks blobs against MaxBlobSize and submits only those that fit. -func (api *API) SubmitWithOptions(ctx context.Context, inputBlobs []da.Blob, gasPrice float64, _ []byte, options []byte) ([]da.ID, error) { +func (api *API) Submit(ctx context.Context, inputBlobs []da.Blob, gasPrice float64, options []byte) ([]da.ID, error) { maxBlobSize := api.MaxBlobSize var ( - blobsToSubmit [][]byte = make([][]byte, 0, len(inputBlobs)) + blobsToSubmit []da.Blob = make([]da.Blob, 0, len(inputBlobs)) currentSize uint64 oversizeBlobs int ) @@ -178,16 +161,16 @@ func (api *API) SubmitWithOptions(ctx context.Context, inputBlobs []da.Blob, gas return []da.ID{}, nil } - api.Logger.Debug("Making RPC call", "method", "SubmitWithOptions", "num_blobs_original", len(inputBlobs), "num_blobs_to_submit", len(blobsToSubmit), "gas_price", gasPrice, "namespace", string(api.Namespace)) - res, err := api.Internal.SubmitWithOptions(ctx, blobsToSubmit, gasPrice, api.Namespace, options) + api.Logger.Debug("Making RPC call", "method", "Submit", "num_blobs_original", len(inputBlobs), "num_blobs_to_submit", len(blobsToSubmit), "gas_price", gasPrice, "namespace", string(api.Namespace)) + res, err := api.Internal.Submit(ctx, blobsToSubmit, gasPrice, api.Namespace, options) if err != nil { if strings.Contains(err.Error(), context.Canceled.Error()) { - api.Logger.Debug("RPC call canceled due to context cancellation", "method", "SubmitWithOptions") + api.Logger.Debug("RPC call canceled due to context cancellation", "method", "Submit") return res, context.Canceled } - api.Logger.Error("RPC call failed", "method", "SubmitWithOptions", "error", err) + api.Logger.Error("RPC call failed", "method", "Submit", "error", err) } else { - api.Logger.Debug("RPC call successful", "method", "SubmitWithOptions", "num_ids_returned", len(res)) + api.Logger.Debug("RPC call successful", "method", "Submit", "num_ids_returned", len(res)) } return res, err diff --git a/da/jsonrpc/proxy_test.go b/da/jsonrpc/proxy_test.go index 1ebc8e46ba..9f0bc2bfd9 100644 --- a/da/jsonrpc/proxy_test.go +++ b/da/jsonrpc/proxy_test.go @@ -34,88 +34,76 @@ const ( var testNamespace = []byte("test") var emptyOptions = []byte{} -// TestProxy runs the go-da DA test suite against the JSONRPC service -// NOTE: This test requires a test JSONRPC service to run on the port -// 3450 which is chosen to be sufficiently distinct from the default port - func getTestDABlockTime() time.Duration { return 100 * time.Millisecond } -func TestProxy(t *testing.T) { +// setupTestProxy initializes a DA server and client for testing. +func setupTestProxy(t *testing.T) (coreda.DA, func()) { + t.Helper() + dummy := coreda.NewDummyDA(100_000, 0, 0, getTestDABlockTime()) dummy.StartHeightTicker() logger := log.NewTestLogger(t) server := proxy.NewServer(logger, ServerHost, ServerPort, dummy) err := server.Start(context.Background()) require.NoError(t, err) - defer func() { - if err := server.Stop(context.Background()); err != nil { - require.NoError(t, err) - } - }() client, err := proxy.NewClient(context.Background(), logger, ClientURL, "", "74657374") require.NoError(t, err) - t.Run("Basic DA test", func(t *testing.T) { - BasicDATest(t, &client.DA) - }) - t.Run("Get IDs and all data", func(t *testing.T) { - GetIDsTest(t, &client.DA) - }) - t.Run("Check Errors", func(t *testing.T) { - CheckErrors(t, &client.DA) - }) - t.Run("Concurrent read/write test", func(t *testing.T) { - ConcurrentReadWriteTest(t, &client.DA) - }) - t.Run("Given height is from the future", func(t *testing.T) { - HeightFromFutureTest(t, &client.DA) - }) - dummy.StopHeightTicker() + cleanup := func() { + dummy.StopHeightTicker() + if err := server.Stop(context.Background()); err != nil { + require.NoError(t, err) + } + } + return &client.DA, cleanup } -// BasicDATest tests round trip of messages to DA and back. -func BasicDATest(t *testing.T, d coreda.DA) { +// TestProxyBasicDATest tests round trip of messages to DA and back. +func TestProxyBasicDATest(t *testing.T) { + d, cleanup := setupTestProxy(t) + defer cleanup() + msg1 := []byte("message 1") msg2 := []byte("message 2") - ctx := t.Context() - id1, err := d.Submit(ctx, []coreda.Blob{msg1}, 0, testNamespace) + ctx := context.TODO() + id1, err := d.Submit(ctx, []coreda.Blob{msg1}, 0, nil) assert.NoError(t, err) assert.NotEmpty(t, id1) - id2, err := d.Submit(ctx, []coreda.Blob{msg2}, 0, testNamespace) + id2, err := d.Submit(ctx, []coreda.Blob{msg2}, 0, nil) assert.NoError(t, err) assert.NotEmpty(t, id2) time.Sleep(getTestDABlockTime()) - id3, err := d.SubmitWithOptions(ctx, []coreda.Blob{msg1}, 0, testNamespace, []byte("random options")) + id3, err := d.Submit(ctx, []coreda.Blob{msg1}, 0, []byte("random options")) assert.NoError(t, err) assert.NotEmpty(t, id3) assert.NotEqual(t, id1, id2) assert.NotEqual(t, id1, id3) - ret, err := d.Get(ctx, id1, testNamespace) + ret, err := d.Get(ctx, id1) assert.NoError(t, err) assert.Equal(t, []coreda.Blob{msg1}, ret) - commitment1, err := d.Commit(ctx, []coreda.Blob{msg1}, []byte{}) + commitment1, err := d.Commit(ctx, []coreda.Blob{msg1}) assert.NoError(t, err) assert.NotEmpty(t, commitment1) - commitment2, err := d.Commit(ctx, []coreda.Blob{msg2}, []byte{}) + commitment2, err := d.Commit(ctx, []coreda.Blob{msg2}) assert.NoError(t, err) assert.NotEmpty(t, commitment2) ids := []coreda.ID{id1[0], id2[0], id3[0]} - proofs, err := d.GetProofs(ctx, ids, testNamespace) + proofs, err := d.GetProofs(ctx, ids) assert.NoError(t, err) assert.NotEmpty(t, proofs) - oks, err := d.Validate(ctx, ids, proofs, testNamespace) + oks, err := d.Validate(ctx, ids, proofs) assert.NoError(t, err) assert.NotEmpty(t, oks) for _, ok := range oks { @@ -123,21 +111,27 @@ func BasicDATest(t *testing.T, d coreda.DA) { } } -// CheckErrors ensures that errors are handled properly by DA. -func CheckErrors(t *testing.T, d coreda.DA) { - ctx := t.Context() - blob, err := d.Get(ctx, []coreda.ID{[]byte("invalid blob id")}, testNamespace) +// TestProxyCheckErrors ensures that errors are handled properly by DA. +func TestProxyCheckErrors(t *testing.T) { + d, cleanup := setupTestProxy(t) + defer cleanup() + + ctx := context.TODO() + blob, err := d.Get(ctx, []coreda.ID{[]byte("invalid blob id")}) assert.Error(t, err) assert.ErrorContains(t, err, coreda.ErrBlobNotFound.Error()) assert.Empty(t, blob) } -// GetIDsTest tests iteration over DA -func GetIDsTest(t *testing.T, d coreda.DA) { +// TestProxyGetIDsTest tests iteration over DA +func TestProxyGetIDsTest(t *testing.T) { + d, cleanup := setupTestProxy(t) + defer cleanup() + msgs := []coreda.Blob{[]byte("msg1"), []byte("msg2"), []byte("msg3")} - ctx := t.Context() - ids, err := d.Submit(ctx, msgs, 0, testNamespace) + ctx := context.TODO() + ids, err := d.Submit(ctx, msgs, 0, nil) time.Sleep(getTestDABlockTime()) assert.NoError(t, err) assert.Len(t, ids, len(msgs)) @@ -148,17 +142,22 @@ func GetIDsTest(t *testing.T, d coreda.DA) { // As we're the only user, we don't need to handle external data (that could be submitted in real world). // There is no notion of height, so we need to scan the DA to get test data back. for i := uint64(1); !found && !time.Now().After(end); i++ { - ret, err := d.GetIDs(ctx, i, []byte{}) + ret, err := d.GetIDs(ctx, i) if err != nil { + if errors.Is(err, coreda.ErrBlobNotFound) { + // It's okay to not find blobs at a particular height, continue scanning + continue + } if strings.Contains(err.Error(), coreda.ErrHeightFromFuture.Error()) { break } - t.Error("failed to get IDs:", err) + t.Logf("failed to get IDs at height %d: %v", i, err) // Log other errors + continue // Continue to avoid nil pointer dereference on ret } - assert.NotNil(t, ret) + assert.NotNil(t, ret, "ret should not be nil after GetIDs if no error or ErrBlobNotFound") assert.NotZero(t, ret.Timestamp) if len(ret.IDs) > 0 { - blobs, err := d.Get(ctx, ret.IDs, testNamespace) + blobs, err := d.Get(ctx, ret.IDs) assert.NoError(t, err) // Submit ensures atomicity of batch, so it makes sense to compare actual blobs (bodies) only when lengths @@ -185,8 +184,11 @@ func GetIDsTest(t *testing.T, d coreda.DA) { assert.True(t, found) } -// ConcurrentReadWriteTest tests the use of mutex lock in DummyDA by calling separate methods that use `d.data` and making sure there's no race conditions -func ConcurrentReadWriteTest(t *testing.T, d coreda.DA) { +// TestProxyConcurrentReadWriteTest tests the use of mutex lock in DummyDA +func TestProxyConcurrentReadWriteTest(t *testing.T) { + d, cleanup := setupTestProxy(t) + defer cleanup() + var wg sync.WaitGroup ctx, cancel := context.WithTimeout(t.Context(), 5*time.Second) defer cancel() @@ -211,7 +213,15 @@ func ConcurrentReadWriteTest(t *testing.T, d coreda.DA) { case <-writeDone: return default: - d.GetIDs(ctx, 0, []byte("test")) + ret, err := d.GetIDs(ctx, 1) + if err != nil { + // Only check ret for nil, do not access ret.IDs if err is not nil + assert.Nil(t, ret) + } else { + assert.NotNil(t, ret) + // Only access ret.IDs if ret is not nil + assert.NotNil(t, ret.IDs) + } } } }() @@ -219,10 +229,13 @@ func ConcurrentReadWriteTest(t *testing.T, d coreda.DA) { wg.Wait() } -// HeightFromFutureTest tests the case when the given height is from the future -func HeightFromFutureTest(t *testing.T, d coreda.DA) { - ctx := t.Context() - _, err := d.GetIDs(ctx, 999999999, []byte("test")) +// TestProxyHeightFromFutureTest tests the case when the given height is from the future +func TestProxyHeightFromFutureTest(t *testing.T) { + d, cleanup := setupTestProxy(t) + defer cleanup() + + ctx := context.TODO() + _, err := d.GetIDs(ctx, 999999999) assert.Error(t, err) // Specifically check if the error contains the error message ErrHeightFromFuture assert.ErrorContains(t, err, coreda.ErrHeightFromFuture.Error()) @@ -238,10 +251,13 @@ func TestSubmitWithOptions(t *testing.T) { // Helper function to create a client with a mocked internal API createMockedClient := func(internalAPI *mocks.DA) *proxy.Client { client := &proxy.Client{} - client.DA.Internal.SubmitWithOptions = internalAPI.SubmitWithOptions client.DA.Namespace = testNamespace client.DA.MaxBlobSize = testMaxBlobSize client.DA.Logger = log.NewTestLogger(t) + // Wire the Internal.Submit to the mock's Submit method + client.DA.Internal.Submit = func(ctx context.Context, blobs []coreda.Blob, gasPrice float64, ns []byte, options []byte) ([]coreda.ID, error) { + return internalAPI.Submit(ctx, blobs, gasPrice, options) + } return client } @@ -252,9 +268,9 @@ func TestSubmitWithOptions(t *testing.T) { blobs := []coreda.Blob{[]byte("blob1"), []byte("blob2")} expectedIDs := []coreda.ID{[]byte("id1"), []byte("id2")} - mockAPI.On("SubmitWithOptions", ctx, blobs, gasPrice, testNamespace, testOptions).Return(expectedIDs, nil).Once() + mockAPI.On("Submit", ctx, blobs, gasPrice, testOptions).Return(expectedIDs, nil).Once() - ids, err := client.DA.SubmitWithOptions(ctx, blobs, gasPrice, testNamespace, testOptions) + ids, err := client.DA.Submit(ctx, blobs, gasPrice, testOptions) require.NoError(t, err) assert.Equal(t, expectedIDs, ids) @@ -268,7 +284,7 @@ func TestSubmitWithOptions(t *testing.T) { largerBlob := make([]byte, testMaxBlobSize+1) blobs := []coreda.Blob{largerBlob, []byte("this blob is definitely too large")} - _, err := client.DA.SubmitWithOptions(ctx, blobs, gasPrice, testNamespace, testOptions) + _, err := client.DA.Submit(ctx, blobs, gasPrice, testOptions) require.Error(t, err) mockAPI.AssertExpectations(t) @@ -285,9 +301,9 @@ func TestSubmitWithOptions(t *testing.T) { expectedSubmitBlobs := []coreda.Blob{blobs[0], blobs[1]} expectedIDs := []coreda.ID{[]byte("idA"), []byte("idB")} - mockAPI.On("SubmitWithOptions", ctx, expectedSubmitBlobs, gasPrice, testNamespace, testOptions).Return(expectedIDs, nil).Once() + mockAPI.On("Submit", ctx, expectedSubmitBlobs, gasPrice, testOptions).Return(expectedIDs, nil).Once() - ids, err := client.DA.SubmitWithOptions(ctx, blobs, gasPrice, testNamespace, testOptions) + ids, err := client.DA.Submit(ctx, blobs, gasPrice, testOptions) require.NoError(t, err) assert.Equal(t, expectedIDs, ids) @@ -301,13 +317,13 @@ func TestSubmitWithOptions(t *testing.T) { largerBlob := make([]byte, testMaxBlobSize+1) blobs := []coreda.Blob{largerBlob, []byte("small")} - ids, err := client.DA.SubmitWithOptions(ctx, blobs, gasPrice, testNamespace, testOptions) + ids, err := client.DA.Submit(ctx, blobs, gasPrice, testOptions) require.Error(t, err) assert.ErrorIs(t, err, coreda.ErrBlobSizeOverLimit) assert.Nil(t, ids) - mockAPI.AssertNotCalled(t, "SubmitWithOptions", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything) + mockAPI.AssertNotCalled(t, "Submit", mock.Anything, mock.Anything, mock.Anything, mock.Anything) mockAPI.AssertExpectations(t) }) @@ -317,25 +333,25 @@ func TestSubmitWithOptions(t *testing.T) { var blobs []coreda.Blob - ids, err := client.DA.SubmitWithOptions(ctx, blobs, gasPrice, testNamespace, testOptions) + ids, err := client.DA.Submit(ctx, blobs, gasPrice, testOptions) require.NoError(t, err) assert.Empty(t, ids) - mockAPI.AssertNotCalled(t, "SubmitWithOptions", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything) + mockAPI.AssertNotCalled(t, "Submit", mock.Anything, mock.Anything, mock.Anything, mock.Anything) mockAPI.AssertExpectations(t) }) - t.Run("Error During SubmitWithOptions RPC", func(t *testing.T) { + t.Run("Error During Submit RPC", func(t *testing.T) { mockAPI := mocks.NewDA(t) client := createMockedClient(mockAPI) blobs := []coreda.Blob{[]byte("blob1")} expectedError := errors.New("rpc submit failed") - mockAPI.On("SubmitWithOptions", ctx, blobs, gasPrice, testNamespace, testOptions).Return(nil, expectedError).Once() + mockAPI.On("Submit", ctx, blobs, gasPrice, testOptions).Return(nil, expectedError).Once() - ids, err := client.DA.SubmitWithOptions(ctx, blobs, gasPrice, testNamespace, testOptions) + ids, err := client.DA.Submit(ctx, blobs, gasPrice, testOptions) require.Error(t, err) assert.ErrorIs(t, err, expectedError) diff --git a/da/jsonrpc/server.go b/da/jsonrpc/server.go index e75216307f..03db1e6afd 100644 --- a/da/jsonrpc/server.go +++ b/da/jsonrpc/server.go @@ -19,31 +19,85 @@ type Server struct { srv *http.Server rpc *jsonrpc.RPCServer listener net.Listener + daImpl da.DA started atomic.Bool } -// RegisterService registers a service onto the RPC server. All methods on the service will then be -// exposed over the RPC. -func (s *Server) RegisterService(namespace string, service interface{}, out interface{}) { - s.rpc.Register(namespace, service) +// serverInternalAPI provides the actual RPC methods. +type serverInternalAPI struct { + logger log.Logger + daImpl da.DA +} + +// Get implements the RPC method. +func (s *serverInternalAPI) Get(ctx context.Context, ids []da.ID, ns []byte) ([]da.Blob, error) { + s.logger.Debug("RPC server: Get called", "num_ids", len(ids), "namespace", string(ns)) + return s.daImpl.Get(ctx, ids) +} + +// GetIDs implements the RPC method. +func (s *serverInternalAPI) GetIDs(ctx context.Context, height uint64, ns []byte) (*da.GetIDsResult, error) { + s.logger.Debug("RPC server: GetIDs called", "height", height, "namespace", string(ns)) + return s.daImpl.GetIDs(ctx, height) +} + +// GetProofs implements the RPC method. +func (s *serverInternalAPI) GetProofs(ctx context.Context, ids []da.ID, ns []byte) ([]da.Proof, error) { + s.logger.Debug("RPC server: GetProofs called", "num_ids", len(ids), "namespace", string(ns)) + return s.daImpl.GetProofs(ctx, ids) +} + +// Commit implements the RPC method. +func (s *serverInternalAPI) Commit(ctx context.Context, blobs []da.Blob, ns []byte) ([]da.Commitment, error) { + s.logger.Debug("RPC server: Commit called", "num_blobs", len(blobs), "namespace", string(ns)) + return s.daImpl.Commit(ctx, blobs) +} + +// Validate implements the RPC method. +func (s *serverInternalAPI) Validate(ctx context.Context, ids []da.ID, proofs []da.Proof, ns []byte) ([]bool, error) { + s.logger.Debug("RPC server: Validate called", "num_ids", len(ids), "num_proofs", len(proofs), "namespace", string(ns)) + return s.daImpl.Validate(ctx, ids, proofs) +} + +// Submit implements the RPC method. This is the primary submit method which includes options. +func (s *serverInternalAPI) Submit(ctx context.Context, blobs []da.Blob, gasPrice float64, ns []byte, options []byte) ([]da.ID, error) { + s.logger.Debug("RPC server: Submit called", "num_blobs", len(blobs), "gas_price", gasPrice, "namespace", string(ns), "options", string(options)) + return s.daImpl.Submit(ctx, blobs, gasPrice, options) // Pass options to underlying DA +} + +// GasPrice implements the RPC method. +func (s *serverInternalAPI) GasPrice(ctx context.Context) (float64, error) { + s.logger.Debug("RPC server: GasPrice called") + return s.daImpl.GasPrice(ctx) +} + +// GasMultiplier implements the RPC method. +func (s *serverInternalAPI) GasMultiplier(ctx context.Context) (float64, error) { + s.logger.Debug("RPC server: GasMultiplier called") + return s.daImpl.GasMultiplier(ctx) } // NewServer accepts the host address port and the DA implementation to serve as a jsonrpc service -func NewServer(logger log.Logger, address, port string, DA da.DA) *Server { +func NewServer(logger log.Logger, address, port string, daImplementation da.DA) *Server { rpc := jsonrpc.NewServer(jsonrpc.WithServerErrors(getKnownErrorsMapping())) srv := &Server{ - rpc: rpc, + rpc: rpc, + logger: logger, + daImpl: daImplementation, srv: &http.Server{ - Addr: address + ":" + port, - // the amount of time allowed to read request headers. set to the default 2 seconds + Addr: address + ":" + port, ReadHeaderTimeout: 2 * time.Second, }, - logger: logger, } srv.srv.Handler = http.HandlerFunc(rpc.ServeHTTP) - // Wrap the provided DA implementation with the logging decorator - srv.RegisterService("da", DA, &API{Logger: logger}) // Register the wrapper + + apiHandler := &serverInternalAPI{ + logger: logger, + daImpl: daImplementation, + } + + srv.rpc.Register("da", apiHandler) return srv } diff --git a/scripts/test.mk b/scripts/test.mk index ce6d53d90c..d65a672e4a 100644 --- a/scripts/test.mk +++ b/scripts/test.mk @@ -11,9 +11,9 @@ test: .PHONY: test ## test-e2e: Running e2e tests -test-integration: +test-integration: @echo "--> Running e2e tests" - @cd node && go test -mod=readonly -failfast -timeout=15m -tags='integration' ./... + @cd node && go test -mod=readonly -failfast -timeout=15m -tags='integration' ./... .PHONY: test-integration ## test-e2e: Running e2e tests @@ -42,4 +42,4 @@ test-evm: ## test-docker-e2e: Running Docker E2E tests test-docker-e2e: @echo "--> Running Docker E2E tests" - @cd test/docker-e2e && go test -mod=readonly -failfast -timeout=30m ./... + @cd test/docker-e2e && go test -mod=readonly -failfast -tags='docker_e2e' -timeout=30m ./... diff --git a/scripts/test_cover.go b/scripts/test_cover.go index 5aee7e4fc6..22c5c81555 100644 --- a/scripts/test_cover.go +++ b/scripts/test_cover.go @@ -10,15 +10,12 @@ import ( "os" "os/exec" "path/filepath" - "slices" "strings" ) func main() { rootDir := "." - excludeDirs := []string{filepath.ToSlash("test/docker-e2e")} - var coverFiles []string var testFailures bool @@ -41,11 +38,6 @@ func main() { fullCoverProfilePath := filepath.Join(modDir, "cover.out") relativeCoverProfileArg := "cover.out" - if slices.Contains(excludeDirs, modDir) { - fmt.Printf("--> Skipping tests in: %s\n as they are marked as excluded", modDir) - return nil - } - fmt.Printf("--> Running tests with coverage in: %s (profile: %s)\n", modDir, relativeCoverProfileArg) cmd := exec.Command("go", "test", "./...", "-race", "-coverprofile="+relativeCoverProfileArg, "-covermode=atomic") cmd.Dir = modDir diff --git a/scripts/utils.mk b/scripts/utils.mk index 1e7364915e..9eff8b6390 100644 --- a/scripts/utils.mk +++ b/scripts/utils.mk @@ -45,7 +45,6 @@ mock-gen: @echo "-> Generating mocks" mockery --output da/internal/mocks --srcpkg github.com/rollkit/rollkit/core/da --name DA --filename="da.go" mockery --output test/mocks --srcpkg github.com/rollkit/rollkit/core/da --name DA --filename="da.go" - mockery --output test/mocks --srcpkg github.com/rollkit/rollkit/core/da --name Client --filename="daclient.go" mockery --output test/mocks --srcpkg github.com/rollkit/rollkit/core/execution --name Executor --filename="execution.go" mockery --output test/mocks --srcpkg github.com/rollkit/rollkit/core/sequencer --name Sequencer --filename="sequencer.go" mockery --output test/mocks --srcpkg github.com/rollkit/rollkit/pkg/store --name Store --filename="store.go" diff --git a/sequencers/based/sequencer.go b/sequencers/based/sequencer.go index ab2f6e0288..279bd45286 100644 --- a/sequencers/based/sequencer.go +++ b/sequencers/based/sequencer.go @@ -218,13 +218,13 @@ func (s *Sequencer) VerifyBatch(ctx context.Context, req coresequencer.VerifyBat return nil, ErrInvalidId } // Use stored namespace - proofs, err := s.DA.GetProofs(ctx, req.BatchData, []byte("placeholder")) + proofs, err := s.DA.GetProofs(ctx, req.BatchData) if err != nil { return nil, fmt.Errorf("failed to get proofs: %w", err) } // verify the proof - valid, err := s.DA.Validate(ctx, req.BatchData, proofs, []byte("placeholder")) + valid, err := s.DA.Validate(ctx, req.BatchData, proofs) if err != nil { return nil, fmt.Errorf("failed to validate proof: %w", err) } diff --git a/sequencers/single/sequencer.go b/sequencers/single/sequencer.go index bba325fa9a..ec7527d9fc 100644 --- a/sequencers/single/sequencer.go +++ b/sequencers/single/sequencer.go @@ -153,12 +153,12 @@ func (c *Sequencer) VerifyBatch(ctx context.Context, req coresequencer.VerifyBat if !c.proposer { - proofs, err := c.da.GetProofs(ctx, req.BatchData, []byte("placeholder")) + proofs, err := c.da.GetProofs(ctx, req.BatchData) if err != nil { return nil, fmt.Errorf("failed to get proofs: %w", err) } - valid, err := c.da.Validate(ctx, req.BatchData, proofs, []byte("placeholder")) + valid, err := c.da.Validate(ctx, req.BatchData, proofs) if err != nil { return nil, fmt.Errorf("failed to validate proof: %w", err) } diff --git a/sequencers/single/sequencer_test.go b/sequencers/single/sequencer_test.go index 9670708e20..c37c649071 100644 --- a/sequencers/single/sequencer_test.go +++ b/sequencers/single/sequencer_test.go @@ -239,7 +239,6 @@ func TestSequencer_VerifyBatch(t *testing.T) { }() Id := []byte("test") - namespace := []byte("placeholder") batchData := [][]byte{[]byte("batch1"), []byte("batch2")} proofs := [][]byte{[]byte("proof1"), []byte("proof2")} @@ -260,8 +259,8 @@ func TestSequencer_VerifyBatch(t *testing.T) { assert.NotNil(res) assert.True(res.Status, "Expected status to be true in proposer mode") - mockDA.AssertNotCalled(t, "GetProofs", context.Background(), mock.Anything, mock.Anything) - mockDA.AssertNotCalled(t, "Validate", mock.Anything, mock.Anything, mock.Anything, mock.Anything) + mockDA.AssertNotCalled(t, "GetProofs", context.Background(), mock.Anything) + mockDA.AssertNotCalled(t, "Validate", mock.Anything, mock.Anything, mock.Anything) }) t.Run("Non-Proposer Mode", func(t *testing.T) { @@ -276,8 +275,8 @@ func TestSequencer_VerifyBatch(t *testing.T) { batchSubmissionChan: make(chan coresequencer.Batch, 1), } - mockDA.On("GetProofs", context.Background(), batchData, namespace).Return(proofs, nil).Once() - mockDA.On("Validate", mock.Anything, batchData, proofs, namespace).Return([]bool{true, true}, nil).Once() + mockDA.On("GetProofs", context.Background(), batchData).Return(proofs, nil).Once() + mockDA.On("Validate", mock.Anything, batchData, proofs).Return([]bool{true, true}, nil).Once() res, err := seq.VerifyBatch(context.Background(), coresequencer.VerifyBatchRequest{Id: seq.Id, BatchData: batchData}) assert.NoError(err) @@ -297,8 +296,8 @@ func TestSequencer_VerifyBatch(t *testing.T) { batchSubmissionChan: make(chan coresequencer.Batch, 1), } - mockDA.On("GetProofs", context.Background(), batchData, namespace).Return(proofs, nil).Once() - mockDA.On("Validate", mock.Anything, batchData, proofs, namespace).Return([]bool{true, false}, nil).Once() + mockDA.On("GetProofs", context.Background(), batchData).Return(proofs, nil).Once() + mockDA.On("Validate", mock.Anything, batchData, proofs).Return([]bool{true, false}, nil).Once() res, err := seq.VerifyBatch(context.Background(), coresequencer.VerifyBatchRequest{Id: seq.Id, BatchData: batchData}) assert.NoError(err) @@ -319,14 +318,14 @@ func TestSequencer_VerifyBatch(t *testing.T) { } expectedErr := errors.New("get proofs failed") - mockDA.On("GetProofs", context.Background(), batchData, namespace).Return(nil, expectedErr).Once() + mockDA.On("GetProofs", context.Background(), batchData).Return(nil, expectedErr).Once() res, err := seq.VerifyBatch(context.Background(), coresequencer.VerifyBatchRequest{Id: seq.Id, BatchData: batchData}) assert.Error(err) assert.Nil(res) assert.Contains(err.Error(), expectedErr.Error()) mockDA.AssertExpectations(t) - mockDA.AssertNotCalled(t, "Validate", mock.Anything, mock.Anything, mock.Anything, mock.Anything) + mockDA.AssertNotCalled(t, "Validate", mock.Anything, mock.Anything, mock.Anything) }) t.Run("Validate Error", func(t *testing.T) { @@ -341,8 +340,8 @@ func TestSequencer_VerifyBatch(t *testing.T) { } expectedErr := errors.New("validate failed") - mockDA.On("GetProofs", context.Background(), batchData, namespace).Return(proofs, nil).Once() - mockDA.On("Validate", mock.Anything, batchData, proofs, namespace).Return(nil, expectedErr).Once() + mockDA.On("GetProofs", context.Background(), batchData).Return(proofs, nil).Once() + mockDA.On("Validate", mock.Anything, batchData, proofs).Return(nil, expectedErr).Once() res, err := seq.VerifyBatch(context.Background(), coresequencer.VerifyBatchRequest{Id: seq.Id, BatchData: batchData}) assert.Error(err) @@ -369,8 +368,8 @@ func TestSequencer_VerifyBatch(t *testing.T) { assert.Nil(res) assert.ErrorIs(err, ErrInvalidId) - mockDA.AssertNotCalled(t, "GetProofs", context.Background(), mock.Anything, mock.Anything) - mockDA.AssertNotCalled(t, "Validate", mock.Anything, mock.Anything, mock.Anything, mock.Anything) + mockDA.AssertNotCalled(t, "GetProofs", context.Background(), mock.Anything) + mockDA.AssertNotCalled(t, "Validate", mock.Anything, mock.Anything, mock.Anything) }) }) } @@ -398,7 +397,7 @@ func TestSequencer_GetNextBatch_BeforeDASubmission(t *testing.T) { // Set up mock expectations mockDA.On("GasPrice", mock.Anything).Return(float64(0), nil) mockDA.On("GasMultiplier", mock.Anything).Return(float64(0), nil) - mockDA.On("SubmitWithOptions", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + mockDA.On("Submit", mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(nil, errors.New("mock DA always rejects submissions")) // Submit a batch diff --git a/test/docker-e2e/base_test.go b/test/docker-e2e/base_test.go index 26f3991b88..9efc4bd685 100644 --- a/test/docker-e2e/base_test.go +++ b/test/docker-e2e/base_test.go @@ -1,9 +1,12 @@ +//go:build docker_e2e + package docker_e2e import ( "context" - "github.com/celestiaorg/tastora/framework/types" "testing" + + "github.com/celestiaorg/tastora/framework/types" ) func (s *DockerTestSuite) TestBasicDockerE2E() { diff --git a/test/docker-e2e/docker_test.go b/test/docker-e2e/docker_test.go index e7cb62b7fd..8493a46d05 100644 --- a/test/docker-e2e/docker_test.go +++ b/test/docker-e2e/docker_test.go @@ -1,10 +1,16 @@ +//go:build docker_e2e + package docker_e2e import ( "context" - "cosmossdk.io/math" "encoding/hex" "fmt" + "os" + "strings" + "testing" + + "cosmossdk.io/math" "github.com/celestiaorg/go-square/v2/share" tastoradocker "github.com/celestiaorg/tastora/framework/docker" "github.com/celestiaorg/tastora/framework/testutil/sdkacc" @@ -17,9 +23,6 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/stretchr/testify/suite" "go.uber.org/zap/zaptest" - "os" - "strings" - "testing" ) const ( diff --git a/test/mocks/da.go b/test/mocks/da.go index af123609c1..9fd281ae0b 100644 --- a/test/mocks/da.go +++ b/test/mocks/da.go @@ -14,9 +14,9 @@ type DA struct { mock.Mock } -// Commit provides a mock function with given fields: ctx, blobs, namespace -func (_m *DA) Commit(ctx context.Context, blobs [][]byte, namespace []byte) ([][]byte, error) { - ret := _m.Called(ctx, blobs, namespace) +// Commit provides a mock function with given fields: ctx, blobs +func (_m *DA) Commit(ctx context.Context, blobs [][]byte) ([][]byte, error) { + ret := _m.Called(ctx, blobs) if len(ret) == 0 { panic("no return value specified for Commit") @@ -24,19 +24,19 @@ func (_m *DA) Commit(ctx context.Context, blobs [][]byte, namespace []byte) ([][ var r0 [][]byte var r1 error - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, []byte) ([][]byte, error)); ok { - return rf(ctx, blobs, namespace) + if rf, ok := ret.Get(0).(func(context.Context, [][]byte) ([][]byte, error)); ok { + return rf(ctx, blobs) } - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, []byte) [][]byte); ok { - r0 = rf(ctx, blobs, namespace) + if rf, ok := ret.Get(0).(func(context.Context, [][]byte) [][]byte); ok { + r0 = rf(ctx, blobs) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([][]byte) } } - if rf, ok := ret.Get(1).(func(context.Context, [][]byte, []byte) error); ok { - r1 = rf(ctx, blobs, namespace) + if rf, ok := ret.Get(1).(func(context.Context, [][]byte) error); ok { + r1 = rf(ctx, blobs) } else { r1 = ret.Error(1) } @@ -100,9 +100,9 @@ func (_m *DA) GasPrice(ctx context.Context) (float64, error) { return r0, r1 } -// Get provides a mock function with given fields: ctx, ids, namespace -func (_m *DA) Get(ctx context.Context, ids [][]byte, namespace []byte) ([][]byte, error) { - ret := _m.Called(ctx, ids, namespace) +// Get provides a mock function with given fields: ctx, ids +func (_m *DA) Get(ctx context.Context, ids [][]byte) ([][]byte, error) { + ret := _m.Called(ctx, ids) if len(ret) == 0 { panic("no return value specified for Get") @@ -110,19 +110,19 @@ func (_m *DA) Get(ctx context.Context, ids [][]byte, namespace []byte) ([][]byte var r0 [][]byte var r1 error - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, []byte) ([][]byte, error)); ok { - return rf(ctx, ids, namespace) + if rf, ok := ret.Get(0).(func(context.Context, [][]byte) ([][]byte, error)); ok { + return rf(ctx, ids) } - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, []byte) [][]byte); ok { - r0 = rf(ctx, ids, namespace) + if rf, ok := ret.Get(0).(func(context.Context, [][]byte) [][]byte); ok { + r0 = rf(ctx, ids) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([][]byte) } } - if rf, ok := ret.Get(1).(func(context.Context, [][]byte, []byte) error); ok { - r1 = rf(ctx, ids, namespace) + if rf, ok := ret.Get(1).(func(context.Context, [][]byte) error); ok { + r1 = rf(ctx, ids) } else { r1 = ret.Error(1) } @@ -130,9 +130,9 @@ func (_m *DA) Get(ctx context.Context, ids [][]byte, namespace []byte) ([][]byte return r0, r1 } -// GetIDs provides a mock function with given fields: ctx, height, namespace -func (_m *DA) GetIDs(ctx context.Context, height uint64, namespace []byte) (*da.GetIDsResult, error) { - ret := _m.Called(ctx, height, namespace) +// GetIDs provides a mock function with given fields: ctx, height +func (_m *DA) GetIDs(ctx context.Context, height uint64) (*da.GetIDsResult, error) { + ret := _m.Called(ctx, height) if len(ret) == 0 { panic("no return value specified for GetIDs") @@ -140,19 +140,19 @@ func (_m *DA) GetIDs(ctx context.Context, height uint64, namespace []byte) (*da. var r0 *da.GetIDsResult var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uint64, []byte) (*da.GetIDsResult, error)); ok { - return rf(ctx, height, namespace) + if rf, ok := ret.Get(0).(func(context.Context, uint64) (*da.GetIDsResult, error)); ok { + return rf(ctx, height) } - if rf, ok := ret.Get(0).(func(context.Context, uint64, []byte) *da.GetIDsResult); ok { - r0 = rf(ctx, height, namespace) + if rf, ok := ret.Get(0).(func(context.Context, uint64) *da.GetIDsResult); ok { + r0 = rf(ctx, height) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*da.GetIDsResult) } } - if rf, ok := ret.Get(1).(func(context.Context, uint64, []byte) error); ok { - r1 = rf(ctx, height, namespace) + if rf, ok := ret.Get(1).(func(context.Context, uint64) error); ok { + r1 = rf(ctx, height) } else { r1 = ret.Error(1) } @@ -160,9 +160,9 @@ func (_m *DA) GetIDs(ctx context.Context, height uint64, namespace []byte) (*da. return r0, r1 } -// GetProofs provides a mock function with given fields: ctx, ids, namespace -func (_m *DA) GetProofs(ctx context.Context, ids [][]byte, namespace []byte) ([][]byte, error) { - ret := _m.Called(ctx, ids, namespace) +// GetProofs provides a mock function with given fields: ctx, ids +func (_m *DA) GetProofs(ctx context.Context, ids [][]byte) ([][]byte, error) { + ret := _m.Called(ctx, ids) if len(ret) == 0 { panic("no return value specified for GetProofs") @@ -170,19 +170,19 @@ func (_m *DA) GetProofs(ctx context.Context, ids [][]byte, namespace []byte) ([] var r0 [][]byte var r1 error - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, []byte) ([][]byte, error)); ok { - return rf(ctx, ids, namespace) + if rf, ok := ret.Get(0).(func(context.Context, [][]byte) ([][]byte, error)); ok { + return rf(ctx, ids) } - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, []byte) [][]byte); ok { - r0 = rf(ctx, ids, namespace) + if rf, ok := ret.Get(0).(func(context.Context, [][]byte) [][]byte); ok { + r0 = rf(ctx, ids) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([][]byte) } } - if rf, ok := ret.Get(1).(func(context.Context, [][]byte, []byte) error); ok { - r1 = rf(ctx, ids, namespace) + if rf, ok := ret.Get(1).(func(context.Context, [][]byte) error); ok { + r1 = rf(ctx, ids) } else { r1 = ret.Error(1) } @@ -190,37 +190,9 @@ func (_m *DA) GetProofs(ctx context.Context, ids [][]byte, namespace []byte) ([] return r0, r1 } -// MaxBlobSize provides a mock function with given fields: ctx -func (_m *DA) MaxBlobSize(ctx context.Context) (uint64, error) { - ret := _m.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for MaxBlobSize") - } - - var r0 uint64 - var r1 error - if rf, ok := ret.Get(0).(func(context.Context) (uint64, error)); ok { - return rf(ctx) - } - if rf, ok := ret.Get(0).(func(context.Context) uint64); ok { - r0 = rf(ctx) - } else { - r0 = ret.Get(0).(uint64) - } - - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(ctx) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Submit provides a mock function with given fields: ctx, blobs, gasPrice, namespace -func (_m *DA) Submit(ctx context.Context, blobs [][]byte, gasPrice float64, namespace []byte) ([][]byte, error) { - ret := _m.Called(ctx, blobs, gasPrice, namespace) +// Submit provides a mock function with given fields: ctx, blobs, gasPrice, options +func (_m *DA) Submit(ctx context.Context, blobs [][]byte, gasPrice float64, options []byte) ([][]byte, error) { + ret := _m.Called(ctx, blobs, gasPrice, options) if len(ret) == 0 { panic("no return value specified for Submit") @@ -229,10 +201,10 @@ func (_m *DA) Submit(ctx context.Context, blobs [][]byte, gasPrice float64, name var r0 [][]byte var r1 error if rf, ok := ret.Get(0).(func(context.Context, [][]byte, float64, []byte) ([][]byte, error)); ok { - return rf(ctx, blobs, gasPrice, namespace) + return rf(ctx, blobs, gasPrice, options) } if rf, ok := ret.Get(0).(func(context.Context, [][]byte, float64, []byte) [][]byte); ok { - r0 = rf(ctx, blobs, gasPrice, namespace) + r0 = rf(ctx, blobs, gasPrice, options) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([][]byte) @@ -240,37 +212,7 @@ func (_m *DA) Submit(ctx context.Context, blobs [][]byte, gasPrice float64, name } if rf, ok := ret.Get(1).(func(context.Context, [][]byte, float64, []byte) error); ok { - r1 = rf(ctx, blobs, gasPrice, namespace) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// SubmitWithOptions provides a mock function with given fields: ctx, blobs, gasPrice, namespace, options -func (_m *DA) SubmitWithOptions(ctx context.Context, blobs [][]byte, gasPrice float64, namespace []byte, options []byte) ([][]byte, error) { - ret := _m.Called(ctx, blobs, gasPrice, namespace, options) - - if len(ret) == 0 { - panic("no return value specified for SubmitWithOptions") - } - - var r0 [][]byte - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, float64, []byte, []byte) ([][]byte, error)); ok { - return rf(ctx, blobs, gasPrice, namespace, options) - } - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, float64, []byte, []byte) [][]byte); ok { - r0 = rf(ctx, blobs, gasPrice, namespace, options) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([][]byte) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, [][]byte, float64, []byte, []byte) error); ok { - r1 = rf(ctx, blobs, gasPrice, namespace, options) + r1 = rf(ctx, blobs, gasPrice, options) } else { r1 = ret.Error(1) } @@ -278,9 +220,9 @@ func (_m *DA) SubmitWithOptions(ctx context.Context, blobs [][]byte, gasPrice fl return r0, r1 } -// Validate provides a mock function with given fields: ctx, ids, proofs, namespace -func (_m *DA) Validate(ctx context.Context, ids [][]byte, proofs [][]byte, namespace []byte) ([]bool, error) { - ret := _m.Called(ctx, ids, proofs, namespace) +// Validate provides a mock function with given fields: ctx, ids, proofs +func (_m *DA) Validate(ctx context.Context, ids [][]byte, proofs [][]byte) ([]bool, error) { + ret := _m.Called(ctx, ids, proofs) if len(ret) == 0 { panic("no return value specified for Validate") @@ -288,19 +230,19 @@ func (_m *DA) Validate(ctx context.Context, ids [][]byte, proofs [][]byte, names var r0 []bool var r1 error - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, [][]byte, []byte) ([]bool, error)); ok { - return rf(ctx, ids, proofs, namespace) + if rf, ok := ret.Get(0).(func(context.Context, [][]byte, [][]byte) ([]bool, error)); ok { + return rf(ctx, ids, proofs) } - if rf, ok := ret.Get(0).(func(context.Context, [][]byte, [][]byte, []byte) []bool); ok { - r0 = rf(ctx, ids, proofs, namespace) + if rf, ok := ret.Get(0).(func(context.Context, [][]byte, [][]byte) []bool); ok { + r0 = rf(ctx, ids, proofs) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]bool) } } - if rf, ok := ret.Get(1).(func(context.Context, [][]byte, [][]byte, []byte) error); ok { - r1 = rf(ctx, ids, proofs, namespace) + if rf, ok := ret.Get(1).(func(context.Context, [][]byte, [][]byte) error); ok { + r1 = rf(ctx, ids, proofs) } else { r1 = ret.Error(1) } diff --git a/types/da.go b/types/da.go index a3d737441d..57b23eccab 100644 --- a/types/da.go +++ b/types/da.go @@ -11,9 +11,6 @@ import ( coreda "github.com/rollkit/rollkit/core/da" ) -// TODO: remove this after we modify the da interfaces -var NameSpacePlaceholder = []byte("placeholder") - // SubmitWithHelpers performs blob submission using the underlying DA layer, // handling error mapping to produce a ResultSubmit. // It assumes blob size filtering is handled within the DA implementation's SubmitWithOptions. @@ -26,9 +23,9 @@ func SubmitWithHelpers( gasPrice float64, options []byte, ) coreda.ResultSubmit { // Return core ResultSubmit type - ids, err := da.SubmitWithOptions(ctx, data, gasPrice, NameSpacePlaceholder, options) + ids, err := da.Submit(ctx, data, gasPrice, options) - // Handle errors returned by SubmitWithOptions + // Handle errors returned by Submit if err != nil { if errors.Is(err, context.Canceled) { logger.Debug("DA submission canceled via helper due to context cancellation") @@ -97,7 +94,7 @@ func RetrieveWithHelpers( ) coreda.ResultRetrieve { // 1. Get IDs - idsResult, err := da.GetIDs(ctx, dataLayerHeight, NameSpacePlaceholder) + idsResult, err := da.GetIDs(ctx, dataLayerHeight) if err != nil { // Handle specific "not found" error if strings.Contains(err.Error(), coreda.ErrBlobNotFound.Error()) { @@ -144,7 +141,7 @@ func RetrieveWithHelpers( } // 2. Get Blobs using the retrieved IDs - blobs, err := da.Get(ctx, idsResult.IDs, []byte("placeholder")) + blobs, err := da.Get(ctx, idsResult.IDs) if err != nil { // Handle errors during Get logger.Error("Retrieve helper: Failed to get blobs", "height", dataLayerHeight, "num_ids", len(idsResult.IDs), "error", err) diff --git a/types/da_test.go b/types/da_test.go index 016249a73c..f8fc063e66 100644 --- a/types/da_test.go +++ b/types/da_test.go @@ -117,7 +117,7 @@ func TestSubmitWithHelpers(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { mockDA := mocks.NewDA(t) - mockDA.On("SubmitWithOptions", mock.Anything, tc.data, tc.gasPrice, types.NameSpacePlaceholder, tc.options).Return(tc.submitIDs, tc.submitErr) + mockDA.On("Submit", mock.Anything, tc.data, tc.gasPrice, tc.options).Return(tc.submitIDs, tc.submitErr) result := types.SubmitWithHelpers(context.Background(), mockDA, logger, tc.data, tc.gasPrice, tc.options) @@ -220,10 +220,10 @@ func TestRetrieveWithHelpers(t *testing.T) { t.Run(tc.name, func(t *testing.T) { mockDA := mocks.NewDA(t) - mockDA.On("GetIDs", mock.Anything, dataLayerHeight, types.NameSpacePlaceholder).Return(tc.getIDsResult, tc.getIDsErr) + mockDA.On("GetIDs", mock.Anything, dataLayerHeight).Return(tc.getIDsResult, tc.getIDsErr) if tc.getIDsErr == nil && tc.getIDsResult != nil && len(tc.getIDsResult.IDs) > 0 { - mockDA.On("Get", mock.Anything, tc.getIDsResult.IDs, []byte("placeholder")).Return(mockBlobs, tc.getBlobsErr) + mockDA.On("Get", mock.Anything, tc.getIDsResult.IDs).Return(mockBlobs, tc.getBlobsErr) } result := types.RetrieveWithHelpers(context.Background(), mockDA, logger, dataLayerHeight)