From eb09532b1a102f92ffc2228c4feef5a8cc699ea3 Mon Sep 17 00:00:00 2001 From: Thomas E Lackey Date: Fri, 21 Oct 2022 13:42:07 -0500 Subject: [PATCH] Switch channel to take a *Transaction rather than []byte. This allows us to access the TX fields (eg, for logging) throughout its lifecycle. --- environments/gen.toml | 6 +++--- pkg/auto/config.go | 5 +---- pkg/auto/deployer.go | 6 +++--- pkg/auto/sender.go | 5 +++-- pkg/auto/tx_generator.go | 24 +++++++++--------------- pkg/manual/tx_generator.go | 5 +---- pkg/shared/util.go | 25 +++++++++++++++++++++++-- 7 files changed, 43 insertions(+), 33 deletions(-) diff --git a/environments/gen.toml b/environments/gen.toml index 4caa879..561ef10 100644 --- a/environments/gen.toml +++ b/environments/gen.toml @@ -11,18 +11,18 @@ [contractSpammer] frequency = 10 # how often to send a transaction (in milliseconds) - env: $ETH_CALL_FREQ - totalNumber = 1000 # total number of transactions to send (per sender) - env: $ETH_CALL_TOTAL_NUMBER + totalNumber = 5000 # total number of transactions to send (per sender) - env: $ETH_CALL_TOTAL_NUMBER abiPath = "sol/build/Test.abi" # path to the abi file for the contract we are calling - env: $ETH_CALL_ABI_PATH # NOTE: we expect to be calling a method such as Put(address addr, uint256 val) where the first argument is an # integer than we can increment to store values at new locations in the contract trie (to grow it) and # the second argument is an integer value that we store at these positions methodName = "Put" # the method name we are calling - env: $ETH_CALL_METHOD_NAME - gasLimit = 21000 # gasLimit to use for the eth call txs - env: $ETH_CALL_GAS_LIMIT + gasLimit = 42000 # gasLimit to use for the eth call txs - env: $ETH_CALL_GAS_LIMIT gasTipCap = "1000000000" # gasTipCap to use for the eth call txs - env: $ETH_CALL_GAS_TIP_CAP gasFeeCap = "1000000007" # gasFeeCap to use for the eth call txs - env: $ETH_CALL_GAS_FEE_CAP [sendSpammer] - frequency = 100 # how often to send a transaction (in milliseconds) - env: $ETH_SEND_FREQ + frequency = 50 # how often to send a transaction (in milliseconds) - env: $ETH_SEND_FREQ totalNumber = 1000 # total number of transactions to send (per sender) - env: $ETH_SEND_TOTAL_NUMBER amount = "10000" # amount of wei (1x10^-18 ETH) to send in each tx (be mindful of the genesis allocations) - env: $ETH_SEND_AMOUNT gasLimit = 21000 # gasLimit to use for the eth transfer txs - env: $ETH_SEND_GAS_LIMIT diff --git a/pkg/auto/config.go b/pkg/auto/config.go index 12cb3c6..a463d4e 100644 --- a/pkg/auto/config.go +++ b/pkg/auto/config.go @@ -165,10 +165,7 @@ func NewConfig() (*Config, error) { } // Load signer - signer, err := shared.TxSigner(chainID) - if err != nil { - return nil, err - } + signer := shared.TxSigner(chainID) // Load deployment config deploymentConfig, err := NewDeploymentConfig(chainID) diff --git a/pkg/auto/deployer.go b/pkg/auto/deployer.go index 9dbe0af..cad40f0 100644 --- a/pkg/auto/deployer.go +++ b/pkg/auto/deployer.go @@ -58,8 +58,8 @@ func (cp *ContractDeployer) Deploy() ([]common.Address, error) { for i := uint64(0); i < cp.config.Number; i++ { <-ticker.C for i, key := range cp.senderKeys { - logrus.Infof("Generating contract deployment for %s.", cp.senderAddrs[i].Hex()) - txBytes, contractAddr, err := cp.txGenerator.GenerateTx(&GenParams{ + logrus.Debugf("Generating contract deployment for %s.", cp.senderAddrs[i].Hex()) + signedTx, contractAddr, err := cp.txGenerator.GenerateTx(&GenParams{ ChainID: cp.config.ChainID, Sender: cp.senderAddrs[i], SenderKey: key, @@ -71,7 +71,7 @@ func (cp *ContractDeployer) Deploy() ([]common.Address, error) { if err != nil { return nil, err } - if err := shared.SendRawTransaction(cp.client, txBytes); err != nil { + if err := shared.SendTransaction(cp.client, signedTx); err != nil { return nil, err } contractAddrs = append(contractAddrs, contractAddr) diff --git a/pkg/auto/sender.go b/pkg/auto/sender.go index cc6bb6c..b3718d5 100644 --- a/pkg/auto/sender.go +++ b/pkg/auto/sender.go @@ -17,6 +17,7 @@ package auto import ( + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rpc" "github.com/sirupsen/logrus" "github.com/vulcanize/tx_spammer/pkg/shared" @@ -35,7 +36,7 @@ func NewEthSender(config *Config) *EthSender { } // Send awaits txs off the provided work queue and sends them -func (s *EthSender) Send(quitChan <-chan bool, txChan <-chan []byte) (<-chan bool, <-chan error) { +func (s *EthSender) Send(quitChan <-chan bool, txChan <-chan *types.Transaction) (<-chan bool, <-chan error) { // err channel returned to calling context errChan := make(chan error) doneChan := make(chan bool) @@ -46,7 +47,7 @@ func (s *EthSender) Send(quitChan <-chan bool, txChan <-chan []byte) (<-chan boo select { case tx := <-txChan: counter += 1 - if err := shared.SendRawTransaction(s.client, tx); err != nil { + if err := shared.SendTransaction(s.client, tx); err != nil { errChan <- err } case <-quitChan: diff --git a/pkg/auto/tx_generator.go b/pkg/auto/tx_generator.go index 8af7ecc..6dd6c23 100644 --- a/pkg/auto/tx_generator.go +++ b/pkg/auto/tx_generator.go @@ -19,7 +19,6 @@ package auto import ( "context" "crypto/ecdsa" - "github.com/ethereum/go-ethereum/common/hexutil" log "github.com/sirupsen/logrus" "math/big" "math/rand" @@ -75,8 +74,8 @@ type GenParams struct { Data []byte } -func (gen *TxGenerator) GenerateTxs(quitChan <-chan bool) (<-chan bool, <-chan []byte, <-chan error) { - txChan := make(chan []byte) +func (gen *TxGenerator) GenerateTxs(quitChan <-chan bool) (<-chan bool, <-chan *types.Transaction, <-chan error) { + txChan := make(chan *types.Transaction) errChan := make(chan error) wg := new(sync.WaitGroup) for i, sender := range gen.config.SenderKeys { @@ -97,13 +96,13 @@ func (gen *TxGenerator) GenerateTxs(quitChan <-chan bool) (<-chan bool, <-chan [ return doneChan, txChan, errChan } -func (gen *TxGenerator) genSends(wg *sync.WaitGroup, txChan chan<- []byte, errChan chan<- error, quitChan <-chan bool, senderKey *ecdsa.PrivateKey, senderAddr common.Address, sendConfig *SendConfig) { +func (gen *TxGenerator) genSends(wg *sync.WaitGroup, txChan chan<- *types.Transaction, errChan chan<- error, quitChan <-chan bool, senderKey *ecdsa.PrivateKey, senderAddr common.Address, sendConfig *SendConfig) { defer wg.Done() ticker := time.NewTicker(sendConfig.Frequency) for _, dst := range sendConfig.DestinationAddresses { select { case <-ticker.C: - log.Infof("Generating send from %s to %s.", senderAddr.Hex(), dst.Hex()) + log.Debugf("Generating send from %s to %s.", senderAddr.Hex(), dst.Hex()) rawTx, _, err := gen.GenerateTx(&GenParams{ ChainID: sendConfig.ChainID, To: &dst, @@ -126,14 +125,14 @@ func (gen *TxGenerator) genSends(wg *sync.WaitGroup, txChan chan<- []byte, errCh log.Info("Done generating sends for ", senderAddr.Hex()) } -func (gen *TxGenerator) genCalls(wg *sync.WaitGroup, txChan chan<- []byte, errChan chan<- error, quitChan <-chan bool, senderKey *ecdsa.PrivateKey, senderAddr common.Address, callConfig *CallConfig) { +func (gen *TxGenerator) genCalls(wg *sync.WaitGroup, txChan chan<- *types.Transaction, errChan chan<- error, quitChan <-chan bool, senderKey *ecdsa.PrivateKey, senderAddr common.Address, callConfig *CallConfig) { defer wg.Done() ticker := time.NewTicker(callConfig.Frequency) for i := 0; i < callConfig.TotalNumber; i++ { select { case <-ticker.C: contractAddr := callConfig.ContractAddrs[rand.Intn(len(callConfig.ContractAddrs))] - log.Infof("Generating call from %s to %s.", senderAddr.Hex(), contractAddr.Hex()) + log.Debugf("Generating call from %s to %s.", senderAddr.Hex(), contractAddr.Hex()) data, err := callConfig.ABI.Pack(callConfig.MethodName, contractAddr, big.NewInt(time.Now().UnixNano())) if err != nil { errChan <- err @@ -161,7 +160,7 @@ func (gen *TxGenerator) genCalls(wg *sync.WaitGroup, txChan chan<- []byte, errCh } // GenerateTx generates tx from the provided params -func (gen *TxGenerator) GenerateTx(params *GenParams) ([]byte, common.Address, error) { +func (gen *TxGenerator) GenerateTx(params *GenParams) (*types.Transaction, common.Address, error) { nonce := gen.claimNonce(params.Sender) tx := new(types.Transaction) var contractAddr common.Address @@ -192,17 +191,12 @@ func (gen *TxGenerator) GenerateTx(params *GenParams) ([]byte, common.Address, e Gas: params.GasLimit, To: params.To, Value: params.Amount, - Data: nil, + Data: params.Data, }) } signedTx, err := types.SignTx(tx, gen.config.Signer, params.SenderKey) if err != nil { return nil, common.Address{}, err } - data, err := signedTx.MarshalBinary() - if err != nil { - return nil, common.Address{}, err - } - log.Debugf("Generated TX %s with bytes %s", signedTx.Hash().Hex(), hexutil.Encode(data)) - return data, contractAddr, err + return signedTx, contractAddr, err } diff --git a/pkg/manual/tx_generator.go b/pkg/manual/tx_generator.go index 3c15db8..0ee509e 100644 --- a/pkg/manual/tx_generator.go +++ b/pkg/manual/tx_generator.go @@ -76,10 +76,7 @@ func (gen TxGenerator) GenerateTx(params TxParams) ([]byte, error) { Data: params.Data, }) } - signer, err := shared.TxSigner(params.ChainID) - if err != nil { - return nil, err - } + signer := shared.TxSigner(params.ChainID) signedTx, err := types.SignTx(tx, signer, params.SenderKey) if err != nil { return nil, err diff --git a/pkg/shared/util.go b/pkg/shared/util.go index ff29c64..fba6773 100644 --- a/pkg/shared/util.go +++ b/pkg/shared/util.go @@ -31,8 +31,29 @@ import ( ) // ChainConfig returns the appropriate ethereum chain config for the provided chain id -func TxSigner(chainID *big.Int) (types.Signer, error) { - return types.NewLondonSigner(chainID), nil +func TxSigner(chainID *big.Int) types.Signer { + return types.NewLondonSigner(chainID) +} + +// SendTransaction sends a signed tx using the provided client +func SendTransaction(rpcClient *rpc.Client, tx *types.Transaction) error { + msg, _ := tx.AsMessage(TxSigner(tx.ChainId()), big.NewInt(1)) + if nil == tx.To() { + logrus.Infof("TX %s to create contract %s (from %s)", + tx.Hash().Hex(), crypto.CreateAddress(msg.From(), tx.Nonce()), msg.From().Hex()) + } else if nil == tx.Data() || len(tx.Data()) == 0 { + logrus.Infof("TX %s to %s (from %s)", + tx.Hash().Hex(), msg.To().Hex(), msg.From().Hex()) + } else { + logrus.Infof("TX %s calling contract %s (from %s)", + tx.Hash().Hex(), msg.To().Hex(), msg.From().Hex()) + } + + data, err := tx.MarshalBinary() + if err != nil { + return err + } + return SendRawTransaction(rpcClient, data) } // SendRawTransaction sends a raw, signed tx using the provided client