diff --git a/.golangci.yml b/.golangci.yml index 06fefcf..75463dc 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,13 +1,7 @@ --- run: timeout: 5m - skip-dirs: - - state/runtime/fakevm - - state/runtime/instrumentation - - test - - ci - - mocks - + linters: enable: - whitespace # Tool for detection of leading and trailing whitespace @@ -50,6 +44,12 @@ issues: linters: - gosec - lll + exclude-dirs: + - state/runtime/fakevm + - state/runtime/instrumentation + - test + - ci + - mocks include: - EXC0012 # EXC0012 revive: Annoying issue about not having a comment. The rare codebase has such comments - EXC0014 # EXC0014 revive: Annoying issue about not having a comment. The rare codebase has such comments diff --git a/rpc/handler.go b/rpc/handler.go index e21bb35..24146f5 100644 --- a/rpc/handler.go +++ b/rpc/handler.go @@ -197,7 +197,7 @@ func (h *Handler) registerService(service Service) { fv: mv.Func, } var err error - if fd.inNum, fd.reqt, err = validateFunc(funcName, fd.fv, true); err != nil { + if fd.inNum, fd.reqt, err = validateFunc(funcName, fd.fv); err != nil { panic(fmt.Sprintf("jsonrpc: %s", err)) } // check if last item is a pointer @@ -217,10 +217,11 @@ func (h *Handler) registerService(service Service) { } func (h *Handler) getFnHandler(req Request) (*serviceData, *funcData, Error) { + const endpointNameParts = 2 methodNotFoundErrorMessage := fmt.Sprintf("the method %s does not exist/is not available", req.Method) - callName := strings.SplitN(req.Method, "_", 2) //nolint:mnd - if len(callName) != 2 { //nolint:mnd + callName := strings.SplitN(req.Method, "_", endpointNameParts) + if len(callName) != endpointNameParts { return nil, nil, NewRPCError(NotFoundErrorCode, methodNotFoundErrorMessage) } @@ -238,9 +239,9 @@ func (h *Handler) getFnHandler(req Request) (*serviceData, *funcData, Error) { return service, fd, nil } -func validateFunc(funcName string, fv reflect.Value, isMethod bool) (inNum int, reqt []reflect.Type, err error) { +func validateFunc(funcName string, fv reflect.Value) (inNum int, reqt []reflect.Type, err error) { if funcName == "" { - err = fmt.Errorf("getBlockNumByArg cannot be empty") + err = fmt.Errorf("function name cannot be empty") return } diff --git a/rpc/types.go b/rpc/types.go index d8f810c..f8e6490 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -18,8 +18,8 @@ type Request struct { type Response struct { JSONRPC string `json:"jsonrpc"` ID interface{} `json:"id"` - Result json.RawMessage `json:"result"` - Error *ErrorObject `json:"error"` + Result json.RawMessage `json:"result,omitempty"` + Error *ErrorObject `json:"error,omitempty"` } // NewResponse returns Success/Error response object diff --git a/services/datacom/datacom.go b/services/datacom/datacom.go index e474b36..b83c4b5 100644 --- a/services/datacom/datacom.go +++ b/services/datacom/datacom.go @@ -51,23 +51,23 @@ func (d *Endpoints) signSequence(signedSequence types.SignedSequenceInterface) ( // Verify that the request comes from the sequencer sender, err := signedSequence.Signer() if err != nil { - return "0x0", rpc.NewRPCError(rpc.DefaultErrorCode, "failed to verify sender") + return nil, rpc.NewRPCError(rpc.DefaultErrorCode, "failed to verify sender") } if sender != d.sequencerTracker.GetAddr() { - return "0x0", rpc.NewRPCError(rpc.DefaultErrorCode, "unauthorized") + return nil, rpc.NewRPCError(rpc.DefaultErrorCode, "unauthorized") } // Store off-chain data by hash (hash(L2Data): L2Data) if err = d.db.StoreOffChainData(context.Background(), signedSequence.OffChainData()); err != nil { - return "0x0", rpc.NewRPCError(rpc.DefaultErrorCode, + return nil, rpc.NewRPCError(rpc.DefaultErrorCode, fmt.Errorf("failed to store offchain data. Error: %w", err).Error()) } // Sign signature, err := signedSequence.Sign(d.privateKey) if err != nil { - return "0x0", rpc.NewRPCError(rpc.DefaultErrorCode, fmt.Errorf("failed to sign. Error: %w", err).Error()) + return nil, rpc.NewRPCError(rpc.DefaultErrorCode, fmt.Errorf("failed to sign. Error: %w", err).Error()) } // Return signature return signature, nil diff --git a/services/status/status.go b/services/status/status.go index 20d1c6b..904a075 100644 --- a/services/status/status.go +++ b/services/status/status.go @@ -37,11 +37,15 @@ func (s *Endpoints) GetStatus() (interface{}, rpc.Error) { rowCount, err := s.db.CountOffchainData(ctx) if err != nil { log.Errorf("failed to get the key count from the offchain_data table: %v", err) + + return nil, rpc.NewRPCError(rpc.DefaultErrorCode, "failed to retrieve data from the storage") } lastSynchronizedBlock, err := s.db.GetLastProcessedBlock(ctx, string(synchronizer.L1SyncTask)) if err != nil { log.Errorf("failed to get last block processed by the synchronizer: %v", err) + + return nil, rpc.NewRPCError(rpc.DefaultErrorCode, "failed to retrieve data from the storage") } return types.DACStatus{ diff --git a/services/status/status_test.go b/services/status/status_test.go index bf0e55a..a5def4e 100644 --- a/services/status/status_test.go +++ b/services/status/status_test.go @@ -30,11 +30,13 @@ func TestEndpoints_GetStatus(t *testing.T) { name: "failed to count offchain data", countOffchainDataErr: errors.New("test error"), getLastProcessedBlock: 2, + expectedError: errors.New("failed to retrieve data from the storage"), }, { name: "failed to count offchain data and last processed block", countOffchainDataErr: errors.New("test error"), getLastProcessedBlockErr: errors.New("test error"), + expectedError: errors.New("failed to retrieve data from the storage"), }, } @@ -50,7 +52,7 @@ func TestEndpoints_GetStatus(t *testing.T) { Return(tt.countOffchainData, tt.countOffchainDataErr) dbMock.On("GetLastProcessedBlock", mock.Anything, mock.Anything). - Return(tt.getLastProcessedBlock, tt.getLastProcessedBlockErr) + Return(tt.getLastProcessedBlock, tt.getLastProcessedBlockErr).Maybe() statusEndpoints := NewEndpoints(dbMock) diff --git a/services/sync/sync.go b/services/sync/sync.go index f525d63..37b4db0 100644 --- a/services/sync/sync.go +++ b/services/sync/sync.go @@ -35,7 +35,7 @@ func (z *Endpoints) GetOffChainData(hash types.ArgHash) (interface{}, rpc.Error) data, err := z.db.GetOffChainData(context.Background(), hash.Hash()) if err != nil { log.Errorf("failed to get the offchain requested data from the DB: %v", err) - return "0x0", rpc.NewRPCError(rpc.DefaultErrorCode, "failed to get the requested data") + return nil, rpc.NewRPCError(rpc.DefaultErrorCode, "failed to get the requested data") } return types.ArgBytes(data.Value), nil @@ -45,7 +45,7 @@ func (z *Endpoints) GetOffChainData(hash types.ArgHash) (interface{}, rpc.Error) func (z *Endpoints) ListOffChainData(hashes []types.ArgHash) (interface{}, rpc.Error) { if len(hashes) > maxListHashes { log.Errorf("too many hashes requested in ListOffChainData: %d", len(hashes)) - return "0x0", rpc.NewRPCError(rpc.InvalidRequestErrorCode, "too many hashes requested") + return nil, rpc.NewRPCError(rpc.InvalidRequestErrorCode, "too many hashes requested") } keys := make([]common.Hash, len(hashes)) @@ -56,10 +56,10 @@ func (z *Endpoints) ListOffChainData(hashes []types.ArgHash) (interface{}, rpc.E list, err := z.db.ListOffChainData(context.Background(), keys) if err != nil { log.Errorf("failed to list the requested data from the DB: %v", err) - return "0x0", rpc.NewRPCError(rpc.DefaultErrorCode, "failed to list the requested data") + return nil, rpc.NewRPCError(rpc.DefaultErrorCode, "failed to list the requested data") } - listMap := make(map[common.Hash]types.ArgBytes) + listMap := make(map[common.Hash]types.ArgBytes, len(list)) for _, data := range list { listMap[data.Key] = data.Value }