spamoor

package
v1.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 21, 2026 License: MIT Imports: 33 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// BatcherBaseGas is the base gas overhead of a batcher transaction
	// (tx intrinsic + batcher dispatch). Per-recipient cost is added on top by
	// WalletPool.batcherGasFor.
	BatcherBaseGas = 50000
	// BatcherDefaultGasPerTx is the legacy-model default per-recipient gas in
	// the batch, used when funding_gas_limit is not configured and the
	// pre-Amsterdam fee model is active (cpsb == 0). On Amsterdam,
	// WalletPool.batcherGasFor computes per-recipient cost dynamically from
	// target emptiness and the current cpsb.
	BatcherDefaultGasPerTx = 35000
	// BatcherRPCGasCap is the maximum gas allowed per RPC call (geth default: 16M).
	// Batch boundaries are computed to keep total gas under this cap; see
	// WalletPool.packFundingBatches.
	BatcherRPCGasCap = 16_000_000
)
View Source
const (
	// AccountCreationSize is the EIP-8037 charge unit count for creating a
	// new account. State gas = AccountCreationSize * cpsb.
	AccountCreationSize = 120
	// AuthorizationCreationSize is the EIP-8037 charge unit count applied to
	// each EIP-7702 SetCode authorization that creates a delegator account.
	AuthorizationCreationSize = 23
)

EIP-8037 spec constants reused by FundingGasFor / batcherGasFor here and by scenarios that need to size per-authorization / per-account state gas (e.g. scenarios/setcodetx).

View Source
const CostPerStateByte uint64 = 1530

CostPerStateByte is the EIP-8037 cost_per_state_byte value spamoor uses when the Amsterdam fee model is active. State-gas charges (account creation, code deposit, authorization delegators) multiply this by the per-charge size constants below.

Variables

This section is empty.

Functions

func LoadPrivateKey added in v1.1.16

func LoadPrivateKey(privkey string) (*ecdsa.PrivateKey, common.Address, error)

loadPrivateKey loads a private key from a hex string or generates a new random key. If privkey is empty, it generates a new random private key. If privkey is provided, it accepts hex strings with or without "0x" prefix. Also derives and sets the wallet's Ethereum address from the private key.

func ResolveFees added in v1.1.16

func ResolveFees(baseFeeGwei, tipFeeGwei float64, baseFeeWei, tipFeeWei string) (baseFee, tipFee *big.Int)

ResolveFees resolves fee values with precedence: Wei > Gwei > nil (network fetch). Wei values are parsed from strings to support precise sub-Gwei fees on L2s.

Types

type BatchOptions added in v1.1.6

type BatchOptions struct {
	SendTransactionOptions

	// Maximum number of pending transactions per wallet
	// If 0, no limit is enforced per wallet
	PendingLimit uint64

	// Maximum number of retries for failed submissions
	// If 0, no retries are attempted
	MaxRetries int

	// Pool of clients to assign to wallet groups
	// If set, assigns client 0 to first wallet, client 1 to second wallet, etc.
	// Cycles through the pool if there are more wallets than clients
	ClientPool  *ClientPool
	ClientGroup string // optional client group filter

	// Optional logging callback called after every LogInterval confirmed transactions
	LogFn func(confirmedCount int, totalCount int)

	// Interval for calling LogFn (number of confirmed transactions)
	// If 0, LogFn is never called
	LogInterval int
}

BatchOptions contains options for batch transaction submission.

type BlockInfo added in v1.1.3

type BlockInfo struct {
	Number     uint64
	Hash       common.Hash
	ParentHash common.Hash
	Timestamp  uint64
	GasLimit   uint64
}

BlockInfo represents information about a processed block including hash, parent hash, gas limit, and timestamp for chain reorganization detection.

type BlockStatsCallback added in v1.1.5

type BlockStatsCallback func(blockNumber uint64, walletPoolStats *WalletPoolBlockStats)

BlockStatsCallback is called when a block is processed with statistics for a specific wallet pool

type BlockSubscription added in v1.1.5

type BlockSubscription struct {
	ID         uint64
	WalletPool *WalletPool
	Callback   BlockStatsCallback
}

BlockSubscription represents a subscription to block updates for a specific wallet pool

type BlockWithHash added in v1.1.11

type BlockWithHash struct {
	Hash  common.Hash
	Block *types.Block
}

BlockWithHash represents a block with its hash.

type BulkBlockStatsCallback added in v1.1.6

type BulkBlockStatsCallback func(blockNumber uint64, globalBlockStats *GlobalBlockStats)

BulkBlockStatsCallback is called when a block is processed with statistics for ALL wallet pools

type BulkBlockSubscription added in v1.1.6

type BulkBlockSubscription struct {
	ID       uint64
	Callback BulkBlockStatsCallback
}

BulkBlockSubscription represents a subscription to block updates for ALL wallet pools

type Client added in v1.1.3

type Client struct {
	Timeout time.Duration
	// contains filtered or unexported fields
}

Client represents an Ethereum RPC client with additional functionality for transaction management, gas estimation caching, and block height tracking. It wraps the standard go-ethereum ethclient with enhanced features for spam testing and transaction automation.

func NewClient added in v1.1.3

func NewClient(options *ClientOptions) (*Client, error)

NewClient creates a new Client instance with the specified RPC host URL. The rpchost parameter supports special prefixes:

  • headers(key:value|key2:value2) - sets custom HTTP headers
  • group(name) - assigns the client to a named group (can be used multiple times)
  • group(name1,name2,name3) - assigns the client to multiple groups (comma-separated)
  • name(custom_name) - sets a custom display name override
  • type(client_type) - sets the client type (e.g., "builder" for builder clients)

Example: "headers(Authorization:Bearer token|User-Agent:MyApp)group(mainnet)group(primary)name(My Custom Node)http://localhost:8545" Example: "group(mainnet,primary,backup)name(MainNet Primary)http://localhost:8545" Example: "type(builder)group(builders)name(Builder Node)http://localhost:8545"

func (*Client) EstimateGas added in v1.2.0

func (client *Client) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error)

EstimateGas runs eth_estimateGas against the chain for the provided call message and returns the suggested gas limit. Used by deploy paths that need an accurate pre-send estimate under EIP-8037 where static guesses tend to under-allocate.

func (*Client) GetBalanceAt added in v1.1.3

func (client *Client) GetBalanceAt(ctx context.Context, wallet common.Address) (*big.Int, error)

GetBalanceAt returns the balance of the given address at the latest block.

func (*Client) GetBlockHeight added in v1.1.3

func (client *Client) GetBlockHeight(ctx context.Context) (uint64, error)

GetBlockHeight returns the current block number. Results are cached for 12 seconds to reduce RPC calls.

func (*Client) GetChainId added in v1.1.3

func (client *Client) GetChainId(ctx context.Context) (*big.Int, error)

GetChainId returns the chain ID of the connected Ethereum network.

func (*Client) GetClientGroup added in v1.1.3

func (client *Client) GetClientGroup() string

GetClientGroup returns the first client group name assigned during initialization. Defaults to "default" if no group was specified. For multiple groups, use GetClientGroups().

func (*Client) GetClientGroups added in v1.1.5

func (client *Client) GetClientGroups() []string

GetClientGroups returns all client group names assigned to this client.

func (*Client) GetClientType added in v1.1.9

func (client *Client) GetClientType() ClientType

GetClientType returns the client type. If a database override is set, it returns the override; otherwise returns the parsed type.

func (*Client) GetClientVersion added in v1.1.3

