write out contract and acct addrs

This commit is contained in:
Ian Norden 2020-10-16 01:07:07 -05:00
parent 87ecc732cd
commit 958e64d33f
3 changed files with 91 additions and 39 deletions

View File

@ -1,5 +1,6 @@
[eth] [eth]
txs = ["L2ContractDeployment", "L2ContractPutCall", "L2ContractGetCall"] txs = ["L2ContractDeployment", "L2ContractPutCall", "L2ContractGetCall"] # $ETH_TX_LIST
addrLogPath = "" # ETH_ADDR_LOG
[L2ContractDeployment] [L2ContractDeployment]
type = "L2" type = "L2"
@ -12,6 +13,7 @@
data = "" data = ""
senderKeyPath = "" senderKeyPath = ""
writeSenderPath = "" writeSenderPath = ""
writeDeploymentAddrPath = ""
frequency = 1 frequency = 1
totalNumber = 1 totalNumber = 1
delay = 0 delay = 0

View File

@ -20,6 +20,7 @@ import (
"crypto/ecdsa" "crypto/ecdsa"
"fmt" "fmt"
"math/big" "math/big"
"os"
"strings" "strings"
"time" "time"
@ -31,6 +32,7 @@ import (
"github.com/spf13/viper" "github.com/spf13/viper"
) )
// TxParams holds the parameters for a given transaction
type TxParams struct { type TxParams struct {
// Name of this tx in the .toml file // Name of this tx in the .toml file
Name string Name string
@ -63,8 +65,9 @@ type TxParams struct {
FeeCap *big.Int FeeCap *big.Int
// Sender key, if left the senderKeyPath is empty we generate a new key // Sender key, if left the senderKeyPath is empty we generate a new key
SenderKey *ecdsa.PrivateKey SenderKey *ecdsa.PrivateKey
StartingNonce uint64 StartingNonce uint64
ContractAddrWritePath string
// Sending params // Sending params
// How often we send a tx of this type // How often we send a tx of this type
@ -76,7 +79,11 @@ type TxParams struct {
} }
const ( const (
ETH_TX_LIST = "ETH_TX_LIST" ETH_TX_LIST = "ETH_TX_LIST"
ETH_ADDR_LOG = "ETH_ADDR_LOG"
defaultGenKeyWritePathPrefix = "./accounts/keys/"
defaultAddrLogPath = "./accounts/addresses/accounts"
typeSuffix = ".type" typeSuffix = ".type"
httpPathSuffix = ".http" httpPathSuffix = ".http"
@ -98,12 +105,15 @@ const (
startingNonceSuffix = ".startingNonce" startingNonceSuffix = ".startingNonce"
queueOriginSuffix = ".queueOrigin" queueOriginSuffix = ".queueOrigin"
chainIDSuffix = ".chainID" chainIDSuffix = ".chainID"
contractWriteSuffix = ".writeDeploymentAddrPath"
) )
// NewConfig returns a new tx spammer config // NewConfig returns a new tx spammer config
func NewTxParams() ([]TxParams, error) { func NewTxParams() ([]TxParams, error) {
viper.BindEnv("eth.txs", ETH_TX_LIST) viper.BindEnv("eth.txs", ETH_TX_LIST)
viper.BindEnv("eth.addrLogPath", ETH_ADDR_LOG)
addrLogPath := viper.GetString("eth.addrLogPath")
txs := viper.GetStringSlice("eth.txs") txs := viper.GetStringSlice("eth.txs")
txParams := make([]TxParams, len(txs)) txParams := make([]TxParams, len(txs))
for i, txName := range txs { for i, txName := range txs {
@ -129,7 +139,6 @@ func NewTxParams() ([]TxParams, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
chainID := viper.GetUint64(txName + chainIDSuffix)
// Get basic fields // Get basic fields
toStr := viper.GetString(txName + toSuffix) toStr := viper.GetString(txName + toSuffix)
@ -174,11 +183,16 @@ func NewTxParams() ([]TxParams, error) {
return nil, fmt.Errorf("unable to generate ecdsa key for tx %s", txName) return nil, fmt.Errorf("unable to generate ecdsa key for tx %s", txName)
} }
writePath := viper.GetString(txName + writeSenderPathSuffix) writePath := viper.GetString(txName + writeSenderPathSuffix)
if writePath != "" { if writePath == "" {
if err := crypto.SaveECDSA(writePath, key); err != nil { writePath = defaultGenKeyWritePathPrefix + txName
return nil, err
}
} }
if err := crypto.SaveECDSA(writePath, key); err != nil {
return nil, err
}
}
sender := crypto.PubkeyToAddress(key.PublicKey)
if err := writeSenderAddr(addrLogPath, sender); err != nil {
return nil, err
} }
// Attempt to load Optimism fields // Attempt to load Optimism fields
@ -214,33 +228,44 @@ func NewTxParams() ([]TxParams, error) {
} }
} }
// Load starting nonce and sending params
startingNonce := viper.GetUint64(txName + startingNonceSuffix)
frequency := viper.GetDuration(txName + frequencySuffix)
totalNumber := viper.GetUint64(txName + totalNumberSuffix)
delay := viper.GetDuration(txName + delaySuffix)
txParams[i] = TxParams{ txParams[i] = TxParams{
Client: rpcClient, Name: txName,
Type: txType, Client: rpcClient,
Name: txName, Type: txType,
To: toAddr, ChainID: viper.GetUint64(txName + chainIDSuffix),
Amount: amount, To: toAddr,
GasLimit: gasLimit, GasLimit: gasLimit,
GasPrice: gasPrice, GasPrice: gasPrice,
GasPremium: gasPremium, Amount: amount,
FeeCap: feeCap, Data: data,
Data: data, Sender: sender,
L1SenderAddr: l1Sender, L1SenderAddr: l1Sender,
L1RollupTxId: &l1rtid, L1RollupTxId: &l1rtid,
SigHashType: (types.SignatureHashType)(uint8(sigHashType)), SigHashType: (types.SignatureHashType)(uint8(sigHashType)),
Frequency: frequency, QueueOrigin: (types.QueueOrigin)(queueOrigin),
TotalNumber: totalNumber, GasPremium: gasPremium,
Delay: delay, FeeCap: feeCap,
StartingNonce: startingNonce, SenderKey: key,
QueueOrigin: (types.QueueOrigin)(queueOrigin), StartingNonce: viper.GetUint64(txName + startingNonceSuffix),
ChainID: chainID, ContractAddrWritePath: viper.GetString(txName + contractWriteSuffix),
Frequency: viper.GetDuration(txName + frequencySuffix),
TotalNumber: viper.GetUint64(txName + totalNumberSuffix),
Delay: viper.GetDuration(txName + delaySuffix),
} }
} }
return txParams, nil return txParams, nil
} }
func writeSenderAddr(filePath string, senderAddr common.Address) error {
if filePath == "" {
filePath = defaultAddrLogPath
}
f, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return err
}
if _, err := f.WriteString(senderAddr.Hex() + "\n"); err != nil {
return err
}
return f.Close()
}

