Skip to content
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

feat: nonce handling with signer (backport #3196) #3213

Merged
merged 6 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ test-short:
## test-race: Run unit tests in race mode.
test-race:
@echo "--> Running tests in race mode"
@go test ./... -v -race -skip "TestPrepareProposalConsistency|TestIntegrationTestSuite|TestQGBRPCQueries|TestSquareSizeIntegrationTest|TestStandardSDKIntegrationTestSuite|TestTxsimCommandFlags|TestTxsimCommandEnvVar|TestMintIntegrationTestSuite|TestQGBCLI|TestUpgrade|TestMaliciousTestNode|TestMaxTotalBlobSizeSuite|TestQGBIntegrationSuite|TestSignerTestSuite|TestPriorityTestSuite|TestTimeInPrepareProposalContext"
@go test ./... -v -race -skip "TestPrepareProposalConsistency|TestIntegrationTestSuite|TestQGBRPCQueries|TestSquareSizeIntegrationTest|TestStandardSDKIntegrationTestSuite|TestTxsimCommandFlags|TestTxsimCommandEnvVar|TestMintIntegrationTestSuite|TestQGBCLI|TestUpgrade|TestMaliciousTestNode|TestMaxTotalBlobSizeSuite|TestQGBIntegrationSuite|TestSignerTestSuite|TestPriorityTestSuite|TestTimeInPrepareProposalContext|TestSignerTwins|TestConcurrentTxSubmission"
cmwaters marked this conversation as resolved.
Show resolved Hide resolved
.PHONY: test-race

## test-bench: Run unit tests in bench mode.
Expand Down
20 changes: 18 additions & 2 deletions app/errors/nonce_mismatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"strconv"
"strings"

sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)
Expand All @@ -13,16 +14,31 @@ func IsNonceMismatch(err error) bool {
return errors.Is(err, sdkerrors.ErrWrongSequence)
}

// IsNonceMismatch checks if the error code matches the sequence mismatch.
func IsNonceMismatchCode(code uint32) bool {
return code == sdkerrors.ErrWrongSequence.ABCICode()
}

// ParseNonceMismatch extracts the expected sequence number from the
// ErrWrongSequence error.
func ParseNonceMismatch(err error) (uint64, error) {
if !IsNonceMismatch(err) {
return 0, errors.New("error is not a sequence mismatch")
}

numbers := regexpInt.FindAllString(err.Error(), -1)
return ParseExpectedSequence(err.Error())
}

// ParseExpectedSequence extracts the expected sequence number from the
// ErrWrongSequence error.
func ParseExpectedSequence(str string) (uint64, error) {
if !strings.HasPrefix(str, "account sequence mismatch") {
return 0, fmt.Errorf("unexpected wrong sequence error: %s", str)
}

numbers := regexpInt.FindAllString(str, -1)
if len(numbers) != 2 {
return 0, fmt.Errorf("unexpected wrong sequence error: %w", err)
return 0, fmt.Errorf("expected two numbers in string, got %d", len(numbers))
}

// the first number is the expected sequence number
Expand Down
57 changes: 31 additions & 26 deletions app/test/priority_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package app_test
import (
"encoding/hex"
"sort"
"sync"
"testing"
"time"

Expand Down Expand Up @@ -70,43 +71,47 @@ func (s *PriorityTestSuite) TestPriorityByGasPrice() {
t := s.T()

// quickly submit blobs with a random fee
hashes := make([]string, 0, len(s.signers))

hashes := make(chan string, len(s.signers))
blobSize := uint32(100)
gasLimit := blobtypes.DefaultEstimateGas([]uint32{blobSize})
wg := &sync.WaitGroup{}
for _, signer := range s.signers {
blobSize := uint32(100)
gasLimit := blobtypes.DefaultEstimateGas([]uint32{blobSize})
gasPrice := s.rand.Float64()
btx, err := signer.CreatePayForBlob(
blobfactory.ManyBlobs(
t,
s.rand,
[]namespace.Namespace{namespace.RandomBlobNamespace()},
[]int{100}),
user.SetGasLimitAndFee(gasLimit, gasPrice),
)
require.NoError(t, err)
resp, err := signer.BroadcastTx(s.cctx.GoContext(), btx)
require.NoError(t, err)
require.Equal(t, abci.CodeTypeOK, resp.Code)
hashes = append(hashes, resp.TxHash)
wg.Add(1)
go func() {
defer wg.Done()
gasPrice := float64(s.rand.Intn(1000)+1) / 1000
resp, err := signer.SubmitPayForBlob(
s.cctx.GoContext(),
blobfactory.ManyBlobs(
t,
s.rand,
[]namespace.Namespace{namespace.RandomBlobNamespace()},
[]int{100}),
user.SetGasLimitAndFee(gasLimit, gasPrice),
)
require.NoError(t, err)
require.Equal(t, abci.CodeTypeOK, resp.Code, resp.RawLog)
hashes <- resp.TxHash
}()
}

wg.Wait()
close(hashes)

err := s.cctx.WaitForNextBlock()
require.NoError(t, err)

// get the responses for each tx for analysis and sort by height
// note: use rpc types because they contain the tx index
heightMap := make(map[int64][]*rpctypes.ResultTx)
for _, hash := range hashes {
resp, err := s.signers[0].ConfirmTx(s.cctx.GoContext(), hash)
require.NoError(t, err)
require.NotNil(t, resp)
require.Equal(t, abci.CodeTypeOK, resp.Code)
for hash := range hashes {
// use the core rpc type because it contains the tx index
hash, err := hex.DecodeString(hash)
require.NoError(t, err)
coreRes, err := s.cctx.Client.Tx(s.cctx.GoContext(), hash, false)
require.NoError(t, err)
heightMap[resp.Height] = append(heightMap[resp.Height], coreRes)
heightMap[coreRes.Height] = append(heightMap[coreRes.Height], coreRes)
}
require.GreaterOrEqual(t, len(heightMap), 1)

Expand All @@ -123,7 +128,7 @@ func (s *PriorityTestSuite) TestPriorityByGasPrice() {

// check that there was at least one block with more than three transactions
// in it. This is more of a sanity check than a test.
require.True(t, highestNumOfTxsPerBlock > 3)
require.Greater(t, highestNumOfTxsPerBlock, 3)
}

func sortByIndex(txs []*rpctypes.ResultTx) []*rpctypes.ResultTx {
Expand All @@ -135,14 +140,14 @@ func sortByIndex(txs []*rpctypes.ResultTx) []*rpctypes.ResultTx {

func isSortedByFee(t *testing.T, ecfg encoding.Config, responses []*rpctypes.ResultTx) bool {
for i := 0; i < len(responses)-1; i++ {
if gasPrice(t, ecfg, responses[i]) <= gasPrice(t, ecfg, responses[i+1]) {
if getGasPrice(t, ecfg, responses[i]) <= getGasPrice(t, ecfg, responses[i+1]) {
return false
}
}
return true
}

func gasPrice(t *testing.T, ecfg encoding.Config, resp *rpctypes.ResultTx) float64 {
func getGasPrice(t *testing.T, ecfg encoding.Config, resp *rpctypes.ResultTx) float64 {
sdkTx, err := ecfg.TxConfig.TxDecoder()(resp.Tx)
require.NoError(t, err)
feeTx := sdkTx.(sdk.FeeTx)
Expand Down
Loading
Loading