Skip to content

Commit 97ac079

Browse files
red-0neokdas
andcommitted
[RelayMiner] Use gas for claim and proof txs (#1018)
This pull request includes several changes to the `pkg/client` package, focusing on adding gas limit and gas price parameters to transaction signing and broadcasting functions, as well as making related updates in tests and configurations. It also updates the `BroadcastTx` method in `pkg/client/tx/context.go` to use `BroadcastTxSync` instead of `BroadcastTxAsync` for better error handling during the check-tx ABCI operation. Minor Fix: Changed the URL in `makefiles/relay.mk` to include a trailing slash. ![image](https://github.com/user-attachments/assets/535e99b3-621b-46bd-a335-49e167c50cba) Select one or more from the following: - [ ] New feature, functionality or library - [ ] Consensus breaking; add the `consensus-breaking` label if so. See - [x] Bug fix - [ ] Code health or cleanup - [ ] Documentation - [ ] Other (specify) - [ ] **Documentation**: `make docusaurus_start`; only needed if you make doc changes - [x] **Unit Tests**: `make go_develop_and_test` - [x] **LocalNet E2E Tests**: `make test_e2e` - [ ] **DevNet E2E Tests**: Add the `devnet-test-e2e` label to the PR. - [x] I have tested my changes using the available tooling - [x] I have commented my code - [x] I have performed a self-review of my own code; both comments & source code - [ ] I create and reference any new tickets, if applicable - [x] I have left TODOs throughout the codebase, if applicable --------- Co-authored-by: Dima K. <[email protected]> Co-authored-by: Dmitry K <[email protected]>
1 parent d54e9bb commit 97ac079

File tree

9 files changed

+126
-11
lines changed

9 files changed

+126
-11
lines changed

e2e/tests/session_steps_test.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,10 @@ func (s *suite) TheUserShouldWaitForTheModuleMessageToBeSubmitted(module, msgTyp
5252
// so that next steps that assert on supplier rewards can do it without having
5353
// the proof submission fee skewing the results.
5454
switch msgType {
55+
case "CreateClaim":
56+
fallthrough
5557
case "SubmitProof":
56-
supplierOperatorAddress := getMsgSubmitProofSenderAddress(event)
58+
supplierOperatorAddress := getMsgSenderAddress(event)
5759
require.NotEmpty(s, supplierOperatorAddress)
5860

5961
supplierAccName := accAddrToNameMap[supplierOperatorAddress]
@@ -417,8 +419,8 @@ func combineEventMatchFns(fns ...func(*abci.Event) bool) func(*abci.Event) bool
417419
}
418420
}
419421

420-
// getMsgSubmitProofSenderAddress returns the sender address from the given event.
421-
func getMsgSubmitProofSenderAddress(event *abci.Event) string {
422+
// getMsgSenderAddress returns the sender address from the given event.
423+
func getMsgSenderAddress(event *abci.Event) string {
422424
senderAttrIdx := slices.IndexFunc(event.Attributes, func(attr abci.EventAttribute) bool {
423425
return attr.Key == "sender"
424426
})

makefiles/relay.mk

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ send_relay_path_JSONRPC: test_e2e_env ## Send a JSONRPC relay through PATH to a
99
-H "target-service-id: anvil" \
1010
--data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
1111
http://localhost:3000/v1/
12-
# $(subst http://,http://anvil.,$(PATH_URL))/v1
1312

1413
# TODO_MAINNET(@red-0ne): Re-enable this once PATH Gateway supports REST.
1514
# See https://github.com/buildwithgrove/path/issues/87

pkg/client/interface.go

+7
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,13 @@ type TxContext interface {
126126

127127
// GetClientCtx returns the cosmos-sdk client context associated with the transaction context.
128128
GetClientCtx() cosmosclient.Context
129+
130+
// GetSimulatedTxGas returns the estimated gas for the given messages.
131+
GetSimulatedTxGas(
132+
ctx context.Context,
133+
signingKeyName string,
134+
msgs ...cosmostypes.Msg,
135+
) (uint64, error)
129136
}
130137

131138
// Block is an interface which abstracts the details of a block to its minimal

pkg/client/tx/client.go

+26-2
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ import (
88
"sync"
99

1010
"cosmossdk.io/depinject"
11+
"cosmossdk.io/math"
1112
abci "github.com/cometbft/cometbft/abci/types"
1213
"github.com/cometbft/cometbft/libs/json"
1314
rpctypes "github.com/cometbft/cometbft/rpc/jsonrpc/types"
1415
comettypes "github.com/cometbft/cometbft/types"
1516
cosmostypes "github.com/cosmos/cosmos-sdk/types"
1617
"go.uber.org/multierr"
1718

19+
"github.com/pokt-network/poktroll/app/volatile"
1820
"github.com/pokt-network/poktroll/pkg/client"
1921
"github.com/pokt-network/poktroll/pkg/client/events"
2022
"github.com/pokt-network/poktroll/pkg/client/keyring"
@@ -103,6 +105,9 @@ type txClient struct {
103105
// that they have not already by the given timeout height.
104106
txTimeoutPool txTimeoutPool
105107

108+
// gasPrices is the gas unit prices used for sending transactions.
109+
gasPrices cosmostypes.DecCoins
110+
106111
// connRetryLimit is the number of times the underlying replay client
107112
// should retry in the event that it encounters an error or its connection is interrupted.
108113
// If connRetryLimit is < 0, it will retry indefinitely.
@@ -229,6 +234,12 @@ func (txnClient *txClient) SignAndBroadcast(
229234
return either.SyncErr(validationErrs)
230235
}
231236

237+
// Simulate the transaction to calculate the gas limit.
238+
gasLimit, simErr := txnClient.txCtx.GetSimulatedTxGas(ctx, txnClient.signingKeyName, msgs...)
239+
if simErr != nil {
240+
return either.SyncErr(simErr)
241+
}
242+
232243
// Construct the transactions using cosmos' transactions builder.
233244
txBuilder := txnClient.txCtx.NewTxBuilder()
234245
if err := txBuilder.SetMsgs(msgs...); err != nil {
@@ -240,8 +251,21 @@ func (txnClient *txClient) SignAndBroadcast(
240251
timeoutHeight := txnClient.blockClient.LastBlock(ctx).
241252
Height() + txnClient.commitTimeoutHeightOffset
242253

243-
// TODO_TECHDEBT: this should be configurable
244-
txBuilder.SetGasLimit(690000042)
254+
txBuilder.SetGasLimit(gasLimit)
255+
256+
gasLimitDec := math.LegacyNewDec(int64(gasLimit))
257+
feeAmountDec := txnClient.gasPrices.MulDec(gasLimitDec)
258+
259+
feeCoins, changeCoins := feeAmountDec.TruncateDecimal()
260+
// Ensure that any decimal remainder is added to the corresponding coin as a
261+
// whole number.
262+
// Since changeCoins is the result of DecCoins#TruncateDecimal, it will always
263+
// be less than 1 unit of the feeCoins.
264+
if !changeCoins.IsZero() {
265+
feeCoins = feeCoins.Add(cosmostypes.NewInt64Coin(volatile.DenomuPOKT, 1))
266+
}
267+
txBuilder.SetFeeAmount(feeCoins)
268+
245269
txBuilder.SetTimeoutHeight(uint64(timeoutHeight))
246270

247271
// sign transactions

pkg/client/tx/context.go

+39-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ func (txCtx cosmosTxContext) EncodeTx(txBuilder cosmosclient.TxBuilder) ([]byte,
8686
// ABCI operation completes and returns a TxResponse of the transaction status at that point in time.
8787
func (txCtx cosmosTxContext) BroadcastTx(txBytes []byte) (*cosmostypes.TxResponse, error) {
8888
clientCtx := cosmosclient.Context(txCtx.clientCtx)
89-
return clientCtx.BroadcastTxAsync(txBytes)
89+
// BroadcastTxSync is used to capture any transaction error that occurs during
90+
// the check-tx ABCI operation, otherwise errors would not be returned.
91+
return clientCtx.BroadcastTxSync(txBytes)
9092
}
9193

9294
// QueryTx queries the transaction based on its hash and optionally provides proof
@@ -103,3 +105,39 @@ func (txCtx cosmosTxContext) QueryTx(
103105
func (txCtx cosmosTxContext) GetClientCtx() cosmosclient.Context {
104106
return cosmosclient.Context(txCtx.clientCtx)
105107
}
108+
109+
// GetSimulatedTxGas calculates the gas for the given messages using the simulation mode.
110+
func (txCtx cosmosTxContext) GetSimulatedTxGas(
111+
ctx context.Context,
112+
signingKeyName string,
113+
msgs ...cosmostypes.Msg,
114+
) (uint64, error) {
115+
clientCtx := cosmosclient.Context(txCtx.clientCtx)
116+
keyRecord, err := txCtx.GetKeyring().Key(signingKeyName)
117+
if err != nil {
118+
return 0, err
119+
}
120+
121+
accAddress, err := keyRecord.GetAddress()
122+
if err != nil {
123+
return 0, err
124+
}
125+
126+
accountRetriever := txCtx.clientCtx.AccountRetriever
127+
_, seq, err := accountRetriever.GetAccountNumberSequence(clientCtx, accAddress)
128+
if err != nil {
129+
return 0, err
130+
}
131+
132+
txf := txCtx.txFactory.
133+
WithSimulateAndExecute(true).
134+
WithFromName(signingKeyName).
135+
WithSequence(seq)
136+
137+
_, gas, err := cosmostx.CalculateGas(txCtx.GetClientCtx(), txf, msgs...)
138+
if err != nil {
139+
return 0, err
140+
}
141+
142+
return gas, nil
143+
}

pkg/client/tx/options.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package tx
22

3-
import "github.com/pokt-network/poktroll/pkg/client"
3+
import (
4+
cosmostypes "github.com/cosmos/cosmos-sdk/types"
5+
6+
"github.com/pokt-network/poktroll/pkg/client"
7+
)
48

59
// WithCommitTimeoutBlocks sets the timeout duration in terms of number of blocks
610
// for the client to wait for broadcast transactions to be committed before
@@ -28,3 +32,10 @@ func WithConnRetryLimit(limit int) client.TxClientOption {
2832
client.(*txClient).connRetryLimit = limit
2933
}
3034
}
35+
36+
// WithGasPrices sets the gas price to be used when constructing transactions.
37+
func WithGasPrices(gasPrices cosmostypes.DecCoins) client.TxClientOption {
38+
return func(client client.TxClient) {
39+
client.(*txClient).gasPrices = gasPrices
40+
}
41+
}

pkg/deps/config/suppliers.go

+31-3
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@ package config
22

33
import (
44
"context"
5+
"fmt"
56
"net/url"
67

78
"cosmossdk.io/depinject"
89
sdkclient "github.com/cosmos/cosmos-sdk/client"
910
cosmosflags "github.com/cosmos/cosmos-sdk/client/flags"
11+
cosmostypes "github.com/cosmos/cosmos-sdk/types"
1012
"github.com/cosmos/gogoproto/grpc"
1113
"github.com/spf13/cobra"
1214

15+
"github.com/pokt-network/poktroll/app/volatile"
1316
"github.com/pokt-network/poktroll/pkg/client/block"
1417
"github.com/pokt-network/poktroll/pkg/client/delegation"
1518
"github.com/pokt-network/poktroll/pkg/client/events"
@@ -350,11 +353,21 @@ func NewSupplySupplierClientsFn(signingKeyNames []string) SupplierFn {
350353
return func(
351354
ctx context.Context,
352355
deps depinject.Config,
353-
_ *cobra.Command,
356+
cmd *cobra.Command,
354357
) (depinject.Config, error) {
358+
gasPriceStr, err := cmd.Flags().GetString(cosmosflags.FlagGasPrices)
359+
if err != nil {
360+
return nil, err
361+
}
362+
363+
gasPrices, err := cosmostypes.ParseDecCoins(gasPriceStr)
364+
if err != nil {
365+
return nil, err
366+
}
367+
355368
suppliers := supplier.NewSupplierClientMap()
356369
for _, signingKeyName := range signingKeyNames {
357-
txClientDepinjectConfig, err := newSupplyTxClientsFn(ctx, deps, signingKeyName)
370+
txClientDepinjectConfig, err := newSupplyTxClientsFn(ctx, deps, signingKeyName, gasPrices)
358371
if err != nil {
359372
return nil, err
360373
}
@@ -466,12 +479,27 @@ func NewSupplyBankQuerierFn() SupplierFn {
466479

467480
// newSupplyTxClientFn returns a new depinject.Config which is supplied with
468481
// the given deps and the new TxClient.
469-
func newSupplyTxClientsFn(ctx context.Context, deps depinject.Config, signingKeyName string) (depinject.Config, error) {
482+
func newSupplyTxClientsFn(
483+
ctx context.Context,
484+
deps depinject.Config,
485+
signingKeyName string,
486+
gasPrices cosmostypes.DecCoins,
487+
) (depinject.Config, error) {
488+
// Ensure that the gas prices include upokt
489+
for _, gasPrice := range gasPrices {
490+
if gasPrice.Denom != volatile.DenomuPOKT {
491+
// TODO_TECHDEBT(red-0ne): Allow other gas prices denominations once supported (e.g. mPOKT, POKT)
492+
// See https://docs.cosmos.network/main/build/architecture/adr-024-coin-metadata#decision
493+
return nil, fmt.Errorf("only gas prices with %s denom are supported", volatile.DenomuPOKT)
494+
}
495+
}
496+
470497
txClient, err := tx.NewTxClient(
471498
ctx,
472499
deps,
473500
tx.WithSigningKeyName(signingKeyName),
474501
tx.WithCommitTimeoutBlocks(tx.DefaultCommitTimeoutHeightOffset),
502+
tx.WithGasPrices(gasPrices),
475503
)
476504
if err != nil {
477505
return nil, err

pkg/relayer/cmd/cmd.go

+2
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ for such operations.`,
7575
cmd.Flags().Bool(cosmosflags.FlagGRPCInsecure, true, "Used to initialize the Cosmos query context with grpc security options. It can be used to override the `QueryNodeGRPCInsecure` field in the config file if specified.")
7676
cmd.Flags().String(cosmosflags.FlagChainID, "poktroll", "The network chain ID")
7777
cmd.Flags().StringVar(&flagLogLevel, cosmosflags.FlagLogLevel, "debug", "The logging level (debug|info|warn|error)")
78+
cmd.Flags().Float64(cosmosflags.FlagGasAdjustment, 1.5, "The adjustment factor to be multiplied by the gas estimate returned by the tx simulation")
79+
cmd.Flags().String(cosmosflags.FlagGasPrices, "1upokt", "Set the gas unit price in upokt")
7880

7981
return cmd
8082
}

testutil/testclient/testtx/context.go

+4
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ func NewOneTimeErrTxTimeoutTxContext(
9595
},
9696
).Times(1)
9797

98+
txCtxMock.EXPECT().GetSimulatedTxGas(gomock.Any(), gomock.Any(), gomock.Any()).
99+
Return(uint64(1), nil).
100+
Times(1)
101+
98102
txCtxMock.EXPECT().QueryTx(
99103
gomock.AssignableToTypeOf(context.Background()),
100104
gomock.AssignableToTypeOf([]byte{}),

0 commit comments

Comments
 (0)