From 0dbcdbde700a5444d88758e3d2ace816f0533c9a Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Wed, 25 Aug 2021 22:10:44 +0300 Subject: [PATCH] Make Ethereum client as interface --- blockchain/miner.go | 4 +- consensus/consensus_handler.go | 7 +-- consensus/dispute_manager.go | 7 +-- ethclient/ethereum.go | 85 ++++++++++++++++++---------------- ethclient/stake.go | 4 +- ethclient/wallet.go | 4 +- node/node.go | 6 +-- node/node_dep_providers.go | 13 ------ 8 files changed, 61 insertions(+), 69 deletions(-) diff --git a/blockchain/miner.go b/blockchain/miner.go index 3f5c97d..caeafbb 100644 --- a/blockchain/miner.go +++ b/blockchain/miner.go @@ -32,7 +32,7 @@ var ( type Miner struct { bus EventBus.Bus address peer.ID - ethClient *ethclient.EthereumClient + ethClient ethclient.EthereumSideAPI minerStake *big.Int networkStake *big.Int privateKey crypto.PrivKey @@ -43,7 +43,7 @@ type Miner struct { func NewMiner( h host.Host, - ethClient *ethclient.EthereumClient, + ethClient ethclient.EthereumSideAPI, privateKey crypto.PrivKey, mempool *pool.Mempool, bus EventBus.Bus, diff --git a/consensus/consensus_handler.go b/consensus/consensus_handler.go index 66d975e..a9daa1b 100644 --- a/consensus/consensus_handler.go +++ b/consensus/consensus_handler.go @@ -8,6 +8,8 @@ import ( "sort" "time" + "github.com/Secured-Finance/dione/ethclient" + "github.com/libp2p/go-libp2p-core/host" drand2 "github.com/Secured-Finance/dione/beacon/drand" @@ -29,7 +31,6 @@ import ( "github.com/Secured-Finance/dione/consensus/types" types2 "github.com/Secured-Finance/dione/types" - "github.com/Secured-Finance/dione/ethclient" "github.com/sirupsen/logrus" "github.com/Secured-Finance/dione/pubsub" @@ -44,7 +45,7 @@ type ConsensusHandler struct { psb *pubsub.PubSubRouter privKey crypto.PrivKey validator *ConsensusValidator - ethereumClient *ethclient.EthereumClient + ethereumClient ethclient.EthereumSideAPI miner *blockchain.Miner consensus *ConsensusManager mempool *pool.Mempool @@ -57,7 +58,7 @@ func NewConsensusHandler( bus EventBus.Bus, psb *pubsub.PubSubRouter, privKey crypto.PrivKey, - ethereumClient *ethclient.EthereumClient, + ethereumClient ethclient.EthereumSideAPI, miner *blockchain.Miner, bc *blockchain.BlockChain, bp *ConsensusManager, diff --git a/consensus/dispute_manager.go b/consensus/dispute_manager.go index 9bdfc38..64f4ae2 100644 --- a/consensus/dispute_manager.go +++ b/consensus/dispute_manager.go @@ -6,6 +6,8 @@ import ( "math/big" "time" + "github.com/Secured-Finance/dione/ethclient" + "github.com/asaskevich/EventBus" "github.com/ethereum/go-ethereum/common" @@ -28,13 +30,12 @@ import ( "github.com/Secured-Finance/dione/contracts/dioneDispute" "github.com/Secured-Finance/dione/contracts/dioneOracle" - "github.com/Secured-Finance/dione/ethclient" ) type DisputeManager struct { ctx context.Context bus EventBus.Bus - ethClient *ethclient.EthereumClient + ethClient ethclient.EthereumSideAPI voteWindow time.Duration blockchain *blockchain.BlockChain @@ -64,7 +65,7 @@ type Submission struct { Checked bool } -func NewDisputeManager(bus EventBus.Bus, ethClient *ethclient.EthereumClient, bc *blockchain.BlockChain, cfg *config.Config, cm cache.CacheManager) (*DisputeManager, error) { +func NewDisputeManager(bus EventBus.Bus, ethClient ethclient.EthereumSideAPI, bc *blockchain.BlockChain, cfg *config.Config, cm cache.CacheManager) (*DisputeManager, error) { ctx := context.TODO() submissionChan, submSubscription, err := ethClient.SubscribeOnNewSubmissions(ctx) diff --git a/ethclient/ethereum.go b/ethclient/ethereum.go index 2b0dc9d..33a07ac 100644 --- a/ethclient/ethereum.go +++ b/ethclient/ethereum.go @@ -6,6 +6,8 @@ import ( "fmt" "math/big" + "github.com/sirupsen/logrus" + hdwallet "github.com/miguelmota/go-ethereum-hdwallet" "github.com/Secured-Finance/dione/config" @@ -21,8 +23,7 @@ import ( "github.com/ethereum/go-ethereum/event" ) -// TODO: change artifacts for other contracts -type EthereumClient struct { +type ethereumClient struct { client *ethclient.Client ethAddress *common.Address authTransactor *bind.TransactOpts @@ -31,51 +32,50 @@ type EthereumClient struct { dioneOracle *dioneOracle.DioneOracleSession } -type Ethereum interface { - Initialize(ctx context.Context, url, connectionType, privateKey, oracleEmitterContractAddress, aggregatorContractAddress string) error - Balance(context.Context, string) (*big.Int, error) - SubmitRequestAnswer(reqID *big.Int, data string, callbackAddress common.Address, callbackMethodID [4]byte) error +type EthereumSideAPI interface { + SubmitRequestAnswer(reqID *big.Int, data []byte) error BeginDispute(miner common.Address, requestID *big.Int) error - VoteDispute(dhash string, voteStatus bool) error - FinishDispute(dhash string) error + VoteDispute(dhash [32]byte, voteStatus bool) error + FinishDispute(dhash [32]byte) error + SubscribeOnOracleEvents(ctx context.Context) (chan *dioneOracle.DioneOracleNewOracleRequest, event.Subscription, error) SubscribeOnNewDisputes(ctx context.Context) (chan *dioneDispute.DioneDisputeNewDispute, event.Subscription, error) + SubscribeOnNewSubmissions(ctx context.Context) (chan *dioneOracle.DioneOracleSubmittedOracleRequest, event.Subscription, error) + GetEthAddress() *common.Address + GetTotalStake() (*big.Int, error) + GetMinerStake(minerAddress common.Address) (*big.Int, error) } -func NewEthereumClient() *EthereumClient { - ethereumClient := &EthereumClient{} +func NewEthereumClient(cfg *config.Config) (EthereumSideAPI, error) { + c := ðereumClient{} - return ethereumClient -} - -func (c *EthereumClient) Initialize(cfg *config.EthereumConfig) error { - client, err := ethclient.Dial(cfg.GatewayAddress) + client, err := ethclient.Dial(cfg.Ethereum.GatewayAddress) if err != nil { - return err + return nil, err } c.client = client key, err := c.getPrivateKey(cfg) if err != nil { - return err + return nil, err } - authTransactor, err := bind.NewKeyedTransactorWithChainID(key, big.NewInt(int64(cfg.ChainID))) + authTransactor, err := bind.NewKeyedTransactorWithChainID(key, big.NewInt(int64(cfg.Ethereum.ChainID))) if err != nil { - return err + return nil, err } c.authTransactor = authTransactor c.ethAddress = &c.authTransactor.From - stakingContract, err := dioneStaking.NewDioneStaking(common.HexToAddress(cfg.DioneStakingContractAddress), client) + stakingContract, err := dioneStaking.NewDioneStaking(common.HexToAddress(cfg.Ethereum.DioneStakingContractAddress), client) if err != nil { - return err + return nil, err } - oracleContract, err := dioneOracle.NewDioneOracle(common.HexToAddress(cfg.DioneOracleContractAddress), client) + oracleContract, err := dioneOracle.NewDioneOracle(common.HexToAddress(cfg.Ethereum.DioneOracleContractAddress), client) if err != nil { - return err + return nil, err } - disputeContract, err := dioneDispute.NewDioneDispute(common.HexToAddress(cfg.DisputeContractAddress), client) + disputeContract, err := dioneDispute.NewDioneDispute(common.HexToAddress(cfg.Ethereum.DisputeContractAddress), client) if err != nil { - return err + return nil, err } c.dioneStaking = &dioneStaking.DioneStakingSession{ Contract: stakingContract, @@ -122,24 +122,27 @@ func (c *EthereumClient) Initialize(cfg *config.EthereumConfig) error { Context: context.Background(), }, } - return nil + + logrus.WithField("ethAddress", c.GetEthAddress().Hex()).Info("Ethereum client has been initialized!") + + return c, nil } -func (c *EthereumClient) getPrivateKey(cfg *config.EthereumConfig) (*ecdsa.PrivateKey, error) { - if cfg.PrivateKey != "" { - key, err := crypto.HexToECDSA(cfg.PrivateKey) +func (c *ethereumClient) getPrivateKey(cfg *config.Config) (*ecdsa.PrivateKey, error) { + if cfg.Ethereum.PrivateKey != "" { + key, err := crypto.HexToECDSA(cfg.Ethereum.PrivateKey) return key, err } - if cfg.MnemonicPhrase != "" { - wallet, err := hdwallet.NewFromMnemonic(cfg.MnemonicPhrase) + if cfg.Ethereum.MnemonicPhrase != "" { + wallet, err := hdwallet.NewFromMnemonic(cfg.Ethereum.MnemonicPhrase) if err != nil { return nil, err } path := hdwallet.DefaultBaseDerivationPath - if cfg.HDDerivationPath != "" { - parsedPath, err := hdwallet.ParseDerivationPath(cfg.HDDerivationPath) + if cfg.Ethereum.HDDerivationPath != "" { + parsedPath, err := hdwallet.ParseDerivationPath(cfg.Ethereum.HDDerivationPath) if err != nil { return nil, err } @@ -160,11 +163,11 @@ func (c *EthereumClient) getPrivateKey(cfg *config.EthereumConfig) (*ecdsa.Priva return nil, fmt.Errorf("private key or mnemonic phrase isn't specified") } -func (c *EthereumClient) GetEthAddress() *common.Address { +func (c *ethereumClient) GetEthAddress() *common.Address { return c.ethAddress } -func (c *EthereumClient) SubscribeOnOracleEvents(ctx context.Context) (chan *dioneOracle.DioneOracleNewOracleRequest, event.Subscription, error) { +func (c *ethereumClient) SubscribeOnOracleEvents(ctx context.Context) (chan *dioneOracle.DioneOracleNewOracleRequest, event.Subscription, error) { resChan := make(chan *dioneOracle.DioneOracleNewOracleRequest) requestsFilter := c.dioneOracle.Contract.DioneOracleFilterer subscription, err := requestsFilter.WatchNewOracleRequest(&bind.WatchOpts{ @@ -177,7 +180,7 @@ func (c *EthereumClient) SubscribeOnOracleEvents(ctx context.Context) (chan *dio return resChan, subscription, err } -func (c *EthereumClient) SubmitRequestAnswer(reqID *big.Int, data []byte) error { +func (c *ethereumClient) SubmitRequestAnswer(reqID *big.Int, data []byte) error { _, err := c.dioneOracle.SubmitOracleRequest(reqID, data) if err != nil { return err @@ -186,7 +189,7 @@ func (c *EthereumClient) SubmitRequestAnswer(reqID *big.Int, data []byte) error return nil } -func (c *EthereumClient) BeginDispute(miner common.Address, requestID *big.Int) error { +func (c *ethereumClient) BeginDispute(miner common.Address, requestID *big.Int) error { _, err := c.disputeContract.BeginDispute(miner, requestID) if err != nil { return err @@ -195,7 +198,7 @@ func (c *EthereumClient) BeginDispute(miner common.Address, requestID *big.Int) return nil } -func (c *EthereumClient) VoteDispute(dhash [32]byte, voteStatus bool) error { +func (c *ethereumClient) VoteDispute(dhash [32]byte, voteStatus bool) error { _, err := c.disputeContract.Vote(dhash, voteStatus) if err != nil { return err @@ -204,7 +207,7 @@ func (c *EthereumClient) VoteDispute(dhash [32]byte, voteStatus bool) error { return nil } -func (c *EthereumClient) FinishDispute(dhash [32]byte) error { +func (c *ethereumClient) FinishDispute(dhash [32]byte) error { _, err := c.disputeContract.FinishDispute(dhash) if err != nil { return err @@ -213,7 +216,7 @@ func (c *EthereumClient) FinishDispute(dhash [32]byte) error { return nil } -func (c *EthereumClient) SubscribeOnNewDisputes(ctx context.Context) (chan *dioneDispute.DioneDisputeNewDispute, event.Subscription, error) { +func (c *ethereumClient) SubscribeOnNewDisputes(ctx context.Context) (chan *dioneDispute.DioneDisputeNewDispute, event.Subscription, error) { resChan := make(chan *dioneDispute.DioneDisputeNewDispute) requestsFilter := c.disputeContract.Contract.DioneDisputeFilterer subscription, err := requestsFilter.WatchNewDispute(&bind.WatchOpts{ @@ -226,7 +229,7 @@ func (c *EthereumClient) SubscribeOnNewDisputes(ctx context.Context) (chan *dion return resChan, subscription, err } -func (c *EthereumClient) SubscribeOnNewSubmissions(ctx context.Context) (chan *dioneOracle.DioneOracleSubmittedOracleRequest, event.Subscription, error) { +func (c *ethereumClient) SubscribeOnNewSubmissions(ctx context.Context) (chan *dioneOracle.DioneOracleSubmittedOracleRequest, event.Subscription, error) { resChan := make(chan *dioneOracle.DioneOracleSubmittedOracleRequest) requestsFilter := c.dioneOracle.Contract.DioneOracleFilterer subscription, err := requestsFilter.WatchSubmittedOracleRequest(&bind.WatchOpts{ diff --git a/ethclient/stake.go b/ethclient/stake.go index a3ac145..87bb71b 100644 --- a/ethclient/stake.go +++ b/ethclient/stake.go @@ -11,7 +11,7 @@ const ( ) // GetTotalStake for getting total stake in DioneStaking contract -func (c *EthereumClient) GetTotalStake() (*big.Int, error) { +func (c *ethereumClient) GetTotalStake() (*big.Int, error) { totalStake, err := c.dioneStaking.TotalStake() if err != nil { return nil, err @@ -21,7 +21,7 @@ func (c *EthereumClient) GetTotalStake() (*big.Int, error) { } // GetMinerStake for getting specified miner stake in DioneStaking contract -func (c *EthereumClient) GetMinerStake(minerAddress common.Address) (*big.Int, error) { +func (c *ethereumClient) GetMinerStake(minerAddress common.Address) (*big.Int, error) { minerStake, err := c.dioneStaking.MinerStake(minerAddress) if err != nil { return nil, err diff --git a/ethclient/wallet.go b/ethclient/wallet.go index 10ff9ee..6cada58 100644 --- a/ethclient/wallet.go +++ b/ethclient/wallet.go @@ -12,7 +12,7 @@ import ( ) // // Balance returns the balance of the given ethereum address. -func (c *EthereumClient) Balance(ctx context.Context, address string) (*big.Int, error) { +func (c *ethereumClient) Balance(ctx context.Context, address string) (*big.Int, error) { ethereumAddress := common.HexToAddress(address) value, err := c.client.BalanceAt(ctx, ethereumAddress, nil) if err != nil { @@ -21,7 +21,7 @@ func (c *EthereumClient) Balance(ctx context.Context, address string) (*big.Int, return value, nil } -func (c *EthereumClient) SendTransaction(ctx context.Context, private_key, to string, amount int64) string { +func (c *ethereumClient) SendTransaction(ctx context.Context, private_key, to string, amount int64) string { privateKey, err := crypto.HexToECDSA(private_key) if err != nil { logrus.Fatal("Failed to parse private key", err) diff --git a/node/node.go b/node/node.go index 5e94590..6901733 100644 --- a/node/node.go +++ b/node/node.go @@ -46,7 +46,7 @@ func runNode( lc fx.Lifecycle, cfg *config.Config, disco discovery.Discovery, - ethClient *ethclient.EthereumClient, + ethClient ethclient.EthereumSideAPI, h host.Host, mp *pool.Mempool, syncManager sync.SyncManager, @@ -135,7 +135,7 @@ func runLibp2pAsync(ctx context.Context, h host.Host, cfg *config.Config, disco return nil } -func subscribeOnEthContractsAsync(ctx context.Context, ethClient *ethclient.EthereumClient, mp *pool.Mempool) error { +func subscribeOnEthContractsAsync(ctx context.Context, ethClient ethclient.EthereumSideAPI, mp *pool.Mempool) error { eventChan, subscription, err := ethClient.SubscribeOnOracleEvents(ctx) if err != nil { return err @@ -195,7 +195,7 @@ func Start() { provideCacheManager, providePrivateKey, provideLibp2pHost, - provideEthereumClient, + ethclient.NewEthereumClient, providePubsub, providePubsubRouter, provideBootstrapAddrs, diff --git a/node/node_dep_providers.go b/node/node_dep_providers.go index 19debc6..288b4c6 100644 --- a/node/node_dep_providers.go +++ b/node/node_dep_providers.go @@ -38,7 +38,6 @@ import ( "github.com/Secured-Finance/dione/cache" "github.com/Secured-Finance/dione/config" - "github.com/Secured-Finance/dione/ethclient" "github.com/Secured-Finance/dione/pubsub" pex "github.com/Secured-Finance/go-libp2p-pex" "github.com/libp2p/go-libp2p" @@ -106,18 +105,6 @@ func provideBlockchainDatabase(cfg *config.Config) (database.Database, error) { // return w, nil //} -func provideEthereumClient(config *config.Config) *ethclient.EthereumClient { - ethereum := ethclient.NewEthereumClient() - err := ethereum.Initialize(&config.Ethereum) - if err != nil { - logrus.Fatal(err) - } - - logrus.WithField("ethAddress", ethereum.GetEthAddress().Hex()).Info("Ethereum client has been initialized!") - - return ethereum -} - func providePubsub(h host.Host) (*pubsub2.PubSub, error) { return pubsub2.NewFloodSub( context.TODO(),