Skip to content

feat: implement gas price and gas limit customization for txsim (backport #4447) #4591

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

Draft
wants to merge 2 commits into
base: v3.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ well funded account that can act as the master account. The command runs until a
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
64 changes: 51 additions & 13 deletions test/txsim/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ import (
"google.golang.org/grpc"
)

const defaultFee = DefaultGasLimit * appconsts.DefaultMinGasPrice

type AccountManager struct {
keys keyring.Keyring
conn *grpc.ClientConn
pending []*account
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 @@ -224,15 +224,44 @@ func (am *AccountManager) Submit(ctx context.Context, op Operation) error {
}

opts := make([]user.TxOption, 0)
if op.GasLimit == 0 {
opts = append(opts, user.SetGasLimit(DefaultGasLimit), user.SetFee(defaultFee))
} else {
opts = append(opts, user.SetGasLimit(op.GasLimit))
if op.GasPrice > 0 {
opts = append(opts, user.SetFee(uint64(math.Ceil(float64(op.GasLimit)*op.GasPrice))))
} else {
opts = append(opts, user.SetFee(uint64(math.Ceil(float64(op.GasLimit)*appconsts.DefaultMinGasPrice))))
var gasLimit, fee uint64
var gasPrice float64

// Step 1: Determine gas limit
switch {
case op.GasLimit > 0:
gasLimit = op.GasLimit
case am.gasLimit > 0:
gasLimit = am.gasLimit
default:
gasLimit = DefaultGasLimit
}

// Set gas limit
if gasLimit > 0 {
opts = append(opts, user.SetGasLimit(gasLimit))
}

// Step 2: Determine gas price
switch {
case op.GasPrice > 0:
gasPrice = op.GasPrice
case am.gasPrice > 0:
gasPrice = am.gasPrice
if gasPrice < appconsts.DefaultMinGasPrice {
log.Warn().
Float64("gas_price", gasPrice).
Float64("default_min_gas_price", appconsts.DefaultMinGasPrice).
Msg("custom gas price is lower than default minimum")
}
default:
gasPrice = appconsts.DefaultMinGasPrice
}

// Step 3: Calculate fee
if fee == 0 {
fee = uint64(math.Ceil(float64(gasLimit) * gasPrice))
opts = append(opts, user.SetFee(fee))
}

if am.useFeegrant {
Expand Down Expand Up @@ -409,9 +438,18 @@ func (am *AccountManager) updateHeight(ctx context.Context) (uint64, error) {
}

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
56 changes: 56 additions & 0 deletions test/txsim/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import (
"context"
"crypto/tls"
"errors"
"fmt"
"math/rand"
"net"
"time"

"github.com/celestiaorg/celestia-app/v3/app/encoding"
Expand All @@ -13,6 +15,7 @@
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
)

Expand Down Expand Up @@ -63,6 +66,16 @@
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 @@ -129,6 +142,8 @@
pollTime time.Duration
useFeeGrant bool
suppressLogger bool
gasLimit uint64
gasPrice float64
}

func (o *Options) Fill() {
Expand Down Expand Up @@ -170,3 +185,44 @@
o.pollTime = pollTime
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) {

Check failure on line 200 in test/txsim/run.go

View workflow job for this annotation

GitHub Actions / lint / golangci-lint

func `buildGrpcConn` is unused (unused)
netConn, err := net.Dial("tcp", grpcEndpoint)
if err != nil {
log.Error().Str("errorMessage", err.Error()).Msg("grpc server is not reachable via tcp")
return nil, err
}

tlsConn := tls.Client(netConn, config)
err = tlsConn.Handshake()
if err != nil {
log.Warn().Str("errorMessage", err.Error()).Msg(
"failed to connect with the config to grpc server; proceeding with insecure connection",
)

conn, err := grpc.NewClient(grpcEndpoint,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(grpcMaxRecvMsgSize), grpc.MaxCallSendMsgSize(grpcMaxSendMsgSize)))

return conn, err
}

conn, err := grpc.NewClient(grpcEndpoint,
grpc.WithTransportCredentials(credentials.NewTLS(config)),
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(grpcMaxRecvMsgSize), grpc.MaxCallSendMsgSize(grpcMaxSendMsgSize)))
if err != nil {
return nil, fmt.Errorf("error connecting to %s: %w", grpcEndpoint, err)
}
return conn, err
}
Loading