From a1a54c7ac84a0eda398ab925f1f90be44742fffc Mon Sep 17 00:00:00 2001 From: Ian Norden Date: Fri, 23 Oct 2020 10:28:03 -0500 Subject: [PATCH] refactor --- cmd/root.go | 2 +- pkg/manual/config.go | 34 +---------------------- pkg/manual/env.go | 57 ++++++++++++++++++++++++++++++++++++++ pkg/manual/sender.go | 16 ++++------- pkg/manual/service.go | 14 +++------- pkg/manual/tx_generator.go | 41 ++++++++++----------------- pkg/shared/env.go | 21 ++++++++++++++ pkg/shared/interface.go | 22 +++++++++++++++ pkg/shared/util.go | 27 ++++++++++++++++++ 9 files changed, 152 insertions(+), 82 deletions(-) create mode 100644 pkg/manual/env.go create mode 100644 pkg/shared/env.go create mode 100644 pkg/shared/interface.go diff --git a/cmd/root.go b/cmd/root.go index 9a0b1cf..a7bef78 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -83,7 +83,7 @@ func init() { viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) viper.AutomaticEnv() - // flags + // shared flags rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file location") rootCmd.PersistentFlags().String("log-level", log.InfoLevel.String(), "Log level (trace, debug, info, warn, error, fatal, panic") diff --git a/pkg/manual/config.go b/pkg/manual/config.go index bbc7747..1ac0397 100644 --- a/pkg/manual/config.go +++ b/pkg/manual/config.go @@ -33,36 +33,6 @@ import ( "github.com/spf13/viper" ) -const ( - ETH_TX_LIST = "ETH_TX_LIST" - ETH_ADDR_LOG = "ETH_ADDR_LOG" - - defaultGenKeyWritePathPrefix = "./accounts/keys/" - defaultAddrLogPath = "./accounts/addresses/accounts" - - typeSuffix = ".type" - httpPathSuffix = ".http" - toSuffix = ".to" - amountSuffix = ".amount" - gasLimitSuffix = ".gasLimit" - gasPriceSuffix = ".gasPrice" - gasPremiumSuffix = ".gasPremium" - feeCapSuffix = ".feeCap" - dataSuffix = ".data" - senderKeyPathSuffix = ".senderKeyPath" - writeSenderPathSuffix = ".writeSenderPath" - l1SenderSuffix = ".l1Sender" - l1RollupTxIdSuffix = ".l1RollupTxId" - sigHashTypeSuffix = ".sigHashType" - frequencySuffix = ".frequency" - totalNumberSuffix = ".totalNumber" - delaySuffix = ".delay" - startingNonceSuffix = ".startingNonce" - queueOriginSuffix = ".queueOrigin" - chainIDSuffix = ".chainID" - contractWriteSuffix = ".writeDeploymentAddrPath" -) - // TxParams holds the parameters for a given transaction type TxParams struct { // Name of this tx in the .toml file @@ -111,9 +81,7 @@ type TxParams struct { // NewConfig returns a new tx spammer config func NewTxParams() ([]TxParams, error) { - viper.BindEnv("eth.txs", ETH_TX_LIST) - viper.BindEnv("eth.addrLogPath", ETH_ADDR_LOG) - + bindEnv() addrLogPath := viper.GetString("eth.addrLogPath") txs := viper.GetStringSlice("eth.txs") txParams := make([]TxParams, len(txs)) diff --git a/pkg/manual/env.go b/pkg/manual/env.go new file mode 100644 index 0000000..c0ba50a --- /dev/null +++ b/pkg/manual/env.go @@ -0,0 +1,57 @@ +// VulcanizeDB +// Copyright © 2020 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package manual + +import "github.com/spf13/viper" + +const ( + // env variables + ETH_TX_LIST = "ETH_TX_LIST" + ETH_ADDR_LOG = "ETH_ADDR_LOG" + + // write paths + defaultGenKeyWritePathPrefix = "./accounts/keys/out/" + defaultAddrLogPath = "./accounts/addresses/accounts" + + // .toml binding suffixes + typeSuffix = ".type" + httpPathSuffix = ".http" + toSuffix = ".to" + amountSuffix = ".amount" + gasLimitSuffix = ".gasLimit" + gasPriceSuffix = ".gasPrice" + gasPremiumSuffix = ".gasPremium" + feeCapSuffix = ".feeCap" + dataSuffix = ".data" + senderKeyPathSuffix = ".senderKeyPath" + writeSenderPathSuffix = ".writeSenderPath" + l1SenderSuffix = ".l1Sender" + l1RollupTxIdSuffix = ".l1RollupTxId" + sigHashTypeSuffix = ".sigHashType" + frequencySuffix = ".frequency" + totalNumberSuffix = ".totalNumber" + delaySuffix = ".delay" + startingNonceSuffix = ".startingNonce" + queueOriginSuffix = ".queueOrigin" + chainIDSuffix = ".chainID" + contractWriteSuffix = ".writeDeploymentAddrPath" +) + +func bindEnv() { + viper.BindEnv("eth.txs", ETH_TX_LIST) + viper.BindEnv("eth.addrLogPath", ETH_ADDR_LOG) +} \ No newline at end of file diff --git a/pkg/manual/sender.go b/pkg/manual/sender.go index c420709..926332a 100644 --- a/pkg/manual/sender.go +++ b/pkg/manual/sender.go @@ -17,14 +17,12 @@ package manual import ( - "context" "fmt" + "github.com/sirupsen/logrus" "sync" "time" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/rpc" - "github.com/sirupsen/logrus" + "github.com/vulcanize/tx_spammer/pkg/shared" ) // TxSender type for @@ -86,10 +84,6 @@ func (s *TxSender) genAndSend(p TxParams) error { if err != nil { return err } - return sendRawTransaction(p.Client, tx, p.Name) -} - -func sendRawTransaction(rpcClient *rpc.Client, txRlp []byte, name string) error { - logrus.Infof("sending tx %s", name) - return rpcClient.CallContext(context.Background(), nil, "eth_sendRawTransaction", hexutil.Encode(txRlp)) -} + logrus.Infof("sending tx %s", p.Name) + return shared.SendRawTransaction(p.Client, tx) +} \ No newline at end of file diff --git a/pkg/manual/service.go b/pkg/manual/service.go index 6e01d9c..a512b7f 100644 --- a/pkg/manual/service.go +++ b/pkg/manual/service.go @@ -17,31 +17,24 @@ package manual import ( - "sync" - "github.com/sirupsen/logrus" + "github.com/vulcanize/tx_spammer/pkg/shared" ) -type Service interface { - Loop(wg *sync.WaitGroup, quitChan <-chan bool) -} - type Spammer struct { Sender *TxSender } -func NewTxSpammer(params []TxParams) Service { +func NewTxSpammer(params []TxParams) shared.Service { return &Spammer{ Sender: NewTxSender(params), } } -func (s *Spammer) Loop(wg *sync.WaitGroup, quitChan <-chan bool) { +func (s *Spammer) Loop(quitChan <-chan bool) <-chan bool { forwardQuit := make(chan bool) doneChan, errChan := s.Sender.Send(forwardQuit) - wg.Add(1) go func() { - defer wg.Done() for { select { case err := <-errChan: @@ -53,4 +46,5 @@ func (s *Spammer) Loop(wg *sync.WaitGroup, quitChan <-chan bool) { } } }() + return doneChan } diff --git a/pkg/manual/tx_generator.go b/pkg/manual/tx_generator.go index cdd7a20..1f7eae7 100644 --- a/pkg/manual/tx_generator.go +++ b/pkg/manual/tx_generator.go @@ -17,19 +17,14 @@ package manual import ( + "errors" "fmt" - "github.com/vulcanize/tx_spammer/pkg/shared" - "os" "sync/atomic" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/rlp" -) - -const ( - defaultDeploymentAddrLogPathPrefix = "./accounts/addresses/" + "github.com/vulcanize/tx_spammer/pkg/shared" ) // TxGenerator generates and signs txs @@ -54,7 +49,9 @@ func NewTxGenerator(params []TxParams) *TxGenerator { func (tg TxGenerator) GenerateTx(params TxParams) ([]byte, error) { tx := make([]byte, 0) switch params.Type { - case shared.Standard, shared.OptimismL1ToL2, shared.OptimismL2: + case shared.OptimismL2: + return tg.genL2(params) + case shared.Standard: return tg.gen(params) case shared.EIP1559: return tg.gen1559(params) @@ -64,19 +61,19 @@ func (tg TxGenerator) GenerateTx(params TxParams) ([]byte, error) { return tx, nil } -func (gen TxGenerator) gen(params TxParams) ([]byte, error) { +func (gen TxGenerator) genL2(params TxParams) ([]byte, error) { nonce := atomic.AddUint64(gen.nonces[params.Sender], 1) tx := new(types.Transaction) if params.To == nil { tx = types.NewContractCreation(nonce, params.Amount, params.GasLimit, params.GasPrice, params.Data, params.L1SenderAddr, params.L1RollupTxId, params.QueueOrigin) - if err := writeContractAddr(params.ContractAddrWritePath, params.Sender, nonce); err != nil { + if err := shared.WriteContractAddr(params.ContractAddrWritePath, params.Sender, nonce); err != nil { return nil, err } } else { tx = types.NewTransaction(nonce, *params.To, params.Amount, params.GasLimit, params.GasPrice, params.Data, params.L1SenderAddr, params.L1RollupTxId, params.QueueOrigin, params.SigHashType) } - signer, err := shared.TxSigner(params.Type, params.ChainID) + signer, err := shared.TxSigner(shared.OptimismL2, params.ChainID) if err != nil { return nil, err } @@ -91,22 +88,12 @@ func (gen TxGenerator) gen(params TxParams) ([]byte, error) { return txRlp, nil } -func (gen TxGenerator) gen1559(params TxParams) ([]byte, error) { - // TODO: support EIP1559; new to make a new major version, vendor it, or release with different pkg name so that we can import both optimism and eip1559 geth - return nil, fmt.Errorf("1559 support not yet available") +func (gen TxGenerator) gen(params TxParams) ([]byte, error) { + // TODO: support standard geth + return nil, errors.New("L1 support not yet available") } -func writeContractAddr(filePath string, senderAddr common.Address, nonce uint64) error { - if filePath == "" { - filePath = defaultDeploymentAddrLogPathPrefix + senderAddr.Hex() - } - contractAddr := crypto.CreateAddress(senderAddr, nonce) - f, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return err - } - if _, err := f.WriteString(contractAddr.Hex() + "\n"); err != nil { - return err - } - return f.Close() +func (gen TxGenerator) gen1559(params TxParams) ([]byte, error) { + // TODO: support EIP1559 + return nil, errors.New("1559 support not yet available") } diff --git a/pkg/shared/env.go b/pkg/shared/env.go new file mode 100644 index 0000000..b09f951 --- /dev/null +++ b/pkg/shared/env.go @@ -0,0 +1,21 @@ +// VulcanizeDB +// Copyright © 2020 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package shared + +const ( + DefaultDeploymentAddrLogPathPrefix = "./accounts/addresses/" +) \ No newline at end of file diff --git a/pkg/shared/interface.go b/pkg/shared/interface.go new file mode 100644 index 0000000..5a570a4 --- /dev/null +++ b/pkg/shared/interface.go @@ -0,0 +1,22 @@ +// VulcanizeDB +// Copyright © 2020 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package shared + +// Service looping interface +type Service interface { + Loop(quitChan <-chan bool) (doneChan <-chan bool) +} \ No newline at end of file diff --git a/pkg/shared/util.go b/pkg/shared/util.go index 788caab..0c9975e 100644 --- a/pkg/shared/util.go +++ b/pkg/shared/util.go @@ -17,10 +17,16 @@ package shared import ( + "context" "fmt" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" "math/big" + "os" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/temp/common/hexutil" ) // ChainConfig returns the appropriate ethereum chain config for the provided chain id @@ -34,3 +40,24 @@ func TxSigner(kind TxType, chainID uint64) (types.Signer, error) { return nil, fmt.Errorf("chain config for chainid %d not available", chainID) } } + +// SendRawTransaction sends a raw, signed tx using the provided client +func SendRawTransaction(rpcClient *rpc.Client, txRlp []byte) error { + return rpcClient.CallContext(context.Background(), nil, "eth_sendRawTransaction", hexutil.Encode(txRlp)) +} + +// WriteContractAddr appends a contract addr to an out file +func WriteContractAddr(filePath string, senderAddr common.Address, nonce uint64) error { + if filePath == "" { + filePath = DefaultDeploymentAddrLogPathPrefix + senderAddr.Hex() + } + contractAddr := crypto.CreateAddress(senderAddr, nonce) + f, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return err + } + if _, err := f.WriteString(contractAddr.Hex() + "\n"); err != nil { + return err + } + return f.Close() +} \ No newline at end of file