Skip to content

Commit

Permalink
spammer: unstuck transactions before spamming
Browse files Browse the repository at this point in the history
  • Loading branch information
MariusVanDerWijden committed Oct 14, 2023
1 parent ab7dc69 commit 892beeb
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 9 deletions.
2 changes: 2 additions & 0 deletions cmd/livefuzzer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ func runAirdrop(c *cli.Context) error {
}

func spam(config *spammer.Config, spamFn spammer.Spam, airdropValue *big.Int) error {
// Make sure the accounts are unstuck before sending any transactions
spammer.Unstuck(config)
for {
if err := spammer.Airdrop(config, airdropValue); err != nil {
return err
Expand Down
6 changes: 4 additions & 2 deletions spammer/basic.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import (
"github.com/ethereum/go-ethereum/log"
)

const TX_TIMEOUT = 5 * time.Minute

func SendBasicTransactions(config *Config, key *ecdsa.PrivateKey, f *filler.Filler) error {
backend := ethclient.NewClient(config.backend)
sender := crypto.PubkeyToAddress(key.PublicKey)
Expand Down Expand Up @@ -48,10 +50,10 @@ func SendBasicTransactions(config *Config, key *ecdsa.PrivateKey, f *filler.Fill
time.Sleep(10 * time.Millisecond)
}
if lastTx != nil {
ctx, cancel := context.WithTimeout(context.Background(), 24*time.Second)
ctx, cancel := context.WithTimeout(context.Background(), TX_TIMEOUT)
defer cancel()
if _, err := bind.WaitMined(ctx, backend, lastTx); err != nil {
fmt.Printf("Wait mined failed for SendBaikalTransactions: %v\n", err.Error())
fmt.Printf("Waiting for transactions to be mined failed: %v\n", err.Error())
}
}
return nil
Expand Down
4 changes: 2 additions & 2 deletions spammer/blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ func SendBlobTransactions(config *Config, key *ecdsa.PrivateKey, f *filler.Fille
}

if lastTx != nil {
ctx, cancel := context.WithTimeout(context.Background(), 24*time.Second)
ctx, cancel := context.WithTimeout(context.Background(), TX_TIMEOUT)
defer cancel()
if _, err := bind.WaitMined(ctx, backend, lastTx); err != nil {
fmt.Printf("Wait mined failed for blob transactions: %v\n", err.Error())
fmt.Printf("Waiting for transactions to be mined failed: %v\n", err.Error())
}
}
return nil
Expand Down
33 changes: 28 additions & 5 deletions spammer/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,18 @@ import (
"github.com/ethereum/go-ethereum/ethclient"
)

const batchSize = 50

func SendTx(sk *ecdsa.PrivateKey, backend *ethclient.Client, to common.Address, value *big.Int) (*types.Transaction, error) {
sender := crypto.PubkeyToAddress(sk.PublicKey)
nonce, err := backend.NonceAt(context.Background(), sender, nil)
if err != nil {
fmt.Printf("Could not get pending nonce: %v", err)
}
fmt.Printf("Nonce: %v\n", nonce)
return sendTxWithNonce(sk, backend, to, value, nonce)
}

func sendTxWithNonce(sk *ecdsa.PrivateKey, backend *ethclient.Client, to common.Address, value *big.Int, nonce uint64) (*types.Transaction, error) {
chainid, err := backend.ChainID(context.Background())
if err != nil {
return nil, err
Expand All @@ -32,6 +37,21 @@ func SendTx(sk *ecdsa.PrivateKey, backend *ethclient.Client, to common.Address,
return signedTx, backend.SendTransaction(context.Background(), signedTx)
}

func sendRecurringTx(sk *ecdsa.PrivateKey, backend *ethclient.Client, to common.Address, value *big.Int, numTxs uint64) (*types.Transaction, error) {
sender := crypto.PubkeyToAddress(sk.PublicKey)
nonce, err := backend.NonceAt(context.Background(), sender, nil)
if err != nil {
return nil, err
}
var (
tx *types.Transaction
)
for i := 0; i < int(numTxs); i++ {
tx, err = sendTxWithNonce(sk, backend, to, value, nonce+uint64(i))
}
return tx, err
}

func Unstuck(config *Config) error {
if err := tryUnstuck(config, config.faucet); err != nil {
return err
Expand All @@ -58,13 +78,16 @@ func tryUnstuck(config *Config, sk *ecdsa.PrivateKey) error {
return nil
}

fmt.Println("Sending transaction to unstuck account")
// Self-transfer of 1 wei to unstuck
tx, err := SendTx(sk, client, addr, big.NewInt(1))
if noTx > batchSize {
noTx = batchSize
}
fmt.Println("Sending transaction to unstuck account")
tx, err := sendRecurringTx(sk, client, addr, big.NewInt(1), noTx)
if err != nil {
return err
}
ctx, cancel := context.WithTimeout(context.Background(), 24*time.Second)
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()
if _, err := bind.WaitMined(ctx, client, tx); err != nil {
return err
Expand All @@ -87,7 +110,7 @@ func isStuck(config *Config, account common.Address) (uint64, error) {
}

if pendingNonce != nonce {
fmt.Printf("Account %v is stuck: pendingNonce: %v currentNonce: %v\n", account, pendingNonce, nonce)
fmt.Printf("Account %v is stuck: pendingNonce: %v currentNonce: %v, missing nonces: %v\n", account, pendingNonce, nonce, pendingNonce-nonce)
return pendingNonce - nonce, nil
}
return 0, nil
Expand Down

0 comments on commit 892beeb

Please sign in to comment.