Skip to content

Commit

Permalink
feat: add gas estimation to the signer (#3017)
Browse files Browse the repository at this point in the history
  • Loading branch information
cmwaters authored Mar 1, 2024
1 parent bd28f0a commit 2b13533
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 28 deletions.
10 changes: 5 additions & 5 deletions pkg/proof/proof_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,21 +185,21 @@ func TestNewShareInclusionProof(t *testing.T) {
{
name: "shares from PFB namespace",
startingShare: 53,
endingShare: 56,
endingShare: 55,
namespaceID: appns.PayForBlobNamespace,
expectErr: false,
},
{
name: "blob shares for first namespace",
startingShare: 56,
endingShare: 58,
startingShare: 55,
endingShare: 57,
namespaceID: ns1,
expectErr: false,
},
{
name: "blob shares for third namespace",
startingShare: 60,
endingShare: 62,
startingShare: 59,
endingShare: 61,
namespaceID: ns3,
expectErr: false,
},
Expand Down
66 changes: 43 additions & 23 deletions pkg/user/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ func (s *Signer) CreateTx(msgs []sdktypes.Msg, opts ...TxOption) ([]byte, error)
return nil, err
}

if err := s.signTransaction(txBuilder); err != nil {
if err := s.signTransaction(txBuilder, s.getAndIncrementSequence()); err != nil {
return nil, err
}

Expand Down Expand Up @@ -243,6 +243,31 @@ func (s *Signer) ConfirmTx(ctx context.Context, txHash string) (*sdktypes.TxResp
}
}

func (s *Signer) EstimateGas(ctx context.Context, msgs []sdktypes.Msg, opts ...TxOption) (uint64, error) {
txBuilder := s.txBuilder(opts...)
if err := txBuilder.SetMsgs(msgs...); err != nil {
return 0, err
}

if err := s.signTransaction(txBuilder, s.Sequence()); err != nil {
return 0, err
}

txBytes, err := s.enc.TxEncoder()(txBuilder.GetTx())
if err != nil {
return 0, err
}

resp, err := tx.NewServiceClient(s.grpc).Simulate(ctx, &tx.SimulateRequest{
TxBytes: txBytes,
})
if err != nil {
return 0, err
}

return resp.GasInfo.GasUsed, nil
}

// ChainID returns the chain ID of the signer.
func (s *Signer) ChainID() string {
return s.chainID
Expand Down Expand Up @@ -308,7 +333,7 @@ func (s *Signer) Keyring() keyring.Keyring {
return s.keys
}

func (s *Signer) signTransaction(builder client.TxBuilder) error {
func (s *Signer) signTransaction(builder client.TxBuilder, sequence uint64) error {
signers := builder.GetTx().GetSigners()
if len(signers) != 1 {
return fmt.Errorf("expected 1 signer, got %d", len(signers))
Expand All @@ -318,20 +343,9 @@ func (s *Signer) signTransaction(builder client.TxBuilder) error {
return fmt.Errorf("expected signer %s, got %s", s.address.String(), signers[0].String())
}

sequence := s.getAndIncrementSequence()

// To ensure we have the correct bytes to sign over we produce
// a dry run of the signing data
draftsigV2 := signing.SignatureV2{
PubKey: s.pk,
Data: &signing.SingleSignatureData{
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
Signature: nil,
},
Sequence: sequence,
}

err := builder.SetSignatures(draftsigV2)
err := builder.SetSignatures(s.getSignatureV2(sequence, nil))
if err != nil {
return fmt.Errorf("error setting draft signatures: %w", err)
}
Expand All @@ -341,16 +355,8 @@ func (s *Signer) signTransaction(builder client.TxBuilder) error {
if err != nil {
return fmt.Errorf("error creating signature: %w", err)
}
sigV2 := signing.SignatureV2{
PubKey: s.pk,
Data: &signing.SingleSignatureData{
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
Signature: signature,
},
Sequence: sequence,
}

err = builder.SetSignatures(sigV2)
err = builder.SetSignatures(s.getSignatureV2(sequence, signature))
if err != nil {
return fmt.Errorf("error setting signatures: %w", err)
}
Expand Down Expand Up @@ -413,3 +419,17 @@ func QueryAccount(ctx context.Context, conn *grpc.ClientConn, encCfg encoding.Co
accNum, seqNum = acc.GetAccountNumber(), acc.GetSequence()
return accNum, seqNum, nil
}

func (s *Signer) getSignatureV2(sequence uint64, signature []byte) signing.SignatureV2 {
sigV2 := signing.SignatureV2{
Data: &signing.SingleSignatureData{
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
Signature: signature,
},
Sequence: sequence,
}
if sequence == 0 {
sigV2.PubKey = s.pk
}
return sigV2
}
7 changes: 7 additions & 0 deletions pkg/user/signer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ func (s *SignerTestSuite) TestConfirmTx() {
})
}

func (s *SignerTestSuite) TestGasEstimation() {
msg := bank.NewMsgSend(s.signer.Address(), testnode.RandomAddress().(sdk.AccAddress), sdk.NewCoins(sdk.NewInt64Coin(app.BondDenom, 10)))
gas, err := s.signer.EstimateGas(context.Background(), []sdk.Msg{msg})
require.NoError(s.T(), err)
require.Greater(s.T(), gas, uint64(0))
}

// TestGasConsumption verifies that the amount deducted from a user's balance is
// based on the fee provided in the tx instead of the gas used by the tx. This
// behavior leads to poor UX because tx submitters must over-estimate the amount
Expand Down

0 comments on commit 2b13533

Please sign in to comment.