This commit is contained in:
Ian Norden 2020-10-23 10:28:03 -05:00
parent fa16927113
commit a1a54c7ac8
9 changed files with 152 additions and 82 deletions

View File

@ -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")

View File

@ -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))

57
pkg/manual/env.go Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
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)
}

View File

@ -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)
}

View File

@ -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
}

View File

@ -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")
}

21
pkg/shared/env.go Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
package shared
const (
DefaultDeploymentAddrLogPathPrefix = "./accounts/addresses/"
)

22
pkg/shared/interface.go Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
package shared
// Service looping interface
type Service interface {
Loop(quitChan <-chan bool) (doneChan <-chan bool)
}

View File

@ -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()
}