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
|
- name: Run docker build
|
||||||
run: make docker-build
|
run: make docker-build
|
||||||
- name: Tag docker image
|
- 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
|
- 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
|
- 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=sha::$(echo ${GITHUB_SHA:0:7})
|
||||||
echo ::set-output name=tag::$(echo ${GITHUB_REF#refs/tags/})
|
echo ::set-output name=tag::$(echo ${GITHUB_REF#refs/tags/})
|
||||||
- name: Docker Login to Github Registry
|
- 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
|
- 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
|
- name: Docker Login to Docker Registry
|
||||||
run: echo ${{ secrets.VULCANIZEJENKINS_PAT }} | docker login -u vulcanizejenkins --password-stdin
|
run: echo ${{ secrets.VULCANIZEJENKINS_PAT }} | docker login -u vulcanizejenkins --password-stdin
|
||||||
- name: Tag docker image
|
- 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
|
- 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)
|
# Dependency directories (remove the comment below to include it)
|
||||||
# vendor/
|
# vendor/
|
||||||
.idea/
|
.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
|
# DEBUG
|
||||||
RUN apk add busybox-extras
|
RUN apk add busybox-extras
|
||||||
|
|
||||||
# Get and build tx_spammer
|
# Get and build tx-spammer
|
||||||
ADD . /go/src/github.com/vulcanize/tx_spammer
|
WORKDIR /go/src/github.com/cerc-io/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 .
|
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
|
# app container
|
||||||
FROM alpine
|
FROM alpine
|
||||||
@ -22,11 +26,12 @@ USER $USER
|
|||||||
|
|
||||||
# chown first so dir is writable
|
# chown first so dir is writable
|
||||||
# note: using $USER is merged, but not in the stable release yet
|
# 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/cerc-io/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/startup_script.sh .
|
||||||
|
|
||||||
# keep binaries immutable
|
# keep binaries immutable
|
||||||
COPY --from=builder /go/src/github.com/vulcanize/tx_spammer/tx_spammer tx_spammer
|
COPY --from=builder /go/src/github.com/cerc-io/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/environments environments
|
||||||
|
COPY --from=builder /go/src/github.com/cerc-io/tx-spammer/sol sol
|
||||||
|
|
||||||
ENTRYPOINT ["/app/startup_script.sh"]
|
ENTRYPOINT ["/app/startup_script.sh"]
|
||||||
|
4
Makefile
4
Makefile
@ -1,11 +1,11 @@
|
|||||||
## Build docker image
|
## Build docker image
|
||||||
.PHONY: docker-build
|
.PHONY: docker-build
|
||||||
docker-build:
|
docker-build:
|
||||||
docker build -t vulcanize/tx_spammer -f Dockerfile .
|
docker build -t cerc/tx-spammer -f Dockerfile .
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build:
|
build:
|
||||||
GO111MODULE=on go build -o tx_spammer .
|
GO111MODULE=on go build -o tx-spammer .
|
||||||
|
|
||||||
.PHONY: contract
|
.PHONY: contract
|
||||||
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
|
Tools to enable the semi-reproducible growth of a large and complex chain over RPC, for testing and benchmarking purposes
|
||||||
|
|
||||||
Usage:
|
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.
|
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.
|
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/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"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
|
// 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() {
|
func autoSend() {
|
||||||
config, err := auto.NewConfig()
|
config, err := auto.NewConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logWithCommand.Fatal(err)
|
logWithCommand.Fatal(err)
|
||||||
}
|
}
|
||||||
|
logrus.WithFields(logrus.Fields{"config": config}).Debug("Loaded config")
|
||||||
txSpammer := auto.NewTxSpammer(config)
|
txSpammer := auto.NewTxSpammer(config)
|
||||||
quitChan := make(chan bool)
|
quitChan := make(chan bool)
|
||||||
doneChan, err := txSpammer.Loop(quitChan)
|
doneChan, err := txSpammer.Loop(quitChan)
|
||||||
|
@ -33,7 +33,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
Use: "tx_spammer",
|
Use: "tx-spammer",
|
||||||
PersistentPreRun: initFuncs,
|
PersistentPreRun: initFuncs,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ func Execute() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func initFuncs(cmd *cobra.Command, args []string) {
|
func initFuncs(cmd *cobra.Command, args []string) {
|
||||||
logfile := viper.GetString("logfile")
|
logfile := viper.GetString("log.file")
|
||||||
if logfile != "" {
|
if logfile != "" {
|
||||||
file, err := os.OpenFile(logfile,
|
file, err := os.OpenFile(logfile,
|
||||||
os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||||
@ -65,13 +65,13 @@ func initFuncs(cmd *cobra.Command, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func logLevel() error {
|
func logLevel() error {
|
||||||
viper.BindEnv("log.level", "LOGRUS_LEVEL")
|
viper.BindEnv("log.level", "LOG_LEVEL")
|
||||||
lvl, err := log.ParseLevel(viper.GetString("log.level"))
|
lvl, err := log.ParseLevel(viper.GetString("log.level"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.SetLevel(lvl)
|
log.SetLevel(lvl)
|
||||||
if lvl > log.InfoLevel {
|
if lvl > log.DebugLevel {
|
||||||
log.SetReportCaller(true)
|
log.SetReportCaller(true)
|
||||||
}
|
}
|
||||||
log.Info("Log level set to ", lvl.String())
|
log.Info("Log level set to ", lvl.String())
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/vulcanize/tx_spammer/pkg/manual"
|
"github.com/cerc-io/tx-spammer/pkg/manual"
|
||||||
)
|
)
|
||||||
|
|
||||||
// sendTxsCmd represents the sendTxs command
|
// sendTxsCmd represents the sendTxs command
|
||||||
|
@ -1,65 +1,40 @@
|
|||||||
[eth]
|
[eth]
|
||||||
txs = ["L2ContractDeployment", "L2ContractPutCall", "L2ContractGetCall"] # $ETH_TX_LIST
|
keyDirPath = "./keys/" # path to the directory with all of the key pairs to use - env: $ETH_KEY_DIR_PATH
|
||||||
addrLogPath = "" # ETH_ADDR_LOG
|
httpPath = "http://localhost:8545" # http url for the node we wish to send all our transactions to - env: $ETH_HTTP_PATH
|
||||||
|
|
||||||
[L2ContractDeployment]
|
[deployment]
|
||||||
type = "L2"
|
number = 1 # number of contracts we will deploy for each key at keyPath - env: $ETH_DEPLOYMENT_NUMBER
|
||||||
httpPath = ""
|
binPath = "sol/build/Test.bin" # hex data for the contracts we will deploy - env: $ETH_DEPLOYMENT_BIN_PATH
|
||||||
chainID = 420
|
gasLimit = 100000 # gasLimit to use for the deployment txs - env: $ETH_DEPLOYMENT_GAS_LIMIT
|
||||||
to = ""
|
gasTipCap = "1000000000" # gasTipCap to use for the deployment txs - env: $ETH_DEPLOYMENT_GAS_TIP_CAP
|
||||||
amount = "0"
|
gasFeeCap = "1000000007" # gasFeeCap to use for the deployment txs - env: $ETH_DEPLOYMENT_GAS_FEE_CAP
|
||||||
gasLimit = 0
|
|
||||||
gasPrice = "0"
|
|
||||||
data = ""
|
|
||||||
senderKeyPath = ""
|
|
||||||
writeSenderPath = ""
|
|
||||||
writeDeploymentAddrPath = ""
|
|
||||||
frequency = 1
|
|
||||||
totalNumber = 1
|
|
||||||
delay = 0
|
|
||||||
l1Sender = ""
|
|
||||||
l1RollupTxId = 0
|
|
||||||
sigHashType = 0
|
|
||||||
queueOrigin = 0
|
|
||||||
|
|
||||||
[L2ContractPutCall]
|
[contractSpammer]
|
||||||
type = "L2"
|
frequency = -1 # how often to send a transaction (in milliseconds, -1 for no delay) - env: $ETH_CALL_FREQ
|
||||||
httpPath = ""
|
totalNumber = -1 # total number of transactions to send (per sender, -1 for unlimited) - env: $ETH_CALL_TOTAL_NUMBER
|
||||||
chainID = 420
|
abiPath = "sol/build/Test.abi" # path to the abi file for the contract we are calling - env: $ETH_CALL_ABI_PATH
|
||||||
to = ""
|
# NOTE: we expect to be calling a method such as Put(address addr, uint256 val) where the first argument is an
|
||||||
amount = "0"
|
# integer than we can increment to store values at new locations in the contract trie (to grow it) and
|
||||||
gasLimit = 0
|
# the second argument is an integer value that we store at these positions
|
||||||
gasPrice = "0"
|
methodName = "Put" # the method name we are calling - env: $ETH_CALL_METHOD_NAME
|
||||||
data = ""
|
gasLimit = 42000 # gasLimit to use for the eth call txs - env: $ETH_CALL_GAS_LIMIT
|
||||||
senderKeyPath = ""
|
gasTipCap = "1000000000" # gasTipCap to use for the eth call txs - env: $ETH_CALL_GAS_TIP_CAP
|
||||||
writeSenderPath = ""
|
gasFeeCap = "1000000007" # gasFeeCap to use for the eth call txs - env: $ETH_CALL_GAS_FEE_CAP
|
||||||
frequency = 15
|
|
||||||
totalNumber = 1
|
|
||||||
delay = 60
|
|
||||||
l1Sender = ""
|
|
||||||
l1RollupTxId = 0
|
|
||||||
sigHashType = 0
|
|
||||||
queueOrigin = 0
|
|
||||||
|
|
||||||
[L2ContractGetCall]
|
[sendSpammer]
|
||||||
type = "L2"
|
frequency = -1 # how often to send a transaction (in milliseconds, -1 for no delay) - env: $ETH_SEND_FREQ
|
||||||
httpPath = ""
|
totalNumber = -1 # total number of transactions to send (per sender, -1 for unlimited) - env: $ETH_SEND_TOTAL_NUMBER
|
||||||
chainID = 420
|
amount = "10000" # amount of wei (1x10^-18 ETH) to send in each tx (be mindful of the genesis allocations) - env: $ETH_SEND_AMOUNT
|
||||||
to = ""
|
gasLimit = 21000 # gasLimit to use for the eth transfer txs - env: $ETH_SEND_GAS_LIMIT
|
||||||
amount = "0"
|
gasTipCap = "1000000000" # gasTipCap to use for the eth transfer txs - env: $ETH_SEND_GAS_TIP_CAP
|
||||||
gasLimit = 0
|
gasFeeCap = "1000000007" # gasFeeCap to use for the eth transfer txs - env: $ETH_SEND_GAS_FEE_CAP
|
||||||
gasPrice = "0"
|
|
||||||
data = ""
|
|
||||||
senderKeyPath = ""
|
|
||||||
writeSenderPath = ""
|
|
||||||
frequency = 60
|
|
||||||
totalNumber = 2
|
|
||||||
delay = 30
|
|
||||||
l1Sender = ""
|
|
||||||
l1RollupTxId = 0
|
|
||||||
sigHashType = 0
|
|
||||||
queueOrigin = 0
|
|
||||||
|
|
||||||
[log]
|
[blobSpammer]
|
||||||
level = "info"
|
frequency = 500 # how often to send a transaction (in milliseconds, -1 for no delay) - env: $ETH_SEND_FREQ
|
||||||
file = ""
|
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 (
|
require (
|
||||||
github.com/Azure/azure-pipeline-go v0.2.2 // indirect
|
github.com/ethereum/go-ethereum v1.14.5
|
||||||
github.com/Azure/azure-storage-blob-go v0.7.0 // indirect
|
github.com/holiman/uint256 v1.2.4
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.8.0 // indirect
|
github.com/sirupsen/logrus v1.9.3
|
||||||
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/spf13/cobra v1.6.0
|
github.com/spf13/cobra v1.6.0
|
||||||
github.com/spf13/viper v1.13.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
|
package main
|
||||||
|
|
||||||
import "github.com/vulcanize/tx_spammer/cmd"
|
import "github.com/cerc-io/tx-spammer/cmd"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cmd.Execute()
|
cmd.Execute()
|
||||||
|
@ -21,7 +21,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
@ -29,13 +28,16 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"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/accounts/abi"
|
||||||
"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/crypto"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"github.com/vulcanize/tx_spammer/pkg/shared"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -49,10 +51,12 @@ func init() {
|
|||||||
|
|
||||||
// Config holds all the parameters for the auto tx spammer
|
// Config holds all the parameters for the auto tx spammer
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
// Whether to stop service on any error from tx generation or sending
|
||||||
|
StopOnSendError bool
|
||||||
|
|
||||||
// HTTP client for sending transactions
|
// HTTP client for sending transactions
|
||||||
RpcClient *rpc.Client
|
RpcClient *rpc.Client
|
||||||
EthClient *ethclient.Client
|
EthClient *ethclient.Client
|
||||||
ChainID *big.Int
|
|
||||||
|
|
||||||
// Key pairs for the accounts we will use to deploy contracts and send txs
|
// Key pairs for the accounts we will use to deploy contracts and send txs
|
||||||
SenderKeys []*ecdsa.PrivateKey
|
SenderKeys []*ecdsa.PrivateKey
|
||||||
@ -69,6 +73,9 @@ type Config struct {
|
|||||||
|
|
||||||
// Configuration for the eth transfer txs
|
// Configuration for the eth transfer txs
|
||||||
SendConfig *SendConfig
|
SendConfig *SendConfig
|
||||||
|
|
||||||
|
// Configuration for the blob txs
|
||||||
|
BlobTxConfig *BlobTxConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeploymentConfig holds the parameters for the contract deployment contracts
|
// DeploymentConfig holds the parameters for the contract deployment contracts
|
||||||
@ -110,7 +117,24 @@ type SendConfig struct {
|
|||||||
TotalNumber int
|
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) {
|
func NewConfig() (*Config, error) {
|
||||||
|
stopOnError := viper.GetBool(SpammerStopOnError)
|
||||||
|
|
||||||
// Initialize rpc client
|
// Initialize rpc client
|
||||||
httpPathStr := viper.GetString(ethHttpPath)
|
httpPathStr := viper.GetString(ethHttpPath)
|
||||||
if httpPathStr == "" {
|
if httpPathStr == "" {
|
||||||
@ -180,8 +204,15 @@ func NewConfig() (*Config, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load blob tx config
|
||||||
|
blobTxConfig, err := NewBlobTxConfig(chainID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// Assemble and return
|
// Assemble and return
|
||||||
return &Config{
|
return &Config{
|
||||||
|
StopOnSendError: stopOnError,
|
||||||
RpcClient: rpcClient,
|
RpcClient: rpcClient,
|
||||||
EthClient: ethClient,
|
EthClient: ethClient,
|
||||||
SenderKeys: keys,
|
SenderKeys: keys,
|
||||||
@ -190,6 +221,7 @@ func NewConfig() (*Config, error) {
|
|||||||
DeploymentConfig: deploymentConfig,
|
DeploymentConfig: deploymentConfig,
|
||||||
CallConfig: callConfig,
|
CallConfig: callConfig,
|
||||||
SendConfig: sendConfig,
|
SendConfig: sendConfig,
|
||||||
|
BlobTxConfig: blobTxConfig,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,3 +323,37 @@ func NewSendConfig(chainID *big.Int) (*SendConfig, error) {
|
|||||||
TotalNumber: totalNumber,
|
TotalNumber: totalNumber,
|
||||||
}, nil
|
}, 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 (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/cerc-io/tx-spammer/pkg/shared"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/vulcanize/tx_spammer/pkg/shared"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -59,7 +60,7 @@ func (cp *ContractDeployer) Deploy() ([]common.Address, error) {
|
|||||||
<-ticker.C
|
<-ticker.C
|
||||||
for i, key := range cp.senderKeys {
|
for i, key := range cp.senderKeys {
|
||||||
logrus.Debugf("Generating contract deployment for %s.", cp.senderAddrs[i].Hex())
|
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,
|
ChainID: cp.config.ChainID,
|
||||||
Sender: cp.senderAddrs[i],
|
Sender: cp.senderAddrs[i],
|
||||||
SenderKey: key,
|
SenderKey: key,
|
||||||
|
@ -19,9 +19,12 @@ package auto
|
|||||||
import "github.com/spf13/viper"
|
import "github.com/spf13/viper"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
SPAMMER_STOP_ON_ERROR = "SPAMMER_STOP_ON_ERROR"
|
||||||
|
|
||||||
// env variables
|
// env variables
|
||||||
ETH_KEY_DIR_PATH = "ETH_KEY_DIR_PATH"
|
ETH_KEY_DIR_PATH = "ETH_KEY_DIR_PATH"
|
||||||
ETH_HTTP_PATH = "ETH_HTTP_PATH"
|
ETH_HTTP_PATH = "ETH_HTTP_PATH"
|
||||||
|
ETH_CONTRACT_ADDR_PATH = "ETH_CONTRACT_ADDR_PATH"
|
||||||
|
|
||||||
ETH_DEPLOYMENT_NUMBER = "ETH_DEPLOYMENT_NUMBER"
|
ETH_DEPLOYMENT_NUMBER = "ETH_DEPLOYMENT_NUMBER"
|
||||||
ETH_DEPLOYMENT_BIN_PATH = "ETH_DEPLOYMENT_BIN_PATH"
|
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_FEE_CAP = "ETH_SEND_GAS_FEE_CAP"
|
||||||
ETH_SEND_GAS_TIP_CAP = "ETH_SEND_GAS_TIP_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
|
// toml bindings
|
||||||
|
SpammerStopOnError = "service.stopOnError"
|
||||||
|
|
||||||
ethKeyDirPath = "eth.keyDirPath"
|
ethKeyDirPath = "eth.keyDirPath"
|
||||||
ethHttpPath = "eth.httpPath"
|
ethHttpPath = "eth.httpPath"
|
||||||
|
ethContractAddrPath = "eth.contractAddrPath"
|
||||||
|
|
||||||
ethDeploymentBinPath = "deployment.binPath"
|
ethDeploymentBinPath = "deployment.binPath"
|
||||||
ethDeploymentNumber = "deployment.number"
|
ethDeploymentNumber = "deployment.number"
|
||||||
@ -68,11 +83,23 @@ const (
|
|||||||
ethSendGasLimit = "sendSpammer.gasLimit"
|
ethSendGasLimit = "sendSpammer.gasLimit"
|
||||||
ethSendGasFeeCap = "sendSpammer.gasFeeCap"
|
ethSendGasFeeCap = "sendSpammer.gasFeeCap"
|
||||||
ethSendGasTipCap = "sendSpammer.gasTipCap"
|
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() {
|
func bindEnv() {
|
||||||
|
viper.BindEnv(SpammerStopOnError, SPAMMER_STOP_ON_ERROR)
|
||||||
|
|
||||||
viper.BindEnv(ethKeyDirPath, ETH_KEY_DIR_PATH)
|
viper.BindEnv(ethKeyDirPath, ETH_KEY_DIR_PATH)
|
||||||
viper.BindEnv(ethHttpPath, ETH_HTTP_PATH)
|
viper.BindEnv(ethHttpPath, ETH_HTTP_PATH)
|
||||||
|
viper.BindEnv(ethContractAddrPath, ETH_CONTRACT_ADDR_PATH)
|
||||||
|
|
||||||
viper.BindEnv(ethDeploymentNumber, ETH_DEPLOYMENT_NUMBER)
|
viper.BindEnv(ethDeploymentNumber, ETH_DEPLOYMENT_NUMBER)
|
||||||
viper.BindEnv(ethDeploymentBinPath, ETH_DEPLOYMENT_BIN_PATH)
|
viper.BindEnv(ethDeploymentBinPath, ETH_DEPLOYMENT_BIN_PATH)
|
||||||
@ -95,4 +122,13 @@ func bindEnv() {
|
|||||||
viper.BindEnv(ethSendGasFeeCap, ETH_SEND_GAS_FEE_CAP)
|
viper.BindEnv(ethSendGasFeeCap, ETH_SEND_GAS_FEE_CAP)
|
||||||
viper.BindEnv(ethSendGasTipCap, ETH_SEND_GAS_TIP_CAP)
|
viper.BindEnv(ethSendGasTipCap, ETH_SEND_GAS_TIP_CAP)
|
||||||
viper.BindEnv(ethSendGasLimit, ETH_CALL_GAS_LIMIT)
|
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
|
package auto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/cerc-io/tx-spammer/pkg/shared"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/vulcanize/tx_spammer/pkg/shared"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// EthSender sends eth value transfer txs
|
// 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
|
// 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
|
// err channel returned to calling context
|
||||||
errChan := make(chan error)
|
errChan := make(chan error)
|
||||||
doneChan := make(chan bool)
|
doneChan := make(chan bool)
|
||||||
go func() {
|
go func() {
|
||||||
defer close(doneChan)
|
defer close(doneChan)
|
||||||
|
defer close(errChan)
|
||||||
counter := 0
|
counter := 0
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case tx := <-txChan:
|
case tx := <-txChan:
|
||||||
counter += 1
|
counter += 1
|
||||||
if err := shared.SendTransaction(s.client, tx); err != nil {
|
if err := shared.SendTransaction(s.client, tx); err != nil {
|
||||||
errChan <- err
|
errChan <- fmt.Errorf("%w: tx = %s", err, tx.Hash())
|
||||||
} else {
|
} else {
|
||||||
sentCh <- tx
|
sentCh <- tx
|
||||||
}
|
}
|
||||||
case <-quitChan:
|
case <-quitChan:
|
||||||
logrus.Infof("quitting Send loop (sent %d)", counter)
|
log.Infof("quitting Send loop (sent %d)", counter)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,8 @@ package auto
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/cerc-io/tx-spammer/pkg/shared"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/vulcanize/tx_spammer/pkg/shared"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Spammer underlying struct type for spamming service
|
// 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)
|
sendDoneChan, sendErrChan := s.Sender.Send(senderQuit, txChan, watcher.PendingTxCh)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer close(doneChan)
|
<-genDoneChan
|
||||||
for {
|
recoverClose(senderQuit)
|
||||||
select {
|
<-sendDoneChan
|
||||||
case err := <-genErrChan:
|
recoverClose(watcher.quitCh)
|
||||||
|
close(doneChan)
|
||||||
|
}()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for err := range genErrChan {
|
||||||
logrus.Errorf("tx generation error: %v", err)
|
logrus.Errorf("tx generation error: %v", err)
|
||||||
recoverClose(genQuit)
|
recoverClose(genQuit)
|
||||||
<-genDoneChan
|
}
|
||||||
recoverClose(senderQuit)
|
}()
|
||||||
<-sendDoneChan
|
|
||||||
recoverClose(watcher.quitCh)
|
go func() {
|
||||||
case err := <-sendErrChan:
|
for err := range sendErrChan {
|
||||||
logrus.Errorf("tx sending error: %v", err)
|
logrus.Errorf("tx sending error: %v", err)
|
||||||
|
if s.config.StopOnSendError {
|
||||||
recoverClose(genQuit)
|
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
|
return doneChan, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,16 +19,20 @@ package auto
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"errors"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"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/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/vulcanize/tx_spammer/pkg/shared"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TxGenerator generates and signs txs
|
// TxGenerator generates and signs txs
|
||||||
@ -73,6 +77,14 @@ type GenParams struct {
|
|||||||
To *common.Address
|
To *common.Address
|
||||||
Amount *big.Int
|
Amount *big.Int
|
||||||
Data []byte
|
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) {
|
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)
|
wg.Add(1)
|
||||||
go gen.genCalls(wg, txChan, errChan, quitChan, sender, gen.config.SenderAddrs[i], gen.config.CallConfig)
|
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)
|
doneChan := make(chan bool)
|
||||||
go func() {
|
go func() {
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
close(errChan)
|
||||||
close(doneChan)
|
close(doneChan)
|
||||||
}()
|
}()
|
||||||
return doneChan, txChan, errChan
|
return doneChan, txChan, errChan
|
||||||
@ -105,7 +129,7 @@ func (gen *TxGenerator) genSends(wg *sync.WaitGroup, txChan chan<- *types.Transa
|
|||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
dst := crypto.CreateAddress(receiverAddressSeed, uint64(i))
|
dst := crypto.CreateAddress(receiverAddressSeed, uint64(i))
|
||||||
log.Debugf("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{
|
params := &GenParams{
|
||||||
ChainID: sendConfig.ChainID,
|
ChainID: sendConfig.ChainID,
|
||||||
To: &dst,
|
To: &dst,
|
||||||
Sender: senderAddr,
|
Sender: senderAddr,
|
||||||
@ -114,7 +138,8 @@ func (gen *TxGenerator) genSends(wg *sync.WaitGroup, txChan chan<- *types.Transa
|
|||||||
GasFeeCap: sendConfig.GasFeeCap,
|
GasFeeCap: sendConfig.GasFeeCap,
|
||||||
GasTipCap: sendConfig.GasTipCap,
|
GasTipCap: sendConfig.GasTipCap,
|
||||||
Amount: sendConfig.Amount,
|
Amount: sendConfig.Amount,
|
||||||
})
|
}
|
||||||
|
rawTx, _, err := gen.createTx(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errChan <- err
|
errChan <- err
|
||||||
continue
|
continue
|
||||||
@ -140,7 +165,7 @@ func (gen *TxGenerator) genCalls(wg *sync.WaitGroup, txChan chan<- *types.Transa
|
|||||||
errChan <- err
|
errChan <- err
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
rawTx, _, err := gen.GenerateTx(&GenParams{
|
rawTx, _, err := gen.createTx(&GenParams{
|
||||||
Sender: senderAddr,
|
Sender: senderAddr,
|
||||||
SenderKey: senderKey,
|
SenderKey: senderKey,
|
||||||
GasLimit: callConfig.GasLimit,
|
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())
|
log.Info("Done generating calls for ", senderAddr.Hex())
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateTx generates tx from the provided params
|
type senderArgs struct {
|
||||||
func (gen *TxGenerator) GenerateTx(params *GenParams) (*types.Transaction, common.Address, error) {
|
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)
|
nonce := gen.claimNonce(params.Sender)
|
||||||
tx := new(types.Transaction)
|
tx := new(types.Transaction)
|
||||||
var contractAddr common.Address
|
var contractAddr common.Address
|
||||||
var err error
|
var err error
|
||||||
if params.To == nil {
|
if params.To == nil {
|
||||||
|
if params.BlobParams != nil {
|
||||||
|
return nil, common.Address{}, errors.New("BlobTx cannot be used for contract creation")
|
||||||
|
}
|
||||||
tx = types.NewTx(
|
tx = types.NewTx(
|
||||||
&types.DynamicFeeTx{
|
&types.DynamicFeeTx{
|
||||||
ChainID: params.ChainID,
|
ChainID: params.ChainID,
|
||||||
@ -183,7 +266,7 @@ func (gen *TxGenerator) GenerateTx(params *GenParams) (*types.Transaction, commo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, common.Address{}, err
|
return nil, common.Address{}, err
|
||||||
}
|
}
|
||||||
} else {
|
} else if params.BlobParams == nil {
|
||||||
tx = types.NewTx(
|
tx = types.NewTx(
|
||||||
&types.DynamicFeeTx{
|
&types.DynamicFeeTx{
|
||||||
ChainID: params.ChainID,
|
ChainID: params.ChainID,
|
||||||
@ -195,10 +278,53 @@ func (gen *TxGenerator) GenerateTx(params *GenParams) (*types.Transaction, commo
|
|||||||
Value: params.Amount,
|
Value: params.Amount,
|
||||||
Data: params.Data,
|
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)
|
signedTx, err := types.SignTx(tx, gen.config.Signer, params.SenderKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, common.Address{}, err
|
return nil, common.Address{}, err
|
||||||
}
|
}
|
||||||
return signedTx, contractAddr, 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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
"github.com/ethereum/go-ethereum/ethclient"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type TxWatcher struct {
|
type TxWatcher struct {
|
||||||
@ -44,8 +45,8 @@ func (tw *TxWatcher) Start() {
|
|||||||
sleep *= 2
|
sleep *= 2
|
||||||
} else {
|
} else {
|
||||||
elapsed := time.Now().Sub(tw.startedAt)
|
elapsed := time.Now().Sub(tw.startedAt)
|
||||||
logrus.Debugf("TxW: TX %s found in block %s after %dms.", tx.Hash().Hex(),
|
logrus.Debugf("TxW: TX %s found in block %s after %v.", tx.Hash().Hex(),
|
||||||
receipt.BlockNumber.String(), time.Now().Sub(start).Milliseconds())
|
receipt.BlockNumber.String(), time.Now().Sub(start))
|
||||||
logrus.Infof("TxW: %d in %.0f seconds (%.2f/sec, %d pending)",
|
logrus.Infof("TxW: %d in %.0f seconds (%.2f/sec, %d pending)",
|
||||||
tw.counter, elapsed.Seconds(), float64(tw.counter)/elapsed.Seconds(), len(tw.PendingTxCh))
|
tw.counter, elapsed.Seconds(), float64(tw.counter)/elapsed.Seconds(), len(tw.PendingTxCh))
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ import (
|
|||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/vulcanize/tx_spammer/pkg/shared"
|
"github.com/cerc-io/tx-spammer/pkg/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TxSender type for
|
// TxSender type for
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
package manual
|
package manual
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/cerc-io/tx-spammer/pkg/shared"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/vulcanize/tx_spammer/pkg/shared"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Spammer struct {
|
type Spammer struct {
|
||||||
|
@ -19,10 +19,10 @@ package manual
|
|||||||
import (
|
import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
|
"github.com/cerc-io/tx-spammer/pkg/shared"
|
||||||
"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/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/vulcanize/tx_spammer/pkg/shared"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TxGenerator generates and signs txs
|
// TxGenerator generates and signs txs
|
||||||
|
@ -18,37 +18,53 @@ package shared
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"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/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"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 {
|
func TxSigner(chainID *big.Int) types.Signer {
|
||||||
return types.NewLondonSigner(chainID)
|
return types.NewCancunSigner(chainID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendTransaction sends a signed tx using the provided client
|
// SendTransaction sends a signed tx using the provided client
|
||||||
func SendTransaction(rpcClient *rpc.Client, tx *types.Transaction) error {
|
func SendTransaction(rpcClient *rpc.Client, tx *types.Transaction) error {
|
||||||
msg, _ := tx.AsMessage(TxSigner(tx.ChainId()), big.NewInt(1))
|
msg, err := core.TransactionToMessage(tx, TxSigner(tx.ChainId()), big.NewInt(1))
|
||||||
if nil == tx.To() {
|
if err != nil {
|
||||||
logrus.Debugf("TX %s to create contract %s (sender %s)",
|
return err
|
||||||
tx.Hash().Hex(), crypto.CreateAddress(msg.From(), tx.Nonce()), msg.From().Hex())
|
}
|
||||||
} else if nil == tx.Data() || len(tx.Data()) == 0 {
|
if nil == tx.To() {
|
||||||
logrus.Debugf("TX %s sending %s Wei to %s (sender %s)",
|
logrus.WithFields(logrus.Fields{
|
||||||
tx.Hash().Hex(), tx.Value().String(), msg.To().Hex(), msg.From().Hex())
|
"hash": tx.Hash(),
|
||||||
} else {
|
"from": msg.From,
|
||||||
logrus.Debugf("TX %s calling contract %s (sender %s)",
|
"contract": crypto.CreateAddress(msg.From, tx.Nonce()),
|
||||||
tx.Hash().Hex(), msg.To().Hex(), msg.From().Hex())
|
}).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()
|
data, err := tx.MarshalBinary()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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
|
// SendRawTransaction sends a raw, signed tx using the provided client
|
||||||
func SendRawTransaction(rpcClient *rpc.Client, raw []byte) error {
|
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))
|
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
|
#!/bin/sh
|
||||||
|
|
||||||
set -e
|
|
||||||
set +x
|
|
||||||
test $SPAMMER_COMMAND
|
|
||||||
set +e
|
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"
|
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
|
if [ $? -eq 0 ]; then
|
||||||
echo "tx spammer ran successfully"
|
echo "tx spammer ran successfully"
|
||||||
|
Loading…
Reference in New Issue
Block a user