Documentation
¶
Index ¶
- Constants
- func LoadPrivateKey(privkey string) (*ecdsa.PrivateKey, common.Address, error)
- func ResolveFees(baseFeeGwei, tipFeeGwei float64, baseFeeWei, tipFeeWei string) (baseFee, tipFee *big.Int)
- type BatchOptions
- type BlockInfo
- type BlockStatsCallback
- type BlockSubscription
- type BlockWithHash
- type BulkBlockStatsCallback
- type BulkBlockSubscription
- type Client
- func (client *Client) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error)
- func (client *Client) GetBalanceAt(ctx context.Context, wallet common.Address) (*big.Int, error)
- func (client *Client) GetBlockHeight(ctx context.Context) (uint64, error)
- func (client *Client) GetChainId(ctx context.Context) (*big.Int, error)
- func (client *Client) GetClientGroup() string
- func (client *Client) GetClientGroups() []string
- func (client *Client) GetClientType() ClientType
- func (client *Client) GetClientVersion(ctx context.Context) (string, error)
- func (client *Client) GetEthClient() *ethclient.Client
- func (client *Client) GetLastBlockHeight() (uint64, time.Time)
- func (client *Client) GetName() string
- func (client *Client) GetNameOverride() string
- func (client *Client) GetNonceAt(ctx context.Context, wallet common.Address, blockNumber *big.Int) (uint64, error)
- func (client *Client) GetPendingNonceAt(ctx context.Context, wallet common.Address) (uint64, error)
- func (client *Client) GetRPCHost() string
- func (client *Client) GetRequestStats() (total, txRequests, rpcFailures uint64)
- func (client *Client) GetSuggestedFee(ctx context.Context) (*big.Int, *big.Int, error)
- func (client *Client) GetTransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)
- func (client *Client) HasGroup(group string) bool
- func (client *Client) IsBuilder() bool
- func (client *Client) IsEnabled() bool
- func (client *Client) SendRawTransaction(ctx context.Context, tx []byte) error
- func (client *Client) SendTransaction(ctx context.Context, tx *types.Transaction) error
- func (client *Client) SetClientGroups(groups []string)
- func (client *Client) SetClientTypeOverride(clientType string)
- func (client *Client) SetEnabled(enabled bool)
- func (client *Client) SetNameOverride(name string)
- func (client *Client) UpdateWallet(ctx context.Context, wallet *Wallet) error
- type ClientOptions
- type ClientPool
- func (pool *ClientPool) GetAllClients() []*Client
- func (pool *ClientPool) GetAllGoodClients() []*Client
- func (pool *ClientPool) GetChainId() *big.Int
- func (pool *ClientPool) GetClient(options ...ClientSelectionOption) *Client
- func (pool *ClientPool) InitClients(clientOptions []*ClientOptions) error
- func (pool *ClientPool) PrepareClients() error
- type ClientSelectionMode
- type ClientSelectionOption
- type ClientType
- type ExternalBlockEvent
- type ExternalBlockSource
- type ExternalClientOptions
- type FundingRequest
- type GlobalBlockStats
- type PendingTx
- type RootWallet
- func (wallet *RootWallet) GetTxBatcher() *TxBatcher
- func (wallet *RootWallet) GetWallet() *Wallet
- func (wallet *RootWallet) InitTxBatcher(ctx context.Context, txpool *TxPool)
- func (wallet *RootWallet) Shutdown()
- func (wallet *RootWallet) WithWalletLock(ctx context.Context, txCount int, fundingAmount *uint256.Int, ...) error
- type SendTransactionOptions
- type TxBatcher
- type TxCompleteFn
- type TxConfirmFn
- type TxEncodeFn
- type TxInfo
- type TxLogFn
- type TxPool
- func (p *TxPool) AwaitTransaction(ctx context.Context, wallet *Wallet, tx *types.Transaction) (*types.Receipt, error)
- func (pool *TxPool) GetActiveWalletPools() []*WalletPool
- func (pool *TxPool) GetCostPerStateByte() uint64
- func (pool *TxPool) GetCurrentBaseFee() *big.Int
- func (pool *TxPool) GetCurrentBaseFeeWithInit() (*big.Int, error)
- func (pool *TxPool) GetCurrentGasLimit() uint64
- func (pool *TxPool) GetCurrentGasLimitWithInit() (uint64, error)
- func (pool *TxPool) GetRecentBlockGasTotals() (totalGasUsed, totalGasLimit uint64)
- func (pool *TxPool) GetRegisteredWallet(address common.Address) *Wallet
- func (pool *TxPool) GetSuggestedFees(client *Client, baseFeeWei *big.Int, tipFeeWei *big.Int, feeStrategy ...string) (feeCap *big.Int, tipCap *big.Int, err error)
- func (pool *TxPool) HasObservedHead() bool
- func (pool *TxPool) InitializeBlockStats(ctx context.Context) error
- func (pool *TxPool) IsAmsterdam() bool
- func (pool *TxPool) MaxTxGas() uint64
- func (pool *TxPool) MinIntrinsicGas() uint64
- func (pool *TxPool) RegisterWallet(wallet *Wallet, ctx context.Context) *Wallet
- func (pool *TxPool) RegisterWalletPool(walletPool *WalletPool)
- func (p *TxPool) SendAndAwaitTransaction(ctx context.Context, wallet *Wallet, tx *types.Transaction, ...) (*types.Receipt, error)
- func (p *TxPool) SendMultiTransactionBatch(ctx context.Context, walletTxs map[*Wallet][]*types.Transaction, ...) (map[*Wallet][]*types.Receipt, error)
- func (p *TxPool) SendTransaction(ctx context.Context, wallet *Wallet, tx *types.Transaction, ...) error
- func (p *TxPool) SendTransactionBatch(ctx context.Context, wallet *Wallet, txs []*types.Transaction, ...) ([]*types.Receipt, error)
- func (pool *TxPool) SubscribeToBlockUpdates(walletPool *WalletPool, callback BlockStatsCallback) uint64
- func (pool *TxPool) SubscribeToBulkBlockUpdates(callback BulkBlockStatsCallback) uint64
- func (pool *TxPool) UnsubscribeFromBlockUpdates(id uint64)
- func (pool *TxPool) UnsubscribeFromBulkBlockUpdates(id uint64)
- type TxPoolOptions
- type Wallet
- func (wallet *Wallet) AddBalance(amount *big.Int)
- func (wallet *Wallet) BuildAccessListTx(txData *types.AccessListTx) (*types.Transaction, error)
- func (wallet *Wallet) BuildBlobTx(txData *types.BlobTx) (*types.Transaction, error)
- func (wallet *Wallet) BuildBoundTx(ctx context.Context, txData *txbuilder.TxMetadata, ...) (*types.Transaction, error)
- func (wallet *Wallet) BuildBoundTxWithEstimate(ctx context.Context, client *Client, txpool *TxPool, ...) (*types.Transaction, error)
- func (wallet *Wallet) BuildDynamicFeeTx(txData *types.DynamicFeeTx) (*types.Transaction, error)
- func (wallet *Wallet) BuildFillerTx(nonce uint64, gasTipCap, gasFeeCap *big.Int, gas uint64) (*types.Transaction, error)
- func (wallet *Wallet) BuildLegacyTx(txData *types.LegacyTx) (*types.Transaction, error)
- func (wallet *Wallet) BuildSetCodeTx(txData *types.SetCodeTx) (*types.Transaction, error)
- func (wallet *Wallet) GetAddress() common.Address
- func (wallet *Wallet) GetBalance() *big.Int
- func (wallet *Wallet) GetChainId() *big.Int
- func (wallet *Wallet) GetConfirmedNonce() uint64
- func (wallet *Wallet) GetLowestPendingNonce() (uint64, bool)
- func (wallet *Wallet) GetNextNonce() uint64
- func (wallet *Wallet) GetNonce() uint64
- func (wallet *Wallet) GetNonceGaps() []uint64
- func (wallet *Wallet) GetPendingTx(tx *types.Transaction) *PendingTx
- func (wallet *Wallet) GetPendingTxs() []*PendingTx
- func (wallet *Wallet) GetPrivateKey() *ecdsa.PrivateKey
- func (wallet *Wallet) GetReadableBalance(unitDigits, maxPreCommaDigitsBeforeTrim, digits int, ...) string
- func (wallet *Wallet) GetSubmittedTxCount() uint64
- func (wallet *Wallet) IncrementSubmittedTxCount()
- func (wallet *Wallet) MarkNeedResync()
- func (wallet *Wallet) MarkSkippedNonce(nonce uint64)
- func (wallet *Wallet) ReplaceAccessListTx(txData *types.AccessListTx, nonce uint64) (*types.Transaction, error)
- func (wallet *Wallet) ReplaceBlobTx(txData *types.BlobTx, nonce uint64) (*types.Transaction, error)
- func (wallet *Wallet) ReplaceDynamicFeeTx(txData *types.DynamicFeeTx, nonce uint64) (*types.Transaction, error)
- func (wallet *Wallet) ReplaceLegacyTx(txData *types.LegacyTx, nonce uint64) (*types.Transaction, error)
- func (wallet *Wallet) ReplaceSetCodeTx(txData *types.SetCodeTx, nonce uint64) (*types.Transaction, error)
- func (wallet *Wallet) ResetNoncesIfNeeded(ctx context.Context, client *Client) error
- func (wallet *Wallet) SetAddress(address common.Address)
- func (wallet *Wallet) SetBalance(balance *big.Int)
- func (wallet *Wallet) SetChainId(chainid *big.Int)
- func (wallet *Wallet) SetNonce(nonce uint64)
- func (wallet *Wallet) SubBalance(amount *big.Int)
- func (wallet *Wallet) UpdateWallet(ctx context.Context, client *Client, refresh bool) error
- type WalletPool
- func (pool *WalletPool) AddWellKnownWallet(config *WellKnownWalletConfig)
- func (pool *WalletPool) CheckChildWalletBalance(childWallet *Wallet) error
- func (pool *WalletPool) EstimateDeployGas(ctx context.Context, client *Client, from common.Address, value *uint256.Int, ...) uint64
- func (pool *WalletPool) FundingGasFor(isEmpty bool) uint64
- func (pool *WalletPool) GetAllWallets() []*Wallet
- func (pool *WalletPool) GetChainId() *big.Int
- func (pool *WalletPool) GetClient(options ...ClientSelectionOption) *Client
- func (pool *WalletPool) GetClientPool() *ClientPool
- func (pool *WalletPool) GetConfiguredWalletCount() uint64
- func (pool *WalletPool) GetContext() context.Context
- func (pool *WalletPool) GetFundingGasLimit() uint64
- func (pool *WalletPool) GetRootWallet() *RootWallet
- func (pool *WalletPool) GetSpammerID() uint64
- func (pool *WalletPool) GetSuggestedFees(client *Client, baseFeeWei *big.Int, tipFeeWei *big.Int) (feeCap *big.Int, tipCap *big.Int, err error)
- func (pool *WalletPool) GetTransactionTracker() func(err error)
- func (pool *WalletPool) GetTxPool() *TxPool
- func (pool *WalletPool) GetVeryWellKnownWalletAddress(name string) common.Address
- func (pool *WalletPool) GetWallet(mode WalletSelectionMode, input int) *Wallet
- func (pool *WalletPool) GetWalletCount() uint64
- func (pool *WalletPool) GetWalletName(address common.Address) string
- func (pool *WalletPool) GetWellKnownWallet(name string) *Wallet
- func (pool *WalletPool) LoadConfig(configYaml string) error
- func (pool *WalletPool) MarshalConfig() (string, error)
- func (pool *WalletPool) PrepareWallets() error
- func (pool *WalletPool) ReclaimFunds(ctx context.Context, client *Client) error
- func (pool *WalletPool) SetFeeStrategy(strategy string)
- func (pool *WalletPool) SetFundingGasLimit(gasLimit uint64)
- func (pool *WalletPool) SetRefillAmount(amount *uint256.Int)
- func (pool *WalletPool) SetRefillBalance(balance *uint256.Int)
- func (pool *WalletPool) SetRefillInterval(interval uint64)
- func (pool *WalletPool) SetRunFundings(runFundings bool)
- func (pool *WalletPool) SetSpammerID(spammerID uint64)
- func (pool *WalletPool) SetTransactionTracker(tracker func(err error))
- func (pool *WalletPool) SetWalletCount(count uint64)
- func (pool *WalletPool) SetWalletPrivkeys(privkeys []string)
- func (pool *WalletPool) SetWalletSeed(seed string)
- func (pool *WalletPool) StopFunding()
- type WalletPoolBlockStats
- type WalletPoolConfig
- type WalletSelectionMode
- type WellKnownWalletConfig
Constants ¶
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 )
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).
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
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
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
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
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
GetBalanceAt returns the balance of the given address at the latest block.
func (*Client) GetBlockHeight ¶ added in v1.1.3
GetBlockHeight returns the current block number. Results are cached for 12 seconds to reduce RPC calls.
func (*Client) GetChainId ¶ added in v1.1.3
GetChainId returns the chain ID of the connected Ethereum network.
func (*Client) GetClientGroup ¶ added in v1.1.3
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
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
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
GetEthClient returns the underlying go-ethereum ethclient.Client instance.
func (*Client) GetLastBlockHeight ¶ added in v1.1.3
GetLastBlockHeight returns the last cached block height and the time it was retrieved.
func (*Client) GetName ¶ added in v1.1.3
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
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
GetPendingNonceAt returns the pending nonce for the given address, including transactions in the mempool.
func (*Client) GetRPCHost ¶ added in v1.1.3
GetRPCHost returns the original RPC host URL used to create this client.
func (*Client) GetRequestStats ¶ added in v1.1.9
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
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
HasGroup checks if the client belongs to the specified group.
func (*Client) IsBuilder ¶ added in v1.1.9
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
IsEnabled returns whether the client is enabled for selection.
func (*Client) SendRawTransaction ¶ added in v1.1.4
SendRawTransaction submits a raw transaction bytes to the network using eth_sendRawTransaction RPC call.
func (*Client) SendTransaction ¶ added in v1.1.4
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
SetClientGroups sets multiple client group names for the client, replacing all existing groups.
func (*Client) SetClientTypeOverride ¶ added in v1.1.9
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
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
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.
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 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
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
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
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
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
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
GetCurrentBaseFee returns the current base fee of the chain.
func (*TxPool) GetCurrentBaseFeeWithInit ¶ added in v1.1.6
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
GetCurrentGasLimit returns the current gas limit of the chain.
func (*TxPool) GetCurrentGasLimitWithInit ¶ added in v1.1.5
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
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
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
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
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
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
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
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
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
UnsubscribeFromBlockUpdates removes a block update subscription.
func (*TxPool) UnsubscribeFromBulkBlockUpdates ¶ added in v1.1.6
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
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
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:
- Build the tx with a large placeholder gas so abigen does not try to self-estimate.
- Run eth_estimateGas against the resulting {from, to, data, value}.
- Apply the fee-model-aware buffer (and cpsb when known) to the RPC result.
- Clamp to the current block gas limit so the tx isn't doomed to be skipped for "gas limit reached" at block building time.
- 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
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
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
GetAddress returns the Ethereum address associated with this wallet.
func (*Wallet) GetBalance ¶ added in v1.1.3
GetBalance returns the current balance of the wallet. The returned value is thread-safe to read.
func (*Wallet) GetChainId ¶ added in v1.1.3
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
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
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
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
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
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) 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) GetSubmittedTxCount ¶ added in v1.1.6
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
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
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) SetAddress ¶ added in v1.1.3
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
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
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
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
SubBalance subtracts the specified amount from the wallet's balance. This is typically called when a transaction is confirmed to update the balance.
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.