From 7eba3182ed4e8edc41a6adf646e51f2463278cbe Mon Sep 17 00:00:00 2001 From: Mohamed Sohail Date: Wed, 18 May 2022 12:52:50 +0300 Subject: [PATCH] refactor: rpc provider (#6) - provider now lives on its own - existing modules need the provider as a param --- batch_balance/batch_balance.go | 22 ++--------- batch_balance/batch_balance_test.go | 10 ++++- batch_balance/token_balances.go | 2 +- batch_balance/token_balances_test.go | 7 +++- net/cic_net.go | 44 +++------------------ net/cic_net_test.go | 12 ++++-- net/erc20_demurrage_token.go | 12 +++--- net/erc20_demurrage_token_test.go | 58 ++++++++++++++++------------ net/erc20_token.go | 7 ++-- net/erc20_token_test.go | 18 ++++++--- net/token_index.go | 7 ++-- net/token_index_test.go | 20 +++++++--- net/util.go | 18 +++++---- provider/provider.go | 48 +++++++++++++++++++++++ 14 files changed, 167 insertions(+), 118 deletions(-) create mode 100644 provider/provider.go diff --git a/batch_balance/batch_balance.go b/batch_balance/batch_balance.go index 68b4325..05e7101 100644 --- a/batch_balance/batch_balance.go +++ b/batch_balance/batch_balance.go @@ -2,31 +2,17 @@ package balance import ( "github.com/ethereum/go-ethereum/common" - "github.com/lmittmann/w3" + "github.com/grassrootseconomics/cic-go/provider" ) type BatchBalance struct { - ethClient *w3.Client + provider *provider.Provider batchContract common.Address } -func NewBatchBalance(rpcEndpoint string, batchContract common.Address) (*BatchBalance, error) { - ethClient, err := w3.Dial(rpcEndpoint) - if err != nil { - return nil, err - } - +func NewBatchBalance(rpcProvider provider.Provider, batchContract common.Address) (*BatchBalance, error) { return &BatchBalance{ - ethClient: ethClient, + provider: &rpcProvider, batchContract: batchContract, }, nil } - -func (c *BatchBalance) Close() error { - err := c.ethClient.Close() - if err != nil { - return err - } - - return nil -} diff --git a/batch_balance/batch_balance_test.go b/batch_balance/batch_balance_test.go index c863640..d4d94a9 100644 --- a/batch_balance/batch_balance_test.go +++ b/batch_balance/batch_balance_test.go @@ -4,6 +4,7 @@ import ( "os" "testing" + "github.com/grassrootseconomics/cic-go/provider" "github.com/lmittmann/w3" ) @@ -21,10 +22,15 @@ func TestBatchBalance_Connect(t *testing.T) { name := "Test RPC connection" wantErr := false - cicnet, _ := NewBatchBalance(conf.rpcProvider, w3.A(conf.batchContract)) + newProvider, err := provider.NewRpcProvider(conf.rpcProvider) + if err != nil { + t.Errorf("Creating an rpc instance failed = %v", err) + } + + batchBalance, _ := NewBatchBalance(*newProvider, w3.A(conf.batchContract)) t.Run(name, func(t *testing.T) { - if err := cicnet.Close(); (err != nil) != wantErr { + if err := batchBalance.provider.EthClient.Close(); (err != nil) != wantErr { t.Errorf("Close() error = %v, wantErr %v", err, wantErr) } }) diff --git a/batch_balance/token_balances.go b/batch_balance/token_balances.go index b51f2da..3ceb40a 100644 --- a/batch_balance/token_balances.go +++ b/batch_balance/token_balances.go @@ -12,7 +12,7 @@ import ( func (c *BatchBalance) TokensBalance(ctx context.Context, owner common.Address, tokens []common.Address) ([]*big.Int, error) { var balancesResults []*big.Int - err := c.ethClient.CallCtx( + err := c.provider.EthClient.CallCtx( ctx, eth.CallFunc(w3.MustNewFunc("tokensBalance(address owner, address[] contracts)", "uint256[]"), c.batchContract, owner, tokens).Returns(&balancesResults), ) diff --git a/batch_balance/token_balances_test.go b/batch_balance/token_balances_test.go index d499874..c63215b 100644 --- a/batch_balance/token_balances_test.go +++ b/batch_balance/token_balances_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" + "github.com/grassrootseconomics/cic-go/provider" "github.com/lmittmann/w3" ) @@ -35,7 +36,11 @@ func TestBatchBalance_TokensBalance(t *testing.T) { }, } - batchBalance, err := NewBatchBalance(conf.rpcProvider, w3.A(conf.batchContract)) + newProvider, err := provider.NewRpcProvider(conf.rpcProvider) + if err != nil { + t.Errorf("Creating an rpc instance failed = %v", err) + } + batchBalance, err := NewBatchBalance(*newProvider, w3.A(conf.batchContract)) if err != nil { t.Fatalf("NewBatchBalance error = %v", err) diff --git a/net/cic_net.go b/net/cic_net.go index 63f0de2..61767a0 100644 --- a/net/cic_net.go +++ b/net/cic_net.go @@ -1,50 +1,18 @@ package net import ( - "crypto/ecdsa" - "math/big" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/lmittmann/w3" -) - -const ( - kitabuMainnetChainId = 6060 + "github.com/grassrootseconomics/cic-go/provider" ) type CicNet struct { - ethClient *w3.Client - tokenIndex common.Address - kitabuSigner types.Signer + provider *provider.Provider + tokenIndex common.Address } -type WriteTx struct { - from common.Address - to common.Address - gasLimit uint64 - nonce uint64 - privateKey ecdsa.PrivateKey -} - -func NewCicNet(rpcEndpoint string, tokenIndex common.Address) (*CicNet, error) { - ethClient, err := w3.Dial(rpcEndpoint) - if err != nil { - return nil, err - } - +func NewCicNet(rpcProvider provider.Provider, tokenIndex common.Address) (*CicNet, error) { return &CicNet{ - ethClient: ethClient, - tokenIndex: tokenIndex, - kitabuSigner: types.NewEIP155Signer(big.NewInt(kitabuMainnetChainId)), + provider: &rpcProvider, + tokenIndex: tokenIndex, }, nil } - -func (c *CicNet) Close() error { - err := c.ethClient.Close() - if err != nil { - return err - } - - return nil -} diff --git a/net/cic_net_test.go b/net/cic_net_test.go index 8d0f74c..0735edc 100644 --- a/net/cic_net_test.go +++ b/net/cic_net_test.go @@ -4,6 +4,7 @@ import ( "os" "testing" + "github.com/grassrootseconomics/cic-go/provider" "github.com/lmittmann/w3" ) @@ -20,13 +21,18 @@ var conf = &tConfig{ } func TestCicNet_Connect(t *testing.T) { - name := "Test RPC connection" + name := "Test CicNet connect" wantErr := false - cicnet, _ := NewCicNet(conf.rpcProvider, w3.A(conf.tokenIndex)) + newProvider, err := provider.NewRpcProvider(conf.rpcProvider) + if err != nil { + t.Errorf("Creating an rpc instance failed = %v", err) + } + + cicnet, _ := NewCicNet(*newProvider, w3.A(conf.tokenIndex)) t.Run(name, func(t *testing.T) { - if err := cicnet.Close(); (err != nil) != wantErr { + if err := cicnet.provider.EthClient.Close(); (err != nil) != wantErr { t.Errorf("Error() error = %v, wantErr %v", err, wantErr) } }) diff --git a/net/erc20_demurrage_token.go b/net/erc20_demurrage_token.go index 9056a68..86ae868 100644 --- a/net/erc20_demurrage_token.go +++ b/net/erc20_demurrage_token.go @@ -2,10 +2,12 @@ package net import ( "context" + "math/big" + "github.com/ethereum/go-ethereum/common" + "github.com/grassrootseconomics/cic-go/provider" "github.com/lmittmann/w3" "github.com/lmittmann/w3/module/eth" - "math/big" ) type DemurrageTokenInfo struct { @@ -34,7 +36,7 @@ func (c *CicNet) DemurrageTokenInfo(ctx context.Context, tokenAddress common.Add redistributionCount big.Int ) - err := c.ethClient.CallCtx( + err := c.provider.EthClient.CallCtx( ctx, eth.CallFunc(w3.MustNewFunc("demurrageAmount()", "uint128"), tokenAddress).Returns(&demurrageAmount), eth.CallFunc(w3.MustNewFunc("demurrageTimestamp()", "uint256"), tokenAddress).Returns(&demurrageTimestamp), @@ -67,7 +69,7 @@ func (c *CicNet) DemurrageTokenInfo(ctx context.Context, tokenAddress common.Add func (c *CicNet) BaseBalanceOf(ctx context.Context, tokenAddress common.Address, accountAddress common.Address) (big.Int, error) { var balance big.Int - err := c.ethClient.CallCtx( + err := c.provider.EthClient.CallCtx( ctx, eth.CallFunc(w3.MustNewFunc("baseBalanceOf(address _account)", "uint256"), tokenAddress, accountAddress).Returns(&balance), ) @@ -78,7 +80,7 @@ func (c *CicNet) BaseBalanceOf(ctx context.Context, tokenAddress common.Address, return balance, nil } -func (c *CicNet) ChangePeriod(ctx context.Context, txData WriteTx) (common.Hash, error) { +func (c *CicNet) ChangePeriod(ctx context.Context, txData provider.WriteTx) (common.Hash, error) { sig := w3.MustNewFunc("changePeriod()", "bool") input, err := sig.EncodeArgs() if err != nil { @@ -93,7 +95,7 @@ func (c *CicNet) ChangePeriod(ctx context.Context, txData WriteTx) (common.Hash, return txHash, nil } -func (c *CicNet) ApplyDemurrageLimited(ctx context.Context, rounds int64, txData WriteTx) (common.Hash, error) { +func (c *CicNet) ApplyDemurrageLimited(ctx context.Context, rounds int64, txData provider.WriteTx) (common.Hash, error) { sig := w3.MustNewFunc("applyDemurrageLimited(uint256 _rounds)", "bool") input, err := sig.EncodeArgs(big.NewInt(rounds)) if err != nil { diff --git a/net/erc20_demurrage_token_test.go b/net/erc20_demurrage_token_test.go index 21b7d0e..966a586 100644 --- a/net/erc20_demurrage_token_test.go +++ b/net/erc20_demurrage_token_test.go @@ -3,11 +3,13 @@ package net import ( "context" "crypto/ecdsa" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/lmittmann/w3" "math/big" "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/grassrootseconomics/cic-go/provider" + "github.com/lmittmann/w3" ) func TestCicNet_DemurrageToken_DemurrageTokeInfo(t *testing.T) { @@ -44,7 +46,11 @@ func TestCicNet_DemurrageToken_DemurrageTokeInfo(t *testing.T) { }, } - cicnet, err := NewCicNet(conf.rpcProvider, w3.A(conf.tokenIndex)) + newProvider, err := provider.NewRpcProvider(conf.rpcProvider) + if err != nil { + t.Errorf("Creating an rpc instance failed = %v", err) + } + cicnet, err := NewCicNet(*newProvider, w3.A(conf.tokenIndex)) if err != nil { t.Fatalf("NewCicNet error = %v", err) @@ -109,11 +115,11 @@ func TestCicNet_DemurrageToken_BaseBalanceOf(t *testing.T) { }, } - cicnet, err := NewCicNet(conf.rpcProvider, w3.A(conf.tokenIndex)) - + newProvider, err := provider.NewRpcProvider(conf.rpcProvider) if err != nil { - t.Fatalf("NewCicNet error = %v", err) + t.Errorf("Creating an rpc instance failed = %v", err) } + cicnet, err := NewCicNet(*newProvider, w3.A(conf.tokenIndex)) for _, testcase := range tests { tt := testcase @@ -136,7 +142,7 @@ func TestCicNet_DemurrageToken_BaseBalanceOf(t *testing.T) { func TestCicNet_DemurrageToken_ChangePeriod(t *testing.T) { type args struct { - writeTx WriteTx + writeTx provider.WriteTx } // Bootstrap signer @@ -151,10 +157,11 @@ func TestCicNet_DemurrageToken_ChangePeriod(t *testing.T) { } fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA) - cicnet, err := NewCicNet(conf.rpcProvider, w3.A(conf.tokenIndex)) + newProvider, err := provider.NewRpcProvider(conf.rpcProvider) if err != nil { - t.Fatalf("NewCicNet error = %v", err) + t.Errorf("Creating an rpc instance failed = %v", err) } + cicnet, err := NewCicNet(*newProvider, w3.A(conf.tokenIndex)) nonce, err := cicnet.LastNonce(context.Background(), fromAddress) if err != nil { @@ -170,12 +177,12 @@ func TestCicNet_DemurrageToken_ChangePeriod(t *testing.T) { { name: "ChangePeriod for Sarafu", args: args{ - writeTx: WriteTx{ - from: fromAddress, - to: w3.A("0xaB89822F31c2092861F713F6F34bd6877a8C1878"), - nonce: nonce + 1, - gasLimit: 12000000, - privateKey: *privateKey, + writeTx: provider.WriteTx{ + From: fromAddress, + To: w3.A("0xaB89822F31c2092861F713F6F34bd6877a8C1878"), + Nonce: nonce + 1, + GasLimit: 12000000, + PrivateKey: *privateKey, }, }, wantErr: false, @@ -200,7 +207,7 @@ func TestCicNet_DemurrageToken_ChangePeriod(t *testing.T) { func TestCicNet_DemurrageToken_ApplyDemurrageLimited(t *testing.T) { type args struct { rounds int64 - writeTx WriteTx + writeTx provider.WriteTx } // Bootstrap signer @@ -215,10 +222,11 @@ func TestCicNet_DemurrageToken_ApplyDemurrageLimited(t *testing.T) { } fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA) - cicnet, err := NewCicNet(conf.rpcProvider, w3.A(conf.tokenIndex)) + newProvider, err := provider.NewRpcProvider(conf.rpcProvider) if err != nil { - t.Fatalf("NewCicNet error = %v", err) + t.Errorf("Creating an rpc instance failed = %v", err) } + cicnet, err := NewCicNet(*newProvider, w3.A(conf.tokenIndex)) nonce, err := cicnet.LastNonce(context.Background(), fromAddress) if err != nil { @@ -235,12 +243,12 @@ func TestCicNet_DemurrageToken_ApplyDemurrageLimited(t *testing.T) { name: "ChangePeriod for Sarafu", args: args{ rounds: 1000, - writeTx: WriteTx{ - from: fromAddress, - to: w3.A("0xaB89822F31c2092861F713F6F34bd6877a8C1878"), - nonce: nonce + 1, - gasLimit: 12000000, - privateKey: *privateKey, + writeTx: provider.WriteTx{ + From: fromAddress, + To: w3.A("0xaB89822F31c2092861F713F6F34bd6877a8C1878"), + Nonce: nonce + 1, + GasLimit: 12000000, + PrivateKey: *privateKey, }, }, wantErr: false, diff --git a/net/erc20_token.go b/net/erc20_token.go index a81f97d..3b85200 100644 --- a/net/erc20_token.go +++ b/net/erc20_token.go @@ -2,10 +2,11 @@ package net import ( "context" + "math/big" + "github.com/ethereum/go-ethereum/common" "github.com/lmittmann/w3" "github.com/lmittmann/w3/module/eth" - "math/big" ) type ERC20Token struct { @@ -21,7 +22,7 @@ func (c *CicNet) ERC20TokenInfo(ctx context.Context, tokenAddress common.Address tokenDecimals big.Int ) - err := c.ethClient.CallCtx( + err := c.provider.EthClient.CallCtx( ctx, eth.CallFunc(w3.MustNewFunc("name()", "string"), tokenAddress).Returns(&tokenName), eth.CallFunc(w3.MustNewFunc("symbol()", "string"), tokenAddress).Returns(&tokenSymbol), @@ -40,7 +41,7 @@ func (c *CicNet) ERC20TokenInfo(ctx context.Context, tokenAddress common.Address func (c *CicNet) BalanceOf(ctx context.Context, tokenAddress common.Address, accountAddress common.Address) (big.Int, error) { var balance big.Int - err := c.ethClient.CallCtx( + err := c.provider.EthClient.CallCtx( ctx, eth.CallFunc(w3.MustNewFunc("balanceOf(address _account)", "uint256"), tokenAddress, accountAddress).Returns(&balance), ) diff --git a/net/erc20_token_test.go b/net/erc20_token_test.go index e3a3e64..b159ecf 100644 --- a/net/erc20_token_test.go +++ b/net/erc20_token_test.go @@ -2,10 +2,12 @@ package net import ( "context" - "github.com/ethereum/go-ethereum/common" - "github.com/lmittmann/w3" "math/big" "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/grassrootseconomics/cic-go/provider" + "github.com/lmittmann/w3" ) func TestCicNet_ERC20Token_ERC20TokenInfo(t *testing.T) { @@ -37,7 +39,11 @@ func TestCicNet_ERC20Token_ERC20TokenInfo(t *testing.T) { }, } - cicnet, err := NewCicNet(conf.rpcProvider, w3.A(conf.tokenIndex)) + newProvider, err := provider.NewRpcProvider(conf.rpcProvider) + if err != nil { + t.Errorf("Creating an rpc instance failed = %v", err) + } + cicnet, err := NewCicNet(*newProvider, w3.A(conf.tokenIndex)) if err != nil { t.Fatalf("NewCicNet error = %v", err) @@ -92,11 +98,11 @@ func TestCicNet_ERC20Token_BalanceOf(t *testing.T) { }, } - cicnet, err := NewCicNet(conf.rpcProvider, w3.A(conf.tokenIndex)) - + newProvider, err := provider.NewRpcProvider(conf.rpcProvider) if err != nil { - t.Fatalf("NewCicNet error = %v", err) + t.Errorf("Creating an rpc instance failed = %v", err) } + cicnet, err := NewCicNet(*newProvider, w3.A(conf.tokenIndex)) for _, testcase := range tests { tt := testcase diff --git a/net/token_index.go b/net/token_index.go index bfd5e26..3e06bab 100644 --- a/net/token_index.go +++ b/net/token_index.go @@ -2,16 +2,17 @@ package net import ( "context" + "math/big" + "github.com/ethereum/go-ethereum/common" "github.com/lmittmann/w3" "github.com/lmittmann/w3/module/eth" - "math/big" ) func (c *CicNet) EntryCount(ctx context.Context) (big.Int, error) { var tokenCount big.Int - err := c.ethClient.CallCtx( + err := c.provider.EthClient.CallCtx( ctx, eth.CallFunc(w3.MustNewFunc("entryCount()", "uint256"), c.tokenIndex).Returns(&tokenCount), ) @@ -25,7 +26,7 @@ func (c *CicNet) EntryCount(ctx context.Context) (big.Int, error) { func (c *CicNet) AddressAtIndex(ctx context.Context, index *big.Int) (string, error) { var address common.Address - err := c.ethClient.CallCtx( + err := c.provider.EthClient.CallCtx( ctx, eth.CallFunc(w3.MustNewFunc("entry(uint256 _idx)", "address"), c.tokenIndex, index).Returns(&address), ) diff --git a/net/token_index_test.go b/net/token_index_test.go index 3d9bf75..1d05715 100644 --- a/net/token_index_test.go +++ b/net/token_index_test.go @@ -2,23 +2,29 @@ package net import ( "context" - "github.com/lmittmann/w3" "math/big" "testing" + + "github.com/grassrootseconomics/cic-go/provider" + "github.com/lmittmann/w3" ) func TestCicNet_TokenIndex_EntryCount(t *testing.T) { name := "Entry count" wantErr := false - tokenIndex, err := NewCicNet(conf.rpcProvider, w3.A(conf.tokenIndex)) + newProvider, err := provider.NewRpcProvider(conf.rpcProvider) + if err != nil { + t.Errorf("Creating an rpc instance failed = %v", err) + } + cicnet, err := NewCicNet(*newProvider, w3.A(conf.tokenIndex)) if err != nil { t.Fatalf("NewCicNet error = %v", err) } t.Run(name, func(t *testing.T) { - got, err := tokenIndex.EntryCount(context.Background()) + got, err := cicnet.EntryCount(context.Background()) if (err != nil) != wantErr { t.Errorf("EntryCount() error = %v, wantErr %v", err, wantErr) @@ -59,7 +65,11 @@ func TestCicNet_TokenIndex_AddressAtIndex(t *testing.T) { }, } - tokenIndex, err := NewCicNet(conf.rpcProvider, w3.A(conf.tokenIndex)) + newProvider, err := provider.NewRpcProvider(conf.rpcProvider) + if err != nil { + t.Errorf("Creating an rpc instance failed = %v", err) + } + cicnet, err := NewCicNet(*newProvider, w3.A(conf.tokenIndex)) if err != nil { t.Fatalf("NewCicNet error = %v", err) @@ -69,7 +79,7 @@ func TestCicNet_TokenIndex_AddressAtIndex(t *testing.T) { tt := testcase t.Run(tt.name, func(t *testing.T) { - got, err := tokenIndex.AddressAtIndex(context.Background(), tt.args.index) + got, err := cicnet.AddressAtIndex(context.Background(), tt.args.index) if (err != nil) != tt.wantErr { t.Errorf("AddressAtIndex() error = %v, wantErr %v", err, tt.wantErr) diff --git a/net/util.go b/net/util.go index f353192..1bc18e6 100644 --- a/net/util.go +++ b/net/util.go @@ -2,16 +2,18 @@ package net import ( "context" + "math/big" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/grassrootseconomics/cic-go/provider" "github.com/lmittmann/w3/module/eth" - "math/big" ) func (c *CicNet) LastNonce(ctx context.Context, address common.Address) (uint64, error) { var nonce uint64 - err := c.ethClient.CallCtx( + err := c.provider.EthClient.CallCtx( ctx, eth.Nonce(address, nil).Returns(&nonce), ) @@ -22,18 +24,18 @@ func (c *CicNet) LastNonce(ctx context.Context, address common.Address) (uint64, return nonce, nil } -func (c *CicNet) signAndCall(ctx context.Context, input []byte, txData WriteTx) (common.Hash, error) { +func (c *CicNet) signAndCall(ctx context.Context, input []byte, txData provider.WriteTx) (common.Hash, error) { var txHash common.Hash - tx, err := types.SignNewTx(&txData.privateKey, c.kitabuSigner, &types.LegacyTx{ - To: &txData.to, - Nonce: txData.nonce, + tx, err := types.SignNewTx(&txData.PrivateKey, c.provider.Signer, &types.LegacyTx{ + To: &txData.To, + Nonce: txData.Nonce, Data: input, - Gas: txData.gasLimit, + Gas: txData.GasLimit, GasPrice: big.NewInt(1), }) - err = c.ethClient.CallCtx( + err = c.provider.EthClient.CallCtx( ctx, eth.SendTransaction(tx).Returns(&txHash), ) diff --git a/provider/provider.go b/provider/provider.go new file mode 100644 index 0000000..4bf9231 --- /dev/null +++ b/provider/provider.go @@ -0,0 +1,48 @@ +package provider + +import ( + "crypto/ecdsa" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/lmittmann/w3" +) + +const ( + kitabuMainnetChainId = 6060 +) + +type Provider struct { + EthClient *w3.Client + Signer types.Signer +} + +type WriteTx struct { + From common.Address + To common.Address + GasLimit uint64 + Nonce uint64 + PrivateKey ecdsa.PrivateKey +} + +func NewRpcProvider(rpcEndpoint string) (*Provider, error) { + ethClient, err := w3.Dial(rpcEndpoint) + if err != nil { + return nil, err + } + + return &Provider{ + EthClient: ethClient, + Signer: types.NewEIP155Signer(big.NewInt(kitabuMainnetChainId)), + }, nil +} + +func (c *Provider) CLose() error { + err := c.EthClient.Close() + if err != nil { + return err + } + + return nil +}