View File

@ -18,24 +18,31 @@ package tx_spammer
import ( import (
"fmt" "fmt"
"os"
"sync/atomic"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
) )
const (
defaultDeploymentAddrLogPathPrefix = "./accounts/addresses/"
)
// TxGenerator generates and signs txs // TxGenerator generates and signs txs
type TxGenerator struct { type TxGenerator struct {
// keep track of account nonces locally so we aren't spamming to determine the nonce // keep track of account nonces locally so we aren't spamming to determine the nonce
// this assumes these accounts are not sending txs outside this process // this assumes these accounts are not sending txs outside this process
nonces map[common.Address]uint64 nonces map[common.Address]*uint64
} }
// NewTxGenerator creates a new tx generator // NewTxGenerator creates a new tx generator
func NewTxGenerator(params []TxParams) *TxGenerator { func NewTxGenerator(params []TxParams) *TxGenerator {
nonces := make(map[common.Address]uint64) nonces := make(map[common.Address]*uint64)
for _, p := range params { for _, p := range params {
nonces[p.Sender] = p.StartingNonce nonces[p.Sender] = &p.StartingNonce
} }
return &TxGenerator{ return &TxGenerator{
nonces: nonces, nonces: nonces,
@ -57,10 +64,14 @@ func (tg TxGenerator) GenerateTx(params TxParams) ([]byte, error) {
} }
func (gen TxGenerator) gen(params TxParams) ([]byte, error) { func (gen TxGenerator) gen(params TxParams) ([]byte, error) {
nonce := gen.nonces[params.Sender] nonce := atomic.AddUint64(gen.nonces[params.Sender], 1)
tx := new(types.Transaction) tx := new(types.Transaction)
if params.To == nil { if params.To == nil {
tx = types.NewContractCreation(nonce, params.Amount, params.GasLimit, params.GasPrice, params.Data, params.L1SenderAddr, params.L1RollupTxId, params.QueueOrigin) 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 {
return nil, err
}
} else { } else {
tx = types.NewTransaction(nonce, *params.To, params.Amount, params.GasLimit, params.GasPrice, params.Data, params.L1SenderAddr, params.L1RollupTxId, params.QueueOrigin, params.SigHashType) tx = types.NewTransaction(nonce, *params.To, params.Amount, params.GasLimit, params.GasPrice, params.Data, params.L1SenderAddr, params.L1RollupTxId, params.QueueOrigin, params.SigHashType)
} }
@ -76,7 +87,6 @@ func (gen TxGenerator) gen(params TxParams) ([]byte, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
gen.nonces[params.Sender]++
return txRlp, nil return txRlp, nil
} }
@ -84,3 +94,18 @@ 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 // 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") return nil, fmt.Errorf("1559 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()
}