github.com/cgcardona/r-subnet-evm@v0.1.5/cmd/simulator/txs/tx_generator.go (about) 1 // Copyright (C) 2023, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package txs 5 6 import ( 7 "context" 8 "crypto/ecdsa" 9 "fmt" 10 11 "github.com/cgcardona/r-subnet-evm/core/types" 12 "github.com/cgcardona/r-subnet-evm/ethclient" 13 ethcrypto "github.com/ethereum/go-ethereum/crypto" 14 ) 15 16 var _ TxSequence[*types.Transaction] = (*txSequence)(nil) 17 18 type CreateTx func(key *ecdsa.PrivateKey, nonce uint64) (*types.Transaction, error) 19 20 // GenerateTxSequence fetches the current nonce of key and calls [generator] [numTxs] times sequentially to generate a sequence of transactions. 21 func GenerateTxSequence(ctx context.Context, generator CreateTx, client ethclient.Client, key *ecdsa.PrivateKey, numTxs uint64) (TxSequence[*types.Transaction], error) { 22 address := ethcrypto.PubkeyToAddress(key.PublicKey) 23 startingNonce, err := client.NonceAt(ctx, address, nil) 24 if err != nil { 25 return nil, fmt.Errorf("failed to fetch nonce for address %s: %w", address, err) 26 } 27 txs := make([]*types.Transaction, 0, numTxs) 28 for i := uint64(0); i < numTxs; i++ { 29 tx, err := generator(key, startingNonce+i) 30 if err != nil { 31 return nil, fmt.Errorf("failed to sign tx at index %d: %w", i, err) 32 } 33 txs = append(txs, tx) 34 } 35 return ConvertTxSliceToSequence(txs), nil 36 } 37 38 func GenerateTxSequences(ctx context.Context, generator CreateTx, client ethclient.Client, keys []*ecdsa.PrivateKey, txsPerKey uint64) ([]TxSequence[*types.Transaction], error) { 39 txSequences := make([]TxSequence[*types.Transaction], len(keys)) 40 for i, key := range keys { 41 txs, err := GenerateTxSequence(ctx, generator, client, key, txsPerKey) 42 if err != nil { 43 return nil, fmt.Errorf("failed to generate tx sequence at index %d: %w", i, err) 44 } 45 txSequences[i] = txs 46 } 47 return txSequences, nil 48 } 49 50 type txSequence struct { 51 txChan chan *types.Transaction 52 } 53 54 func ConvertTxSliceToSequence(txs []*types.Transaction) TxSequence[*types.Transaction] { 55 txChan := make(chan *types.Transaction, len(txs)) 56 for _, tx := range txs { 57 txChan <- tx 58 } 59 close(txChan) 60 61 return &txSequence{ 62 txChan: txChan, 63 } 64 } 65 66 func (t *txSequence) Chan() <-chan *types.Transaction { 67 return t.txChan 68 }