Compare commits
7 Commits
telackey/r
...
main
Author | SHA1 | Date | |
---|---|---|---|
8f7e737896 | |||
|
24f7fd5e97 | ||
|
01cb9fb46c | ||
|
18518e7cb5 | ||
|
d1455a9cbd | ||
|
b699663536 | ||
e09975d0c8 |
6
.github/workflows/on-main.yml
vendored
6
.github/workflows/on-main.yml
vendored
@ -17,9 +17,9 @@ jobs:
|
||||
- name: Run docker build
|
||||
run: make docker-build
|
||||
- name: Tag docker image
|
||||
run: docker tag vulcanize/tx_spammer docker.pkg.github.com/vulcanize/tx_spammer/tx_spammer:${{steps.vars.outputs.sha}}
|
||||
run: docker tag cerc-io/tx-spammer git.vdb.to/cerc-io/tx-spammer/tx-spammer:${{steps.vars.outputs.sha}}
|
||||
- name: Docker Login
|
||||
run: echo ${{ secrets.GITHUB_TOKEN }} | docker login https://docker.pkg.github.com -u vulcanize --password-stdin
|
||||
run: echo ${{ secrets.GITHUB_TOKEN }} | docker login https://git.vdb.to -u cerc-io --password-stdin
|
||||
- name: Docker Push
|
||||
run: docker push docker.pkg.github.com/vulcanize/tx_spammer/tx_spammer:${{steps.vars.outputs.sha}}
|
||||
run: docker push git.vdb.to/cerc-io/tx-spammer/tx-spammer:${{steps.vars.outputs.sha}}
|
||||
|
||||
|
8
.github/workflows/publish.yml
vendored
8
.github/workflows/publish.yml
vendored
@ -13,13 +13,13 @@ jobs:
|
||||
echo ::set-output name=sha::$(echo ${GITHUB_SHA:0:7})
|
||||
echo ::set-output name=tag::$(echo ${GITHUB_REF#refs/tags/})
|
||||
- name: Docker Login to Github Registry
|
||||
run: echo ${{ secrets.GITHUB_TOKEN }} | docker login https://docker.pkg.github.com -u vulcanize --password-stdin
|
||||
run: echo ${{ secrets.GITHUB_TOKEN }} | docker login https://git.vdb.to -u vulcanize --password-stdin
|
||||
- name: Docker Pull
|
||||
run: docker pull docker.pkg.github.com/vulcanize/tx_spammer/tx_spammer:${{steps.vars.outputs.sha}}
|
||||
run: docker pull git.vdb.to/cerc-io/tx-spammer/tx-spammer:${{steps.vars.outputs.sha}}
|
||||
- name: Docker Login to Docker Registry
|
||||
run: echo ${{ secrets.VULCANIZEJENKINS_PAT }} | docker login -u vulcanizejenkins --password-stdin
|
||||
- name: Tag docker image
|
||||
run: docker tag docker.pkg.github.com/vulcanize/tx_spammer/tx_spammer:${{steps.vars.outputs.sha}} vulcanize/tx_spammer:${{steps.vars.outputs.tag}}
|
||||
run: docker tag git.vdb.to/cerc-io/tx-spammer/tx-spammer:${{steps.vars.outputs.sha}} cerc-io/tx-spammer:${{steps.vars.outputs.tag}}
|
||||
- name: Docker Push to Docker Hub
|
||||
run: docker push vulcanize/tx_spammer:${{steps.vars.outputs.tag}}
|
||||
run: docker push cerc-io/tx-spammer:${{steps.vars.outputs.tag}}
|
||||
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -14,4 +14,4 @@
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
.idea/
|
||||
tx_spammer
|
||||
tx-spammer
|
||||
|
25
Dockerfile
25
Dockerfile
@ -1,13 +1,17 @@
|
||||
FROM golang:1.19-alpine as builder
|
||||
FROM golang:1.21-alpine as builder
|
||||
|
||||
RUN apk --update --no-cache add make git g++ linux-headers
|
||||
RUN apk --update --no-cache add gcc libc-dev
|
||||
# DEBUG
|
||||
RUN apk add busybox-extras
|
||||
|
||||
# Get and build tx_spammer
|
||||
ADD . /go/src/github.com/vulcanize/tx_spammer
|
||||
WORKDIR /go/src/github.com/vulcanize/tx_spammer
|
||||
RUN GO111MODULE=on GCO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-extldflags "-static"' -o tx_spammer .
|
||||
# Get and build tx-spammer
|
||||
WORKDIR /go/src/github.com/cerc-io/tx-spammer
|
||||
|
||||
ENV GO111MODULE=on
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
COPY . .
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-extldflags "-static"' -o tx-spammer .
|
||||
|
||||
# app container
|
||||
FROM alpine
|
||||
@ -22,11 +26,12 @@ USER $USER
|
||||
|
||||
# chown first so dir is writable
|
||||
# note: using $USER is merged, but not in the stable release yet
|
||||
COPY --chown=5000:5000 --from=builder /go/src/github.com/vulcanize/tx_spammer/$CONFIG_FILE config.toml
|
||||
COPY --chown=5000:5000 --from=builder /go/src/github.com/vulcanize/tx_spammer/startup_script.sh .
|
||||
COPY --chown=5000:5000 --from=builder /go/src/github.com/cerc-io/tx-spammer/$CONFIG_FILE config.toml
|
||||
COPY --chown=5000:5000 --from=builder /go/src/github.com/cerc-io/tx-spammer/startup_script.sh .
|
||||
|
||||
# keep binaries immutable
|
||||
COPY --from=builder /go/src/github.com/vulcanize/tx_spammer/tx_spammer tx_spammer
|
||||
COPY --from=builder /go/src/github.com/vulcanize/tx_spammer/environments environments
|
||||
COPY --from=builder /go/src/github.com/cerc-io/tx-spammer/tx-spammer tx-spammer
|
||||
COPY --from=builder /go/src/github.com/cerc-io/tx-spammer/environments environments
|
||||
COPY --from=builder /go/src/github.com/cerc-io/tx-spammer/sol sol
|
||||
|
||||
ENTRYPOINT ["/app/startup_script.sh"]
|
||||
|
4
Makefile
4
Makefile
@ -1,11 +1,11 @@
|
||||
## Build docker image
|
||||
.PHONY: docker-build
|
||||
docker-build:
|
||||
docker build -t vulcanize/tx_spammer -f Dockerfile .
|
||||
docker build -t cerc/tx-spammer -f Dockerfile .
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
GO111MODULE=on go build -o tx_spammer .
|
||||
GO111MODULE=on go build -o tx-spammer .
|
||||
|
||||
.PHONY: contract
|
||||
contract:
|
||||
|
@ -1,9 +1,9 @@
|
||||
# tx_spammer
|
||||
# tx-spammer
|
||||
Tools to enable the semi-reproducible growth of a large and complex chain over RPC, for testing and benchmarking purposes
|
||||
|
||||
Usage:
|
||||
|
||||
`./tx_spammer autoSend --config=./environments/gen.toml`
|
||||
`./tx-spammer autoSend --config=./environments/gen.toml`
|
||||
|
||||
The `autoSend` command takes as input a .toml config of the below format, the fields can be overridden with the env variables in the comments.
|
||||
It uses the provided key pairs and configuraiton parameters to generate and deploy a number of contracts with a simple interface for `Put`ing to a dynamic data structure.
|
||||
|
@ -21,7 +21,9 @@ import (
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/vulcanize/tx_spammer/pkg/auto"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/cerc-io/tx-spammer/pkg/auto"
|
||||
)
|
||||
|
||||
// autoSendCmd represents the autoSend command
|
||||
@ -38,11 +40,18 @@ Support standard, optimism L2, optimism L1 to L2, and EIP1559 transactions`,
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
autoSendCmd.PersistentFlags().Bool("stop-on-error", true,
|
||||
"stop service when SendTransaction returns an error")
|
||||
viper.BindPFlag(auto.SpammerStopOnError, autoSendCmd.PersistentFlags().Lookup("stop-on-error"))
|
||||
}
|
||||
|
||||
func autoSend() {
|
||||
config, err := auto.NewConfig()
|
||||
if err != nil {
|
||||
logWithCommand.Fatal(err)
|
||||
}
|
||||
logrus.WithFields(logrus.Fields{"config": config}).Debug("Loaded config")
|
||||
txSpammer := auto.NewTxSpammer(config)
|
||||
quitChan := make(chan bool)
|
||||
doneChan, err := txSpammer.Loop(quitChan)
|
||||
|
@ -33,7 +33,7 @@ var (
|
||||
)
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "tx_spammer",
|
||||
Use: "tx-spammer",
|
||||
PersistentPreRun: initFuncs,
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ func Execute() {
|
||||
}
|
||||
|
||||
func initFuncs(cmd *cobra.Command, args []string) {
|
||||
logfile := viper.GetString("logfile")
|
||||
logfile := viper.GetString("log.file")
|
||||
if logfile != "" {
|
||||
file, err := os.OpenFile(logfile,
|
||||
os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
@ -65,13 +65,13 @@ func initFuncs(cmd *cobra.Command, args []string) {
|
||||
}
|
||||
|
||||
func logLevel() error {
|
||||
viper.BindEnv("log.level", "LOGRUS_LEVEL")
|
||||
viper.BindEnv("log.level", "LOG_LEVEL")
|
||||
lvl, err := log.ParseLevel(viper.GetString("log.level"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.SetLevel(lvl)
|
||||
if lvl > log.InfoLevel {
|
||||
if lvl > log.DebugLevel {
|
||||
log.SetReportCaller(true)
|
||||
}
|
||||
log.Info("Log level set to ", lvl.String())
|
||||
|
@ -22,7 +22,7 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/vulcanize/tx_spammer/pkg/manual"
|
||||
"github.com/cerc-io/tx-spammer/pkg/manual"
|
||||
)
|
||||
|
||||
// sendTxsCmd represents the sendTxs command
|
||||
|
@ -1,65 +1,40 @@
|
||||
[eth]
|
||||
txs = ["L2ContractDeployment", "L2ContractPutCall", "L2ContractGetCall"] # $ETH_TX_LIST
|
||||
addrLogPath = "" # ETH_ADDR_LOG
|
||||
keyDirPath = "./keys/" # path to the directory with all of the key pairs to use - env: $ETH_KEY_DIR_PATH
|
||||
httpPath = "http://localhost:8545" # http url for the node we wish to send all our transactions to - env: $ETH_HTTP_PATH
|
||||
|
||||
[L2ContractDeployment]
|
||||
type = "L2"
|
||||
httpPath = ""
|
||||
chainID = 420
|
||||
to = ""
|
||||
amount = "0"
|
||||
gasLimit = 0
|
||||
gasPrice = "0"
|
||||
data = ""
|
||||
senderKeyPath = ""
|
||||
writeSenderPath = ""
|
||||
writeDeploymentAddrPath = ""
|
||||
frequency = 1
|
||||
totalNumber = 1
|
||||
delay = 0
|
||||
l1Sender = ""
|
||||
l1RollupTxId = 0
|
||||
sigHashType = 0
|
||||
queueOrigin = 0
|
||||
[deployment]
|
||||
number = 1 # number of contracts we will deploy for each key at keyPath - env: $ETH_DEPLOYMENT_NUMBER
|
||||
binPath = "sol/build/Test.bin" # hex data for the contracts we will deploy - env: $ETH_DEPLOYMENT_BIN_PATH
|
||||
gasLimit = 100000 # gasLimit to use for the deployment txs - env: $ETH_DEPLOYMENT_GAS_LIMIT
|
||||
gasTipCap = "1000000000" # gasTipCap to use for the deployment txs - env: $ETH_DEPLOYMENT_GAS_TIP_CAP
|
||||
gasFeeCap = "1000000007" # gasFeeCap to use for the deployment txs - env: $ETH_DEPLOYMENT_GAS_FEE_CAP
|
||||
|
||||
[L2ContractPutCall]
|
||||
type = "L2"
|
||||
httpPath = ""
|
||||
chainID = 420
|
||||
to = ""
|
||||
amount = "0"
|
||||
gasLimit = 0
|
||||
gasPrice = "0"
|
||||
data = ""
|
||||
senderKeyPath = ""
|
||||
writeSenderPath = ""
|
||||
frequency = 15
|
||||
totalNumber = 1
|
||||
delay = 60
|
||||
l1Sender = ""
|
||||
l1RollupTxId = 0
|
||||
sigHashType = 0
|
||||
queueOrigin = 0
|
||||
[contractSpammer]
|
||||
frequency = -1 # how often to send a transaction (in milliseconds, -1 for no delay) - env: $ETH_CALL_FREQ
|
||||
totalNumber = -1 # total number of transactions to send (per sender, -1 for unlimited) - 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 = 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
|
||||
|
||||
[L2ContractGetCall]
|
||||
type = "L2"
|
||||
httpPath = ""
|
||||
chainID = 420
|
||||
to = ""
|
||||
amount = "0"
|
||||
gasLimit = 0
|
||||
gasPrice = "0"
|
||||
data = ""
|
||||
senderKeyPath = ""
|
||||
writeSenderPath = ""
|
||||
frequency = 60
|
||||
totalNumber = 2
|
||||
delay = 30
|
||||
l1Sender = ""
|
||||
l1RollupTxId = 0
|
||||
sigHashType = 0
|
||||
queueOrigin = 0
|
||||
[sendSpammer]
|
||||
frequency = -1 # how often to send a transaction (in milliseconds, -1 for no delay) - env: $ETH_SEND_FREQ
|
||||
totalNumber = -1 # total number of transactions to send (per sender, -1 for unlimited) - 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
|
||||
gasTipCap = "1000000000" # gasTipCap to use for the eth transfer txs - env: $ETH_SEND_GAS_TIP_CAP
|
||||
gasFeeCap = "1000000007" # gasFeeCap to use for the eth transfer txs - env: $ETH_SEND_GAS_FEE_CAP
|
||||
|
||||
[log]
|
||||
level = "info"
|
||||
file = ""
|
||||
[blobSpammer]
|
||||
frequency = 500 # how often to send a transaction (in milliseconds, -1 for no delay) - env: $ETH_SEND_FREQ
|
||||
totalNumber = -1 # total number of transactions to send (per sender, -1 for unlimited) - 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 blob txs - env: $ETH_SEND_GAS_LIMIT
|
||||
gasTipCap = "1000000000" # gasTipCap to use for the blob txs - env: $ETH_SEND_GAS_TIP_CAP
|
||||
gasFeeCap = "1000000007" # gasFeeCap to use for the blob txs - env: $ETH_SEND_GAS_FEE_CAP
|
||||
blobCount = 1 # number of blob sidecars to send with blob txs - env: $ETH_SEND_BLOB_LENGTH
|
||||
blobFeeCap = "1000000" # blobFeeCap to use for the eth blob txs - env: $ETH_SEND_BLOB_FEE_CAP
|
||||
|
@ -1,30 +0,0 @@
|
||||
[eth]
|
||||
keyDirPath = "./keys/" # path to the directory with all of the key pairs to use - env: $ETH_KEY_DIR_PATH
|
||||
httpPath = "http://localhost:8545" # http url for the node we wish to send all our transactions to - env: $ETH_HTTP_PATH
|
||||
|
||||
[deployment]
|
||||
number = 1 # number of contracts we will deploy for each key at keyPath - env: $ETH_DEPLOYMENT_NUMBER
|
||||
binPath = "sol/build/Test.bin" # hex data for the contracts we will deploy - env: $ETH_DEPLOYMENT_BIN_PATH
|
||||
gasLimit = 100000 # gasLimit to use for the deployment txs - env: $ETH_DEPLOYMENT_GAS_LIMIT
|
||||
gasTipCap = "1000000000" # gasTipCap to use for the deployment txs - env: $ETH_DEPLOYMENT_GAS_TIP_CAP
|
||||
gasFeeCap = "1000000007" # gasFeeCap to use for the deployment txs - env: $ETH_DEPLOYMENT_GAS_FEE_CAP
|
||||
|
||||
[contractSpammer]
|
||||
frequency = -1 # how often to send a transaction (in milliseconds, -1 for no delay) - env: $ETH_CALL_FREQ
|
||||
totalNumber = -1 # total number of transactions to send (per sender, -1 for unlimited) - 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 = 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 = -1 # how often to send a transaction (in milliseconds, -1 for no delay) - env: $ETH_SEND_FREQ
|
||||
totalNumber = -1 # total number of transactions to send (per sender, -1 for unlimited) - 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
|
||||
gasTipCap = "1000000000" # gasTipCap to use for the eth transfer txs - env: $ETH_SEND_GAS_TIP_CAP
|
||||
gasFeeCap = "1000000007" # gasFeeCap to use for the eth transfer txs - env: $ETH_SEND_GAS_FEE_CAP
|
128
go.mod
128
go.mod
@ -1,57 +1,85 @@
|
||||
module github.com/vulcanize/tx_spammer
|
||||
module github.com/cerc-io/tx-spammer
|
||||
|
||||
go 1.13
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/Azure/azure-pipeline-go v0.2.2 // indirect
|
||||
github.com/Azure/azure-storage-blob-go v0.7.0 // indirect
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.0 // indirect
|
||||
github.com/StackExchange/wmi v1.2.1 // indirect
|
||||
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847 // indirect
|
||||
github.com/aws/aws-sdk-go v1.25.48 // indirect
|
||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c // indirect
|
||||
github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6 // indirect
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.2.1 // indirect
|
||||
github.com/coreos/bbolt v1.3.2 // indirect
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e // indirect
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
|
||||
github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa // indirect
|
||||
github.com/ethereum/go-ethereum v1.10.25
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-stack/stack v1.8.1 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect
|
||||
github.com/jmoiron/sqlx v1.2.0 // indirect
|
||||
github.com/jonboulle/clockwork v0.1.0 // indirect
|
||||
github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222 // indirect
|
||||
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff // indirect
|
||||
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521 // indirect
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/soheilhy/cmux v0.1.4 // indirect
|
||||
github.com/spf13/afero v1.9.2 // indirect
|
||||
github.com/ethereum/go-ethereum v1.14.5
|
||||
github.com/holiman/uint256 v1.2.4
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/cobra v1.6.0
|
||||
github.com/spf13/viper v1.13.0
|
||||
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 // indirect
|
||||
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
||||
github.com/tklauser/numcpus v0.5.0 // indirect
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect
|
||||
github.com/urfave/cli v1.22.1 // indirect
|
||||
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 // indirect
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
go.etcd.io/bbolt v1.3.2 // indirect
|
||||
golang.org/x/crypto v0.0.0-20221012134737-56aed061732a // indirect
|
||||
golang.org/x/sys v0.1.0 // indirect
|
||||
golang.org/x/text v0.4.0 // indirect
|
||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200316214253-d7b0ff38cac9 // indirect
|
||||
gopkg.in/resty.v1 v1.12.0 // indirect
|
||||
gopkg.in/sourcemap.v1 v1.0.5 // indirect
|
||||
gopkg.in/urfave/cli.v1 v1.20.0 // indirect
|
||||
gotest.tools v2.2.0+incompatible // indirect
|
||||
)
|
||||
|
||||
replace github.com/ethereum/go-ethereum v1.9.10 => github.com/vulcanize/go-ethereum v1.9.10-optimism-0.0.2
|
||||
require (
|
||||
github.com/DataDog/zstd v1.5.2 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/VictoriaMetrics/fastcache v1.12.2 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.10.0 // indirect
|
||||
github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6 // indirect
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.2.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cockroachdb/errors v1.11.1 // indirect
|
||||
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
|
||||
github.com/cockroachdb/pebble v1.1.0 // indirect
|
||||
github.com/cockroachdb/redact v1.1.5 // indirect
|
||||
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
|
||||
github.com/consensys/bavard v0.1.13 // indirect
|
||||
github.com/consensys/gnark-crypto v0.12.1 // indirect
|
||||
github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c // indirect
|
||||
github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect
|
||||
github.com/deckarep/golang-set/v2 v2.6.0 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
|
||||
github.com/ethereum/c-kzg-4844 v1.0.0 // indirect
|
||||
github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/getsentry/sentry-go v0.18.0 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/gofrs/flock v0.8.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/klauspost/compress v1.15.15 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.13 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/mmcloughlin/addchain v0.4.0 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/prometheus/client_golang v1.14.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.39.0 // indirect
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.9.0 // indirect
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
|
||||
github.com/spf13/afero v1.9.2 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/subosito/gotenv v1.4.1 // indirect
|
||||
github.com/supranational/blst v0.3.11 // indirect
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
golang.org/x/crypto v0.22.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
rsc.io/tmplfunc v0.0.3 // indirect
|
||||
)
|
||||
|
2
main.go
2
main.go
@ -15,7 +15,7 @@
|
||||
|
||||
package main
|
||||
|
||||
import "github.com/vulcanize/tx_spammer/cmd"
|
||||
import "github.com/cerc-io/tx-spammer/cmd"
|
||||
|
||||
func main() {
|
||||
cmd.Execute()
|
||||
|
@ -21,7 +21,6 @@ import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"fmt"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"math/big"
|
||||
@ -29,13 +28,16 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/holiman/uint256"
|
||||
|
||||
"github.com/cerc-io/tx-spammer/pkg/shared"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/vulcanize/tx_spammer/pkg/shared"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -49,10 +51,12 @@ func init() {
|
||||
|
||||
// Config holds all the parameters for the auto tx spammer
|
||||
type Config struct {
|
||||
// Whether to stop service on any error from tx generation or sending
|
||||
StopOnSendError bool
|
||||
|
||||
// HTTP client for sending transactions
|
||||
RpcClient *rpc.Client
|
||||
EthClient *ethclient.Client
|
||||
ChainID *big.Int
|
||||
|
||||
// Key pairs for the accounts we will use to deploy contracts and send txs
|
||||
SenderKeys []*ecdsa.PrivateKey
|
||||
@ -69,6 +73,9 @@ type Config struct {
|
||||
|
||||
// Configuration for the eth transfer txs
|
||||
SendConfig *SendConfig
|
||||
|
||||
// Configuration for the blob txs
|
||||
BlobTxConfig *BlobTxConfig
|
||||
}
|
||||
|
||||
// DeploymentConfig holds the parameters for the contract deployment contracts
|
||||
@ -110,7 +117,24 @@ type SendConfig struct {
|
||||
TotalNumber int
|
||||
}
|
||||
|
||||
// SendConfig holds the parameters for the blob txs
|
||||
type BlobTxConfig struct {
|
||||
ChainID *big.Int
|
||||
GasLimit uint64
|
||||
GasFeeCap *big.Int
|
||||
GasTipCap *big.Int
|
||||
Amount *big.Int
|
||||
|
||||
BlobFeeCap *uint256.Int
|
||||
BlobCount int
|
||||
|
||||
Frequency time.Duration
|
||||
TotalNumber int
|
||||
}
|
||||
|
||||
func NewConfig() (*Config, error) {
|
||||
stopOnError := viper.GetBool(SpammerStopOnError)
|
||||
|
||||
// Initialize rpc client
|
||||
httpPathStr := viper.GetString(ethHttpPath)
|
||||
if httpPathStr == "" {
|
||||
@ -180,8 +204,15 @@ func NewConfig() (*Config, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Load blob tx config
|
||||
blobTxConfig, err := NewBlobTxConfig(chainID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Assemble and return
|
||||
return &Config{
|
||||
StopOnSendError: stopOnError,
|
||||
RpcClient: rpcClient,
|
||||
EthClient: ethClient,
|
||||
SenderKeys: keys,
|
||||
@ -190,6 +221,7 @@ func NewConfig() (*Config, error) {
|
||||
DeploymentConfig: deploymentConfig,
|
||||
CallConfig: callConfig,
|
||||
SendConfig: sendConfig,
|
||||
BlobTxConfig: blobTxConfig,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -291,3 +323,37 @@ func NewSendConfig(chainID *big.Int) (*SendConfig, error) {
|
||||
TotalNumber: totalNumber,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewBlobTxConfig constructs and returns a new SendConfig
|
||||
func NewBlobTxConfig(chainID *big.Int) (*BlobTxConfig, error) {
|
||||
amountStr := viper.GetString(ethBlobTxAmount)
|
||||
amount, ok := new(big.Int).SetString(amountStr, 10)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unable to convert amount string (%s) into big.Int", amountStr)
|
||||
}
|
||||
|
||||
var frequency time.Duration
|
||||
tmpFreq := viper.GetDuration(ethBlobTxFrequency)
|
||||
if tmpFreq <= 0 {
|
||||
frequency = time.Microsecond
|
||||
} else {
|
||||
frequency = tmpFreq * time.Millisecond
|
||||
}
|
||||
|
||||
totalNumber := viper.GetInt(ethBlobTxTotalNumber)
|
||||
if totalNumber < 0 {
|
||||
totalNumber = math.MaxInt
|
||||
}
|
||||
|
||||
return &BlobTxConfig{
|
||||
ChainID: chainID,
|
||||
Frequency: frequency,
|
||||
Amount: amount,
|
||||
GasLimit: viper.GetUint64(ethBlobTxGasLimit),
|
||||
GasFeeCap: big.NewInt(viper.GetInt64(ethBlobTxGasFeeCap)),
|
||||
GasTipCap: big.NewInt(viper.GetInt64(ethBlobTxGasTipCap)),
|
||||
BlobFeeCap: uint256.MustFromBig(big.NewInt(viper.GetInt64(ethBlobTxBlobFeeCap))),
|
||||
BlobCount: viper.GetInt(ethBlobTxBlobCount),
|
||||
TotalNumber: totalNumber,
|
||||
}, nil
|
||||
}
|
||||
|
@ -18,12 +18,13 @@ package auto
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"github.com/sirupsen/logrus"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/cerc-io/tx-spammer/pkg/shared"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/vulcanize/tx_spammer/pkg/shared"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -59,7 +60,7 @@ func (cp *ContractDeployer) Deploy() ([]common.Address, error) {
|
||||
<-ticker.C
|
||||
for i, key := range cp.senderKeys {
|
||||
logrus.Debugf("Generating contract deployment for %s.", cp.senderAddrs[i].Hex())
|
||||
signedTx, contractAddr, err := cp.txGenerator.GenerateTx(&GenParams{
|
||||
signedTx, contractAddr, err := cp.txGenerator.createTx(&GenParams{
|
||||
ChainID: cp.config.ChainID,
|
||||
Sender: cp.senderAddrs[i],
|
||||
SenderKey: key,
|
||||
|
@ -19,9 +19,12 @@ package auto
|
||||
import "github.com/spf13/viper"
|
||||
|
||||
const (
|
||||
SPAMMER_STOP_ON_ERROR = "SPAMMER_STOP_ON_ERROR"
|
||||
|
||||
// env variables
|
||||
ETH_KEY_DIR_PATH = "ETH_KEY_DIR_PATH"
|
||||
ETH_HTTP_PATH = "ETH_HTTP_PATH"
|
||||
ETH_CONTRACT_ADDR_PATH = "ETH_CONTRACT_ADDR_PATH"
|
||||
|
||||
ETH_DEPLOYMENT_NUMBER = "ETH_DEPLOYMENT_NUMBER"
|
||||
ETH_DEPLOYMENT_BIN_PATH = "ETH_DEPLOYMENT_BIN_PATH"
|
||||
@ -44,9 +47,21 @@ const (
|
||||
ETH_SEND_GAS_FEE_CAP = "ETH_SEND_GAS_FEE_CAP"
|
||||
ETH_SEND_GAS_TIP_CAP = "ETH_SEND_GAS_TIP_CAP"
|
||||
|
||||
ETH_BLOBTX_FREQ = "ETH_BLOBTX_FREQ"
|
||||
ETH_BLOBTX_TOTAL_NUMBER = "ETH_BLOBTX_TOTAL_NUMBER"
|
||||
ETH_BLOBTX_AMOUNT = "ETH_BLOBTX_AMOUNT"
|
||||
ETH_BLOBTX_GAS_LIMIT = "ETH_BLOBTX_GAS_LIMIT"
|
||||
ETH_BLOBTX_GAS_FEE_CAP = "ETH_BLOBTX_GAS_FEE_CAP"
|
||||
ETH_BLOBTX_GAS_TIP_CAP = "ETH_BLOBTX_GAS_TIP_CAP"
|
||||
ETH_BLOBTX_BLOB_FEE_CAP = "ETH_BLOBTX_BLOB_FEE_CAP"
|
||||
ETH_BLOBTX_BLOB_COUNT = "ETH_BLOBTX_BLOB_COUNT"
|
||||
|
||||
// toml bindings
|
||||
SpammerStopOnError = "service.stopOnError"
|
||||
|
||||
ethKeyDirPath = "eth.keyDirPath"
|
||||
ethHttpPath = "eth.httpPath"
|
||||
ethContractAddrPath = "eth.contractAddrPath"
|
||||
|
||||
ethDeploymentBinPath = "deployment.binPath"
|
||||
ethDeploymentNumber = "deployment.number"
|
||||
@ -68,11 +83,23 @@ const (
|
||||
ethSendGasLimit = "sendSpammer.gasLimit"
|
||||
ethSendGasFeeCap = "sendSpammer.gasFeeCap"
|
||||
ethSendGasTipCap = "sendSpammer.gasTipCap"
|
||||
|
||||
ethBlobTxFrequency = "blobSpammer.frequency"
|
||||
ethBlobTxTotalNumber = "blobSpammer.totalNumber"
|
||||
ethBlobTxAmount = "blobSpammer.amount"
|
||||
ethBlobTxGasLimit = "blobSpammer.gasLimit"
|
||||
ethBlobTxGasFeeCap = "blobSpammer.gasFeeCap"
|
||||
ethBlobTxGasTipCap = "blobSpammer.gasTipCap"
|
||||
ethBlobTxBlobFeeCap = "blobSpammer.blobFeeCap"
|
||||
ethBlobTxBlobCount = "blobSpammer.blobCount"
|
||||
)
|
||||
|
||||
func bindEnv() {
|
||||
viper.BindEnv(SpammerStopOnError, SPAMMER_STOP_ON_ERROR)
|
||||
|
||||
viper.BindEnv(ethKeyDirPath, ETH_KEY_DIR_PATH)
|
||||
viper.BindEnv(ethHttpPath, ETH_HTTP_PATH)
|
||||
viper.BindEnv(ethContractAddrPath, ETH_CONTRACT_ADDR_PATH)
|
||||
|
||||
viper.BindEnv(ethDeploymentNumber, ETH_DEPLOYMENT_NUMBER)
|
||||
viper.BindEnv(ethDeploymentBinPath, ETH_DEPLOYMENT_BIN_PATH)
|
||||
@ -95,4 +122,13 @@ func bindEnv() {
|
||||
viper.BindEnv(ethSendGasFeeCap, ETH_SEND_GAS_FEE_CAP)
|
||||
viper.BindEnv(ethSendGasTipCap, ETH_SEND_GAS_TIP_CAP)
|
||||
viper.BindEnv(ethSendGasLimit, ETH_CALL_GAS_LIMIT)
|
||||
|
||||
viper.BindEnv(ethBlobTxFrequency, ETH_BLOBTX_FREQ)
|
||||
viper.BindEnv(ethBlobTxTotalNumber, ETH_BLOBTX_TOTAL_NUMBER)
|
||||
viper.BindEnv(ethBlobTxAmount, ETH_BLOBTX_AMOUNT)
|
||||
viper.BindEnv(ethBlobTxGasLimit, ETH_BLOBTX_GAS_LIMIT)
|
||||
viper.BindEnv(ethBlobTxGasFeeCap, ETH_BLOBTX_GAS_FEE_CAP)
|
||||
viper.BindEnv(ethBlobTxGasTipCap, ETH_BLOBTX_GAS_TIP_CAP)
|
||||
viper.BindEnv(ethBlobTxBlobFeeCap, ETH_BLOBTX_BLOB_FEE_CAP)
|
||||
viper.BindEnv(ethBlobTxBlobCount, ETH_BLOBTX_BLOB_COUNT)
|
||||
}
|
||||
|
@ -17,10 +17,12 @@
|
||||
package auto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cerc-io/tx-spammer/pkg/shared"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/vulcanize/tx_spammer/pkg/shared"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// EthSender sends eth value transfer txs
|
||||
@ -36,24 +38,25 @@ 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 *types.Transaction, sentCh chan *types.Transaction) (<-chan bool, <-chan error) {
|
||||
func (s *EthSender) Send(quitChan <-chan bool, txChan <-chan *types.Transaction, sentCh chan<- *types.Transaction) (<-chan bool, <-chan error) {
|
||||
// err channel returned to calling context
|
||||
errChan := make(chan error)
|
||||
doneChan := make(chan bool)
|
||||
go func() {
|
||||
defer close(doneChan)
|
||||
defer close(errChan)
|
||||
counter := 0
|
||||
for {
|
||||
select {
|
||||
case tx := <-txChan:
|
||||
counter += 1
|
||||
if err := shared.SendTransaction(s.client, tx); err != nil {
|
||||
errChan <- err
|
||||
errChan <- fmt.Errorf("%w: tx = %s", err, tx.Hash())
|
||||
} else {
|
||||
sentCh <- tx
|
||||
}
|
||||
case <-quitChan:
|
||||
logrus.Infof("quitting Send loop (sent %d)", counter)
|
||||
log.Infof("quitting Send loop (sent %d)", counter)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,8 @@ package auto
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cerc-io/tx-spammer/pkg/shared"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/vulcanize/tx_spammer/pkg/shared"
|
||||
)
|
||||
|
||||
// Spammer underlying struct type for spamming service
|
||||
@ -58,38 +58,35 @@ func (s *Spammer) Loop(quitChan <-chan bool) (<-chan bool, error) {
|
||||
sendDoneChan, sendErrChan := s.Sender.Send(senderQuit, txChan, watcher.PendingTxCh)
|
||||
|
||||
go func() {
|
||||
defer close(doneChan)
|
||||
for {
|
||||
select {
|
||||
case err := <-genErrChan:
|
||||
<-genDoneChan
|
||||
recoverClose(senderQuit)
|
||||
<-sendDoneChan
|
||||
recoverClose(watcher.quitCh)
|
||||
close(doneChan)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
for err := range genErrChan {
|
||||
logrus.Errorf("tx generation error: %v", err)
|
||||
recoverClose(genQuit)
|
||||
<-genDoneChan
|
||||
recoverClose(senderQuit)
|
||||
<-sendDoneChan
|
||||
recoverClose(watcher.quitCh)
|
||||
case err := <-sendErrChan:
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
for err := range sendErrChan {
|
||||
logrus.Errorf("tx sending error: %v", err)
|
||||
if s.config.StopOnSendError {
|
||||
recoverClose(genQuit)
|
||||
<-genDoneChan
|
||||
recoverClose(senderQuit)
|
||||
<-sendDoneChan
|
||||
recoverClose(watcher.quitCh)
|
||||
case <-quitChan:
|
||||
logrus.Info("shutting down tx spammer")
|
||||
recoverClose(genQuit)
|
||||
<-genDoneChan
|
||||
recoverClose(senderQuit)
|
||||
<-sendDoneChan
|
||||
recoverClose(watcher.quitCh)
|
||||
case <-sendDoneChan:
|
||||
recoverClose(watcher.quitCh)
|
||||
return
|
||||
case <-genDoneChan:
|
||||
recoverClose(senderQuit)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
<-quitChan
|
||||
logrus.Info("shutting down tx spammer")
|
||||
recoverClose(genQuit)
|
||||
}()
|
||||
|
||||
return doneChan, nil
|
||||
}
|
||||
|
||||
|
@ -19,16 +19,20 @@ package auto
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"errors"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
||||
"github.com/holiman/uint256"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/cerc-io/tx-spammer/pkg/shared"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/vulcanize/tx_spammer/pkg/shared"
|
||||
)
|
||||
|
||||
// TxGenerator generates and signs txs
|
||||
@ -73,6 +77,14 @@ type GenParams struct {
|
||||
To *common.Address
|
||||
Amount *big.Int
|
||||
Data []byte
|
||||
|
||||
BlobParams *BlobParams
|
||||
}
|
||||
|
||||
type BlobParams struct {
|
||||
BlobFeeCap *uint256.Int
|
||||
BlobHashes []common.Hash
|
||||
Sidecar *types.BlobTxSidecar
|
||||
}
|
||||
|
||||
func (gen *TxGenerator) GenerateTxs(quitChan <-chan bool) (<-chan bool, <-chan *types.Transaction, <-chan error) {
|
||||
@ -88,10 +100,22 @@ func (gen *TxGenerator) GenerateTxs(quitChan <-chan bool) (<-chan bool, <-chan *
|
||||
wg.Add(1)
|
||||
go gen.genCalls(wg, txChan, errChan, quitChan, sender, gen.config.SenderAddrs[i], gen.config.CallConfig)
|
||||
}
|
||||
if gen.config.BlobTxConfig.TotalNumber > 0 {
|
||||
wg.Add(1)
|
||||
go gen.genBlobTx(senderArgs{
|
||||
wg: wg,
|
||||
txChan: txChan,
|
||||
errChan: errChan,
|
||||
quitChan: quitChan,
|
||||
senderKey: sender,
|
||||
senderAddr: gen.config.SenderAddrs[i],
|
||||
}, gen.config.BlobTxConfig)
|
||||
}
|
||||
}
|
||||
doneChan := make(chan bool)
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(errChan)
|
||||
close(doneChan)
|
||||
}()
|
||||
return doneChan, txChan, errChan
|
||||
@ -105,7 +129,7 @@ func (gen *TxGenerator) genSends(wg *sync.WaitGroup, txChan chan<- *types.Transa
|
||||
case <-ticker.C:
|
||||
dst := crypto.CreateAddress(receiverAddressSeed, uint64(i))
|
||||
log.Debugf("Generating send from %s to %s.", senderAddr.Hex(), dst.Hex())
|
||||
rawTx, _, err := gen.GenerateTx(&GenParams{
|
||||
params := &GenParams{
|
||||
ChainID: sendConfig.ChainID,
|
||||
To: &dst,
|
||||
Sender: senderAddr,
|
||||
@ -114,7 +138,8 @@ func (gen *TxGenerator) genSends(wg *sync.WaitGroup, txChan chan<- *types.Transa
|
||||
GasFeeCap: sendConfig.GasFeeCap,
|
||||
GasTipCap: sendConfig.GasTipCap,
|
||||
Amount: sendConfig.Amount,
|
||||
})
|
||||
}
|
||||
rawTx, _, err := gen.createTx(params)
|
||||
if err != nil {
|
||||
errChan <- err
|
||||
continue
|
||||
@ -140,7 +165,7 @@ func (gen *TxGenerator) genCalls(wg *sync.WaitGroup, txChan chan<- *types.Transa
|
||||
errChan <- err
|
||||
continue
|
||||
}
|
||||
rawTx, _, err := gen.GenerateTx(&GenParams{
|
||||
rawTx, _, err := gen.createTx(&GenParams{
|
||||
Sender: senderAddr,
|
||||
SenderKey: senderKey,
|
||||
GasLimit: callConfig.GasLimit,
|
||||
@ -161,13 +186,71 @@ func (gen *TxGenerator) genCalls(wg *sync.WaitGroup, txChan chan<- *types.Transa
|
||||
log.Info("Done generating calls for ", senderAddr.Hex())
|
||||
}
|
||||
|
||||
// GenerateTx generates tx from the provided params
|
||||
func (gen *TxGenerator) GenerateTx(params *GenParams) (*types.Transaction, common.Address, error) {
|
||||
type senderArgs struct {
|
||||
wg *sync.WaitGroup
|
||||
txChan chan<- *types.Transaction
|
||||
errChan chan<- error
|
||||
quitChan <-chan bool
|
||||
senderKey *ecdsa.PrivateKey
|
||||
senderAddr common.Address
|
||||
}
|
||||
|
||||
func (gen *TxGenerator) genBlobTx(args senderArgs, blobTxConfig *BlobTxConfig) {
|
||||
defer args.wg.Done()
|
||||
ticker := time.NewTicker(blobTxConfig.Frequency)
|
||||
for i := 0; i < blobTxConfig.TotalNumber; i++ {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
dst := crypto.CreateAddress(receiverAddressSeed, uint64(i))
|
||||
log.Debugf("Generating send from %s to %s.", args.senderAddr, dst)
|
||||
params := &GenParams{
|
||||
ChainID: blobTxConfig.ChainID,
|
||||
To: &dst,
|
||||
Sender: args.senderAddr,
|
||||
SenderKey: args.senderKey,
|
||||
GasLimit: blobTxConfig.GasLimit,
|
||||
GasFeeCap: blobTxConfig.GasFeeCap,
|
||||
GasTipCap: blobTxConfig.GasTipCap,
|
||||
Amount: blobTxConfig.Amount,
|
||||
}
|
||||
blobdata := make([]byte, blobTxConfig.BlobCount)
|
||||
for i := range blobdata {
|
||||
blobdata[i] = byte(i + 1)
|
||||
}
|
||||
sidecar, err := makeSidecar(blobdata)
|
||||
if err != nil {
|
||||
args.errChan <- err
|
||||
continue
|
||||
}
|
||||
params.BlobParams = &BlobParams{
|
||||
BlobFeeCap: blobTxConfig.BlobFeeCap,
|
||||
BlobHashes: sidecar.BlobHashes(),
|
||||
Sidecar: sidecar,
|
||||
}
|
||||
|
||||
rawTx, _, err := gen.createTx(params)
|
||||
if err != nil {
|
||||
args.errChan <- err
|
||||
continue
|
||||
}
|
||||
args.txChan <- rawTx
|
||||
case <-args.quitChan:
|
||||
return
|
||||
}
|
||||
}
|
||||
log.Info("Done generating sends for ", args.senderAddr)
|
||||
}
|
||||
|
||||
// createTx generates tx from the provided params
|
||||
func (gen *TxGenerator) createTx(params *GenParams) (*types.Transaction, common.Address, error) {
|
||||
nonce := gen.claimNonce(params.Sender)
|
||||
tx := new(types.Transaction)
|
||||
var contractAddr common.Address
|
||||
var err error
|
||||
if params.To == nil {
|
||||
if params.BlobParams != nil {
|
||||
return nil, common.Address{}, errors.New("BlobTx cannot be used for contract creation")
|
||||
}
|
||||
tx = types.NewTx(
|
||||
&types.DynamicFeeTx{
|
||||
ChainID: params.ChainID,
|
||||
@ -183,7 +266,7 @@ func (gen *TxGenerator) GenerateTx(params *GenParams) (*types.Transaction, commo
|
||||
if err != nil {
|
||||
return nil, common.Address{}, err
|
||||
}
|
||||
} else {
|
||||
} else if params.BlobParams == nil {
|
||||
tx = types.NewTx(
|
||||
&types.DynamicFeeTx{
|
||||
ChainID: params.ChainID,
|
||||
@ -195,10 +278,53 @@ func (gen *TxGenerator) GenerateTx(params *GenParams) (*types.Transaction, commo
|
||||
Value: params.Amount,
|
||||
Data: params.Data,
|
||||
})
|
||||
} else {
|
||||
tx = types.NewTx(
|
||||
&types.BlobTx{
|
||||
ChainID: uint256.MustFromBig(params.ChainID),
|
||||
Nonce: nonce,
|
||||
Gas: params.GasLimit,
|
||||
GasTipCap: uint256.MustFromBig(params.GasTipCap),
|
||||
GasFeeCap: uint256.MustFromBig(params.GasFeeCap),
|
||||
To: *params.To,
|
||||
Value: uint256.MustFromBig(params.Amount),
|
||||
Data: params.Data,
|
||||
BlobFeeCap: params.BlobParams.BlobFeeCap,
|
||||
BlobHashes: params.BlobParams.BlobHashes,
|
||||
Sidecar: params.BlobParams.Sidecar,
|
||||
})
|
||||
}
|
||||
|
||||
signedTx, err := types.SignTx(tx, gen.config.Signer, params.SenderKey)
|
||||
if err != nil {
|
||||
return nil, common.Address{}, err
|
||||
}
|
||||
return signedTx, contractAddr, err
|
||||
}
|
||||
|
||||
// From go-ethereum/cmd/devp2p/internal/ethtest/suite.go
|
||||
func makeSidecar(data []byte) (*types.BlobTxSidecar, error) {
|
||||
var (
|
||||
blobs = make([]kzg4844.Blob, len(data))
|
||||
commitments []kzg4844.Commitment
|
||||
proofs []kzg4844.Proof
|
||||
)
|
||||
for i := range blobs {
|
||||
blobs[i][0] = data[i]
|
||||
c, err := kzg4844.BlobToCommitment(&blobs[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p, err := kzg4844.ComputeBlobProof(&blobs[i], c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
commitments = append(commitments, c)
|
||||
proofs = append(proofs, p)
|
||||
}
|
||||
return &types.BlobTxSidecar{
|
||||
Blobs: blobs,
|
||||
Commitments: commitments,
|
||||
Proofs: proofs,
|
||||
}, nil
|
||||
}
|
||||
|
@ -2,10 +2,11 @@ package auto
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/sirupsen/logrus"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TxWatcher struct {
|
||||
@ -44,8 +45,8 @@ func (tw *TxWatcher) Start() {
|
||||
sleep *= 2
|
||||
} else {
|
||||
elapsed := time.Now().Sub(tw.startedAt)
|
||||
logrus.Debugf("TxW: TX %s found in block %s after %dms.", tx.Hash().Hex(),
|
||||
receipt.BlockNumber.String(), time.Now().Sub(start).Milliseconds())
|
||||
logrus.Debugf("TxW: TX %s found in block %s after %v.", tx.Hash().Hex(),
|
||||
receipt.BlockNumber.String(), time.Now().Sub(start))
|
||||
logrus.Infof("TxW: %d in %.0f seconds (%.2f/sec, %d pending)",
|
||||
tw.counter, elapsed.Seconds(), float64(tw.counter)/elapsed.Seconds(), len(tw.PendingTxCh))
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/vulcanize/tx_spammer/pkg/shared"
|
||||
"github.com/cerc-io/tx-spammer/pkg/shared"
|
||||
)
|
||||
|
||||
// TxSender type for
|
||||
|
@ -17,8 +17,8 @@
|
||||
package manual
|
||||
|
||||
import (
|
||||
"github.com/cerc-io/tx-spammer/pkg/shared"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/vulcanize/tx_spammer/pkg/shared"
|
||||
)
|
||||
|
||||
type Spammer struct {
|
||||
|
@ -19,10 +19,10 @@ package manual
|
||||
import (
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/cerc-io/tx-spammer/pkg/shared"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/vulcanize/tx_spammer/pkg/shared"
|
||||
)
|
||||
|
||||
// TxGenerator generates and signs txs
|
||||
|
@ -18,37 +18,53 @@ package shared
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/sirupsen/logrus"
|
||||
"math/big"
|
||||
"os"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
)
|
||||
|
||||
// ChainConfig returns the appropriate ethereum chain config for the provided chain id
|
||||
// TxSigner returns the Cancun signer at the provided block height
|
||||
func TxSigner(chainID *big.Int) types.Signer {
|
||||
return types.NewLondonSigner(chainID)
|
||||
return types.NewCancunSigner(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.Debugf("TX %s to create contract %s (sender %s)",
|
||||
tx.Hash().Hex(), crypto.CreateAddress(msg.From(), tx.Nonce()), msg.From().Hex())
|
||||
} else if nil == tx.Data() || len(tx.Data()) == 0 {
|
||||
logrus.Debugf("TX %s sending %s Wei to %s (sender %s)",
|
||||
tx.Hash().Hex(), tx.Value().String(), msg.To().Hex(), msg.From().Hex())
|
||||
} else {
|
||||
logrus.Debugf("TX %s calling contract %s (sender %s)",
|
||||
tx.Hash().Hex(), msg.To().Hex(), msg.From().Hex())
|
||||
msg, err := core.TransactionToMessage(tx, TxSigner(tx.ChainId()), big.NewInt(1))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if nil == tx.To() {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"hash": tx.Hash(),
|
||||
"from": msg.From,
|
||||
"contract": crypto.CreateAddress(msg.From, tx.Nonce()),
|
||||
}).Debug("Sending TX to create contract")
|
||||
} else {
|
||||
fields := logrus.Fields{
|
||||
"hash": tx.Hash(),
|
||||
"from": msg.From,
|
||||
"to": tx.To(),
|
||||
"nonce": tx.Nonce(),
|
||||
}
|
||||
if numblobs := len(tx.BlobHashes()); numblobs > 0 {
|
||||
fields["blobs"] = numblobs
|
||||
}
|
||||
if len(tx.Data()) == 0 {
|
||||
fields["value"] = tx.Value()
|
||||
logrus.WithFields(fields).Debug("Sending TX to transfer ETH")
|
||||
} else {
|
||||
logrus.WithFields(fields).Debug("Sending TX to call contract")
|
||||
}
|
||||
}
|
||||
|
||||
data, err := tx.MarshalBinary()
|
||||
if err != nil {
|
||||
return err
|
||||
@ -58,7 +74,7 @@ func SendTransaction(rpcClient *rpc.Client, tx *types.Transaction) error {
|
||||
|
||||
// SendRawTransaction sends a raw, signed tx using the provided client
|
||||
func SendRawTransaction(rpcClient *rpc.Client, raw []byte) error {
|
||||
logrus.Debug("eth_sendRawTransaction: ", hexutil.Encode(raw))
|
||||
logrus.Debugf("eth_sendRawTransaction: %x... (%d bytes)", raw[:min(10, len(raw))], len(raw))
|
||||
return rpcClient.CallContext(context.Background(), nil, "eth_sendRawTransaction", hexutil.Encode(raw))
|
||||
}
|
||||
|
||||
|
27
startup_script.sh
Normal file → Executable file
27
startup_script.sh
Normal file → Executable file
@ -1,12 +1,31 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
set +x
|
||||
test $SPAMMER_COMMAND
|
||||
set +e
|
||||
if [ -z "$SPAMMER_COMMAND" ]; then
|
||||
echo "SPAMMER_COMMAND env value is required!"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [ -z "$LOG_LEVEL" ]; then
|
||||
LOG_LEVEL="debug"
|
||||
fi
|
||||
|
||||
if [ ! -z "$ACCOUNTS_CSV_URL" ] && [ ! -d "keys" ]; then
|
||||
mkdir keys
|
||||
wget -O accounts.csv $ACCOUNTS_CSV_URL
|
||||
i=0
|
||||
for line in `cat accounts.csv`; do
|
||||
echo $line | cut -d',' -f3 | sed 's/^0x//' > keys/$i.key
|
||||
i=$((i + 1))
|
||||
done
|
||||
fi
|
||||
|
||||
if [ ! -d "accounts/addresses" ]; then
|
||||
mkdir -p "accounts/addresses"
|
||||
fi
|
||||
|
||||
echo "Running tx spammer"
|
||||
./tx_spammer ${SPAMMER_COMMAND} --config=config.toml --log-file=${LOG_FILE} --log-level=${LOG_LEVEL}
|
||||
./tx-spammer ${SPAMMER_COMMAND} --config=config.toml --log-level=${LOG_LEVEL}
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "tx spammer ran successfully"
|
||||
|
Loading…
Reference in New Issue
Block a user