Repository: NethermindEth/juno
Pull request #288 (2022-07-16 02:10:29)

Delete processes and services
## Changes:
- Delete processes and services to make it easier to run and maintain juno. Services were implemented as singletons which lead to side effects when they are used. The process struct provided a concurrency wrapper around the HTTP server and service calls which lead to concurrent bugs, such as panic on a negative wait group call. 

## Types of changes

What types of changes does your code introduce?
_Put an `x` in the boxes that apply_

- [x] Bugfix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Documentation Update
- [x] Code style update (formatting, renaming)
- [x] Refactoring (no functional changes, no api changes)
- [ ] Build related changes
- [ ] Other (please describe): 

## Testing
**Requires testing**

- [ ] Yes
- [x] No


codecov[bot]: # [Codecov](https://codecov.io/gh/NethermindEth/juno/pull/288?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth) Report
> Merging [#288](https://codecov.io/gh/NethermindEth/juno/pull/288?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth) (fd752a1) into [main](https://codecov.io/gh/NethermindEth/juno/commit/629fa331ca35cebb747837269838004c0e2ce3d1?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth) (629fa33) will **decrease** coverage by `0.57%`.
> The diff coverage is `57.50%`.

> :exclamation: Current head fd752a1 differs from pull request most recent head 466641f. Consider uploading reports for the commit 466641f to get more accurate results

```diff
@@             Coverage Diff             @@
##              main     #288      +/-   ##
===========================================
- Coverage   100.00%   99.42%   -0.58%     
===========================================
  Files           66       61       -5     
  Lines         6857     6743     -114     
===========================================
- Hits          6857     6704     -153     
- Misses           0       38      +38     
- Partials         0        1       +1     
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `99.42% <57.50%> (-0.58%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/NethermindEth/juno/pull/288?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth) | Coverage Δ | |
|---|---|---|
| [internal/metrics/prometheus/metrics.go](https://codecov.io/gh/NethermindEth/juno/pull/288/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth#diff-aW50ZXJuYWwvbWV0cmljcy9wcm9tZXRoZXVzL21ldHJpY3MuZ28=) | `86.61% <0.00%> (-13.39%)` | :arrow_down: |
| [pkg/rpc/types.go](https://codecov.io/gh/NethermindEth/juno/pull/288/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth#diff-cGtnL3JwYy90eXBlcy5nbw==) | `100.00% <ø> (ø)` | |
| [internal/db/contracthash/manager.go](https://codecov.io/gh/NethermindEth/juno/pull/288/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth#diff-aW50ZXJuYWwvZGIvY29udHJhY3RoYXNoL21hbmFnZXIuZ28=) | `40.00% <40.00%> (ø)` | |
| [pkg/rpc/server.go](https://codecov.io/gh/NethermindEth/juno/pull/288/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth#diff-cGtnL3JwYy9zZXJ2ZXIuZ28=) | `58.06% <50.00%> (-41.94%)` | :arrow_down: |
| [pkg/rest/server.go](https://codecov.io/gh/NethermindEth/juno/pull/288/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth#diff-cGtnL3Jlc3Qvc2VydmVyLmdv) | `85.00% <88.23%> (-15.00%)` | :arrow_down: |
| [pkg/rpc/api.go](https://codecov.io/gh/NethermindEth/juno/pull/288/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth#diff-cGtnL3JwYy9hcGkuZ28=) | `100.00% <100.00%> (ø)` | |
| [pkg/starknet/state.go](https://codecov.io/gh/NethermindEth/juno/pull/288/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth#diff-cGtnL3N0YXJrbmV0L3N0YXRlLmdv) | `100.00% <100.00%> (ø)` | |
| ... and [2 more](https://codecov.io/gh/NethermindEth/juno/pull/288/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/NethermindEth/juno/pull/288?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/NethermindEth/juno/pull/288?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth). Last update [629fa33...466641f](https://codecov.io/gh/NethermindEth/juno/pull/288?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=NethermindEth).

tshakalekholoane: Sorry about that 😵 the `// notest` has to go right under the closure that Codecov is flagging i.e. just right above where you see banner in the details section. 

Patch:
diff --git a/cmd/juno/cli/root.go b/cmd/juno/cli/root.go
index d3c86e45..217a1d92 100644
--- a/cmd/juno/cli/root.go
+++ b/cmd/juno/cli/root.go
@@ -9,22 +9,31 @@ import (
 	"path/filepath"
 	"strconv"
 	"syscall"
-
-	"github.com/ethereum/go-ethereum/ethclient"
+	"time"
 
 	"github.com/NethermindEth/juno/internal/config"
 	"github.com/NethermindEth/juno/internal/db"
+	"github.com/NethermindEth/juno/internal/db/abi"
+	"github.com/NethermindEth/juno/internal/db/block"
+	"github.com/NethermindEth/juno/internal/db/contracthash"
+	"github.com/NethermindEth/juno/internal/db/state"
+	"github.com/NethermindEth/juno/internal/db/transaction"
 	"github.com/NethermindEth/juno/internal/errpkg"
 	. "github.com/NethermindEth/juno/internal/log"
 	metric "github.com/NethermindEth/juno/internal/metrics/prometheus"
-	"github.com/NethermindEth/juno/internal/process"
-	"github.com/NethermindEth/juno/internal/services"
 	"github.com/NethermindEth/juno/pkg/feeder"
 	"github.com/NethermindEth/juno/pkg/rest"
 	"github.com/NethermindEth/juno/pkg/rpc"
 	"github.com/NethermindEth/juno/pkg/starknet"
+	"github.com/ethereum/go-ethereum/ethclient"
 	"github.com/spf13/cobra"
 	"github.com/spf13/viper"
+	"github.com/torquem-ch/mdbx-go/mdbx"
+)
+
+const (
+	mdbxOptMaxDb uint64 = 100
+	mdbxFlags    uint   = 0
 )
 
 // Cobra configuration.
@@ -37,117 +46,47 @@ var (
 	// longMsg is the long message shown in the "juno --help" output.
 	//go:embed long.txt
 	longMsg string
+)
 
-	processHandler *process.Handler
-	// rootCmd is the root command of the application.
-	rootCmd = &cobra.Command{
-		Use:   "juno [options]",
-		Short: "Starknet client implementation in Go.",
-		Run: func(_ *cobra.Command, _ []string) {
-			processHandler = process.NewHandler()
-
-			// Handle signal interrupts and exits.
-			sig := make(chan os.Signal, 1)
-			signal.Notify(sig, os.Interrupt, syscall.SIGTERM)
-			go func(sig chan os.Signal) {
-				<-sig
-				Logger.Info("Trying to close...")
-				cleanup()
-				os.Exit(0)
-			}(sig)
-
-			feederGatewayClient := feeder.NewClient(config.Runtime.Starknet.FeederGateway, "/feeder_gateway", nil)
-			// Subscribe the RPC client to the main loop if it is enabled in
-			// the config.
-			if config.Runtime.RPC.Enabled {
-				s := rpc.NewServer(":"+strconv.Itoa(config.Runtime.RPC.Port), feederGatewayClient)
-				// Initialize the RPC Service.
-				processHandler.Add("RPC", true, s.ListenAndServe, s.Close)
-			}
+var (
+	mdbxEnv *mdbx.Env
 
-			if config.Runtime.Metrics.Enabled {
-				s := metric.SetupMetric(":" + strconv.Itoa(config.Runtime.Metrics.Port))
-				// Initialize the Metrics Service.
-				processHandler.Add("Metrics", false, s.ListenAndServe, s.Close)
-			}
+	rpcServer     *rpc.Server
+	metricsServer *metric.Server
+	restServer    *rest.Server
 
-			if err := db.InitializeMDBXEnv(config.Runtime.DbPath, 100, 0); err != nil {
-				Logger.With("Error", err).Fatal("Error starting the database environment")
-			}
+	feederGatewayClient *feeder.Client
 
-			// Initialize ABI Service
-			processHandler.Add("ABI Service", false, services.AbiService.Run, services.AbiService.Close)
-
-			// Initialize State storage service
-			processHandler.Add("State Storage Service", false, services.StateService.Run, services.StateService.Close)
-
-			// Initialize Transactions Storage Service
-			processHandler.Add("Transactions Storage Service", false, services.TransactionService.Run, services.TransactionService.Close)
-
-			// Initialize Block Storage Service
-			processHandler.Add("Block Storage Service", false, services.BlockService.Run, services.BlockService.Close)
-
-			// Initialize Contract Hash storage service
-			processHandler.Add("Contract Hash Storage Service", false, services.ContractHashService.Run, services.ContractHashService.Close)
-
-			// Subscribe the Starknet Synchronizer to the main loop if it is enabled in
-			// the config.
-			if config.Runtime.Starknet.Enabled {
-				var ethereumClient *ethclient.Client
-				if !config.Runtime.Starknet.ApiSync {
-					var err error
-					ethereumClient, err = ethclient.Dial(config.Runtime.Ethereum.Node)
-					if err != nil {
-						Logger.With("Error", err).Fatal("Unable to connect to Ethereum Client")
-					}
-				}
-				// Synchronizer for Starknet State
-				env, err := db.GetMDBXEnv()
-				if err != nil {
-					Logger.Fatal(err)
-				}
-				synchronizerDb, err := db.NewMDBXDatabase(env, "SYNCHRONIZER")
-				if err != nil {
-					Logger.With("Error", err).Fatal("Error starting the SYNCHRONIZER database")
-				}
-				stateSynchronizer := starknet.NewSynchronizer(synchronizerDb, ethereumClient, feederGatewayClient)
-				// Initialize the Starknet Synchronizer Service.
-				processHandler.Add("Starknet Synchronizer", true, stateSynchronizer.UpdateState,
-					stateSynchronizer.Close)
-			}
+	stateSynchronizer *starknet.Synchronizer
 
-			// Subscribe the REST API client to the main loop if it is enabled in
-			// the config.
-			if config.Runtime.REST.Enabled {
-				s := rest.NewServer(":"+strconv.Itoa(config.Runtime.REST.Port), config.Runtime.Starknet.FeederGateway, config.Runtime.REST.Prefix)
-				// Initialize the REST Service.
-				processHandler.Add("REST", true, s.ListenAndServe, s.Close)
-			}
+	contractHashManager *contracthash.Manager
+	abiManager          *abi.Manager
+	stateManager        *state.Manager
+	transactionManager  *transaction.Manager
+	blockManager        *block.Manager
+)
 
-			primaryServiceCheck := processHandler.PrimaryServiceChecker()
+var shutdownTimeout = 5 * time.Second
 
-			if primaryServiceCheck > 0 {
-				// endless running process
-				Logger.Info("Starting all processes...")
-				processHandler.Run()
-				cleanup()
-			} else {
-				cleanup()
-			}
-		},
-	}
-)
+// rootCmd is the root command of the application.
+var rootCmd = &cobra.Command{
+	Use:   "juno [options]",
+	Short: "Starknet client implementation in Go.",
+	Run:   juno,
+}
 
-func cleanup() {
-	processHandler.Close()
-	Logger.Info("App closing...Bye!!!")
+// Execute handle flags for Cobra execution.
+func Execute() {
+	if err := rootCmd.Execute(); err != nil {
+		Logger.With("Error", err).Error("Failed to execute CLI.")
+	}
 }
 
 // init defines flags and handles configuration.
 func init() {
 	fmt.Println(longMsg)
 	// Set the functions to be run when rootCmd.Execute() is called.
-	cobra.OnInitialize(initConfig)
+	initConfig()
 
 	rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", fmt.Sprintf(
 		"config file (default is %s)", filepath.Join(config.Dir, "juno.yaml")))
@@ -155,6 +94,160 @@ func init() {
 		"data path (default is %s)", config.DataDir))
 }
 
+func juno(_ *cobra.Command, _ []string) {
+	setupInterruptHandler()
+	setupDatabaseManagers()
+	setupFeederGateway()
+	setupServers()
+	setupStateSynchronizer()
+
+	errChs := []chan error{make(chan error), make(chan error), make(chan error)}
+	rpcServer.ListenAndServe(errChs[0])
+	metricsServer.ListenAndServe(errChs[1])
+	restServer.ListenAndServe(errChs[2])
+
+	if err := stateSynchronizer.UpdateState(); err != nil {
+		Logger.Fatal("Failed to start State Synchronizer: ", err.Error())
+	}
+
+	checkErrChs(errChs)
+}
+
+func setupStateSynchronizer() {
+	if config.Runtime.Starknet.Enabled {
+		var ethereumClient *ethclient.Client
+		if !config.Runtime.Starknet.ApiSync {
+			var err error
+			ethereumClient, err = ethclient.Dial(config.Runtime.Ethereum.Node)
+			if err != nil {
+				Logger.With("Error", err).Fatal("Unable to connect to Ethereum Client")
+			}
+		}
+		// Synchronizer for Starknet State
+		synchronizerDb, err := db.NewMDBXDatabase(mdbxEnv, "SYNCHRONIZER")
+		if err != nil {
+			Logger.With("Error", err).Fatal("Error starting the SYNCHRONIZER database")
+		}
+		stateSynchronizer = starknet.NewSynchronizer(synchronizerDb, ethereumClient, feederGatewayClient,
+			contractHashManager, abiManager, stateManager, transactionManager, blockManager)
+	}
+}
+
+func setupServers() {
+	if config.Runtime.RPC.Enabled {
+		rpcServer = rpc.NewServer(":"+strconv.Itoa(config.Runtime.RPC.Port), feederGatewayClient, abiManager,
+			stateManager, transactionManager, blockManager)
+	}
+
+	if config.Runtime.Metrics.Enabled {
+		metricsServer = metric.SetupMetric(":" + strconv.Itoa(config.Runtime.Metrics.Port))
+	}
+
+	if config.Runtime.REST.Enabled {
+		restServer = rest.NewServer(":"+strconv.Itoa(config.Runtime.REST.Port),
+			config.Runtime.Starknet.FeederGateway, config.Runtime.REST.Prefix)
+	}
+}
+
+func setupFeederGateway() {
+	feederGatewayClient = feeder.NewClient(config.Runtime.Starknet.FeederGateway, "/feeder_gateway", nil)
+}
+
+func setupDatabaseManagers() {
+	var err error
+	var dbName string
+
+	mdbxEnv, err = db.NewMDBXEnv(config.Runtime.DbPath, mdbxOptMaxDb, mdbxFlags)
+	if err != nil {
+		Logger.Fatal("Failed to create MDBX Database environment: ", err)
+	}
+
+	logDBErr := func(name string, err error) {
+		if err != nil {
+			Logger.Fatalf("Failed to create %s database: %s", name, err.Error())
+		}
+	}
+
+	dbName = "CONTRACT_HASH"
+	contractHashDb, err := db.NewMDBXDatabase(mdbxEnv, dbName)
+	logDBErr(dbName, err)
+
+	dbName = "ABI"
+	abiDb, err := db.NewMDBXDatabase(mdbxEnv, dbName)
+	logDBErr(dbName, err)
+
+	dbName = "CODE"
+	codeDb, err := db.NewMDBXDatabase(mdbxEnv, dbName)
+	logDBErr(dbName, err)
+
+	dbName = "STORAGE"
+	storageDb, err := db.NewMDBXDatabase(mdbxEnv, dbName)
+	logDBErr(dbName, err)
+
+	dbName = "TRANSACTION"
+	txDb, err := db.NewMDBXDatabase(mdbxEnv, dbName)
+	logDBErr(dbName, err)
+
+	dbName = "RECEIPT"
+	receiptDb, err := db.NewMDBXDatabase(mdbxEnv, dbName)
+	logDBErr(dbName, err)
+
+	dbName = "BLOCK"
+	blockDb, err := db.NewMDBXDatabase(mdbxEnv, dbName)
+	logDBErr(dbName, err)
+
+	contractHashManager = contracthash.NewManager(contractHashDb)
+	abiManager = abi.NewManager(abiDb)
+	stateManager = state.NewManager(codeDb, db.NewBlockSpecificDatabase(storageDb))
+	transactionManager = transaction.NewManager(txDb, receiptDb)
+	blockManager = block.NewManager(blockDb)
+}
+
+func setupInterruptHandler() {
+	// Handle signal interrupts and exits.
+	sig := make(chan os.Signal)
+	signal.Notify(sig, os.Interrupt, syscall.SIGTERM)
+	go func(sig chan os.Signal) {
+		<-sig
+		Logger.Info("Shutting down Juno...")
+		shutdown()
+		os.Exit(0)
+	}(sig)
+}
+
+func shutdown() {
+	contractHashManager.Close()
+	abiManager.Close()
+	stateManager.Close()
+	transactionManager.Close()
+	blockManager.Close()
+	stateSynchronizer.Close()
+
+	if err := rpcServer.Close(shutdownTimeout); err != nil {
+		Logger.Fatal("Failed to shutdown RPC server gracefully: ", err.Error())
+	}
+
+	if err := metricsServer.Close(shutdownTimeout); err != nil {
+		Logger.Fatal("Failed to shutdown Metrics server gracefully: ", err.Error())
+	}
+
+	if err := restServer.Close(shutdownTimeout); err != nil {
+		Logger.Fatal("Failed to shutdown REST server gracefully: ", err.Error())
+	}
+}
+
+func checkErrChs(errChs []chan error) {
+	for _, errCh := range errChs {
+		for {
+			if err, ok := <-errCh; err != nil {
+				Logger.Fatal(err)
+			} else if !ok {
+				continue
+			}
+		}
+	}
+}
+
 // initConfig reads in Config file or environment variables if set.
 func initConfig() {
 	if dataDir != "" {
@@ -214,10 +307,3 @@ func initConfig() {
 		"Rest Prefix", config.Runtime.REST.Prefix,
 	).Info("Config values.")
 }
-
-// Execute handle flags for Cobra execution.
-func Execute() {
-	if err := rootCmd.Execute(); err != nil {
-		Logger.With("Error", err).Error("Failed to execute CLI.")
-	}
-}
diff --git a/internal/db/abi/manager.go b/internal/db/abi/manager.go
index 4afa0a4e..8401bdf7 100644
--- a/internal/db/abi/manager.go
+++ b/internal/db/abi/manager.go
@@ -10,8 +10,8 @@ type Manager struct {
 	database db.Database
 }
 
-// NewABIManager creates a new Manager instance.
-func NewABIManager(database db.Database) *Manager {
+// NewManager creates a new Manager instance.
+func NewManager(database db.Database) *Manager {
 	return &Manager{database}
 }
 
diff --git a/internal/db/contracthash/manager.go b/internal/db/contracthash/manager.go
new file mode 100644
index 00000000..cc8dba26
--- /dev/null
+++ b/internal/db/contracthash/manager.go
@@ -0,0 +1,32 @@
+package contracthash
+
+import (
+	"github.com/NethermindEth/juno/internal/db"
+	"github.com/NethermindEth/juno/pkg/felt"
+)
+
+type Manager struct {
+	database db.Database
+}
+
+func NewManager(db db.Database) *Manager {
+	return &Manager{database: db}
+}
+
+func (m *Manager) Close() {
+	// notest
+	m.database.Close()
+}
+
+func (m *Manager) GetContractHash(contractAddr string) (*felt.Felt, error) {
+	// notest
+	rawData, err := m.database.Get([]byte(contractAddr))
+	if err != nil {
+		return nil, err
+	}
+	return new(felt.Felt).SetBytes(rawData), nil
+}
+
+func (m *Manager) StoreContractHash(contractAddr string, contractHash *felt.Felt) error {
+	return m.database.Put([]byte(contractAddr), contractHash.ByteSlice())
+}
diff --git a/internal/db/state/state.go b/internal/db/state/state.go
index cb42d083..0ab80b39 100644
--- a/internal/db/state/state.go
+++ b/internal/db/state/state.go
@@ -11,8 +11,8 @@ type Manager struct {
 	storageDatabase *db.BlockSpecificDatabase
 }
 
-// NewStateManager returns a new instance of Manager with the given database sources.
-func NewStateManager(codeDatabase db.Database, storageDatabase *db.BlockSpecificDatabase) *Manager {
+// NewManager returns a new instance of Manager with the given database sources.
+func NewManager(codeDatabase db.Database, storageDatabase *db.BlockSpecificDatabase) *Manager {
 	return &Manager{codeDatabase, storageDatabase}
 }
 
diff --git a/internal/metrics/prometheus/metrics.go b/internal/metrics/prometheus/metrics.go
index 4e73a597..51835060 100644
--- a/internal/metrics/prometheus/metrics.go
+++ b/internal/metrics/prometheus/metrics.go
@@ -5,7 +5,9 @@ package prometheus
 
 import (
 	"context"
+	"errors"
 	"net/http"
+	"time"
 
 	. "github.com/NethermindEth/juno/internal/log"
 
@@ -341,31 +343,33 @@ func SetupMetric(port string) *Server {
 	return &Server{server: http.Server{Addr: port, Handler: mux}}
 }
 
-// ListenAndServe listens on the TCP network and handles requests on
-// incoming connections.
-func (s *Server) ListenAndServe() error {
+// ListenAndServe listens to TCP port and handles requests on incoming
+// connections. ListenAndServe runs in a separate go routine so that it doesn't
+// block the caller.
+func (s *Server) ListenAndServe(errCh chan<- error) {
 	// notest
-	Logger.Info("Handling metrics .... ")
+	go s.listenAndServe(errCh)
+}
 
-	err := s.server.ListenAndServe()
-	if err != nil {
-		Logger.With("Error", err).Error("Error occurred while trying to handle metrics.")
-		return err
+func (s *Server) listenAndServe(errCh chan<- error) {
+	// notest
+	Logger.Info("Handling Metrics...")
+
+	// Since ListenAndServe always returns an error we need to ensure that there
+	// is no write to a closed channel. Therefore, we check for ErrServerClosed
+	// since that is only returned after ShutDown or Closed is called. Hence, no
+	// write to the channel is required. Otherwise, any other error is written
+	// which will cause the program to exit.
+	if err := s.server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
+		errCh <- errors.New("Failed to ListenAndServe on Metrics server: " + err.Error())
 	}
-	return nil
+	close(errCh)
 }
 
 // Close gracefully shuts down the server.
-func (s *Server) Close(ctx context.Context) {
+func (s *Server) Close(timeout time.Duration) error {
 	// notest
-	Logger.Info("Closing the Metrics server.")
-	select {
-	case <-ctx.Done():
-		err := s.server.Shutdown(ctx)
-		if err != nil {
-			Logger.With("Error", err).Info("Exiting with error.")
-			return
-		}
-	default:
-	}
+	Logger.Info("Shutting down Metrics server...")
+	ctx, _ := context.WithTimeout(context.Background(), timeout)
+	return s.server.Shutdown(ctx)
 }
diff --git a/internal/process/process.go b/internal/process/process.go
deleted file mode 100644
index 475b6369..00000000
--- a/internal/process/process.go
+++ /dev/null
@@ -1,107 +0,0 @@
-// Package process provides a handler to manage processes.
-package process
-
-// notest
-import (
-	"context"
-	"time"
-
-	. "github.com/NethermindEth/juno/internal/log"
-)
-
-// runFunc represents a function that runs a process.
-type runFunc func() error
-
-// stopFunc represents a function that stops a process.
-type stopFunc func(ctx context.Context)
-
-// process contains information and required functions of each process
-type process struct {
-	id        string
-	important bool
-	err       error
-	run       runFunc
-	stop      stopFunc
-}
-
-// Processer defines common methods for a context processor.
-type Processer interface {
-	Add(id string, fnRun runFunc, fnStop stopFunc)
-	Run()
-	Close()
-}
-
-// Handler holds a collection of sub-processes.
-type Handler struct {
-	subprocs []*process
-}
-
-// NewHandler creates a new process.Handler.
-func NewHandler() *Handler {
-	return &Handler{}
-}
-
-// Start starts a process.
-func (p *process) Start() (err error) {
-	return p.run()
-}
-
-// Close closes all running processes.
-func (h *Handler) Close() {
-	// Clear all processes.
-	for _, proc := range h.subprocs {
-		// Set 5 second timeout.
-		ctx, cancel := context.WithDeadline(
-			context.Background(), time.Now().Add(5*time.Second))
-		proc.stop(ctx)
-		if proc.err != nil {
-			Logger.With("Error", proc.err).Error("Error occurred while closing process.")
-		}
-		cancel()
-	}
-}
-
-// Add adds a process to the list of processes in the Handler.
-func (h *Handler) Add(id string, imp bool, fnRun runFunc, fnStop stopFunc) {
-	h.subprocs = append(h.subprocs, &process{
-		id:        id,
-		important: imp,
-		run:       fnRun,
-		stop:      fnStop,
-	})
-}
-
-// Run runs all the processes.
-func (h *Handler) Run() {
-	if len(h.subprocs) == 0 {
-		Logger.Info("No processes found.")
-		return
-	}
-
-	for _, proc := range h.subprocs {
-		go func(p *process) {
-			err := p.Start()
-			if err != nil {
-				p.err = err
-				return
-			}
-		}(proc)
-	}
-
-	// Create an infinite loop.
-	select {}
-}
-
-func (h *Handler) PrimaryServiceChecker() int {
-	// notest
-	primarypkg := 0
-	for _, proc := range h.subprocs {
-		if proc.important {
-			primarypkg = primarypkg + 1
-		}
-	}
-	if primarypkg == 0 {
-		Logger.Info("No primary processes running. Closing the app.")
-	}
-	return primarypkg
-}
diff --git a/internal/services/abi.go b/internal/services/abi.go
deleted file mode 100644
index e5a50f35..00000000
--- a/internal/services/abi.go
+++ /dev/null
@@ -1,86 +0,0 @@
-package services
-
-import (
-	"context"
-
-	"github.com/NethermindEth/juno/internal/db"
-	"github.com/NethermindEth/juno/internal/db/abi"
-	. "github.com/NethermindEth/juno/internal/log"
-)
-
-// AbiService is the service to store and put the contracts ABI. Before
-// using the service, it must be configured with the Setup method;
-// otherwise, the value will be the default. To stop the service, call the
-// Close method.
-var AbiService abiService
-
-type abiService struct {
-	service
-	manager *abi.Manager
-}
-
-// Setup sets the service configuration, service must be not running.
-func (s *abiService) Setup(database db.Database) {
-	// notest
-	if s.Running() {
-		s.logger.Panic("trying to Setup with service running")
-	}
-	s.manager = abi.NewABIManager(database)
-}
-
-// Run starts the service.
-func (s *abiService) Run() error {
-	if s.logger == nil {
-		s.logger = Logger.Named("AbiService")
-	}
-
-	if err := s.service.Run(); err != nil {
-		// notest
-		return err
-	}
-
-	return s.setDefaults()
-}
-
-// setDefaults sets the default value for properties that are not set.
-func (s *abiService) setDefaults() error {
-	if s.manager == nil {
-		// notest
-		env, err := db.GetMDBXEnv()
-		if err != nil {
-			return err
-		}
-		database, err := db.NewMDBXDatabase(env, "ABI")
-		if err != nil {
-			return err
-		}
-		s.manager = abi.NewABIManager(database)
-	}
-	return nil
-}
-
-// Close closes the service.
-func (s *abiService) Close(ctx context.Context) {
-	// notest
-	if !s.Running() {
-		return
-	}
-	s.service.Close(ctx)
-	s.manager.Close()
-}
-
-// StoreAbi stores an ABI in the database. If the key (contractAddress) already
-// exists then the value is overwritten for the given ABI.
-func (s *abiService) StoreAbi(contractAddress string, abi *abi.Abi) error {
-	s.service.AddProcess()
-	defer s.service.DoneProcess()
-	return s.manager.PutABI(contractAddress, abi)
-}
-
-// GetAbi search in the database for the ABI associated with the given contract
-// address.
-func (s *abiService) GetAbi(contractAddress string) (*abi.Abi, error) {
-	s.service.AddProcess()
-	defer s.service.DoneProcess()
-	return s.manager.GetABI(contractAddress)
-}
diff --git a/internal/services/block.go b/internal/services/block.go
deleted file mode 100644
index 4097040b..00000000
--- a/internal/services/block.go
+++ /dev/null
@@ -1,99 +0,0 @@
-package services
-
-import (
-	"context"
-
-	"github.com/NethermindEth/juno/internal/db"
-	"github.com/NethermindEth/juno/internal/db/block"
-	. "github.com/NethermindEth/juno/internal/log"
-	"github.com/NethermindEth/juno/pkg/felt"
-	"github.com/NethermindEth/juno/pkg/types"
-)
-
-// BlockService is a service to manage the block database. Before
-// using the service, it must be configured with the Setup method;
-// otherwise, the value will be the default. To stop the service, call the
-// Close method.
-var BlockService blockService
-
-type blockService struct {
-	service
-	manager *block.Manager
-}
-
-// Setup is used to configure the service before it's started. The database
-// param is the database where the transactions will be stored.
-func (s *blockService) Setup(database db.Database) {
-	if s.service.Running() {
-		// notest
-		s.logger.Panic("trying to Setup with service running")
-	}
-	s.manager = block.NewManager(database)
-}
-
-// Run starts the service. If the Setup method is not called before, the default
-// values are used.
-func (s *blockService) Run() error {
-	if s.logger == nil {
-		s.logger = Logger.Named("Block Service")
-	}
-
-	if err := s.service.Run(); err != nil {
-		// notest
-		return err
-	}
-
-	return s.setDefaults()
-}
-
-func (s *blockService) setDefaults() error {
-	if s.manager == nil {
-		// notest
-		env, err := db.GetMDBXEnv()
-		if err != nil {
-			return err
-		}
-		database, err := db.NewMDBXDatabase(env, "BLOCK")
-		if err != nil {
-			return err
-		}
-		s.manager = block.NewManager(database)
-	}
-	return nil
-}
-
-// Close stops the service, waiting to end the current operations, and closes
-// the database manager.
-func (s *blockService) Close(ctx context.Context) {
-	// notest
-	if !s.Running() {
-		return
-	}
-	s.service.Close(ctx)
-	s.manager.Close()
-}
-
-// GetBlockByHash searches for the block associated with the given block hash.
-// If the block does not exist on the database, then returns nil.
-func (s *blockService) GetBlockByHash(blockHash *felt.Felt) (*types.Block, error) {
-	s.AddProcess()
-	defer s.DoneProcess()
-	return s.manager.GetBlockByHash(blockHash)
-}
-
-// GetBlockByNumber searches for the block associated with the given block
-// number. If the block does not exist on the database, then returns nil.
-func (s *blockService) GetBlockByNumber(blockNumber uint64) (*types.Block, error) {
-	s.AddProcess()
-	defer s.DoneProcess()
-	return s.manager.GetBlockByNumber(blockNumber)
-}
-
-// StoreBlock stores the given block into the database. The key used to map the
-// block it's the hash of the block. If the database already has a block with
-// the same key, then the value is overwritten.
-func (s *blockService) StoreBlock(blockHash *felt.Felt, block *types.Block) error {
-	s.AddProcess()
-	defer s.DoneProcess()
-	return s.manager.PutBlock(blockHash, block)
-}
diff --git a/internal/services/contractHash.go b/internal/services/contractHash.go
deleted file mode 100644
index 69874e3f..00000000
--- a/internal/services/contractHash.go
+++ /dev/null
@@ -1,75 +0,0 @@
-package services
-
-import (
-	"context"
-
-	"github.com/NethermindEth/juno/internal/db"
-	. "github.com/NethermindEth/juno/internal/log"
-	"github.com/NethermindEth/juno/pkg/felt"
-)
-
-var ContractHashService contractHashService
-
-type contractHashService struct {
-	service
-	db db.Database
-}
-
-func (s *contractHashService) Setup(database db.Database) {
-	if s.Running() {
-		// notest
-		s.logger.Panic("trying to Setup with service running")
-	}
-	s.db = database
-}
-
-func (s *contractHashService) Run() error {
-	if s.logger == nil {
-		s.logger = Logger.Named("ContractHash Service")
-	}
-
-	if err := s.service.Run(); err != nil {
-		return err
-	}
-
-	return s.setDefaults()
-}
-
-func (s *contractHashService) setDefaults() error {
-	if s.db == nil {
-		// notest
-		env, err := db.GetMDBXEnv()
-		if err != nil {
-			return err
-		}
-		database, err := db.NewMDBXDatabase(env, "CONTRACT_HASH")
-		if err != nil {
-			return err
-		}
-		s.db = database
-	}
-	return nil
-}
-
-func (s *contractHashService) Close(ctx context.Context) {
-	// notest
-	if !s.Running() {
-		return
-	}
-	s.service.Close(ctx)
-	s.db.Close()
-}
-
-func (s *contractHashService) StoreContractHash(contractAddress string, contractHash *felt.Felt) error {
-	s.AddProcess()
-	defer s.DoneProcess()
-	return s.db.Put([]byte(contractAddress), contractHash.ByteSlice())
-}
-
-func (s *contractHashService) GetContractHash(contractAddress string) (*felt.Felt, error) {
-	// notest
-	s.AddProcess()
-	defer s.DoneProcess()
-	rawData, err := s.db.Get([]byte(contractAddress))
-	return new(felt.Felt).SetBytes(rawData), err
-}
diff --git a/internal/services/service.go b/internal/services/service.go
deleted file mode 100644
index 15f4afbb..00000000
--- a/internal/services/service.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package services
-
-import (
-	"context"
-	"errors"
-	"sync"
-
-	"go.uber.org/zap"
-)
-
-// ErrAlreadyRunning is returned when you try to perform an invalid action
-// while the service is running.
-var ErrAlreadyRunning = errors.New("service is already running")
-
-// Service describes the basic functionalities that all the services have in
-// common.
-type Service interface {
-	Run() error
-	Close(ctx context.Context)
-}
-
-// service is the base struct for the services; it manages the running state,
-// logger, and the waiting group of processes.
-type service struct {
-	running bool
-	logger  *zap.SugaredLogger
-	wg      sync.WaitGroup
-}
-
-// Run makes all the tasks related to the starting process for any service,
-// like updating the running state and writing the logs.
-func (s *service) Run() error {
-	// Check if the service is already started
-	if s.Running() {
-		// notest
-		return ErrAlreadyRunning
-	}
-	s.running = true
-	s.logger.Info("Service started")
-	return nil
-}
-
-// Close makes all the tasks related to the close process for any service, like
-// updating the running state, writing the logs, and waiting for the active
-// process.
-func (s *service) Close(_ context.Context) {
-	// Check if the service is already running
-	if !s.Running() {
-		// notest
-		s.logger.Warn("service is not running")
-		return
-	}
-
-	s.running = false
-
-	s.logger.Info("Waiting for finish the active process")
-	s.wg.Wait()
-	s.logger.Info("Service stopped")
-}
-
-// AddProcess must be used at the beginning of each service process. It adds 1
-// to the counter of the waiting group of process.
-func (s *service) AddProcess() {
-	if !s.Running() {
-		// notest
-		return
-	}
-	s.wg.Add(1)
-}
-
-// DoneProcess must be used at the end of each service process. It decreases by
-// 1 the counter of the waiting group of processes.
-func (s *service) DoneProcess() {
-	s.wg.Done()
-}
-
-// Running returns true if the service is running, and false in another case.
-func (s *service) Running() bool {
-	return s.running
-}
diff --git a/internal/services/state.go b/internal/services/state.go
deleted file mode 100644
index b0272c11..00000000
--- a/internal/services/state.go
+++ /dev/null
@@ -1,107 +0,0 @@
-package services
-
-import (
-	"context"
-
-	"github.com/NethermindEth/juno/internal/db"
-	"github.com/NethermindEth/juno/internal/db/state"
-	. "github.com/NethermindEth/juno/internal/log"
-)
-
-var StateService stateService
-
-type stateService struct {
-	service
-	manager *state.Manager
-}
-
-func (s *stateService) Setup(codeDatabase db.Database, storageDatabase *db.BlockSpecificDatabase) {
-	if s.Running() {
-		// notest
-		s.logger.Panic("service is already running")
-	}
-	s.manager = state.NewStateManager(codeDatabase, storageDatabase)
-}
-
-func (s *stateService) Run() error {
-	if s.logger == nil {
-		s.logger = Logger.Named("StateService")
-	}
-
-	if err := s.service.Run(); err != nil {
-		// notest
-		return err
-	}
-
-	return s.setDefaults()
-}
-
-func (s *stateService) setDefaults() error {
-	if s.manager == nil {
-		// notest
-		env, err := db.GetMDBXEnv()
-		if err != nil {
-			return err
-		}
-		codeDb, err := db.NewMDBXDatabase(env, "CODE")
-		if err != nil {
-			return err
-		}
-		storageDb, err := db.NewMDBXDatabase(env, "STORAGE")
-		if err != nil {
-			return err
-		}
-		storageDatabase := db.NewBlockSpecificDatabase(storageDb)
-		s.manager = state.NewStateManager(codeDb, storageDatabase)
-	}
-	return nil
-}
-
-func (s *stateService) Close(ctx context.Context) {
-	// notest
-	if !s.Running() {
-		return
-	}
-	s.service.Close(ctx)
-	s.manager.Close()
-}
-
-func (s *stateService) StoreCode(contractAddress []byte, code *state.Code) error {
-	s.AddProcess()
-	defer s.DoneProcess()
-	return s.manager.PutCode(contractAddress, code)
-}
-
-func (s *stateService) GetCode(contractAddress []byte) (*state.Code, error) {
-	s.AddProcess()
-	defer s.DoneProcess()
-	return s.manager.GetCode(contractAddress)
-}
-
-func (s *stateService) StoreStorage(contractAddress string, blockNumber uint64, storage *state.Storage) error {
-	s.AddProcess()
-	defer s.DoneProcess()
-	return s.manager.PutStorage(contractAddress, blockNumber, storage)
-}
-
-func (s *stateService) GetStorage(contractAddress string, blockNumber uint64) (*state.Storage, error) {
-	s.AddProcess()
-	defer s.DoneProcess()
-	return s.manager.GetStorage(contractAddress, blockNumber)
-}
-
-func (s *stateService) UpdateStorage(contractAddress string, blockNumber uint64, storage *state.Storage) error {
-	s.AddProcess()
-	defer s.DoneProcess()
-	oldStorage, err := s.GetStorage(contractAddress, blockNumber)
-	if err != nil {
-		return err
-	}
-	if oldStorage == nil {
-		// notest
-		return s.StoreStorage(contractAddress, blockNumber, storage)
-	} else {
-		oldStorage.Update(storage)
-		return s.StoreStorage(contractAddress, blockNumber, oldStorage)
-	}
-}
diff --git a/internal/services/transactions.go b/internal/services/transactions.go
deleted file mode 100644
index 87b8f009..00000000
--- a/internal/services/transactions.go
+++ /dev/null
@@ -1,114 +0,0 @@
-package services
-
-import (
-	"context"
-
-	"github.com/NethermindEth/juno/pkg/felt"
-	"github.com/NethermindEth/juno/pkg/types"
-
-	"github.com/NethermindEth/juno/internal/db"
-	"github.com/NethermindEth/juno/internal/db/transaction"
-	. "github.com/NethermindEth/juno/internal/log"
-)
-
-// TransactionService is a service to manage the transaction database. Before
-// using the service, it must be configured with the Setup method;
-// otherwise, the value will be the default. To stop the service, call the
-// Close method.
-var TransactionService transactionService
-
-type transactionService struct {
-	service
-	manager *transaction.Manager
-}
-
-// Setup is used to configure the service before it's started. The database
-// param is the database where the transactions will be stored.
-func (s *transactionService) Setup(txDb, receiptDb db.Database) {
-	if s.service.Running() {
-		// notest
-		s.logger.Panic("trying to Setup with service running")
-	}
-	s.manager = transaction.NewManager(txDb, receiptDb)
-}
-
-// Run starts the service. If the Setup method is not called before, the default
-// values are used.
-func (s *transactionService) Run() error {
-	if s.logger == nil {
-		s.logger = Logger.Named("Transaction Service")
-	}
-
-	if err := s.service.Run(); err != nil {
-		// notest
-		return err
-	}
-
-	return s.setDefaults()
-}
-
-func (s *transactionService) setDefaults() error {
-	if s.manager == nil {
-		// notest
-		env, err := db.GetMDBXEnv()
-		if err != nil {
-			return err
-		}
-		txDb, err := db.NewMDBXDatabase(env, "TRANSACTION")
-		if err != nil {
-			return err
-		}
-		receiptDb, err := db.NewMDBXDatabase(env, "RECEIPT")
-		if err != nil {
-			return err
-		}
-		s.manager = transaction.NewManager(txDb, receiptDb)
-	}
-	return nil
-}
-
-// Close stops the service, waiting to end the current operations, and closes
-// the database manager.
-func (s *transactionService) Close(ctx context.Context) {
-	// notest
-	if !s.Running() {
-		return
-	}
-	s.service.Close(ctx)
-	s.manager.Close()
-}
-
-// GetTransaction searches for the transaction associated with the given
-// transaction hash. If the transaction does not exist on the database, then
-// returns nil.
-func (s *transactionService) GetTransaction(txHash *felt.Felt) (types.IsTransaction, error) {
-	s.AddProcess()
-	defer s.DoneProcess()
-	return s.manager.GetTransaction(txHash)
-}
-
-// StoreTransaction stores the given transaction into the database. The key used
-// to map the transaction it's the hash of the transaction. If the database
-// already has a transaction with the same key, then the value is overwritten.
-func (s *transactionService) StoreTransaction(txHash *felt.Felt, tx types.IsTransaction) error {
-	s.AddProcess()
-	defer s.DoneProcess()
-	return s.manager.PutTransaction(txHash, tx)
-}
-
-// GetReceipt searches for the transaction receipt associated with the given
-// transaction hash. If the transaction does not exist on the database, then
-// returns nil.
-func (s *transactionService) GetReceipt(txHash *felt.Felt) (*types.TransactionReceipt, error) {
-	s.AddProcess()
-	defer s.DoneProcess()
-	return s.manager.GetReceipt(txHash)
-}
-
-// StoreReceipt stores the given transaction receipt into the database. If the
-// database already has a receipt with the same key, the value is overwritten.
-func (s *transactionService) StoreReceipt(txHash *felt.Felt, receipt *types.TransactionReceipt) error {
-	s.AddProcess()
-	defer s.DoneProcess()
-	return s.manager.PutReceipt(txHash, receipt)
-}
diff --git a/pkg/rest/server.go b/pkg/rest/server.go
index 05b15509..d33ed1d4 100644
--- a/pkg/rest/server.go
+++ b/pkg/rest/server.go
@@ -2,7 +2,9 @@ package rest
 
 import (
 	"context"
+	"errors"
 	"net/http"
+	"time"
 
 	. "github.com/NethermindEth/juno/internal/log"
 )
@@ -12,30 +14,32 @@ type Server struct {
 	server http.Server
 }
 
-// ListenAndServe listens to TCP port and handles requests on
-// incoming connections.
-func (s *Server) ListenAndServe() error {
+// ListenAndServe listens to TCP port and handles requests on incoming
+// connections. ListenAndServe runs in a separate go routine so that it doesn't
+// block the caller.
+func (s *Server) ListenAndServe(errCh chan<- error) {
 	// notest
-	Logger.Info("Listening for connections .... ")
+	go s.listenAndServe(errCh)
+}
+
+func (s *Server) listenAndServe(errCh chan<- error) {
+	Logger.Info("Listening for REST connections...")
 
-	err := s.server.ListenAndServe()
-	if err != nil {
-		Logger.With("Error", err).Error("Error occurred while trying to listen for connections.")
-		return err
+	// Since ListenAndServe always returns an error we need to ensure that there
+	// is no write to a closed channel. Therefore, we check for ErrServerClosed
+	// since that is only returned after ShutDown or Closed is called. Hence, no
+	// write to the channel is required. Otherwise, any other error is written
+	// which will cause the program to exit.
+	if err := s.server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
+		// notest
+		errCh <- errors.New("Failed to ListenAndServe on REST server: " + err.Error())
 	}
-	return nil
+	close(errCh)
 }
 
-// Close shuts down the server.
-func (s *Server) Close(ctx context.Context) {
-	// notest
-	select {
-	case <-ctx.Done():
-		err := s.server.Shutdown(ctx)
-		if err != nil {
-			Logger.With("Error", err).Info("Exiting with error.")
-			return
-		}
-	default:
-	}
+// Close gracefully shuts down the server.
+func (s *Server) Close(timeout time.Duration) error {
+	Logger.Info("Shutting down REST server...")
+	ctx, _ := context.WithTimeout(context.Background(), timeout)
+	return s.server.Shutdown(ctx)
 }
diff --git a/pkg/rpc/api.go b/pkg/rpc/api.go
index d25e2eb4..ab9a1fdb 100644
--- a/pkg/rpc/api.go
+++ b/pkg/rpc/api.go
@@ -8,7 +8,6 @@ import (
 
 	"github.com/NethermindEth/juno/internal/db"
 	dbAbi "github.com/NethermindEth/juno/internal/db/abi"
-	"github.com/NethermindEth/juno/internal/services"
 	"github.com/NethermindEth/juno/pkg/feeder"
 	"github.com/NethermindEth/juno/pkg/types"
 
@@ -163,7 +162,7 @@ func getBlockByTag(_ context.Context, blockTag BlockTag, scope RequestedScope) (
 func getBlockByHash(ctx context.Context, blockHash *felt.Felt, scope RequestedScope) (*BlockResponse, error) {
 	// notest
 	Logger.With("blockHash", blockHash, "scope", scope).Info("StarknetGetBlockByHash")
-	dbBlock, err := services.BlockService.GetBlockByHash(blockHash)
+	dbBlock, err := blockManager.GetBlockByHash(blockHash)
 	if err != nil {
 		// notest
 		if errors.Is(err, db.ErrNotFound) {
@@ -206,7 +205,7 @@ func (HandlerRPC) StarknetGetBlockByHashOpt(ctx context.Context, blockHashOrTag
 func getBlockByNumber(ctx context.Context, blockNumber uint64, scope RequestedScope) (*BlockResponse, error) {
 	// notest
 	Logger.With("blockNumber", blockNumber, "scope", scope).Info("StarknetGetBlockNyNumber")
-	dbBlock, err := services.BlockService.GetBlockByNumber(blockNumber)
+	dbBlock, err := blockManager.GetBlockByNumber(blockNumber)
 	if err != nil {
 		// notest
 		if errors.Is(err, db.ErrNotFound) {
@@ -281,7 +280,7 @@ func (HandlerRPC) StarknetGetStorageAt(
 ) (Felt, error) {
 	var blockNumber uint64
 	if hash := blockHash.Hash; hash != nil {
-		block, err := services.BlockService.GetBlockByHash(blockHash.Hash)
+		block, err := blockManager.GetBlockByHash(blockHash.Hash)
 		if err != nil {
 			// notest
 			if errors.Is(err, db.ErrNotFound) {
@@ -302,7 +301,7 @@ func (HandlerRPC) StarknetGetStorageAt(
 		return "", fmt.Errorf("invalid block hash or tag")
 	}
 
-	storage, err := services.StateService.GetStorage(string(contractAddress), blockNumber)
+	storage, err := stateManager.GetStorage(string(contractAddress), blockNumber)
 	if err != nil {
 		// notest
 		if errors.Is(err, db.ErrNotFound) {
@@ -319,7 +318,7 @@ func (HandlerRPC) StarknetGetStorageAt(
 func (HandlerRPC) StarknetGetTransactionByHash(
 	c context.Context, transactionHash *felt.Felt,
 ) (*Txn, error) {
-	tx, err := services.TransactionService.GetTransaction(transactionHash)
+	tx, err := transactionManager.GetTransaction(transactionHash)
 	if err != nil {
 		// notest
 		if errors.Is(err, db.ErrNotFound) {
@@ -336,7 +335,7 @@ func (HandlerRPC) StarknetGetTransactionByHash(
 // no transaction is found, a null value is returned.
 func (HandlerRPC) StarknetGetTransactionByBlockHashAndIndex(c context.Context, blockHashOrTag BlockHashOrTag, index int) (*Txn, error) {
 	if blockHash := blockHashOrTag.Hash; blockHash != nil {
-		block, err := services.BlockService.GetBlockByHash(blockHash)
+		block, err := blockManager.GetBlockByHash(blockHash)
 		if err != nil {
 			// notest
 			if errors.Is(err, db.ErrNotFound) {
@@ -350,7 +349,7 @@ func (HandlerRPC) StarknetGetTransactionByBlockHashAndIndex(c context.Context, b
 			return nil, fmt.Errorf("invalid index %d", index)
 		}
 		txHash := block.TxHashes[index]
-		txn, err := services.TransactionService.GetTransaction(txHash)
+		txn, err := transactionManager.GetTransaction(txHash)
 		if err != nil {
 			// notest
 			if errors.Is(err, db.ErrNotFound) {
@@ -379,7 +378,7 @@ func (HandlerRPC) StarknetGetTransactionByBlockHashAndIndex(c context.Context, b
 // no transaction is found, null is returned.
 func (HandlerRPC) StarknetGetTransactionByBlockNumberAndIndex(ctx context.Context, blockNumberOrTag BlockNumberOrTag, index int) (*Txn, error) {
 	if blockNumber := blockNumberOrTag.Number; blockNumber != nil {
-		block, err := services.BlockService.GetBlockByNumber(*blockNumber)
+		block, err := blockManager.GetBlockByNumber(*blockNumber)
 		if err != nil {
 			// notest
 			if errors.Is(err, db.ErrNotFound) {
@@ -392,7 +391,7 @@ func (HandlerRPC) StarknetGetTransactionByBlockNumberAndIndex(ctx context.Contex
 			return nil, fmt.Errorf("invalid index %d", index)
 		}
 		txHash := block.TxHashes[index]
-		txn, err := services.TransactionService.GetTransaction(txHash)
+		txn, err := transactionManager.GetTransaction(txHash)
 		if err != nil {
 			// notest
 			if errors.Is(err, db.ErrNotFound) {
@@ -428,7 +427,7 @@ func (HandlerRPC) StarknetGetTransactionReceipt(
 func (HandlerRPC) StarknetGetCode(
 	c context.Context, contractAddress *felt.Felt,
 ) (*CodeResult, error) {
-	abi, err := services.AbiService.GetAbi(contractAddress.Hex())
+	abi, err := abiManager.GetABI(contractAddress.Hex())
 	if err != nil {
 		if errors.Is(err, db.ErrNotFound) {
 			// Try the feeder gateway for pending block
@@ -472,7 +471,7 @@ func (HandlerRPC) StarknetGetCode(
 		}
 		return nil, fmt.Errorf("database error: %v", err)
 	}
-	code, err := services.StateService.GetCode(contractAddress.ByteSlice())
+	code, err := stateManager.GetCode(contractAddress.ByteSlice())
 	if err != nil {
 		// notest
 		if errors.Is(err, db.ErrNotFound) {
diff --git a/pkg/rpc/server.go b/pkg/rpc/server.go
index a9d0bb00..a3704151 100644
--- a/pkg/rpc/server.go
+++ b/pkg/rpc/server.go
@@ -2,15 +2,31 @@ package rpc
 
 import (
 	"context"
+	"errors"
 	"net/http"
+	"time"
 
-	"github.com/NethermindEth/juno/pkg/feeder"
-
+	"github.com/NethermindEth/juno/internal/db/abi"
+	"github.com/NethermindEth/juno/internal/db/block"
+	"github.com/NethermindEth/juno/internal/db/state"
+	"github.com/NethermindEth/juno/internal/db/transaction"
 	. "github.com/NethermindEth/juno/internal/log"
+	"github.com/NethermindEth/juno/pkg/feeder"
 )
 
 // Global feederClient that we use to request pending blocks
-var feederClient *feeder.Client
+// todo: refactor the use of these global variables. Due to the use of
+//  reflection in this package it is difficult to not use these global
+//  variables. While testing it is difficult to understand where and whether
+//  these variables are being set properly and thus difficult to assert the
+//  validity of the testcase.
+var (
+	feederClient       *feeder.Client
+	abiManager         *abi.Manager
+	stateManager       *state.Manager
+	transactionManager *transaction.Manager
+	blockManager       *block.Manager
+)
 
 // Server represents the server structure
 type Server struct {
@@ -33,38 +49,45 @@ func NewHandlerJsonRpc(rpc interface{}) *HandlerJsonRpc {
 }
 
 // NewServer creates a new server.
-func NewServer(addr string, client *feeder.Client) *Server {
+func NewServer(addr string, client *feeder.Client, abiM *abi.Manager, stateM *state.Manager,
+	transactionM *transaction.Manager, blockM *block.Manager,
+) *Server {
+	abiManager = abiM
+	stateManager = stateM
+	transactionManager = transactionM
+	blockManager = blockM
 	mux := http.NewServeMux()
 	mux.Handle("/rpc", NewHandlerJsonRpc(HandlerRPC{}))
 	return &Server{server: http.Server{Addr: addr, Handler: mux}, feederClient: client}
 }
 
-// ListenAndServe listens on the TCP network and handles requests on
-// incoming connections.
-func (s *Server) ListenAndServe() error {
+// ListenAndServe listens to TCP port and handles requests on incoming
+// connections. ListenAndServe runs in a separate go routine so that it doesn't
+// block the caller.
+func (s *Server) ListenAndServe(errCh chan<- error) {
 	feederClient = s.feederClient
 	// notest
-	Logger.Info("Listening for connections .... ")
+	go s.listenAndServe(errCh)
+}
+
+func (s *Server) listenAndServe(errCh chan<- error) {
+	Logger.Info("Listening for RPC connections...")
 
-	err := s.server.ListenAndServe()
-	if err != nil {
-		Logger.With("Error", err).Error("Error occurred while trying to listen for connections.")
-		return err
+	// Since ListenAndServe always returns an error we need to ensure that there
+	// is no write to a closed channel. Therefore, we check for ErrServerClosed
+	// since that is only returned after ShutDown or Closed is called. Hence, no
+	// write to the channel is required. Otherwise, any other error is written
+	// which will cause the program to exit.
+	if err := s.server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
+		// notest
+		errCh <- errors.New("Failed to ListenAndServe on RPC server: " + err.Error())
 	}
-	return nil
+	close(errCh)
 }
 
 // Close gracefully shuts down the server.
-func (s *Server) Close(ctx context.Context) {
-	// notest
-	Logger.Info("Closing RPC server")
-	select {
-	case <-ctx.Done():
-		err := s.server.Shutdown(ctx)
-		if err != nil {
-			Logger.With("Error", err).Info("Exiting with error.")
-			return
-		}
-	default:
-	}
+func (s *Server) Close(timeout time.Duration) error {
+	Logger.Info("Shutting down RPC server...")
+	ctx, _ := context.WithTimeout(context.Background(), timeout)
+	return s.server.Shutdown(ctx)
 }
diff --git a/pkg/rpc/types.go b/pkg/rpc/types.go
index 7df954a7..59ff7a51 100644
--- a/pkg/rpc/types.go
+++ b/pkg/rpc/types.go
@@ -5,8 +5,6 @@ import (
 	"encoding/json"
 	"errors"
 
-	"github.com/NethermindEth/juno/internal/services"
-
 	"github.com/NethermindEth/juno/pkg/common"
 	"github.com/NethermindEth/juno/pkg/felt"
 	"github.com/NethermindEth/juno/pkg/types"
@@ -435,7 +433,7 @@ func NewBlockResponse(block *types.Block, scope RequestedScope) (*BlockResponse,
 	case ScopeFullTxns:
 		txns := make([]*Txn, len(block.TxHashes))
 		for i, txHash := range block.TxHashes {
-			transaction, err := services.TransactionService.GetTransaction(txHash)
+			transaction, err := transactionManager.GetTransaction(txHash)
 			if err != nil {
 				return nil, err
 			}
@@ -447,7 +445,7 @@ func NewBlockResponse(block *types.Block, scope RequestedScope) (*BlockResponse,
 		txns := make([]*TxnAndReceipt, len(block.TxHashes))
 		for i, txHash := range block.TxHashes {
 			txnAndReceipt := &TxnAndReceipt{}
-			transaction, err := services.TransactionService.GetTransaction(txHash)
+			transaction, err := transactionManager.GetTransaction(txHash)
 			if err != nil {
 				return nil, err
 			}
@@ -455,7 +453,7 @@ func NewBlockResponse(block *types.Block, scope RequestedScope) (*BlockResponse,
 				txn := NewTxn(transaction)
 				txnAndReceipt.Txn = *txn
 			}
-			receipt, err := services.TransactionService.GetReceipt(txHash)
+			receipt, err := transactionManager.GetReceipt(txHash)
 			if err != nil {
 				return nil, err
 			}
diff --git a/pkg/starknet/state.go b/pkg/starknet/state.go
index 1e74c3ff..84431202 100644
--- a/pkg/starknet/state.go
+++ b/pkg/starknet/state.go
@@ -12,9 +12,13 @@ import (
 
 	"github.com/NethermindEth/juno/internal/config"
 	"github.com/NethermindEth/juno/internal/db"
+	abiM "github.com/NethermindEth/juno/internal/db/abi"
+	"github.com/NethermindEth/juno/internal/db/block"
+	"github.com/NethermindEth/juno/internal/db/contracthash"
+	"github.com/NethermindEth/juno/internal/db/state"
+	"github.com/NethermindEth/juno/internal/db/transaction"
 	. "github.com/NethermindEth/juno/internal/log"
 	metr "github.com/NethermindEth/juno/internal/metrics/prometheus"
-	"github.com/NethermindEth/juno/internal/services"
 	"github.com/NethermindEth/juno/pkg/feeder"
 	"github.com/NethermindEth/juno/pkg/felt"
 	"github.com/NethermindEth/juno/pkg/starknet/abi"
@@ -36,10 +40,19 @@ type Synchronizer struct {
 	gpsVerifier         *starknetTypes.Dictionary
 	facts               *starknetTypes.Dictionary
 	chainID             int64
+
+	contractHashManager *contracthash.Manager
+	abiManager          *abiM.Manager
+	stateManager        *state.Manager
+	transactionManager  *transaction.Manager
+	blockManager        *block.Manager
 }
 
 // NewSynchronizer creates a new Synchronizer
-func NewSynchronizer(txnDb db.DatabaseTransactional, client *ethclient.Client, fClient *feeder.Client) *Synchronizer {
+func NewSynchronizer(txnDb db.DatabaseTransactional, client *ethclient.Client, fClient *feeder.Client,
+	contractHashM *contracthash.Manager, abiM *abiM.Manager, stateM *state.Manager,
+	transactionM *transaction.Manager, blockM *block.Manager,
+) *Synchronizer {
 	var chainID *big.Int
 	if client == nil {
 		// notest
@@ -64,6 +77,11 @@ func NewSynchronizer(txnDb db.DatabaseTransactional, client *ethclient.Client, f
 		gpsVerifier:         starknetTypes.NewDictionary(txnDb, "gps_verifier"),
 		facts:               starknetTypes.NewDictionary(txnDb, "facts"),
 		chainID:             chainID.Int64(),
+		contractHashManager: contractHashM,
+		abiManager:          abiM,
+		stateManager:        stateM,
+		transactionManager:  transactionM,
+		blockManager:        blockM,
 	}
 }
 
@@ -357,22 +375,20 @@ func (s *Synchronizer) l1Sync() error {
 // updateAndCommitState applies `stateDiff` to the local state and
 // commits the changes to the database.
 // notest
-func (s *Synchronizer) updateAndCommitState(
-	stateDiff *starknetTypes.StateDiff,
-	newRoot string,
+func (s *Synchronizer) updateAndCommitState(stateDiff *starknetTypes.StateDiff, newRoot string,
 	sequenceNumber uint64,
 ) uint64 {
 	start := time.Now()
 	// Save contract hashes of the new contracts
 	for _, deployedContract := range stateDiff.DeployedContracts {
 		contractHash := new(felt.Felt).SetHex(deployedContract.ContractHash)
-		services.ContractHashService.StoreContractHash(remove0x(deployedContract.Address), contractHash)
+		s.contractHashManager.StoreContractHash(remove0x(deployedContract.Address), contractHash)
 	}
 	// Build contractAddress-contractHash map
 	contractHashMap := make(map[string]*felt.Felt)
 	for contractAddress := range stateDiff.StorageDiffs {
 		formattedAddress := remove0x(contractAddress)
-		contractHash, err := services.ContractHashService.GetContractHash(formattedAddress)
+		contractHash, err := s.contractHashManager.GetContractHash(formattedAddress)
 		if err != nil {
 			// notest
 			metr.IncreaseCountStarknetStateFailed()
@@ -438,7 +454,7 @@ func getFactInfo(starknetLogs []ethtypes.Log, contract ethAbi.ABI, fact string,
 }
 
 // Close closes the client for the Layer 1 Ethereum node
-func (s *Synchronizer) Close(_ context.Context) {
+func (s *Synchronizer) Close() {
 	// notest
 	Logger.Info("Closing Layer 1 Synchronizer")
 	if s.ethereumClient != nil {
@@ -552,9 +568,9 @@ func (s *Synchronizer) updateAbiAndCode(update starknetTypes.StateDiff, blockHas
 			return
 		}
 		// Save the ABI
-		services.AbiService.StoreAbi(remove0x(v.Address), toDbAbi(code.Abi))
+		s.abiManager.PutABI(remove0x(v.Address), toDbAbi(code.Abi))
 		// Save the contract code
-		services.StateService.StoreCode(common.Hex2Bytes(remove0x(v.Address)), byteCodeToStateCode(code.Bytecode))
+		s.stateManager.PutCode(common.Hex2Bytes(remove0x(v.Address)), byteCodeToStateCode(code.Bytecode))
 	}
 }
 
@@ -566,7 +582,7 @@ func (s *Synchronizer) updateBlocksAndTransactions(blockHash, blockNumber string
 	}
 	Logger.With("Block Hash", block.BlockHash).
 		Info("Got block")
-	services.BlockService.StoreBlock(new(felt.Felt).SetHex(block.BlockHash), feederBlockToDBBlock(block))
+	s.blockManager.PutBlock(new(felt.Felt).SetHex(block.BlockHash), feederBlockToDBBlock(block))
 
 	for _, bTxn := range block.Transactions {
 		transactionInfo, err := s.feederGatewayClient.GetTransaction(bTxn.TransactionHash, "")
@@ -575,7 +591,7 @@ func (s *Synchronizer) updateBlocksAndTransactions(blockHash, blockNumber string
 		}
 		Logger.With("Transaction Hash", transactionInfo.Transaction.TransactionHash).
 			Info("Got transactions of block")
-		services.TransactionService.StoreTransaction(new(felt.Felt).SetHex(bTxn.TransactionHash),
+		s.transactionManager.PutTransaction(new(felt.Felt).SetHex(bTxn.TransactionHash),
 			feederTransactionToDBTransaction(transactionInfo))
 	}
 }


Test patch:
diff --git a/internal/db/abi/abi_test.go b/internal/db/abi/abi_test.go
deleted file mode 100644
index b7ca6386..00000000
--- a/internal/db/abi/abi_test.go
+++ /dev/null
@@ -1,186 +0,0 @@
-package abi
-
-var abis = map[string]*Abi{
-	"1bd7ca87f139693e6681be2042194cf631c4e8d77027bf0ea9e6d55fc6018ac": {
-		Functions: []*Function{
-			{
-				Name: "initialize",
-				Inputs: []*Function_Input{
-					{
-						Name: "signer",
-						Type: "felt",
-					},
-					{
-						Name: "guardian",
-						Type: "felt",
-					},
-				},
-				Outputs: nil,
-			},
-			{
-				Name: "__execute__",
-				Inputs: []*Function_Input{
-					{
-						Name: "call_array_len",
-						Type: "felt",
-					},
-					{
-						Name: "call_array",
-						Type: "felt",
-					},
-					{
-						Name: "calldata_len",
-						Type: "felt",
-					},
-					{
-						Name: "calldata",
-						Type: "felt*",
-					},
-					{
-						Name: "nonce",
-						Type: "felt",
-					},
-				},
-				Outputs: []*Function_Output{
-					{
-						Name: "retdata_size",
-						Type: "felt",
-					},
-					{
-						Name: "retdata",
-						Type: "felt*",
-					},
-				},
-			},
-			{
-				Name: "upgrade",
-				Inputs: []*Function_Input{
-					{
-						Name: "implementation",
-						Type: "felt",
-					},
-				},
-				Outputs: nil,
-			},
-		},
-		Events: []*AbiEvent{
-			{
-				Data: []*AbiEvent_Data{
-					{
-						Name: "new_signer",
-						Type: "felt",
-					},
-				},
-				Keys: nil,
-				Name: "signer_changed",
-			},
-			{
-				Data: []*AbiEvent_Data{
-					{
-						Name: "new_guardian",
-						Type: "felt",
-					},
-				},
-				Keys: nil,
-				Name: "guardian_changed",
-			},
-			{
-				Data: []*AbiEvent_Data{
-					{
-						Name: "new_guardian",
-						Type: "felt",
-					},
-				},
-				Keys: nil,
-				Name: "guardian_backup_changed",
-			},
-			{
-				Data: []*AbiEvent_Data{
-					{
-						Name: "active_at",
-						Type: "felt",
-					},
-				},
-				Keys: nil,
-				Name: "escape_guardian_triggered",
-			},
-			{
-				Data: []*AbiEvent_Data{
-					{
-						Name: "active_at",
-						Type: "felt",
-					},
-				},
-				Keys: nil,
-				Name: "escape_signer_triggered",
-			},
-			{
-				Data: nil,
-				Keys: nil,
-				Name: "escape_canceled",
-			},
-		},
-		Structs: []*Struct{
-			{
-				Fields: []*Struct_Field{
-					{
-						Name:   "to",
-						Type:   "felt",
-						Offset: 0,
-					},
-					{
-						Name:   "selector",
-						Type:   "felt",
-						Offset: 1,
-					},
-					{
-						Name:   "data_offset",
-						Type:   "felt",
-						Offset: 2,
-					},
-					{
-						Name:   "data_len",
-						Type:   "felt",
-						Offset: 3,
-					},
-				},
-				Name: "CallArray",
-				Size: 4,
-			},
-		},
-		L1Handlers: []*Function{
-			{
-				Name: "__l1_default__",
-				Inputs: []*Function_Input{
-					{
-						Name: "selector",
-						Type: "felt",
-					},
-					{
-						Name: "calldata_size",
-						Type: "felt",
-					},
-					{
-						Name: "calldata",
-						Type: "felt*",
-					},
-				},
-				Outputs: nil,
-			},
-		},
-		Constructor: &Function{
-			Name: "constructor",
-			Inputs: []*Function_Input{
-				{
-					Name: "signer",
-					Type: "felt",
-				},
-				{
-					Name: "guardian",
-					Type: "felt",
-				},
-			},
-			Outputs: nil,
-		},
-	},
-}
diff --git a/internal/db/abi/manager_test.go b/internal/db/abi/manager_test.go
index 5db74ddc..e94195bc 100644
--- a/internal/db/abi/manager_test.go
+++ b/internal/db/abi/manager_test.go
@@ -16,7 +16,7 @@ func TestManager(t *testing.T) {
 	if err != nil {
 		t.Error(err)
 	}
-	manager := NewABIManager(database)
+	manager := NewManager(database)
 
 	for address, abi := range abis {
 		if err := manager.PutABI(address, abi); err != nil {
@@ -35,3 +35,188 @@ func TestManager(t *testing.T) {
 	}
 	manager.Close()
 }
+
+var abis = map[string]*Abi{
+	"1bd7ca87f139693e6681be2042194cf631c4e8d77027bf0ea9e6d55fc6018ac": {
+		Functions: []*Function{
+			{
+				Name: "initialize",
+				Inputs: []*Function_Input{
+					{
+						Name: "signer",
+						Type: "felt",
+					},
+					{
+						Name: "guardian",
+						Type: "felt",
+					},
+				},
+				Outputs: nil,
+			},
+			{
+				Name: "__execute__",
+				Inputs: []*Function_Input{
+					{
+						Name: "call_array_len",
+						Type: "felt",
+					},
+					{
+						Name: "call_array",
+						Type: "felt",
+					},
+					{
+						Name: "calldata_len",
+						Type: "felt",
+					},
+					{
+						Name: "calldata",
+						Type: "felt*",
+					},
+					{
+						Name: "nonce",
+						Type: "felt",
+					},
+				},
+				Outputs: []*Function_Output{
+					{
+						Name: "retdata_size",
+						Type: "felt",
+					},
+					{
+						Name: "retdata",
+						Type: "felt*",
+					},
+				},
+			},
+			{
+				Name: "upgrade",
+				Inputs: []*Function_Input{
+					{
+						Name: "implementation",
+						Type: "felt",
+					},
+				},
+				Outputs: nil,
+			},
+		},
+		Events: []*AbiEvent{
+			{
+				Data: []*AbiEvent_Data{
+					{
+						Name: "new_signer",
+						Type: "felt",
+					},
+				},
+				Keys: nil,
+				Name: "signer_changed",
+			},
+			{
+				Data: []*AbiEvent_Data{
+					{
+						Name: "new_guardian",
+						Type: "felt",
+					},
+				},
+				Keys: nil,
+				Name: "guardian_changed",
+			},
+			{
+				Data: []*AbiEvent_Data{
+					{
+						Name: "new_guardian",
+						Type: "felt",
+					},
+				},
+				Keys: nil,
+				Name: "guardian_backup_changed",
+			},
+			{
+				Data: []*AbiEvent_Data{
+					{
+						Name: "active_at",
+						Type: "felt",
+					},
+				},
+				Keys: nil,
+				Name: "escape_guardian_triggered",
+			},
+			{
+				Data: []*AbiEvent_Data{
+					{
+						Name: "active_at",
+						Type: "felt",
+					},
+				},
+				Keys: nil,
+				Name: "escape_signer_triggered",
+			},
+			{
+				Data: nil,
+				Keys: nil,
+				Name: "escape_canceled",
+			},
+		},
+		Structs: []*Struct{
+			{
+				Fields: []*Struct_Field{
+					{
+						Name:   "to",
+						Type:   "felt",
+						Offset: 0,
+					},
+					{
+						Name:   "selector",
+						Type:   "felt",
+						Offset: 1,
+					},
+					{
+						Name:   "data_offset",
+						Type:   "felt",
+						Offset: 2,
+					},
+					{
+						Name:   "data_len",
+						Type:   "felt",
+						Offset: 3,
+					},
+				},
+				Name: "CallArray",
+				Size: 4,
+			},
+		},
+		L1Handlers: []*Function{
+			{
+				Name: "__l1_default__",
+				Inputs: []*Function_Input{
+					{
+						Name: "selector",
+						Type: "felt",
+					},
+					{
+						Name: "calldata_size",
+						Type: "felt",
+					},
+					{
+						Name: "calldata",
+						Type: "felt*",
+					},
+				},
+				Outputs: nil,
+			},
+		},
+		Constructor: &Function{
+			Name: "constructor",
+			Inputs: []*Function_Input{
+				{
+					Name: "signer",
+					Type: "felt",
+				},
+				{
+					Name: "guardian",
+					Type: "felt",
+				},
+			},
+			Outputs: nil,
+		},
+	},
+}
diff --git a/internal/db/block/block_test.go b/internal/db/block/block_test.go
index 34e33360..d23000a0 100644
--- a/internal/db/block/block_test.go
+++ b/internal/db/block/block_test.go
@@ -36,7 +36,7 @@ func TestManager(t *testing.T) {
 	if err != nil {
 		t.Error(err)
 	}
-	database, err := db.NewMDBXDatabase(env, "ABI")
+	database, err := db.NewMDBXDatabase(env, "BLOCK")
 	if err != nil {
 		t.Error(err)
 	}
diff --git a/internal/db/state/code_test.go b/internal/db/state/code_test.go
index dc17005e..42a66e82 100644
--- a/internal/db/state/code_test.go
+++ b/internal/db/state/code_test.go
@@ -42,7 +42,7 @@ func TestManager_Code(t *testing.T) {
 		t.Error(err)
 	}
 	storageDatabase := db.NewBlockSpecificDatabase(storageDb)
-	manager := NewStateManager(codeDatabase, storageDatabase)
+	manager := NewManager(codeDatabase, storageDatabase)
 	for _, code := range codes {
 		if err := manager.PutCode(code.Address, code.Code); err != nil {
 			t.Error(err)
diff --git a/internal/db/state/storage_test.go b/internal/db/state/storage_test.go
index a55e7743..86457ae7 100644
--- a/internal/db/state/storage_test.go
+++ b/internal/db/state/storage_test.go
@@ -45,7 +45,7 @@ func TestManager_Storage(t *testing.T) {
 		t.Error(err)
 	}
 	storageDatabase := db.NewBlockSpecificDatabase(storageDb)
-	manager := NewStateManager(codeDb, storageDatabase)
+	manager := NewManager(codeDb, storageDatabase)
 	for _, data := range initialData {
 		if err := manager.PutStorage(data.Contract, data.BlockNumber, data.Storage); err != nil {
 			t.Error(err)
diff --git a/internal/services/abi_test.go b/internal/services/abi_test.go
deleted file mode 100644
index 86565687..00000000
--- a/internal/services/abi_test.go
+++ /dev/null
@@ -1,229 +0,0 @@
-package services
-
-import (
-	"context"
-	"errors"
-	"testing"
-
-	"github.com/NethermindEth/juno/internal/db"
-	"github.com/NethermindEth/juno/internal/db/abi"
-)
-
-func TestAbiService_StoreGet(t *testing.T) {
-	env, err := db.NewMDBXEnv(t.TempDir(), 1, 0)
-	if err != nil {
-		t.Error(err)
-	}
-	database, err := db.NewMDBXDatabase(env, "ABI")
-	if err != nil {
-		t.Error(err)
-	}
-	AbiService.Setup(database)
-	if err := AbiService.Run(); err != nil {
-		t.Errorf("unexpeted error in Run: %s", err)
-	}
-	defer AbiService.Close(context.Background())
-
-	for address, a := range abis {
-		if err := AbiService.StoreAbi(address, a); err != nil {
-			t.Error(err)
-		}
-	}
-	for address, a := range abis {
-		result, err := AbiService.GetAbi(address)
-		if err != nil {
-			if errors.Is(err, db.ErrNotFound) {
-				t.Errorf("ABI not found for address %s", address)
-			}
-			t.Error(err)
-		}
-		if !a.Equal(result) {
-			t.Errorf("ABI are not equal after Store-Get operations, address: %s", address)
-		}
-	}
-}
-
-var abis = map[string]*abi.Abi{
-	"1bd7ca87f139693e6681be2042194cf631c4e8d77027bf0ea9e6d55fc6018ac": {
-		Functions: []*abi.Function{
-			{
-				Name: "initialize",
-				Inputs: []*abi.Function_Input{
-					{
-						Name: "signer",
-						Type: "felt",
-					},
-					{
-						Name: "guardian",
-						Type: "felt",
-					},
-				},
-				Outputs: nil,
-			},
-			{
-				Name: "__execute__",
-				Inputs: []*abi.Function_Input{
-					{
-						Name: "call_array_len",
-						Type: "felt",
-					},
-					{
-						Name: "call_array",
-						Type: "felt",
-					},
-					{
-						Name: "calldata_len",
-						Type: "felt",
-					},
-					{
-						Name: "calldata",
-						Type: "felt*",
-					},
-					{
-						Name: "nonce",
-						Type: "felt",
-					},
-				},
-				Outputs: []*abi.Function_Output{
-					{
-						Name: "retdata_size",
-						Type: "felt",
-					},
-					{
-						Name: "retdata",
-						Type: "felt*",
-					},
-				},
-			},
-			{
-				Name: "upgrade",
-				Inputs: []*abi.Function_Input{
-					{
-						Name: "implementation",
-						Type: "felt",
-					},
-				},
-				Outputs: nil,
-			},
-		},
-		Events: []*abi.AbiEvent{
-			{
-				Data: []*abi.AbiEvent_Data{
-					{
-						Name: "new_signer",
-						Type: "felt",
-					},
-				},
-				Keys: nil,
-				Name: "signer_changed",
-			},
-			{
-				Data: []*abi.AbiEvent_Data{
-					{
-						Name: "new_guardian",
-						Type: "felt",
-					},
-				},
-				Keys: nil,
-				Name: "guardian_changed",
-			},
-			{
-				Data: []*abi.AbiEvent_Data{
-					{
-						Name: "new_guardian",
-						Type: "felt",
-					},
-				},
-				Keys: nil,
-				Name: "guardian_backup_changed",
-			},
-			{
-				Data: []*abi.AbiEvent_Data{
-					{
-						Name: "active_at",
-						Type: "felt",
-					},
-				},
-				Keys: nil,
-				Name: "escape_guardian_triggered",
-			},
-			{
-				Data: []*abi.AbiEvent_Data{
-					{
-						Name: "active_at",
-						Type: "felt",
-					},
-				},
-				Keys: nil,
-				Name: "escape_signer_triggered",
-			},
-			{
-				Data: nil,
-				Keys: nil,
-				Name: "escape_canceled",
-			},
-		},
-		Structs: []*abi.Struct{
-			{
-				Fields: []*abi.Struct_Field{
-					{
-						Name:   "to",
-						Type:   "felt",
-						Offset: 0,
-					},
-					{
-						Name:   "selector",
-						Type:   "felt",
-						Offset: 1,
-					},
-					{
-						Name:   "data_offset",
-						Type:   "felt",
-						Offset: 2,
-					},
-					{
-						Name:   "data_len",
-						Type:   "felt",
-						Offset: 3,
-					},
-				},
-				Name: "CallArray",
-				Size: 4,
-			},
-		},
-		L1Handlers: []*abi.Function{
-			{
-				Name: "__l1_default__",
-				Inputs: []*abi.Function_Input{
-					{
-						Name: "selector",
-						Type: "felt",
-					},
-					{
-						Name: "calldata_size",
-						Type: "felt",
-					},
-					{
-						Name: "calldata",
-						Type: "felt*",
-					},
-				},
-				Outputs: nil,
-			},
-		},
-		Constructor: &abi.Function{
-			Name: "constructor",
-			Inputs: []*abi.Function_Input{
-				{
-					Name: "signer",
-					Type: "felt",
-				},
-				{
-					Name: "guardian",
-					Type: "felt",
-				},
-			},
-			Outputs: nil,
-		},
-	},
-}
diff --git a/internal/services/block_test.go b/internal/services/block_test.go
deleted file mode 100644
index 2716fd5e..00000000
--- a/internal/services/block_test.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package services
-
-import (
-	"context"
-	"errors"
-	"reflect"
-	"testing"
-
-	"github.com/NethermindEth/juno/internal/db"
-	"github.com/NethermindEth/juno/pkg/felt"
-	"github.com/NethermindEth/juno/pkg/types"
-)
-
-func TestService(t *testing.T) {
-	blocks := []*types.Block{
-		{
-			BlockHash:    new(felt.Felt).SetHex("43950c9e3565cba1f2627b219d4863380f93a8548818ce26019d1bd5eebb0fb"),
-			ParentHash:   new(felt.Felt).SetHex("f8fe26de3ce9ee4d543b1152deb2ce549e589524d79598227761d6006b74a9"),
-			BlockNumber:  2175,
-			Status:       types.BlockStatusAcceptedOnL2,
-			Sequencer:    new(felt.Felt).SetHex("0"),
-			NewRoot:      new(felt.Felt).SetHex("6a42d697b5b735eef03bb71841ed5099d57088f7b5eec8e356fe2601d5ba08f"),
-			OldRoot:      new(felt.Felt).SetHex("1d932dcf7da6c4f7605117cf514d953147161ab2d8f762dcebbb6dad427e519"),
-			AcceptedTime: 1652492749,
-			TimeStamp:    1652488132,
-			TxCount:      2,
-			TxCommitment: new(felt.Felt).SetHex("0"),
-			TxHashes: []*felt.Felt{
-				new(felt.Felt).SetHex("5ce76214481ebb29f912cb5d31abdff34fd42217f5ece9dda76d9fcfd62dc73"),
-				new(felt.Felt).SetHex("4ff16b7673da1f4c4b114d28e0e1a366bd61b702eca3e21882da6c8939e60a2"),
-			},
-			EventCount:      19,
-			EventCommitment: new(felt.Felt).SetHex("0"),
-		},
-	}
-	env, err := db.NewMDBXEnv(t.TempDir(), 1, 0)
-	if err != nil {
-		t.Error(err)
-	}
-	database, err := db.NewMDBXDatabase(env, "BLOCK")
-	if err != nil {
-		t.Error(err)
-	}
-	BlockService.Setup(database)
-	err = BlockService.Run()
-	if err != nil {
-		t.Errorf("error starting the service: %s", err)
-	}
-	for _, b := range blocks {
-		key := b.BlockHash
-		if err := BlockService.StoreBlock(key, b); err != nil {
-			t.Error(err)
-		}
-		// Get block by hash
-		returnedBlock, err := BlockService.GetBlockByHash(key)
-		if err != nil {
-			if errors.Is(err, db.ErrNotFound) {
-				t.Errorf("Block not found for hash %s", key.Hex())
-			}
-			t.Errorf("Unexpected error: %s", err)
-		}
-		if !reflect.DeepEqual(b, returnedBlock) {
-			t.Errorf("b")
-		}
-		// Get block by number
-		returnedBlock, err = BlockService.GetBlockByNumber(b.BlockNumber)
-		if err != nil {
-			if errors.Is(err, db.ErrNotFound) {
-				t.Errorf("Block not found for number %d", b.BlockNumber)
-			}
-			t.Errorf("Unexpected error: %s", err)
-		}
-		if !reflect.DeepEqual(b, returnedBlock) {
-			t.Errorf("b")
-		}
-	}
-	BlockService.Close(context.Background())
-}
diff --git a/internal/services/state_test.go b/internal/services/state_test.go
deleted file mode 100644
index a534af22..00000000
--- a/internal/services/state_test.go
+++ /dev/null
@@ -1,174 +0,0 @@
-package services
-
-import (
-	"bytes"
-	"context"
-	"encoding/hex"
-	"errors"
-	"testing"
-
-	"github.com/NethermindEth/juno/internal/db"
-	"github.com/NethermindEth/juno/internal/db/state"
-	"google.golang.org/protobuf/proto"
-)
-
-var codes = []struct {
-	Address []byte
-	Code    *state.Code
-}{
-	{
-		Address: decodeString("1bd7ca87f139693e6681be2042194cf631c4e8d77027bf0ea9e6d55fc6018ac"),
-		Code: &state.Code{Code: [][]byte{
-			decodeString("40780017fff7fff"),
-			decodeString("1"),
-			decodeString("208b7fff7fff7ffe"),
-			decodeString("400380007ffb7ffc"),
-			decodeString("400380017ffb7ffd"),
-			decodeString("800000000000010fffffffffffffffffffffffffffffffffffffffffffffffb"),
-			decodeString("107a2e2e5a8b6552e977246c45bfac446305174e86be2e5c74e8c0a20fd1de7"),
-		}},
-	},
-}
-
-func stateServiceInitServices(t *testing.T) {
-	env, err := db.NewMDBXEnv(t.TempDir(), 2, 0)
-	if err != nil {
-		t.Error(err)
-	}
-	codeDb, err := db.NewMDBXDatabase(env, "CODE")
-	if err != nil {
-		t.Error(err)
-	}
-	storageDb, err := db.NewMDBXDatabase(env, "STORAGE")
-	if err != nil {
-		t.Error(err)
-	}
-	storageDatabase := db.NewBlockSpecificDatabase(storageDb)
-	StateService.Setup(codeDb, storageDatabase)
-	err = StateService.Run()
-	if err != nil {
-		t.Error(err)
-	}
-}
-
-func TestStateService_Code(t *testing.T) {
-	stateServiceInitServices(t)
-	defer StateService.Close(context.Background())
-
-	for _, code := range codes {
-		if err := StateService.StoreCode(code.Address, code.Code); err != nil {
-			t.Error(err)
-		}
-		obtainedCode, err := StateService.GetCode(code.Address)
-		if err != nil {
-			if errors.Is(err, db.ErrNotFound) {
-				t.Errorf("code not found: %s", err)
-			}
-			t.Errorf("error: %s", err)
-		}
-		if !equalCodes(t, code.Code, obtainedCode) {
-			t.Errorf("Code are different afte Put-Get operation")
-		}
-	}
-}
-
-func TestService_Storage(t *testing.T) {
-	initialData := [...]struct {
-		Contract    string
-		Storage     *state.Storage
-		BlockNumber uint64
-	}{
-		{
-			"20cfa74ee3564b4cd5435cdace0f9c4d43b939620e4a0bb5076105df0a626c6",
-			&state.Storage{Storage: map[string]string{
-				"5": "22b",
-				"5aee31408163292105d875070f98cb48275b8c87e80380b78d30647e05854d5": "7e5",
-			}},
-			3,
-		},
-		{
-			"20cfa74ee3564b4cd5435cdace0f9c4d43b939620e4a0bb5076105df0a626c6",
-			&state.Storage{Storage: map[string]string{
-				"313ad57fdf765addc71329abf8d74ac2bce6d46da8c2b9b82255a5076620300": "4e7e989d58a17cd279eca440c5eaa829efb6f9967aaad89022acbe644c39b36",
-				"313ad57fdf765addc71329abf8d74ac2bce6d46da8c2b9b82255a5076620301": "453ae0c9610197b18b13645c44d3d0a407083d96562e8752aab3fab616cecb0",
-				"6cf6c2f36d36b08e591e4489e92ca882bb67b9c39a3afccf011972a8de467f0": "7ab344d88124307c07b56f6c59c12f4543e9c96398727854a322dea82c73240",
-			}},
-			5,
-		},
-	}
-	stateServiceInitServices(t)
-	defer StateService.Close(context.Background())
-
-	for _, data := range initialData {
-		if err := StateService.UpdateStorage(data.Contract, data.BlockNumber, data.Storage); err != nil {
-			t.Error(err)
-		}
-	}
-	tests := [...]struct {
-		Contract    string
-		BlockNumber uint64
-		Ok          bool
-		Checks      map[string]string
-	}{
-		{
-			"20cfa74ee3564b4cd5435cdace0f9c4d43b939620e4a0bb5076105df0a626c6",
-			0,
-			false,
-			nil,
-		},
-		{
-			"20cfa74ee3564b4cd5435cdace0f9c4d43b939620e4a0bb5076105df0a626c6",
-			3,
-			true,
-			map[string]string{
-				"5": "22b",
-			},
-		},
-		{
-			"20cfa74ee3564b4cd5435cdace0f9c4d43b939620e4a0bb5076105df0a626c6",
-			10000,
-			true,
-			map[string]string{
-				"313ad57fdf765addc71329abf8d74ac2bce6d46da8c2b9b82255a5076620300": "4e7e989d58a17cd279eca440c5eaa829efb6f9967aaad89022acbe644c39b36",
-			},
-		},
-	}
-	for _, test := range tests {
-		obtainedStorage, err := StateService.GetStorage(test.Contract, test.BlockNumber)
-		if err != nil && !errors.Is(err, db.ErrNotFound) {
-			t.Error(err)
-		}
-		if test.Ok && errors.Is(err, db.ErrNotFound) {
-			t.Errorf("storage of contract %s must not found for bloc %d", test.Contract, test.BlockNumber)
-		}
-		if obtainedStorage != nil && test.Checks != nil {
-			for checkKey, checkValue := range test.Checks {
-				resultValue, ok := obtainedStorage.Storage[checkKey]
-				if !ok {
-					t.Errorf("key %s not found", checkKey)
-				}
-				if resultValue != checkValue {
-					t.Errorf("unexpected key value after Put-Get operations. Contract: %s, Key: %s, Obtained value: %s, Want: %s",
-						test.Contract, checkKey, resultValue, resultValue)
-				}
-			}
-		}
-	}
-}
-
-func decodeString(s string) []byte {
-	x, _ := hex.DecodeString(s)
-	return x
-}
-
-func equalCodes(t *testing.T, a, b *state.Code) bool {
-	aRaw, err := proto.Marshal(a)
-	if err != nil {
-		t.Errorf("marshal error: %s", err)
-	}
-	bRaw, err := proto.Marshal(b)
-	if err != nil {
-		t.Errorf("marshal error: %s", err)
-	}
-	return bytes.Compare(aRaw, bRaw) == 0
-}
diff --git a/internal/services/transactions_test.go b/internal/services/transactions_test.go
deleted file mode 100644
index e74154f5..00000000
--- a/internal/services/transactions_test.go
+++ /dev/null
@@ -1,225 +0,0 @@
-package services
-
-import (
-	"context"
-	"errors"
-	"reflect"
-	"testing"
-
-	"github.com/NethermindEth/juno/pkg/felt"
-	"github.com/NethermindEth/juno/pkg/types"
-
-	"github.com/NethermindEth/juno/internal/db"
-)
-
-var txs = []types.IsTransaction{
-	&types.TransactionInvoke{
-		Hash:               new(felt.Felt).SetHex("0x49eb3544a95587518b0d2a32b9e456cb05b32e0085ebc0bcecb8ef2e15dc3a2"),
-		ContractAddress:    new(felt.Felt).SetHex("0x7e1b2de3dc9e3cf83278452786c23b384cf77a66c3073f94ab451ed0029b5af"),
-		EntryPointSelector: new(felt.Felt).SetHex("0x317eb442b72a9fae758d4fb26830ed0d9f31c8e7da4dbff4e8c59ea6a158e7f"),
-		CallData: []*felt.Felt{
-			new(felt.Felt).SetHex("0x1d24663eb96a2b9a568b88ff520d04779c03ae8ce3087aa55bea1a34f07c6f7"),
-			new(felt.Felt).SetHex("0x2"),
-			new(felt.Felt).SetHex("0x1ab006325ae5196978cfcaefd3d748e8583079ebb33b402537a4b4c174e16c6"),
-			new(felt.Felt).SetHex("0x77575e21a0326adb26b58aaa1ef7139ba8e3164ab54411dbf9a5809b8d6ea8"),
-		},
-		Signature: nil,
-		MaxFee:    new(felt.Felt).SetHex("0x0"),
-	},
-	&types.TransactionInvoke{
-		Hash:               new(felt.Felt).SetHex("0x50398c6ec05a07642e5bd52c656e1650f3b057361283ecbb19d4062199e4626"),
-		ContractAddress:    new(felt.Felt).SetHex("0x3e875a858f9a0229e4a59cb72a4086d324b9b2148242694f2dd12d59d993b62"),
-		EntryPointSelector: new(felt.Felt).SetHex("0x27c3334165536f239cfd400ed956eabff55fc60de4fb56728b6a4f6b87db01c"),
-		CallData: []*felt.Felt{
-			new(felt.Felt).SetHex("0x4d6f00affbeb6239fe0eb3eb4afefddbaea71533c152f44a1cdd113c1fdeade"),
-			new(felt.Felt).SetHex("0x33ce93a3eececa5c9fc70da05f4aff3b00e1820b79587924d514bc76788991a"),
-			new(felt.Felt).SetHex("0x1"),
-			new(felt.Felt).SetHex("0x0"),
-		},
-		Signature: nil,
-		MaxFee:    new(felt.Felt).SetHex("0x0"),
-	},
-	&types.TransactionInvoke{
-		Hash: new(felt.Felt).SetHex("0x1209ae3031dd69ef8ab4507dc4cc2c478d9a0414cb42225ce223670dee5cdcf"),
-
-		ContractAddress:    new(felt.Felt).SetHex("0x764c36cfdc456e1f3565441938f958badcc0ce8f20b7ed5819af30ed18f245"),
-		EntryPointSelector: new(felt.Felt).SetHex("0x317eb442b72a9fae758d4fb26830ed0d9f31c8e7da4dbff4e8c59ea6a158e7f"),
-		CallData: []*felt.Felt{
-			new(felt.Felt).SetHex("0x7e24f78ee360727e9fdd55e2b847202057724bf1f7e5bc25ff78f7760b6895b"),
-			new(felt.Felt).SetHex("0x2"),
-			new(felt.Felt).SetHex("0x51378ba07a08230eab5af933c8e1bd905bc9436bf96ab5f173010eb022eb2a4"),
-			new(felt.Felt).SetHex("0x5f8a361ec261cb4b34d4481803903bb9b8e5c8768e24099aa85ad7f3e8f13b8"),
-		},
-		Signature: nil,
-		MaxFee:    new(felt.Felt).SetHex("0x0"),
-	},
-	&types.TransactionDeploy{
-		Hash:            new(felt.Felt).SetHex("0xe0a2e45a80bb827967e096bcf58874f6c01c191e0a0530624cba66a508ae75"),
-		ContractAddress: new(felt.Felt).SetHex("0x546c86dc6e40a5e5492b782d8964e9a4274ff6ecb16d31eb09cee45a3564015"),
-		ConstructorCallData: []*felt.Felt{
-			new(felt.Felt).SetHex("06cf6c2f36d36b08e591e4489e92ca882bb67b9c39a3afccf011972a8de467f0"),
-			new(felt.Felt).SetHex("7ab344d88124307c07b56f6c59c12f4543e9c96398727854a322dea82c73240"),
-		},
-	},
-	&types.TransactionDeploy{
-		Hash:            new(felt.Felt).SetHex("0x12c96ae3c050771689eb261c9bf78fac2580708c7f1f3d69a9647d8be59f1e1"),
-		ContractAddress: new(felt.Felt).SetHex("0x12afa0f342ece0468ca9810f0ea59f9c7204af32d1b8b0d318c4f2fe1f384e"),
-		ConstructorCallData: []*felt.Felt{
-			new(felt.Felt).SetHex("0xcfc2e2866fd08bfb4ac73b70e0c136e326ae18fc797a2c090c8811c695577e"),
-			new(felt.Felt).SetHex("0x5f1dd5a5aef88e0498eeca4e7b2ea0fa7110608c11531278742f0b5499af4b3"),
-		},
-	},
-}
-
-func initServices(t *testing.T) {
-	env, err := db.NewMDBXEnv(t.TempDir(), 2, 0)
-	if err != nil {
-		t.Error(err)
-	}
-	txDb, err := db.NewMDBXDatabase(env, "TRANSACTION")
-	if err != nil {
-		t.Error(err)
-	}
-	receiptDb, err := db.NewMDBXDatabase(env, "RECEIPT")
-	if err != nil {
-		t.Error(err)
-	}
-	TransactionService.Setup(txDb, receiptDb)
-}
-
-func TestTransactionService_StoreTransaction(t *testing.T) {
-	initServices(t)
-	defer resetTransactionService()
-	err := TransactionService.Run()
-	if err != nil {
-		t.Errorf("error running the service: %s", err)
-	}
-
-	for _, tx := range txs {
-		if err := TransactionService.StoreTransaction(tx.GetHash(), tx); err != nil {
-			t.Error(err)
-		}
-	}
-	TransactionService.Close(context.Background())
-}
-
-func TestManager_GetTransaction(t *testing.T) {
-	initServices(t)
-	defer resetTransactionService()
-	err := TransactionService.Run()
-	if err != nil {
-		t.Errorf("error running the service: %s", err)
-	}
-	// Insert all the transactions
-	for _, tx := range txs {
-		if err := TransactionService.StoreTransaction(tx.GetHash(), tx); err != nil {
-			t.Error(err)
-		}
-	}
-	// Get all the transactions and compare
-	for _, tx := range txs {
-		outTx, err := TransactionService.GetTransaction(tx.GetHash())
-		if err != nil {
-			if errors.Is(err, db.ErrNotFound) {
-				t.Errorf("transaction not found: %s", tx.GetHash().String())
-			}
-			t.Error(err)
-		}
-
-		if !reflect.DeepEqual(tx, outTx) {
-			t.Errorf("transaction not equal after Put/Get operations")
-		}
-	}
-	TransactionService.Close(context.Background())
-}
-
-func resetTransactionService() {
-	TransactionService = transactionService{}
-}
-
-var receipts = []*types.TransactionReceipt{
-	{
-		TxHash:       new(felt.Felt).SetHex("0x7932de7ec535bfd45e2951a35c06e13d22188cb7eb7b7cc43454ee63df78aff"),
-		ActualFee:    new(felt.Felt).SetHex("0x0"),
-		Status:       types.TxStatusAcceptedOnL2,
-		StatusData:   "",
-		MessagesSent: nil,
-		L1OriginMessage: &types.MessageL1ToL2{
-			FromAddress: types.HexToEthAddress("0x659a00c33263d9254Fed382dE81349426C795BB6"),
-			Payload: []*felt.Felt{
-				new(felt.Felt).SetHex("0x68a443797ed3eb691347e1d69e6480d1c3ad37acb0d6b1d17c311600002f3d6"),
-				new(felt.Felt).SetHex("0x2616da7c393d14000"),
-				new(felt.Felt).SetHex("0x0"),
-				new(felt.Felt).SetHex("0xb9d83d298d46c4dd73618f19a2a40084ce36476a"),
-			},
-		},
-		Events: []types.Event{
-			{
-				FromAddress: new(felt.Felt).SetHex("0xda114221cb83fa859dbdb4c44beeaa0bb37c7537ad5ae66fe5e0efd20e6eb3"),
-				Keys: []*felt.Felt{
-					new(felt.Felt).SetHex("99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9"),
-				},
-				Data: []*felt.Felt{
-					new(felt.Felt).SetHex("0"),
-					new(felt.Felt).SetHex("68a443797ed3eb691347e1d69e6480d1c3ad37acb0d6b1d17c311600002f3d6"),
-					new(felt.Felt).SetHex("2616da7c393d14000"),
-					new(felt.Felt).SetHex("0"),
-				},
-			},
-			{
-				FromAddress: new(felt.Felt).SetHex("0x1108cdbe5d82737b9057590adaf97d34e74b5452f0628161d237746b6fe69e"),
-				Keys: []*felt.Felt{
-					new(felt.Felt).SetHex("0x221e5a5008f7a28564f0eaa32cdeb0848d10657c449aed3e15d12150a7c2db3"),
-				},
-				Data: []*felt.Felt{
-					new(felt.Felt).SetHex("0x68a443797ed3eb691347e1d69e6480d1c3ad37acb0d6b1d17c311600002f3d6"),
-					new(felt.Felt).SetHex("0x2616da7c393d14000"),
-					new(felt.Felt).SetHex("0x0"),
-				},
-			},
-		},
-	},
-}
-
-func TestManager_PutReceipt(t *testing.T) {
-	initServices(t)
-	defer resetTransactionService()
-	err := TransactionService.Run()
-	if err != nil {
-		t.Errorf("error running the service: %s", err)
-	}
-	for _, receipt := range receipts {
-		if err := TransactionService.StoreReceipt(receipt.TxHash, receipt); err != nil {
-			t.Error(err)
-		}
-	}
-	TransactionService.Close(context.Background())
-}
-
-func TestManager_GetReceipt(t *testing.T) {
-	initServices(t)
-	defer resetTransactionService()
-	err := TransactionService.Run()
-	if err != nil {
-		t.Errorf("error running the service: %s", err)
-	}
-	for _, receipt := range receipts {
-		if err := TransactionService.StoreReceipt(receipt.TxHash, receipt); err != nil {
-			t.Error(err)
-		}
-	}
-	for _, receipt := range receipts {
-		outReceipt, err := TransactionService.GetReceipt(receipt.TxHash)
-		if err != nil {
-			if errors.Is(err, db.ErrNotFound) {
-				t.Errorf("receipt not found: %s", receipt.TxHash.String())
-			}
-			t.Error(err)
-		}
-
-		if !reflect.DeepEqual(receipt, outReceipt) {
-			t.Errorf("receipt not equal after Put/Get operations")
-		}
-	}
-	TransactionService.Close(context.Background())
-}
diff --git a/pkg/rest/tests/rest_test.go b/pkg/rest/tests/rest_test.go
index 63b1b0ad..2b16313b 100644
--- a/pkg/rest/tests/rest_test.go
+++ b/pkg/rest/tests/rest_test.go
@@ -3,7 +3,6 @@ package tests
 
 import (
 	"bytes"
-	"context"
 	"encoding/json"
 	"errors"
 	"io/ioutil"
@@ -76,12 +75,17 @@ func StructFaker(a interface{}) (string, error) {
 // TestRestClient
 func TestRestClient(t *testing.T) {
 	r := rest.NewServer(":8100", "http://localhost/", "feeder_gateway")
-	go func() {
-		_ = r.ListenAndServe()
-	}()
-	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(2*time.Second))
-	r.Close(ctx)
-	cancel()
+	errCh := make(chan error)
+
+	r.ListenAndServe(errCh)
+	err := r.Close(5 * time.Millisecond)
+	if err != nil {
+		t.Fatalf("did not expect error when shutting down rest server, however got: %s", err.Error())
+	}
+
+	if err = <-errCh; err != nil {
+		t.Fatalf("did not expect error when starting rest server, however got: %s", err.Error())
+	}
 }
 
 // TestRestClientRetryFunction
diff --git a/pkg/rpc/api_test.go b/pkg/rpc/api_test.go
index 2bc248e9..2b95a68c 100644
--- a/pkg/rpc/api_test.go
+++ b/pkg/rpc/api_test.go
@@ -10,13 +10,13 @@ import (
 
 	"github.com/NethermindEth/juno/internal/db"
 	"github.com/NethermindEth/juno/internal/db/abi"
+	"github.com/NethermindEth/juno/internal/db/block"
 	"github.com/NethermindEth/juno/internal/db/state"
-	"github.com/NethermindEth/juno/internal/services"
+	"github.com/NethermindEth/juno/internal/db/transaction"
 	"github.com/NethermindEth/juno/pkg/feeder"
 	"github.com/NethermindEth/juno/pkg/feeder/feederfakes"
 	"github.com/NethermindEth/juno/pkg/felt"
 	"github.com/NethermindEth/juno/pkg/types"
-
 	gocmp "github.com/google/go-cmp/cmp"
 	"gotest.tools/assert"
 )
@@ -81,15 +81,12 @@ func TestStarknetGetStorageAt(t *testing.T) {
 		t.Error(err)
 	}
 	// setup
-	services.BlockService.Setup(blockDb)
-	if err := services.BlockService.Run(); err != nil {
-		t.Fatalf("unexpected error starting block service: %s", err)
-	}
-	defer services.BlockService.Close(context.Background())
+	blockManager = block.NewManager(blockDb)
+	defer blockManager.Close()
 
 	blockHash := *testFelt1
 	blockNumber := uint64(2175)
-	block := &types.Block{
+	b := &types.Block{
 		BlockHash:       &blockHash,
 		BlockNumber:     blockNumber,
 		ParentHash:      new(felt.Felt).SetHex("0xf8fe26de3ce9ee4d543b1152deb2ce549e589524d79598227761d6006b74a9"),
@@ -108,16 +105,10 @@ func TestStarknetGetStorageAt(t *testing.T) {
 			new(felt.Felt).SetHex("0x4ff16b7673da1f4c4b114d28e0e1a366bd61b702eca3e21882da6c8939e60a2"),
 		},
 	}
-	services.BlockService.StoreBlock(&blockHash, block)
+	blockManager.PutBlock(&blockHash, b)
 
-	services.StateService.Setup(
-		codeDb,
-		db.NewBlockSpecificDatabase(storageDb),
-	)
-	if err := services.StateService.Run(); err != nil {
-		t.Fatalf("unexpected error starting state service: %s", err)
-	}
-	defer services.StateService.Close(context.Background())
+	stateManager = state.NewManager(codeDb, db.NewBlockSpecificDatabase(storageDb))
+	defer stateManager.Close()
 
 	address := testFelt2
 	key := testFelt3
@@ -127,10 +118,10 @@ func TestStarknetGetStorageAt(t *testing.T) {
 			key.Hex(): value.Hex(),
 		},
 	}
-	services.StateService.StoreStorage(address.Hex(), blockNumber, storage)
+	stateManager.PutStorage(address.Hex(), blockNumber, storage)
 
 	// Set up feeder client for PENDING block
-	body, err := json.Marshal(block)
+	body, err := json.Marshal(b)
 	if err != nil {
 		t.Fatal("unexpected marshal error", err)
 	}
@@ -158,7 +149,7 @@ func TestStarknetGetCode(t *testing.T) {
 	if err != nil {
 		t.Error(err)
 	}
-	abiDb, err := db.NewMDBXDatabase(env, "BLOCK")
+	abiDb, err := db.NewMDBXDatabase(env, "ABI")
 	if err != nil {
 		t.Error(err)
 	}
@@ -171,11 +162,8 @@ func TestStarknetGetCode(t *testing.T) {
 		t.Error(err)
 	}
 	// setup
-	services.AbiService.Setup(abiDb)
-	if err := services.AbiService.Run(); err != nil {
-		t.Fatalf("unexpected error starting abi service: %s", err)
-	}
-	defer services.AbiService.Close(context.Background())
+	abiManager = abi.NewManager(abiDb)
+	defer abiManager.Close()
 
 	address := *testFelt2
 	wantAbi := &abi.Abi{
@@ -259,17 +247,10 @@ func TestStarknetGetCode(t *testing.T) {
 		},
 	}
 
-	services.StateService.Setup(
-		codeDb,
-		db.NewBlockSpecificDatabase(storageDb),
-	)
-	if err := services.StateService.Run(); err != nil {
-		t.Fatalf("unexpected error starting state service: %s", err)
-	}
-
-	services.AbiService.StoreAbi(address.Hex(), wantAbi)
+	stateManager = state.NewManager(codeDb, db.NewBlockSpecificDatabase(storageDb))
+	defer stateManager.Close()
 
-	defer services.StateService.Close(context.Background())
+	abiManager.PutABI(address.Hex(), wantAbi)
 
 	code := &state.Code{
 		Code: [][]byte{
@@ -279,7 +260,7 @@ func TestStarknetGetCode(t *testing.T) {
 			new(felt.Felt).SetHex("0x1114").ByteSlice(),
 		},
 	}
-	services.StateService.StoreCode(address.ByteSlice(), code)
+	stateManager.PutCode(address.ByteSlice(), code)
 
 	abiResponse, _ := json.Marshal(wantAbi)
 	codeResponse := make([]*felt.Felt, len(code.Code))
@@ -554,28 +535,23 @@ func TestGetBlock(t *testing.T) {
 		t.Error(err)
 	}
 	// Initialize transaction service
-	services.TransactionService.Setup(txDb, receiptDb)
-	if err := services.TransactionService.Run(); err != nil {
-		t.Fatalf("unexpected error starting the transaction service: %s", err)
-	}
-	defer services.TransactionService.Close(context.Background())
+	transactionManager = transaction.NewManager(txDb, receiptDb)
+	defer transactionManager.Close()
+
 	// Initialize block service
-	services.BlockService.Setup(blockDb)
-	if err := services.BlockService.Run(); err != nil {
-		t.Fatalf("unexpeceted error starting the block service: %s", err)
-	}
-	defer services.BlockService.Close(context.Background())
+	blockManager = block.NewManager(blockDb)
+	defer blockManager.Close()
 	// Store transactions
 	for _, txn := range txns {
-		services.TransactionService.StoreTransaction(txn.GetHash(), txn)
+		transactionManager.PutTransaction(txn.GetHash(), txn)
 	}
 	// Store receipts
 	for _, receipt := range receipts {
-		services.TransactionService.StoreReceipt(receipt.TxHash, receipt)
+		transactionManager.PutReceipt(receipt.TxHash, receipt)
 	}
 	// Store blocks
-	for _, block := range blocks {
-		services.BlockService.StoreBlock(block.BlockHash, &block)
+	for _, b := range blocks {
+		blockManager.PutBlock(b.BlockHash, &b)
 	}
 
 	type testItem struct {
@@ -876,14 +852,12 @@ func TestGetTransactionByHash(t *testing.T) {
 	if err != nil {
 		t.Error(err)
 	}
-	services.TransactionService.Setup(txDb, receiptDb)
-	if err := services.TransactionService.Run(); err != nil {
-		t.Fatalf("unexpected error starting the transaction service: %s", err)
-	}
-	defer services.TransactionService.Close(context.Background())
+	transactionManager = transaction.NewManager(txDb, receiptDb)
+	defer transactionManager.Close()
+
 	responses := make(map[string]*Txn)
 	for _, txn := range txns {
-		services.TransactionService.StoreTransaction(txn.GetHash(), txn)
+		transactionManager.PutTransaction(txn.GetHash(), txn)
 		responses[txn.GetHash().String()] = NewTxn(txn)
 	}
 	for _, txn := range txns {
@@ -960,24 +934,20 @@ func TestGetTransactionByBlockHashAndIndex(t *testing.T) {
 		t.Error(err)
 	}
 	// Initialize transaction service
-	services.TransactionService.Setup(txDb, receiptDb)
-	if err := services.TransactionService.Run(); err != nil {
-		t.Fatalf("unexpected error starting the transaction service: %s", err)
-	}
-	defer services.TransactionService.Close(context.Background())
+	transactionManager = transaction.NewManager(txDb, receiptDb)
+	defer transactionManager.Close()
+
 	// Initialize block service
-	services.BlockService.Setup(blockDb)
-	if err := services.BlockService.Run(); err != nil {
-		t.Fatalf("unexpeceted error starting the block service: %s", err)
-	}
-	defer services.BlockService.Close(context.Background())
+	blockManager = block.NewManager(blockDb)
+	defer blockManager.Close()
+
 	// Store transactions
 	for _, txn := range txns {
-		services.TransactionService.StoreTransaction(txn.GetHash(), txn)
+		transactionManager.PutTransaction(txn.GetHash(), txn)
 	}
 	// Store blocks
-	for _, block := range blocks {
-		services.BlockService.StoreBlock(block.BlockHash, &block)
+	for _, b := range blocks {
+		blockManager.PutBlock(b.BlockHash, &b)
 	}
 	// Build test cases
 	tests := make([]rpcTest, 0)
@@ -1057,24 +1027,20 @@ func TestGetTransactionByBlockNumberAndIndex(t *testing.T) {
 		t.Error(err)
 	}
 	// Initialize transaction service
-	services.TransactionService.Setup(txDb, receiptDb)
-	if err := services.TransactionService.Run(); err != nil {
-		t.Fatalf("unexpected error starting the transaction service: %s", err)
-	}
-	defer services.TransactionService.Close(context.Background())
+	transactionManager = transaction.NewManager(txDb, receiptDb)
+	defer transactionManager.Close()
+
 	// Initialize block service
-	services.BlockService.Setup(blockDb)
-	if err := services.BlockService.Run(); err != nil {
-		t.Fatalf("unexpeceted error starting the block service: %s", err)
-	}
-	defer services.BlockService.Close(context.Background())
+	blockManager = block.NewManager(blockDb)
+	defer blockManager.Close()
+
 	// Store transactions
 	for _, txn := range txns {
-		services.TransactionService.StoreTransaction(txn.GetHash(), txn)
+		transactionManager.PutTransaction(txn.GetHash(), txn)
 	}
 	// Store blocks
-	for _, block := range blocks {
-		services.BlockService.StoreBlock(block.BlockHash, &block)
+	for _, b := range blocks {
+		blockManager.PutBlock(b.BlockHash, &b)
 	}
 	// Build test cases
 	tests := make([]rpcTest, 0)
diff --git a/pkg/rpc/rpc_test.go b/pkg/rpc/rpc_test.go
index 4f95254e..0fc1f776 100644
--- a/pkg/rpc/rpc_test.go
+++ b/pkg/rpc/rpc_test.go
@@ -2,7 +2,6 @@ package rpc
 
 import (
 	"bytes"
-	"context"
 	"encoding/json"
 	"fmt"
 	"io"
@@ -70,11 +69,17 @@ func TestRPCServer(t *testing.T) {
 }
 
 func TestServer(t *testing.T) {
-	server := NewServer(":8080", nil)
-	go func() {
-		_ = server.ListenAndServe()
-	}()
-	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(1*time.Second))
-	server.Close(ctx)
-	cancel()
+	server := NewServer(":8080", nil, nil, nil, nil, nil)
+	errCh := make(chan error)
+
+	server.ListenAndServe(errCh)
+
+	err := server.Close(5 * time.Millisecond)
+	if err != nil {
+		t.Fatalf("did not expect error when shutting down rest server, however got: %s", err.Error())
+	}
+
+	if err = <-errCh; err != nil {
+		t.Fatalf("did not expect error when starting rest server, however got: %s", err.Error())
+	}
 }
diff --git a/pkg/starknet/state_test.go b/pkg/starknet/state_test.go
index 8199bc15..2dbbd038 100644
--- a/pkg/starknet/state_test.go
+++ b/pkg/starknet/state_test.go
@@ -1,12 +1,11 @@
 package starknet
 
 import (
-	"context"
 	"math/big"
 	"testing"
 
 	"github.com/NethermindEth/juno/internal/db"
-	"github.com/NethermindEth/juno/internal/services"
+	"github.com/NethermindEth/juno/internal/db/contracthash"
 	"github.com/NethermindEth/juno/pkg/starknet/abi"
 	starknetTypes "github.com/NethermindEth/juno/pkg/starknet/types"
 	ethAbi "github.com/ethereum/go-ethereum/accounts/abi"
@@ -180,7 +179,7 @@ func TestProcessPagesHashes(t *testing.T) {
 	if err != nil {
 		t.Error(err)
 	}
-	sync := NewSynchronizer(synchronizerDb, ec, nil)
+	sync := NewSynchronizer(synchronizerDb, ec, nil, nil, nil, nil, nil, nil)
 	sync.memoryPageHash.Add(hash[2:], starknetTypes.TransactionHash{Hash: finalTx.Hash()})
 
 	pages := sync.processPagesHashes(pagesHashes, memoryContract)
@@ -323,11 +322,8 @@ func TestUpdateAndCommitState(t *testing.T) {
 	if err != nil {
 		t.Error(err)
 	}
-	services.ContractHashService.Setup(contractHashDb)
-	if err := services.ContractHashService.Run(); err != nil {
-		t.Error(err)
-	}
-	defer services.ContractHashService.Close(context.Background())
+
+	contractHashM := contracthash.NewManager(contractHashDb)
 	stateDiff := &starknetTypes.StateDiff{
 		DeployedContracts: []starknetTypes.DeployedContract{
 			{
@@ -339,11 +335,12 @@ func TestUpdateAndCommitState(t *testing.T) {
 	}
 
 	s := &Synchronizer{
-		database:       synchronizerDb,
-		memoryPageHash: starknetTypes.NewDictionary(synchronizerDb, "memory_pages"),
-		gpsVerifier:    starknetTypes.NewDictionary(synchronizerDb, "gps_verifier"),
-		facts:          starknetTypes.NewDictionary(synchronizerDb, "facts"),
-		chainID:        1,
+		database:            synchronizerDb,
+		memoryPageHash:      starknetTypes.NewDictionary(synchronizerDb, "memory_pages"),
+		gpsVerifier:         starknetTypes.NewDictionary(synchronizerDb, "gps_verifier"),
+		facts:               starknetTypes.NewDictionary(synchronizerDb, "facts"),
+		chainID:             1,
+		contractHashManager: contractHashM,
 	}
 	sequenceNumber := uint64(0)
 	s.updateAndCommitState(stateDiff, "", sequenceNumber)