Skip to content

feat: implement gas price and gas limit customization for txsim #4447

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Apr 16, 2025
12 changes: 12 additions & 0 deletions test/cmd/txsim/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ var (
useFeegrant, suppressLogs bool
upgradeSchedule string
blobShareVersion int
gasLimit uint64
gasPrice float64
)

func main() {
Expand Down Expand Up @@ -177,6 +179,14 @@ account that can act as the master account. The command runs until all sequences
opts.SuppressLogs()
}

if gasLimit > 0 {
opts.WithGasLimit(gasLimit)
}

if gasPrice > 0 {
opts.WithGasPrice(gasPrice)
}

encCfg := encoding.MakeConfig(app.ModuleEncodingRegisters...)
err = txsim.Run(
cmd.Context(),
Expand Down Expand Up @@ -217,6 +227,8 @@ func flags() *flag.FlagSet {
flags.BoolVar(&useFeegrant, "feegrant", false, "use the feegrant module to pay for fees")
flags.BoolVar(&suppressLogs, "suppressLogs", false, "disable logging")
flags.IntVar(&blobShareVersion, "blob-share-version", -1, "optionally specify a share version to use for the blob sequences")
flags.Uint64Var(&gasLimit, "gas-limit", 0, "custom gas limit to use for transactions (0 = auto-estimate)")
flags.Float64Var(&gasPrice, "gas-price", 0, "custom gas price to use for transactions (0 = use default)")
return flags
}

Expand Down
37 changes: 33 additions & 4 deletions test/txsim/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
encCfg encoding.Config
pollTime time.Duration
useFeegrant bool
gasLimit uint64
gasPrice float64

// to protect from concurrent writes to the map
mtx sync.Mutex
Expand Down Expand Up @@ -225,11 +227,29 @@

opts := make([]user.TxOption, 0)
if op.GasLimit == 0 {
opts = append(opts, user.SetGasLimit(DefaultGasLimit), user.SetFee(defaultFee))
if am.gasLimit > 0 {
// Use the custom gas limit set on the AccountManager
opts = append(opts, user.SetGasLimit(am.gasLimit))

// Calculate fee based on gas price
var gasPrice float64
if am.gasPrice > 0 {
gasPrice = am.gasPrice
} else {
gasPrice = appconsts.DefaultMinGasPrice
}
opts = append(opts, user.SetFee(uint64(math.Ceil(float64(am.gasLimit)*gasPrice))))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[question] this seems a bit difficult to reason about. Is it possible to extract the fee calculation to after the custom gas limit and gas price have been set. That way this code can remain less indented:

if am.gasLimit > 0 {
    // set custom gas limit
}

if am.gasPrice > 0 {
  // set custom gas price
}

fee := calculateFee(gasLimit, gasPrice)
opts = append(opts, user.SetFee(fee))

That way there's only one line where we set the fee instead of two.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you for the feedback! 36d2c38

} else {
// Use the default gas limit
opts = append(opts, user.SetGasLimit(DefaultGasLimit), user.SetFee(defaultFee))
}
} else {
opts = append(opts, user.SetGasLimit(op.GasLimit))
if op.GasPrice > 0 {

Check failure on line 248 in test/txsim/account.go

View workflow job for this annotation

GitHub Actions / lint / golangci-lint

ifElseChain: rewrite if-else to switch statement (gocritic)
opts = append(opts, user.SetFee(uint64(math.Ceil(float64(op.GasLimit)*op.GasPrice))))
} else if am.gasPrice > 0 {
// Use custom gas price set on AccountManager if available
opts = append(opts, user.SetFee(uint64(math.Ceil(float64(op.GasLimit)*am.gasPrice))))
} else {
opts = append(opts, user.SetFee(uint64(math.Ceil(float64(op.GasLimit)*appconsts.DefaultMinGasPrice))))
}
Expand Down Expand Up @@ -409,9 +429,18 @@
}

func (am *AccountManager) nextAccountName() string {
am.mtx.Lock()
defer am.mtx.Unlock()
return accountName(len(am.pending) + am.accountIndex)
am.accountIndex++
return accountName(am.accountIndex)
}

// SetGasLimit sets a custom gas limit to be used for all transactions
func (am *AccountManager) SetGasLimit(gasLimit uint64) {
am.gasLimit = gasLimit
}

// SetGasPrice sets a custom gas price to be used for all transactions
func (am *AccountManager) SetGasPrice(gasPrice float64) {
am.gasPrice = gasPrice
}

type account struct {
Expand Down
22 changes: 22 additions & 0 deletions test/txsim/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ func Run(
return err
}

// Set custom gas limit if provided
if opts.gasLimit > 0 {
manager.SetGasLimit(opts.gasLimit)
}

// Set custom gas price if provided
if opts.gasPrice > 0 {
manager.SetGasPrice(opts.gasPrice)
}

// Initialize each of the sequences by allowing them to allocate accounts.
for _, sequence := range sequences {
sequence.Init(ctx, manager.conn, manager.AllocateAccounts, r, opts.useFeeGrant)
Expand Down Expand Up @@ -132,6 +142,8 @@ type Options struct {
pollTime time.Duration
useFeeGrant bool
suppressLogger bool
gasLimit uint64
gasPrice float64
}

func (o *Options) Fill() {
Expand Down Expand Up @@ -174,6 +186,16 @@ func (o *Options) WithPollTime(pollTime time.Duration) *Options {
return o
}

func (o *Options) WithGasLimit(gasLimit uint64) *Options {
o.gasLimit = gasLimit
return o
}

func (o *Options) WithGasPrice(gasPrice float64) *Options {
o.gasPrice = gasPrice
return o
}

// buildGrpcConn applies the config if the handshake succeeds; otherwise, it falls back to an insecure connection.
func buildGrpcConn(grpcEndpoint string, config *tls.Config) (*grpc.ClientConn, error) {
netConn, err := net.Dial("tcp", grpcEndpoint)
Expand Down
Loading