func (client *Client) GetClientVersion(ctx context.Context) (string, error)

GetClientVersion returns the client version string from the web3_clientVersion RPC call. Results are cached for 30 minutes to reduce RPC calls.

func (*Client) GetEthClient added in v1.1.3

func (client *Client) GetEthClient() *ethclient.Client

GetEthClient returns the underlying go-ethereum ethclient.Client instance.

func (*Client) GetLastBlockHeight added in v1.1.3

func (client *Client) GetLastBlockHeight() (uint64, time.Time)

GetLastBlockHeight returns the last cached block height and the time it was retrieved.

func (*Client) GetName added in v1.1.3

func (client *Client) GetName() string

GetName returns a shortened name for the client derived from the RPC host URL, removing common suffixes like ".ethpandaops.io". If a name override is set, it returns the override instead.

func (*Client) GetNameOverride added in v1.1.6

func (client *Client) GetNameOverride() string

GetNameOverride returns the name override for the client.

func (*Client) GetNonceAt added in v1.1.3

func (client *Client) GetNonceAt(ctx context.Context, wallet common.Address, blockNumber *big.Int) (uint64, error)

GetNonceAt returns the nonce for the given address at the specified block number. If blockNumber is nil, returns the nonce at the latest block.

func (*Client) GetPendingNonceAt added in v1.1.3

func (client *Client) GetPendingNonceAt(ctx context.Context, wallet common.Address) (uint64, error)

GetPendingNonceAt returns the pending nonce for the given address, including transactions in the mempool.

func (*Client) GetRPCHost added in v1.1.3

func (client *Client) GetRPCHost() string

GetRPCHost returns the original RPC host URL used to create this client.

func (*Client) GetRequestStats added in v1.1.9

func (client *Client) GetRequestStats() (total, txRequests, rpcFailures uint64)

GetRequestStats returns the current request statistics for this client. Returns total requests, transaction requests, and RPC failures.

func (*Client) GetSuggestedFee added in v1.1.3

func (client *Client) GetSuggestedFee(ctx context.Context) (*big.Int, *big.Int, error)

GetSuggestedFee returns suggested gas price and tip cap for transactions. Results are cached for 12 seconds to reduce RPC calls. Returns (gasCap, tipCap, error).

func (*Client) GetTransactionReceipt added in v1.1.4

func (client *Client) GetTransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)

GetTransactionReceipt retrieves the receipt for a given transaction hash. Logs the request at trace level.

func (*Client) HasGroup added in v1.1.5

func (client *Client) HasGroup(group string) bool

HasGroup checks if the client belongs to the specified group.

func (*Client) IsBuilder added in v1.1.9

func (client *Client) IsBuilder() bool

IsBuilder returns true if the client is a builder type. Uses the database override if available, otherwise the parsed type.

func (*Client) IsEnabled added in v1.1.5

func (client *Client) IsEnabled() bool

IsEnabled returns whether the client is enabled for selection.

func (*Client) SendRawTransaction added in v1.1.4

func (client *Client) SendRawTransaction(ctx context.Context, tx []byte) error

SendRawTransaction submits a raw transaction bytes to the network using eth_sendRawTransaction RPC call.

func (*Client) SendTransaction added in v1.1.4

func (client *Client) SendTransaction(ctx context.Context, tx *types.Transaction) error

SendTransaction submits a transaction to the network using the provided context. Logs the transaction hash at trace level.

func (*Client) SetClientGroups added in v1.1.5

func (client *Client) SetClientGroups(groups []string)

SetClientGroups sets multiple client group names for the client, replacing all existing groups.

func (*Client) SetClientTypeOverride added in v1.1.9

func (client *Client) SetClientTypeOverride(clientType string)

SetClientTypeOverride sets a client type override from the database. If set, this type will be used instead of the type parsed from the RPC URL.

func (*Client) SetEnabled added in v1.1.5

func (client *Client) SetEnabled(enabled bool)

SetEnabled sets the enabled state of the client. Disabled clients will not be considered for selection in the client pool.

func (*Client) SetNameOverride added in v1.1.6

func (client *Client) SetNameOverride(name string)

SetNameOverride sets a custom name override for the client. If set, this name will be used instead of the auto-generated name from the RPC host.

func (*Client) UpdateWallet added in v1.1.3

func (client *Client) UpdateWallet(ctx context.Context, wallet *Wallet) error

UpdateWallet refreshes the wallet's chain ID, nonce, and balance by querying the blockchain. If the wallet doesn't have a chain ID set, it will be fetched and assigned.

type ClientOptions added in v1.1.16

type ClientOptions struct {
	RpcHost        string
	ExternalClient *ExternalClientOptions
}

type ClientPool

type ClientPool struct {
	// contains filtered or unexported fields
}

ClientPool manages a pool of Ethereum RPC clients with health monitoring and selection strategies. It automatically monitors client health by checking block heights and maintains a list of "good" clients that are within 2 blocks of the highest observed block height.

func NewClientPool

func NewClientPool(ctx context.Context, logger logrus.FieldLogger) *ClientPool

NewClientPool creates a new ClientPool with the specified RPC hosts and logger. The pool must be initialized with InitClients() and prepared with PrepareClients() before use.

func (*ClientPool) GetAllClients

func (pool *ClientPool) GetAllClients() []*Client

GetAllClients returns a copy of all clients in the pool, regardless of their health status.

func (*ClientPool) GetAllGoodClients

func (pool *ClientPool) GetAllGoodClients() []*Client

GetAllGoodClients returns a copy of all clients currently considered healthy (within 2 blocks of the highest observed block height).

func (*ClientPool) GetChainId added in v1.1.16

func (pool *ClientPool) GetChainId() *big.Int

GetChainId returns the chain ID of the clients in the pool.

func (*ClientPool) GetClient

func (pool *ClientPool) GetClient(options ...ClientSelectionOption) *Client

GetClient returns a client from the pool based on the specified options. By default, it uses round-robin selection with the default group and no type exclusions.

Available options:

  • WithSelectionMode(mode, index...): Set selection mode (ByIndex, Random, RoundRobin), index optional for ByIndex
  • WithClientGroup(group): Set group filter ("" for default, "*" for any, or group name)
  • WithoutBuilder(): Exclude builder clients
  • WithoutClientType(type): Exclude clients of specified type

Examples:

  • pool.GetClient() // Round-robin from default group
  • pool.GetClient(WithSelectionMode(SelectClientRandom)) // Random from default group
  • pool.GetClient(WithClientGroup("builders")) // Round-robin from builders group
  • pool.GetClient(WithoutBuilder()) // Round-robin excluding builders
  • pool.GetClient(WithSelectionMode(SelectClientByIndex, 2)) // Select by index 2

Returns nil if no suitable clients are available.

func (*ClientPool) InitClients added in v1.1.10

func (pool *ClientPool) InitClients(clientOptions []*ClientOptions) error

InitClients initializes the clients in the pool.

func (*ClientPool) PrepareClients

func (pool *ClientPool) PrepareClients() error

PrepareClients initializes all clients in the pool and starts health monitoring. It creates Client instances for each RPC host, determines the chain ID, and begins periodic health checks. Returns an error if no usable clients are found.

type ClientSelectionMode

type ClientSelectionMode uint8

ClientSelectionMode defines how clients are selected from the pool.

var (
	// SelectClientByIndex selects a client by index (modulo pool size).
	SelectClientByIndex ClientSelectionMode = 0
	// SelectClientRandom selects a random client from the pool.
	SelectClientRandom ClientSelectionMode = 1
	// SelectClientRoundRobin selects clients in round-robin fashion.
	SelectClientRoundRobin ClientSelectionMode = 2
)

