-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cmd/livefuzzer: big refactor of the livefuzzer (#37)
* cmd/livefuzzer: big refactor of the livefuzzer * cmd/livefuzzer: cleanup * cmd/livefuzzer: happy lint, happy life
- Loading branch information
1 parent
6dee627
commit 241bebe
Showing
8 changed files
with
254 additions
and
270 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"crypto/ecdsa" | ||
crand "crypto/rand" | ||
"encoding/binary" | ||
"fmt" | ||
"math/rand" | ||
"os" | ||
|
||
txfuzz "github.com/MariusVanDerWijden/tx-fuzz" | ||
"github.com/MariusVanDerWijden/tx-fuzz/mutator" | ||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/crypto" | ||
"github.com/ethereum/go-ethereum/ethclient" | ||
"github.com/ethereum/go-ethereum/rpc" | ||
"github.com/urfave/cli/v2" | ||
) | ||
|
||
type Config struct { | ||
backend *rpc.Client // connection to the rpc provider | ||
|
||
n uint64 // number of transactions send per account | ||
faucet *ecdsa.PrivateKey // private key of the faucet account | ||
keys []*ecdsa.PrivateKey // private keys of accounts | ||
corpus [][]byte // optional corpus to use elements from | ||
accessList bool // whether to create accesslist transactions | ||
gasLimit uint64 // gas limit per transaction | ||
|
||
seed int64 // seed used for generating randomness | ||
mut *mutator.Mutator // Mutator based on the seed | ||
} | ||
|
||
func NewConfigFromContext(c *cli.Context) (*Config, error) { | ||
// Setup RPC | ||
rpcAddr := c.String(rpcFlag.Name) | ||
backend, err := rpc.Dial(rpcAddr) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Setup faucet | ||
faucet := crypto.ToECDSAUnsafe(common.FromHex(txfuzz.SK)) | ||
if sk := c.String(skFlag.Name); sk != "" { | ||
faucet, err = crypto.ToECDSA(common.FromHex(sk)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
// Setup Keys | ||
var keys []*ecdsa.PrivateKey | ||
nKeys := c.Int(countFlag.Name) | ||
if nKeys == 0 || nKeys > len(staticKeys) { | ||
fmt.Printf("Sanitizing count flag from %v to %v\n", nKeys, len(staticKeys)) | ||
nKeys = len(staticKeys) | ||
} | ||
for i := 0; i < nKeys; i++ { | ||
keys = append(keys, crypto.ToECDSAUnsafe(common.FromHex(staticKeys[i]))) | ||
} | ||
|
||
// Setup gasLimit | ||
gasLimit := c.Int(gasLimitFlag.Name) | ||
|
||
// Setup N | ||
N := c.Int(txCountFlag.Name) | ||
if N == 0 { | ||
N, err = setupN(backend, len(keys), gasLimit) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
// Setup seed | ||
seed := c.Int64(seedFlag.Name) | ||
if seed == 0 { | ||
fmt.Println("No seed provided, creating one") | ||
rnd := make([]byte, 8) | ||
crand.Read(rnd) | ||
seed = int64(binary.BigEndian.Uint64(rnd)) | ||
} | ||
|
||
// Setup Mutator | ||
mut := mutator.NewMutator(rand.New(rand.NewSource(seed))) | ||
|
||
// Setup corpus | ||
var corpus [][]byte | ||
if corpusFile := c.String(corpusFlag.Name); corpusFile != "" { | ||
corpus, err = readCorpusElements(corpusFile) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
return &Config{ | ||
backend: backend, | ||
n: uint64(N), | ||
faucet: faucet, | ||
accessList: !c.Bool(noALFlag.Name), | ||
gasLimit: uint64(gasLimit), | ||
seed: seed, | ||
keys: keys, | ||
corpus: corpus, | ||
mut: mut, | ||
}, nil | ||
} | ||
|
||
func setupN(backend *rpc.Client, keys int, gasLimit int) (int, error) { | ||
client := ethclient.NewClient(backend) | ||
header, err := client.HeaderByNumber(context.Background(), nil) | ||
if err != nil { | ||
return 0, err | ||
} | ||
txPerBlock := int(header.GasLimit / uint64(gasLimit)) | ||
txPerAccount := txPerBlock / keys | ||
if txPerAccount == 0 { | ||
return 1, nil | ||
} | ||
return txPerAccount, nil | ||
} | ||
|
||
func readCorpusElements(path string) ([][]byte, error) { | ||
stats, err := os.ReadDir(path) | ||
if err != nil { | ||
return nil, err | ||
} | ||
corpus := make([][]byte, 0, len(stats)) | ||
for _, file := range stats { | ||
b, err := os.ReadFile(fmt.Sprintf("%v/%v", path, file.Name())) | ||
if err != nil { | ||
return nil, err | ||
} | ||
corpus = append(corpus, b) | ||
} | ||
return corpus, nil | ||
} |
Oops, something went wrong.