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  }