type ClientSelectionOption added in v1.1.9

type ClientSelectionOption interface {
	// contains filtered or unexported methods
}

ClientSelectionOption represents an option that can be passed to GetClient.

func WithClientGroup added in v1.1.9

func WithClientGroup(group string) ClientSelectionOption

WithClientGroup sets the client group filter. Use "" for default group, "*" for any group, or specify a group name.

func WithClientSelectionMode added in v1.1.9

func WithClientSelectionMode(mode ClientSelectionMode, args ...int) ClientSelectionOption

WithClientSelectionMode sets the client selection mode. For SelectClientByIndex mode, provide the index as the second parameter.

func WithoutBuilder added in v1.1.9

func WithoutBuilder() ClientSelectionOption

WithoutBuilder excludes builder clients from selection.

func WithoutClientType added in v1.1.9

func WithoutClientType(clientType ClientType) ClientSelectionOption

WithoutClientType excludes clients of the specified type from selection.

type ClientType added in v1.1.9

type ClientType string

ClientType represents the type of Ethereum client

const (
	ClientTypeClient  ClientType = "client"
	ClientTypeBuilder ClientType = "builder"
)

func (ClientType) IsValid added in v1.1.9

func (ct ClientType) IsValid() bool

IsValid checks if the client type is valid

func (ClientType) String added in v1.1.9

func (ct ClientType) String() string

String returns the string representation of the client type

type ExternalBlockEvent added in v1.1.16

type ExternalBlockEvent struct {
	Number   uint64
	Clients  []*Client
	Block    *BlockWithHash
	Receipts []*types.Receipt
}

type ExternalBlockSource added in v1.1.16

type ExternalBlockSource struct {
	SubscribeBlocks func(ctx context.Context, capacity int) chan *ExternalBlockEvent
}

type ExternalClientOptions added in v1.1.16

type ExternalClientOptions struct {
	GetBlockHeight func(ctx context.Context) (uint64, error)
}

type FundingRequest added in v1.1.3

type FundingRequest struct {
	Wallet *Wallet
	Amount *uint256.Int
	// IsEmpty is true when the target wallet was observed as nonce==0 and
	// balance==0 at request-build time. Under EIP-8037/EIP-2780 a transfer
	// to an empty account additionally costs AccountCreationSize*cpsb state
	// gas, so the funding path must reserve more gas for it.
	IsEmpty bool
}

FundingRequest represents a request to fund a wallet with a specific amount. Used internally for batch funding operations.

type GlobalBlockStats added in v1.1.8

type GlobalBlockStats struct {
	Block           *types.Block
	Receipts        []*types.Receipt
	WalletPoolStats map[*WalletPool]*WalletPoolBlockStats
}

type PendingTx added in v1.1.8

type PendingTx struct {
	Tx               *types.Transaction
	Submitted        time.Time
	LastRebroadcast  time.Time
	RebroadcastCount uint64
	Options          *SendTransactionOptions
}

type RootWallet added in v1.1.3

type RootWallet struct {
	// contains filtered or unexported fields
}

RootWallet represents a primary wallet with transaction rate limiting and batching capabilities. It wraps a standard Wallet with a semaphore-based transaction limiter and optional transaction batcher for managing high-volume transaction scenarios.

func InitRootWallet

func InitRootWallet(ctx context.Context, privkey string, clientPool *ClientPool, txpool *TxPool, logger logrus.FieldLogger) (*RootWallet, error)

InitRootWallet creates and initializes a new RootWallet from a private key. It creates the underlying wallet, updates its state from the blockchain, and sets up transaction rate limiting with a default limit of 200 concurrent transactions. Returns the initialized RootWallet and logs wallet information if logger is provided. If a client fails, it will retry with other available clients before giving up.

func (*RootWallet) GetTxBatcher added in v1.1.3

func (wallet *RootWallet) GetTxBatcher() *TxBatcher

GetTxBatcher returns the transaction batcher instance, or nil if not initialized.

func (*RootWallet) GetWallet added in v1.1.3

func (wallet *RootWallet) GetWallet() *Wallet

GetWallet returns the underlying Wallet instance.

func (*RootWallet) InitTxBatcher added in v1.1.3

func (wallet *RootWallet) InitTxBatcher(ctx context.Context, txpool *TxPool)

InitTxBatcher initializes the transaction batcher with the specified transaction pool. This enables batched transaction processing for improved efficiency.

func (*RootWallet) Shutdown added in v1.1.10

func (wallet *RootWallet) Shutdown()

Shutdown gracefully shuts down the root wallet and stops the balance updater.

func (*RootWallet) WithWalletLock added in v1.1.3

func (wallet *RootWallet) WithWalletLock(ctx context.Context, txCount int, fundingAmount *uint256.Int, clientPool *ClientPool, lockedLogFn func(reason string), lockedFn func() error) error

WithWalletLock executes a function while holding transaction semaphore locks and ensuring sufficient balance. It first waits for sufficient balance (including pending amounts), then acquires the specified number of transaction slots from the semaphore, reserves the funding amount, and executes the locked function. The locks and funding reservation are automatically released when the function returns.

Parameters:

  • ctx: context for cancellation
  • txCount: number of transaction slots to acquire
  • fundingAmount: total amount to reserve from wallet balance (nil to skip balance check)
  • clientPool: client pool for balance updates during waiting
  • lockedLogFn: optional function called once when waiting for locks (can be nil)
  • lockedFn: function to execute while holding the locks

type SendTransactionOptions added in v1.1.3

type SendTransactionOptions struct {
	// Client to use for sending (optional, uses pool selection if nil)
	Client *Client
	// ClientGroup to prefer when selecting clients
	ClientGroup string
	// ClientList to use for sending (optional, uses pool selection if nil)
	ClientList []*Client
	// ClientsStartOffset for client selection
	ClientsStartOffset int
	// SubmitCount is the number of times to submit the transaction in the first attempt (default 3)
	SubmitCount int

	// Enable reliable rebroadcasting
	Rebroadcast bool

	// Callbacks
	OnConfirm  TxConfirmFn  // Called only if tx was sent successfully and confirmed
	OnComplete TxCompleteFn // Always called when processing completes
	OnEncode   TxEncodeFn   // Called to encode tx to bytes on-demand
	LogFn      TxLogFn      // Custom logging function (uses default if nil)
}

SendTransactionOptions contains options for transaction submission including client selection, confirmation callbacks, rebroadcast settings, and logging.

type TxBatcher added in v1.1.3

type TxBatcher struct {
	// contains filtered or unexported fields
}

TxBatcher manages the deployment and operation of a smart contract that batches multiple fund transfers into a single transaction. It compiles and deploys assembly code that efficiently forwards funds to multiple recipients.

func NewTxBatcher added in v1.1.3

func NewTxBatcher(txpool *TxPool) *TxBatcher

NewTxBatcher creates a new TxBatcher instance with the specified transaction pool. The batcher must be deployed with Deploy() before it can be used.

func (*TxBatcher) Deploy added in v1.1.3

func (b *TxBatcher) Deploy(ctx context.Context, wallet *Wallet, client *Client) error

Deploy compiles and deploys the batcher smart contract to the blockchain. It uses assembly code to create an efficient contract that can forward funds to multiple addresses in a single transaction. The deployment is protected by a mutex to ensure it only happens once.

