Skip to content

Commit

Permalink
Introduce mockery for mocking interfaces (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
begmaroman authored Dec 20, 2023
1 parent b4ec4d0 commit 993f423
Show file tree
Hide file tree
Showing 26 changed files with 988 additions and 380 deletions.
11 changes: 11 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
include version.mk

# Check for required dependencies
CHECK_MOCKERY := $(shell command -v mockery 2> /dev/null)
CHECK_GO := $(shell command -v go 2> /dev/null)
CHECK_CURL := $(shell command -v curl 2> /dev/null)
CHECK_DOCKER := $(shell command -v docker 2> /dev/null)

check-mockery:
ifndef CHECK_MOCKERY
$(error "Mockery is not installed. Please install Mockery and retry.")
endif

check-go:
ifndef CHECK_GO
$(error "Go is not installed. Please install Go and retry.")
Expand All @@ -21,6 +27,7 @@ ifndef CHECK_DOCKER
endif

# Targets that require the checks
generate: check-go
build: check-go
build-docker: check-docker
build-docker-nc: check-docker
Expand Down Expand Up @@ -49,6 +56,10 @@ LDFLAGS += -X 'github.com/0xPolygon/cdk-data-availability.GitRev=$(GITREV)'
LDFLAGS += -X 'github.com/0xPolygon/cdk-data-availability.GitBranch=$(GITBRANCH)'
LDFLAGS += -X 'github.com/0xPolygon/cdk-data-availability.BuildDate=$(DATE)'

.PHONY: generate
generate: ## Generates mocks and other autogenerated types
$(GOENVVARS) go generate ./...

.PHONY: build
build: ## Builds the binary locally into ./dist
$(GOENVVARS) go build -ldflags "all=$(LDFLAGS)" -o $(GOBIN)/$(GOBINARY) $(GOCMD)
Expand Down
10 changes: 7 additions & 3 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,25 @@ import (
)

// IClientFactory interface for the client factory
//
//go:generate mockery --name IClientFactory --output ../mocks --case=underscore --filename client_factory.generated.go
type IClientFactory interface {
New(url string) IClient
}

// IClient is the interface that defines the implementation of all the endpoints
//
//go:generate mockery --name IClient --output ../mocks --case=underscore --filename client.generated.go
type IClient interface {
GetOffChainData(ctx context.Context, hash common.Hash) ([]byte, error)
SignSequence(signedSequence types.SignedSequence) ([]byte, error)
}

// ClientFactory is the implementation of the data committee client factory
type ClientFactory struct{}
// Factory is the implementation of the data committee client factory
type Factory struct{}

// New returns an implementation of the data committee node client
func (f *ClientFactory) New(url string) IClient {
func (f *Factory) New(url string) IClient {
return New(url)
}

Expand Down
4 changes: 2 additions & 2 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func start(cliCtx *cli.Context) error {

var cancelFuncs []context.CancelFunc

sequencerTracker, err := sequencer.NewSequencerTracker(c.L1, etherman)
sequencerTracker, err := sequencer.NewTracker(c.L1, etherman)
if err != nil {
log.Fatal(err)
}
Expand All @@ -118,7 +118,7 @@ func start(cliCtx *cli.Context) error {
cancelFuncs = append(cancelFuncs, detector.Stop)

batchSynchronizer, err := synchronizer.NewBatchSynchronizer(c.L1, selfAddr,
storage, detector.Subscribe(), etherman, sequencerTracker, &client.ClientFactory{})
storage, detector.Subscribe(), etherman, sequencerTracker, &client.Factory{})
if err != nil {
log.Fatal(err)
}
Expand Down
38 changes: 20 additions & 18 deletions db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package db
import (
"context"
"database/sql"
"database/sql/driver"
"errors"

"github.com/0xPolygon/cdk-data-availability/types"
Expand All @@ -15,45 +16,46 @@ var (
ErrStateNotSynchronized = errors.New("state not synchronized")
)

// IDB defines functions that a DB instance should implement
type IDB interface {
BeginStateTransaction(ctx context.Context) (IDBTx, error)
// DB defines functions that a DB instance should implement
//
//go:generate mockery --name DB --output ../mocks --case=underscore --filename db.generated.go
type DB interface {
BeginStateTransaction(ctx context.Context) (Tx, error)
Exists(ctx context.Context, key common.Hash) bool
GetLastProcessedBlock(ctx context.Context, task string) (uint64, error)
GetOffChainData(ctx context.Context, key common.Hash, dbTx sqlx.QueryerContext) (types.ArgBytes, error)
StoreLastProcessedBlock(ctx context.Context, task string, block uint64, dbTx sqlx.ExecerContext) error
StoreOffChainData(ctx context.Context, od []types.OffChainData, dbTx sqlx.ExecerContext) error
}

// IDBTx is the interface that defines functions a db tx has to implement
type IDBTx interface {
// Tx is the interface that defines functions a db tx has to implement
//
//go:generate mockery --name Tx --output ../mocks --case=underscore --filename tx.generated.go
type Tx interface {
sqlx.ExecerContext
sqlx.QueryerContext
Rollback() error
Commit() error
driver.Tx
}

var _ IDB = (*DB)(nil)

// DB is the database layer of the data node
type DB struct {
type pgDB struct {
pg *sqlx.DB
}

// New instantiates a DB
func New(pg *sqlx.DB) *DB {
return &DB{
func New(pg *sqlx.DB) DB {
return &pgDB{
pg: pg,
}
}

// BeginStateTransaction begins a DB transaction. The caller is responsible for committing or rolling back the transaction
func (db *DB) BeginStateTransaction(ctx context.Context) (IDBTx, error) {
func (db *pgDB) BeginStateTransaction(ctx context.Context) (Tx, error) {
return db.pg.BeginTxx(ctx, nil)
}

// StoreOffChainData stores and array of key values in the Db
func (db *DB) StoreOffChainData(ctx context.Context, od []types.OffChainData, dbTx sqlx.ExecerContext) error {
func (db *pgDB) StoreOffChainData(ctx context.Context, od []types.OffChainData, dbTx sqlx.ExecerContext) error {
const storeOffChainDataSQL = `
INSERT INTO data_node.offchain_data (key, value)
VALUES ($1, $2)
Expand All @@ -74,7 +76,7 @@ func (db *DB) StoreOffChainData(ctx context.Context, od []types.OffChainData, db
}

// GetOffChainData returns the value identified by the key
func (db *DB) GetOffChainData(ctx context.Context, key common.Hash, dbTx sqlx.QueryerContext) (types.ArgBytes, error) {
func (db *pgDB) GetOffChainData(ctx context.Context, key common.Hash, dbTx sqlx.QueryerContext) (types.ArgBytes, error) {
const getOffchainDataSQL = `
SELECT value
FROM data_node.offchain_data
Expand All @@ -96,7 +98,7 @@ func (db *DB) GetOffChainData(ctx context.Context, key common.Hash, dbTx sqlx.Qu
}

// Exists checks if a key exists in offchain data table
func (db *DB) Exists(ctx context.Context, key common.Hash) bool {
func (db *pgDB) Exists(ctx context.Context, key common.Hash) bool {
const keyExists = "SELECT COUNT(*) FROM data_node.offchain_data WHERE key = $1;"

var (
Expand All @@ -111,7 +113,7 @@ func (db *DB) Exists(ctx context.Context, key common.Hash) bool {
}

// StoreLastProcessedBlock stores a record of a block processed by the synchronizer for named task
func (db *DB) StoreLastProcessedBlock(ctx context.Context, task string, block uint64, dbTx sqlx.ExecerContext) error {
func (db *pgDB) StoreLastProcessedBlock(ctx context.Context, task string, block uint64, dbTx sqlx.ExecerContext) error {
const storeLastProcessedBlockSQL = `
INSERT INTO data_node.sync_tasks (task, block)
VALUES ($1, $2)
Expand All @@ -127,7 +129,7 @@ func (db *DB) StoreLastProcessedBlock(ctx context.Context, task string, block ui
}

// GetLastProcessedBlock returns the latest block successfully processed by the synchronizer for named task
func (db *DB) GetLastProcessedBlock(ctx context.Context, task string) (uint64, error) {
func (db *pgDB) GetLastProcessedBlock(ctx context.Context, task string) (uint64, error) {
const getLastProcessedBlockSQL = "SELECT block FROM data_node.sync_tasks WHERE task = $1;"

var (
Expand Down
26 changes: 9 additions & 17 deletions etherman/etherman.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,15 @@ import (
"github.com/0xPolygon/cdk-data-availability/etherman/smartcontracts/cdkdatacommittee"
"github.com/0xPolygon/cdk-data-availability/etherman/smartcontracts/cdkvalidium"
"github.com/0xPolygon/cdk-data-availability/log"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
)

type ethereumClient interface {
ethereum.ChainReader
ethereum.ChainStateReader
ethereum.ContractCaller
ethereum.GasEstimator
ethereum.GasPricer
ethereum.LogFilterer
ethereum.TransactionReader
ethereum.TransactionSender

bind.DeployBackend
}

// IEtherman defines functions that should be implemented by Etherman
//
//go:generate mockery --name IEtherman --output ../mocks --case=underscore --filename etherman.generated.go
type IEtherman interface {
GetCurrentDataCommittee() (*DataCommittee, error)
GetCurrentDataCommitteeMembers() ([]DataCommitteeMember, error)
Expand All @@ -45,29 +33,33 @@ var _ IEtherman = (*Etherman)(nil)

// Etherman is the implementation of EtherMan.
type Etherman struct {
EthClient ethereumClient
EthClient *ethclient.Client
CDKValidium *cdkvalidium.Cdkvalidium
DataCommittee *cdkdatacommittee.Cdkdatacommittee
}

// New creaters a enw etherman
// New creates a new etherman
func New(cfg config.L1Config) (*Etherman, error) {
ctx, cancel := context.WithTimeout(context.Background(), cfg.Timeout.Duration)
defer cancel()

ethClient, err := ethclient.DialContext(ctx, cfg.WsURL)
if err != nil {
log.Errorf("error connecting to %s: %+v", cfg.WsURL, err)
return nil, err
}

cdkValidium, err := cdkvalidium.NewCdkvalidium(common.HexToAddress(cfg.CDKValidiumAddress), ethClient)
if err != nil {
return nil, err
}

dataCommittee, err :=
cdkdatacommittee.NewCdkdatacommittee(common.HexToAddress(cfg.DataCommitteeAddress), ethClient)
if err != nil {
return nil, err
}

return &Etherman{
EthClient: ethClient,
CDKValidium: cdkValidium,
Expand Down Expand Up @@ -130,7 +122,7 @@ func (e *Etherman) GetCurrentDataCommittee() (*DataCommittee, error) {
}

return &DataCommittee{
AddressesHash: common.Hash(addrsHash),
AddressesHash: addrsHash,
RequiredSignatures: reqSign.Uint64(),
Members: members,
}, nil
Expand Down
85 changes: 85 additions & 0 deletions mocks/client.generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 44 additions & 0 deletions mocks/client_factory.generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 993f423

Please sign in to comment.