Parameters:

  • ctx: context for the deployment transaction
  • wallet: wallet to deploy the contract from
  • client: optional client to use (if nil, uses pool's default client)

func (*TxBatcher) GetAddress added in v1.1.3

func (b *TxBatcher) GetAddress() common.Address

GetAddress returns the deployed contract address. Returns zero address if the contract hasn't been deployed yet.

func (*TxBatcher) GetRequestCalldata added in v1.1.3

func (b *TxBatcher) GetRequestCalldata(requests []*FundingRequest) ([]byte, error)

GetRequestCalldata encodes funding requests into calldata format expected by the batcher contract. Each request is encoded as 32 bytes: 20 bytes for the address and 12 bytes for the amount. Returns the encoded calldata that can be used in a transaction to the batcher contract.

type TxCompleteFn added in v1.1.6

type TxCompleteFn func(tx *types.Transaction, receipt *types.Receipt, err error)

TxCompleteFn is a callback function called when transaction processing is complete (confirmed or failed). Always called regardless of success/failure.

type TxConfirmFn added in v1.1.3

type TxConfirmFn func(tx *types.Transaction, receipt *types.Receipt)

TxConfirmFn is a callback function called when a transaction is confirmed or fails. It receives the transaction, receipt (if successful), and any error that occurred.

type TxEncodeFn added in v1.1.6

type TxEncodeFn func(tx *types.Transaction) ([]byte, error)

TxEncodeFn is a callback function called to encode a transaction to bytes. It receives the transaction and should return the encoded bytes.

type TxInfo added in v1.1.3

type TxInfo struct {
	TxHash     common.Hash
	From       common.Address
	To         *common.Address
	Tx         *types.Transaction
	TxFees     *utils.TxFees
	FromWallet *Wallet
	ToWallet   *Wallet
	Options    *SendTransactionOptions
}

TxInfo represents information about a confirmed transaction including the transaction details, associated wallets, and send options.

type TxLogFn added in v1.1.3

type TxLogFn func(client *Client, retry int, rebroadcast int, err error)

TxLogFn is a callback function for logging transaction submission attempts. It receives the client used, retry count, rebroadcast count, and any error.

func GetDefaultLogFn added in v1.1.6

func GetDefaultLogFn(logger logrus.FieldLogger, txTypeName string, txIdx string, tx *types.Transaction) TxLogFn

type TxPool added in v1.1.3

type TxPool struct {
	// contains filtered or unexported fields
}

TxPool manages transaction submission, confirmation tracking, and chain reorganization handling. It monitors blockchain blocks, tracks transaction confirmations, handles reorgs by re-submitting affected transactions, and provides transaction awaiting functionality with automatic rebroadcasting.

func NewTxPool added in v1.1.3

func NewTxPool(options *TxPoolOptions) *TxPool

NewTxPool creates a new transaction pool with the specified options. It starts background goroutines for block processing and stale transaction handling. The pool automatically begins monitoring the blockchain for new blocks and managing transaction confirmations and reorgs.

func (*TxPool) AwaitTransaction added in v1.1.3

func (p *TxPool) AwaitTransaction(ctx context.Context, wallet *Wallet, tx *types.Transaction) (*types.Receipt, error)

Await waits for a transaction to be confirmed and returns its receipt. It monitors the blockchain for the transaction and handles reorgs by continuing to wait if the transaction gets reorged out of the chain.

func (*TxPool) GetActiveWalletPools added in v1.1.6

func (pool *TxPool) GetActiveWalletPools() []*WalletPool

GetActiveWalletPools returns all active wallet pools

func (*TxPool) GetCostPerStateByte added in v1.2.0

func (pool *TxPool) GetCostPerStateByte() uint64

GetCostPerStateByte returns the EIP-8037 cost_per_state_byte spamoor charges for state-creation gas budgeting. Returns the flat CostPerStateByte constant on Amsterdam (default), or 0 when the pre-Amsterdam fee model is forced.

func (*TxPool) GetCurrentBaseFee added in v1.1.6

func (pool *TxPool) GetCurrentBaseFee() *big.Int

GetCurrentBaseFee returns the current base fee of the chain.

func (*TxPool) GetCurrentBaseFeeWithInit added in v1.1.6

func (pool *TxPool) GetCurrentBaseFeeWithInit() (*big.Int, error)

GetCurrentBaseFeeWithInit returns the current base fee. With the current startup sequence (InitializeBlockStats runs before scenarios start) the state is always populated, but the lazy-init fallback is retained for plugin ABI compatibility.

func (*TxPool) GetCurrentGasLimit added in v1.1.5

func (pool *TxPool) GetCurrentGasLimit() uint64

GetCurrentGasLimit returns the current gas limit of the chain.

func (*TxPool) GetCurrentGasLimitWithInit added in v1.1.5

func (pool *TxPool) GetCurrentGasLimitWithInit() (uint64, error)

GetCurrentGasLimitWithInit returns the current gas limit. With the current startup sequence (InitializeBlockStats runs before scenarios start) the state is always populated, but the lazy-init fallback is retained for plugin ABI compatibility.

func (*TxPool) GetRecentBlockGasTotals added in v1.2.0

func (pool *TxPool) GetRecentBlockGasTotals() (totalGasUsed, totalGasLimit uint64)

GetRecentBlockGasTotals returns the sum of gas used and gas limits over the recent block window. Must not hold blockStatsMutex.

func (*TxPool) GetRegisteredWallet added in v1.1.16

func (pool *TxPool) GetRegisteredWallet(address common.Address) *Wallet

GetRegisteredWallet returns a wallet by address.

func (*TxPool) GetSuggestedFees added in v1.1.6

func (pool *TxPool) GetSuggestedFees(client *Client, baseFeeWei *big.Int, tipFeeWei *big.Int, feeStrategy ...string) (feeCap *big.Int, tipCap *big.Int, err error)

GetSuggestedFees returns the suggested fees for a transaction. If baseFeeWei and tipFeeWei are provided (non-nil), they are used directly. If not provided (nil), the fees are fetched from the client.

With FeeStrategy "adaptive", the dynamic fee mechanism computes feeCap from the current baseFee with adaptive headroom and normal distribution spread, using baseFeeWei as a maximum cap instead.

func (*TxPool) HasObservedHead added in v1.2.0

func (pool *TxPool) HasObservedHead() bool

HasObservedHead reports whether the pool has loaded chain state via InitializeBlockStats or processBlock. With the current startup sequence this always returns true once scenarios are running; the method is retained for plugin ABI compatibility.

func (*TxPool) InitializeBlockStats added in v1.2.0

func (pool *TxPool) InitializeBlockStats(ctx context.Context) error

InitializeBlockStats fetches the current block stats from the network and must be called once during startup, after the client pool is prepared and before any scenario starts using the txpool. It blocks (with backoff) until either a head block is loaded or ctx is cancelled, so that downstream code can rely on GetCurrentBaseFee / GetCurrentGasLimit / IsAmsterdam returning real chain state. The call is idempotent: a second invocation with already populated state returns immediately.

func (*TxPool) IsAmsterdam added in v1.2.0

func (pool *TxPool) IsAmsterdam() bool

IsAmsterdam reports whether spamoor uses the Amsterdam (EIP-8037) gas/fee model. Defaults to true; set TxPoolOptions.PreAmsterdamFeeModel to true to force the legacy model. The Amsterdam model is safe to keep on non-Amsterdam chains because its gas budgets are strictly higher than the legacy ones.

func (*TxPool) MaxTxGas added in v1.2.0

func (pool *TxPool) MaxTxGas() uint64

MaxTxGas returns the effective per-tx gas cap for the connected chain. On Amsterdam, EIP-8037 caps only the state-creation portion at EIP-7825's TX_MAX_GAS_LIMIT (16,777,216) while regular (compute) gas is bounded only by the block gas limit, so MaxTxGas returns the block gas limit. Pre-Amsterdam the cap is utils.MaxGasLimitPerTx, clamped to the block limit on chains whose block limit is below 16.7M.

func (*TxPool) MinIntrinsicGas added in v1.2.0

func (pool *TxPool) MinIntrinsicGas() uint64

MinIntrinsicGas returns the base intrinsic gas cost for a simple ETH transfer to an existing recipient (no calldata, no account creation). This is the minimum tx.Gas value any transaction must set, and the value our filler / funding paths use as the per-tx baseline.

Currently always returns 21,000. Geth removed the prior +10% txpool intrinsic buffer, so the raw base cost is what the validator enforces.

EIP-2780 (Reduce intrinsic transaction gas) will lower this base cost once activated (4,500 base + accessory charges that vary by tx shape; ~7,756 for a value transfer to an existing account). Centralized here so consumers update through a single method when EL clients ship 2780.

func (*TxPool) RegisterWallet added in v1.1.16

func (pool *TxPool) RegisterWallet(wallet *Wallet, ctx context.Context) *Wallet

RegisterWallet registers a wallet with the transaction pool. It is used to track the wallets that are active and need to be processed. The registration is removed when the context is cancelled.

func (*TxPool) RegisterWalletPool added in v1.1.16

func (pool *TxPool) RegisterWalletPool(walletPool *WalletPool)

RegisterWalletPool registers a wallet pool with the transaction pool. It is used to track the wallet pools that are active and need to be processed.

func (*TxPool) SendAndAwaitTransaction added in v1.1.6

func (p *TxPool) SendAndAwaitTransaction(ctx context.Context, wallet *Wallet, tx *types.Transaction, opts *SendTransactionOptions) (*types.Receipt, error)

SendAndAwaitTransaction submits a transaction with custom options and waits for confirmation. Allows specifying client preferences, rebroadcast settings, etc.

Example:

options := &SendOptions{
    Client: specificClient,
    Rebroadcast: true,
}
receipt, err := submitter.SendAndAwaitTransaction(ctx, wallet, tx, options)

func (*TxPool) SendMultiTransactionBatch added in v1.1.6

func (p *TxPool) SendMultiTransactionBatch(ctx context.Context, walletTxs map[*Wallet][]*types.Transaction, opts *BatchOptions) (map[*Wallet][]*types.Receipt, error)

SendMultiTransactionBatch submits transactions for multiple wallets with sliding window submission. Returns receipts in the same order as input transactions for each wallet. Respects both per-wallet PendingLimit and GlobalPendingLimit to control concurrent submissions. Implements retry logic with MaxRetries for failed submissions.

Example:

options := &BatchOptions{
    SendTransactionOptions: SendTransactionOptions{Rebroadcast: true},
    PendingLimit: 50, // 50 pending per wallet
    MaxRetries: 3,    // 3 retries per transaction
}
receipts, err := submitter.SendMultiTransactionBatch(ctx, walletTxs, options)

func (*TxPool) SendTransaction added in v1.1.3

func (p *TxPool) SendTransaction(ctx context.Context, wallet *Wallet, tx *types.Transaction, opts *SendTransactionOptions) error

SendTransaction submits a single transaction with the given options. This is a lower-level interface that provides access to all callback options.

func (*TxPool) SendTransactionBatch added in v1.1.6

func (p *TxPool) SendTransactionBatch(ctx context.Context, wallet *Wallet, txs []*types.Transaction, opts *BatchOptions) ([]*types.Receipt, error)

SendBatchWithOptions submits multiple transactions with custom options and waits for all confirmations. Returns receipts in the same order as input transactions. Respects PendingLimit to control concurrent submissions.

Example:

options := &BatchOptions{
    SendOptions: SendOptions{Rebroadcast: true},
    PendingLimit: 100,
}
receipts, err := submitter.SendBatchWithOptions(ctx, wallet, txs, options)

func (*TxPool) SubscribeToBlockUpdates added in v1.1.5

func (pool *TxPool) SubscribeToBlockUpdates(walletPool *WalletPool, callback BlockStatsCallback) uint64

SubscribeToBlockUpdates subscribes to block update notifications for a specific wallet pool. Returns a unique subscription ID that can be used to unsubscribe later.

func (*TxPool) SubscribeToBulkBlockUpdates added in v1.1.6

func (pool *TxPool) SubscribeToBulkBlockUpdates(callback BulkBlockStatsCallback) uint64

SubscribeToBulkBlockUpdates subscribes to block update notifications for ALL wallet pools. Returns a unique subscription ID that can be used to unsubscribe later.

func (*TxPool) UnsubscribeFromBlockUpdates added in v1.1.5

func (pool *TxPool) UnsubscribeFromBlockUpdates(id uint64)

UnsubscribeFromBlockUpdates removes a block update subscription.

func (*TxPool) UnsubscribeFromBulkBlockUpdates added in v1.1.6

func (pool *TxPool) UnsubscribeFromBulkBlockUpdates(id uint64)

UnsubscribeFromBulkBlockUpdates removes a bulk block update subscription.

type TxPoolOptions added in v1.1.3

type TxPoolOptions struct {
	Context             context.Context
	Logger              *logrus.Entry
	ClientPool          *ClientPool
	ReorgDepth          int // Number of blocks to keep in memory for reorg tracking
	ChainId             *big.Int
	ExternalBlockSource *ExternalBlockSource
	// PreAmsterdamFeeModel forces the legacy (pre-EIP-8037) gas/fee model.
	// When false (default) spamoor uses the Amsterdam fee model, which is
	// safe to keep on non-Amsterdam chains because its gas budgets are
	// strictly higher than the legacy ones.
	PreAmsterdamFeeModel bool
}

TxPoolOptions contains configuration options for the transaction pool.

type Wallet added in v1.1.3

type Wallet struct {
	// contains filtered or unexported fields
}

Wallet represents an Ethereum wallet with private key management, nonce tracking, and balance management. It provides thread-safe operations for transaction building, nonce management, and balance updates. The wallet automatically handles nonce sequencing and provides confirmation tracking for submitted transactions.

func NewWallet added in v1.1.3

func NewWallet(privkey *ecdsa.PrivateKey, address common.Address) *Wallet

NewWallet creates a new wallet from a private key string. If privkey is empty, generates a new random private key. The privkey parameter accepts hex strings with or without "0x" prefix.

func (*Wallet) AddBalance added in v1.1.3

func (wallet *Wallet) AddBalance(amount *big.Int)

AddBalance adds the specified amount to the wallet's balance. This is typically called when the wallet receives funds.

func (*Wallet) BuildAccessListTx added in v1.1.15

func (wallet *Wallet) BuildAccessListTx(txData *types.AccessListTx) (*types.Transaction, error)

BuildAccessListTx builds and signs an access list transaction. It automatically assigns the next available nonce and signs the transaction.

func (*Wallet) BuildBlobTx added in v1.1.3

func (wallet *Wallet) BuildBlobTx(txData *types.BlobTx) (*types.Transaction, error)

BuildBlobTx builds and signs a blob transaction (EIP-4844). It automatically assigns the next available nonce and signs the transaction.

func (*Wallet) BuildBoundTx added in v1.1.3

func (wallet *Wallet) BuildBoundTx(ctx context.Context, txData *txbuilder.TxMetadata, buildFn func(transactOpts *bind.TransactOpts) (*types.Transaction, error)) (*types.Transaction, error)

BuildBoundTx builds a transaction using the go-ethereum bind package. It sets up a TransactOpts with the wallet's credentials and calls the provided buildFn to construct the actual transaction. Useful for contract interactions.

func (*Wallet) BuildBoundTxWithEstimate added in v1.2.0

func (wallet *Wallet) BuildBoundTxWithEstimate(
	ctx context.Context,
	client *Client,
	txpool *TxPool,
	txData *txbuilder.TxMetadata,
	buildFn func(transactOpts *bind.TransactOpts) (*types.Transaction, error),
) (*types.Transaction, error)

BuildBoundTxWithEstimate is a gas-estimating variant of BuildBoundTx for deployment paths (and other large infrequent calls like factory deploys) where static gas guesses tend to under-allocate under EIP-8037 state creation costs. Flow:

  1. Build the tx with a large placeholder gas so abigen does not try to self-estimate.
  2. Run eth_estimateGas against the resulting {from, to, data, value}.
  3. Apply the fee-model-aware buffer (and cpsb when known) to the RPC result.
  4. Clamp to the current block gas limit so the tx isn't doomed to be skipped for "gas limit reached" at block building time.
  5. Re-sign the tx with the refined gas at the same nonce.

If txData.Gas is non-zero, the explicit value is honored and estimation is skipped. If the RPC round-trip fails, a size-based formula fallback is used (conservative on the high side since deploys are rare init steps).

Works for both contract creation (tx.To() == nil) and call txs (e.g., CREATE2 via factory). Only supports DynamicFeeTx tx types; other types return the placeholder-sized tx unchanged.

Pass the wallet pool's TxPool so the active fee model, current cost-per-state-byte, and block gas limit are used by the estimator.

func (*Wallet) BuildDynamicFeeTx added in v1.1.3

func (wallet *Wallet) BuildDynamicFeeTx(txData *types.DynamicFeeTx) (*types.Transaction, error)

BuildDynamicFeeTx builds and signs a dynamic fee (EIP-1559) transaction. It automatically assigns the next available nonce and signs the transaction.

func (*Wallet) BuildFillerTx added in v1.1.15

func (wallet *Wallet) BuildFillerTx(nonce uint64, gasTipCap, gasFeeCap *big.Int, gas uint64) (*types.Transaction, error)

BuildFillerTx creates a simple self-transfer transaction to fill a nonce gap. The transaction sends 0 value to the wallet's own address. Callers pass the target gas value; pool-level callers should use TxPool.MinIntrinsicGas so they automatically follow EIP-2780 once it ships.

func (*Wallet) BuildLegacyTx added in v1.1.15

func (wallet *Wallet) BuildLegacyTx(txData *types.LegacyTx) (*types.Transaction, error)

BuildLegacyTx builds and signs a legacy transaction. It automatically assigns the next available nonce and signs the transaction.

func (*Wallet) BuildSetCodeTx added in v1.1.3

func (wallet *Wallet) BuildSetCodeTx(txData *types.SetCodeTx) (*types.Transaction, error)

BuildSetCodeTx builds and signs a set code transaction (EIP-7702). It automatically assigns the next available nonce and signs the transaction.

func (*Wallet) GetAddress added in v1.1.3

func (wallet *Wallet) GetAddress() common.Address

GetAddress returns the Ethereum address associated with this wallet.

func (*Wallet) GetBalance added in v1.1.3

func (wallet *Wallet) GetBalance() *big.Int

GetBalance returns the current balance of the wallet. The returned value is thread-safe to read.

func (*Wallet) GetChainId added in v1.1.3

func (wallet *Wallet) GetChainId() *big.Int

GetChainId returns the chain ID this wallet is configured for. Returns nil if no chain ID has been set.

func (*Wallet) GetConfirmedNonce added in v1.1.3

func (wallet *Wallet) GetConfirmedNonce() uint64

GetConfirmedNonce returns the last confirmed nonce for this wallet. This represents the highest nonce that has been confirmed on-chain.

func (*Wallet) GetLowestPendingNonce added in v1.1.15

func (wallet *Wallet) GetLowestPendingNonce() (uint64, bool)

GetLowestPendingNonce returns the lowest pending nonce for this wallet. Returns 0, false if there are no pending transactions.

func (*Wallet) GetNextNonce added in v1.1.3

func (wallet *Wallet) GetNextNonce() uint64

GetNextNonce atomically increments and returns the next available nonce. This is used when building transactions to ensure unique nonces. It first checks for any skipped nonces that can be reused.

func (*Wallet) GetNonce added in v1.1.3

func (wallet *Wallet) GetNonce() uint64

GetNonce returns the current pending nonce for this wallet. This nonce is the next nonce that should be used for the next transaction, but it is for informational purposes only. To actually use a nonce, you need to call GetNextNonce() which will increment the nonce and return the next nonce.

func (*Wallet) GetNonceGaps added in v1.1.15

func (wallet *Wallet) GetNonceGaps() []uint64

GetNonceGaps returns missing nonces between confirmedTxCount and the lowest pending nonce. This helps detect nonce gaps that need to be filled with dummy transactions.

func (*Wallet) GetPendingTx added in v1.1.8

func (wallet *Wallet) GetPendingTx(tx *types.Transaction) *PendingTx

func (*Wallet) GetPendingTxs added in v1.1.8

func (wallet *Wallet) GetPendingTxs() []*PendingTx

func (*Wallet) GetPrivateKey added in v1.1.3

func (wallet *Wallet) GetPrivateKey() *ecdsa.PrivateKey

GetPrivateKey returns the wallet's private key. Returns nil if the wallet is protected (e.g. the root wallet). Handle with care to avoid exposing sensitive data.

func (*Wallet) GetReadableBalance added in v1.1.16

func (wallet *Wallet) GetReadableBalance(unitDigits, maxPreCommaDigitsBeforeTrim, digits int, addPositiveSign, trimAmount bool) string

func (*Wallet) GetSubmittedTxCount added in v1.1.6

func (wallet *Wallet) GetSubmittedTxCount() uint64

GetSubmittedTxCount returns the total number of transactions submitted by this wallet. This represents the cumulative count of all transactions that have been submitted to the network.

func (*Wallet) IncrementSubmittedTxCount added in v1.1.6

func (wallet *Wallet) IncrementSubmittedTxCount()

IncrementSubmittedTxCount increments the submitted transaction counter. This should be called when a transaction is successfully submitted to the network.

func (*Wallet) MarkNeedResync added in v1.1.10

func (wallet *Wallet) MarkNeedResync()

func (*Wallet) MarkSkippedNonce added in v1.1.10

func (wallet *Wallet) MarkSkippedNonce(nonce uint64)

MarkSkippedNonce marks a nonce as skipped/failed so it can be reused later. This should be called when a transaction fails to submit.

func (*Wallet) ReplaceAccessListTx added in v1.1.15

func (wallet *Wallet) ReplaceAccessListTx(txData *types.AccessListTx, nonce uint64) (*types.Transaction, error)

ReplaceAccessListTx builds a replacement access list transaction with a specific nonce. This is useful for replacing stuck transactions with higher gas prices.

func (*Wallet) ReplaceBlobTx added in v1.1.3

func (wallet *Wallet) ReplaceBlobTx(txData *types.BlobTx, nonce uint64) (*types.Transaction, error)

ReplaceBlobTx builds a replacement blob transaction with a specific nonce. This is useful for replacing stuck blob transactions with higher gas prices.

func (*Wallet) ReplaceDynamicFeeTx added in v1.1.3

func (wallet *Wallet) ReplaceDynamicFeeTx(txData *types.DynamicFeeTx, nonce uint64) (*types.Transaction, error)

ReplaceDynamicFeeTx builds a replacement dynamic fee transaction with a specific nonce. This is useful for replacing stuck transactions with higher gas prices.

func (*Wallet) ReplaceLegacyTx added in v1.1.15

func (wallet *Wallet) ReplaceLegacyTx(txData *types.LegacyTx, nonce uint64) (*types.Transaction, error)

ReplaceLegacyTx builds a replacement legacy transaction with a specific nonce. This is useful for replacing stuck transactions with higher gas prices.

func (*Wallet) ReplaceSetCodeTx added in v1.1.16

func (wallet *Wallet) ReplaceSetCodeTx(txData *types.SetCodeTx, nonce uint64) (*types.Transaction, error)

ReplaceSetCodeTx builds a replacement set code transaction with a specific nonce. This is useful for replacing stuck set code transactions with higher gas prices.

func (*Wallet) ResetNoncesIfNeeded added in v1.1.10

func (wallet *Wallet) ResetNoncesIfNeeded(ctx context.Context, client *Client) error

func (*Wallet) SetAddress added in v1.1.3

func (wallet *Wallet) SetAddress(address common.Address)

SetAddress updates the wallet's Ethereum address. This is typically only used for special cases or testing.

func (*Wallet) SetBalance added in v1.1.3

func (wallet *Wallet) SetBalance(balance *big.Int)

SetBalance sets the wallet's balance to the specified amount. This is typically called when syncing wallet state with the blockchain.

func (*Wallet) SetChainId added in v1.1.3

func (wallet *Wallet) SetChainId(chainid *big.Int)

SetChainId sets the chain ID for this wallet. This affects transaction signing and should match the target network.

func (*Wallet) SetNonce added in v1.1.3

func (wallet *Wallet) SetNonce(nonce uint64)

SetNonce updates both the confirmed and pending nonce if the new nonce is higher. This is typically called when syncing wallet state with the blockchain.

func (*Wallet) SubBalance added in v1.1.3

func (wallet *Wallet) SubBalance(amount *big.Int)

SubBalance subtracts the specified amount from the wallet's balance. This is typically called when a transaction is confirmed to update the balance.

func (*Wallet) UpdateWallet added in v1.1.16

func (wallet *Wallet) UpdateWallet(ctx context.Context, client *Client, refresh bool) error

type WalletPool

type WalletPool struct {
	// contains filtered or unexported fields
}

WalletPool manages a pool of child wallets derived from a root wallet with automatic funding and balance monitoring. It provides wallet selection strategies, automatic refills when balances drop below thresholds, and batch funding operations for efficiency.

func NewWalletPool

func NewWalletPool(ctx context.Context, logger logrus.FieldLogger, rootWallet *RootWallet, clientPool *ClientPool, txpool *TxPool) *WalletPool

NewWalletPool creates a new wallet pool with the specified dependencies. The pool must be configured and prepared with PrepareWallets() before use.

func (*WalletPool) AddWellKnownWallet added in v1.1.1

func (pool *WalletPool) AddWellKnownWallet(config *WellKnownWalletConfig)

AddWellKnownWallet adds a named wallet with custom funding configuration. Well-known wallets are created alongside regular numbered wallets.

func (*WalletPool) CheckChildWalletBalance

func (pool *WalletPool) CheckChildWalletBalance(childWallet *Wallet) error

CheckChildWalletBalance checks and refills a specific wallet if needed. This can be used to manually trigger funding for a single wallet.

func (*WalletPool) EstimateDeployGas added in v1.2.0

func (pool *WalletPool) EstimateDeployGas(ctx context.Context, client *Client, from common.Address, value *uint256.Int, data []byte) uint64

EstimateDeployGas determines the gas limit for a contract-creation transaction with the given initcode (data). Primary path: eth_estimateGas via the provided client. Fallback path (RPC error or nil client): a formula-based upper bound sized for post-Amsterdam state-creation costs.

Static guesses under EIP-8037 frequently under-allocate because state-creation cost scales with both account creation (112·cpsb) and code deposit (per-byte cpsb), so the fallback is intentionally conservative.

func (*WalletPool) FundingGasFor added in v1.2.0

func (pool *WalletPool) FundingGasFor(isEmpty bool) uint64

FundingGasFor returns the gas limit for a single direct EOA funding tx to a target with the given emptiness. Honors an explicit SetFundingGasLimit override when configured; otherwise computes from the active fee model.

Base: TxPool.MinIntrinsicGas (21,000). Empty recipient on Amsterdam: + AccountCreationSize·cpsb (EIP-8037 state gas for new account creation).

func (*WalletPool) GetAllWallets

func (pool *WalletPool) GetAllWallets() []*Wallet

GetAllWallets returns a slice containing all wallets (well-known and child wallets). The root wallet is not included in this list.

func (*WalletPool) GetChainId added in v1.1.3

func (pool *WalletPool) GetChainId() *big.Int

GetChainId returns the chain ID from the root wallet.

func (*WalletPool) GetClient

func (pool *WalletPool) GetClient(options ...ClientSelectionOption) *Client

GetClient returns a client from the client pool using the specified options.

func (*WalletPool) GetClientPool

func (pool *WalletPool) GetClientPool() *ClientPool

GetClientPool returns the client pool used for blockchain interactions.

func (*WalletPool) GetConfiguredWalletCount added in v1.1.3

func (pool *WalletPool) GetConfiguredWalletCount() uint64

GetConfiguredWalletCount returns the configured number of child wallets.

func (*WalletPool) GetContext

func (pool *WalletPool) GetContext() context.Context

GetContext returns the context associated with this wallet pool.

func (*WalletPool) GetFundingGasLimit added in v1.1.16

func (pool *WalletPool) GetFundingGasLimit() uint64

GetFundingGasLimit returns the gas limit for a worst-case (empty target) direct funding transaction. Preserved for backwards compatibility with callers that need a single conservative number.

func (*WalletPool) GetRootWallet

func (pool *WalletPool) GetRootWallet() *RootWallet

GetRootWallet returns the root wallet that funds all child wallets.

func (*WalletPool) GetSpammerID added in v1.1.6

func (pool *WalletPool) GetSpammerID() uint64

GetSpammerID returns the spammer ID for metrics tracking

func (*WalletPool) GetSuggestedFees added in v1.2.0

func (pool *WalletPool) GetSuggestedFees(client *Client, baseFeeWei *big.Int, tipFeeWei *big.Int) (feeCap *big.Int, tipCap *big.Int, err error)

GetSuggestedFees returns suggested fees using this pool's configured fee strategy.

func (*WalletPool) GetTransactionTracker added in v1.1.5

func (pool *WalletPool) GetTransactionTracker() func(err error)

GetTransactionTracker returns the transaction tracking callback if set.

func (*WalletPool) GetTxPool

func (pool *WalletPool) GetTxPool() *TxPool

GetTxPool returns the transaction pool used by this wallet pool.

func (*WalletPool) GetVeryWellKnownWalletAddress added in v1.1.5

func (pool *WalletPool) GetVeryWellKnownWalletAddress(name string) common.Address

GetVeryWellKnownWalletAddress derives the address of a "very well known" wallet without registering it. Very well known wallets are derived only from the root wallet's private key and the wallet name, without any scenario seed. This makes them consistent across different scenario runs.

func (*WalletPool) GetWallet

func (pool *WalletPool) GetWallet(mode WalletSelectionMode, input int) *Wallet

GetWallet returns a wallet from the pool using the specified selection strategy. Returns nil if no wallets are available.

func (*WalletPool) GetWalletCount

func (pool *WalletPool) GetWalletCount() uint64

GetWalletCount returns the actual number of child wallets created.

func (*WalletPool) GetWalletName added in v1.1.1

func (pool *WalletPool) GetWalletName(address common.Address) string

GetWalletName returns a human-readable name for the given wallet address. Returns "root" for the root wallet, numbered names for child wallets, custom names for well-known wallets, or "unknown" if not found.

func (*WalletPool) GetWellKnownWallet added in v1.1.1

func (pool *WalletPool) GetWellKnownWallet(name string) *Wallet

GetWellKnownWallet returns a well-known wallet by name. Returns nil if the wallet doesn't exist.

func (*WalletPool) LoadConfig

func (pool *WalletPool) LoadConfig(configYaml string) error

LoadConfig loads wallet pool configuration from YAML string.

func (*WalletPool) MarshalConfig

func (pool *WalletPool) MarshalConfig() (string, error)

MarshalConfig returns the current configuration as a YAML string.

func (*WalletPool) PrepareWallets

func (pool *WalletPool) PrepareWallets() error

PrepareWallets creates all configured wallets and funds them if needed. It generates deterministic wallets based on the root wallet and seed, then funds any wallets below the refill threshold. Also starts the automatic balance monitoring if funding is enabled.

func (*WalletPool) ReclaimFunds added in v1.1.4

func (pool *WalletPool) ReclaimFunds(ctx context.Context, client *Client) error

ReclaimFunds reclaims all funds from child wallets back to the root wallet. This is typically called when shutting down to consolidate remaining funds. After calling this, automatic funding is disabled.

func (*WalletPool) SetFeeStrategy added in v1.2.0

func (pool *WalletPool) SetFeeStrategy(strategy string)

SetFeeStrategy sets the fee calculation strategy for this wallet pool.

func (*WalletPool) SetFundingGasLimit added in v1.1.16

func (pool *WalletPool) SetFundingGasLimit(gasLimit uint64)

SetFundingGasLimit sets an explicit per-recipient gas limit for wallet funding transactions, overriding the fee-model-derived default. Use 100000+ for L2 chains like Arbitrum/Optimism. When set to 0 (default), spamoor derives the limit from the active fee model: TxPool.MinIntrinsicGas plus AccountCreationSize·cpsb for empty-target funding under EIP-8037.

func (*WalletPool) SetRefillAmount

func (pool *WalletPool) SetRefillAmount(amount *uint256.Int)

SetRefillAmount sets the amount sent to wallets when they need funding.

func (*WalletPool) SetRefillBalance

func (pool *WalletPool) SetRefillBalance(balance *uint256.Int)

SetRefillBalance sets the balance threshold below which wallets are automatically refilled.

func (*WalletPool) SetRefillInterval

func (pool *WalletPool) SetRefillInterval(interval uint64)

SetRefillInterval sets the interval in seconds between automatic balance checks.

func (*WalletPool) SetRunFundings added in v1.1.4

func (pool *WalletPool) SetRunFundings(runFundings bool)

SetRunFundings enables or disables automatic wallet funding. When disabled, wallets will not be automatically refilled when their balance drops. This should be called before PrepareWallets(). To stop an already running funding loop, use StopFunding() instead.

func (*WalletPool) SetSpammerID added in v1.1.6

func (pool *WalletPool) SetSpammerID(spammerID uint64)

SetSpammerID sets the spammer ID for metrics tracking

func (*WalletPool) SetTransactionTracker added in v1.1.5

func (pool *WalletPool) SetTransactionTracker(tracker func(err error))

SetTransactionTracker sets the optional callback to track transaction results for metrics.

func (*WalletPool) SetWalletCount

func (pool *WalletPool) SetWalletCount(count uint64)

SetWalletCount sets the number of child wallets to create.

func (*WalletPool) SetWalletPrivkeys added in v1.1.11

func (pool *WalletPool) SetWalletPrivkeys(privkeys []string)

SetWalletPrivkeys sets custom wallet private keys used for child wallets. The privkey parameter accepts hex strings with or without "0x" prefix. You should supply as many privkeys as you want to create wallets for (SetWalletCount), otherwise the remaining wallets will be generated deterministically based on the root wallet & seed.

func (*WalletPool) SetWalletSeed

func (pool *WalletPool) SetWalletSeed(seed string)

SetWalletSeed sets the seed used for deterministic wallet generation. The same seed will always generate the same set of wallets.

func (*WalletPool) StopFunding added in v1.1.16

func (pool *WalletPool) StopFunding()

StopFunding stops the automatic wallet funding loop. This can be called after PrepareWallets() to stop the background funding goroutine. It blocks until the funding loop has fully stopped.

type WalletPoolBlockStats added in v1.1.5

type WalletPoolBlockStats struct {
	ConfirmedTxCount uint64
	TotalTxFees      *big.Int
	AffectedWallets  int
	Block            *types.Block
	ConfirmedTxs     []*TxInfo
	Receipts         []*types.Receipt
}

WalletPoolBlockStats contains transaction statistics for a wallet pool in a specific block

type WalletPoolConfig

type WalletPoolConfig struct {
	WalletCount     uint64       `yaml:"wallet_count,omitempty"`
	RefillAmount    *uint256.Int `yaml:"refill_amount"`
	RefillBalance   *uint256.Int `yaml:"refill_balance"`
	RefillInterval  uint64       `yaml:"refill_interval"`
	WalletSeed      string       `yaml:"seed"`
	FundingGasLimit uint64       `yaml:"funding_gas_limit"`
	FeeStrategy     string       `yaml:"fee_strategy,omitempty"` // Fee calculation strategy: "" (legacy) or "adaptive"
}

WalletPoolConfig contains configuration settings for the wallet pool including wallet count, funding amounts, and automatic refill behavior.

func GetDefaultWalletConfig added in v1.1.1

func GetDefaultWalletConfig(scenarioName string) *WalletPoolConfig

GetDefaultWalletConfig returns default wallet pool configuration for a given scenario. It generates a random seed and sets reasonable defaults for refill amounts and intervals.

type WalletSelectionMode

type WalletSelectionMode uint8

WalletSelectionMode defines how wallets are selected from the pool.

var (
	// SelectWalletByIndex selects a wallet by index (modulo pool size).
	SelectWalletByIndex WalletSelectionMode = 0
	// SelectWalletRandom selects a random wallet from the pool.
	SelectWalletRandom WalletSelectionMode = 1
	// SelectWalletRoundRobin selects wallets in round-robin fashion.
	SelectWalletRoundRobin WalletSelectionMode = 2
	// SelectWalletByPendingTxCount selects a wallet by pending tx count (lowest pending tx count first).
	SelectWalletByPendingTxCount WalletSelectionMode = 3
)

type WellKnownWalletConfig added in v1.1.1

type WellKnownWalletConfig struct {
	Name          string
	RefillAmount  *uint256.Int
	RefillBalance *uint256.Int
	VeryWellKnown bool
	PrivateKey    string
}

WellKnownWalletConfig defines configuration for a named wallet with custom funding settings. Well-known wallets have specific names and can have different refill amounts than regular wallets.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL