diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 133dd6e865..10800d575c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,17 +10,15 @@ jobs: runs-on: ubuntu-latest steps: - name: Install Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: go-version: 1.16.x - name: Checkout code - uses: actions/checkout@v2 - with: - submodules: recursive + uses: actions/checkout@v3 - name: Lint - uses: golangci/golangci-lint-action@v2 + uses: golangci/golangci-lint-action@v3 with: version: latest args: @@ -49,25 +47,26 @@ jobs: -E dupl -E errname -E errorlint - skip-go-installation: true test: runs-on: ubuntu-latest steps: - name: Install Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: go-version: 1.16.x - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive - + # We need to build the binary with the race flag enabled + # because it will get picked up and run during e2e tests + # and the e2e tests should error out if any kind of race is found - name: Go build with race run: CGO_ENABLED=1 GOOS=linux go build -race -a -o artifacts/polygon-edge . - - name: Add race artifacts directory to the path + - name: Add artifacts directory to the path run: echo "$(pwd)/artifacts" >> $GITHUB_PATH - name: Go test @@ -76,7 +75,7 @@ jobs: - name: Go build without race run: CGO_ENABLED=0 GOOS=linux go build -a -o artifacts/polygon-edge . - - name: Replace artificats + - name: Replace artifacts run: echo "$(pwd)/artifacts" >> $GITHUB_PATH - name: Extract branch name diff --git a/archive/backup_test.go b/archive/backup_test.go index 7337288bdc..1d5d589816 100644 --- a/archive/backup_test.go +++ b/archive/backup_test.go @@ -91,6 +91,8 @@ func (m *systemClientMock) BlockByNumber( } func Test_determineTo(t *testing.T) { + t.Parallel() + toPtr := func(x uint64) *uint64 { return &x } @@ -154,7 +156,10 @@ func Test_determineTo(t *testing.T) { } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + resTo, resToHash, err := determineTo(context.Background(), tt.systemClientMock, tt.targetTo) assert.Equal(t, tt.err, err) if tt.err == nil { diff --git a/chain/chain_test.go b/chain/chain_test.go index 178fa6380b..c8c913644a 100644 --- a/chain/chain_test.go +++ b/chain/chain_test.go @@ -22,6 +22,8 @@ func hash(str string) types.Hash { } func TestGenesisAlloc(t *testing.T) { + t.Parallel() + cases := []struct { input string output map[types.Address]GenesisAccount @@ -81,7 +83,11 @@ func TestGenesisAlloc(t *testing.T) { } for _, c := range cases { + c := c + t.Run("", func(t *testing.T) { + t.Parallel() + var dec map[types.Address]GenesisAccount if err := json.Unmarshal([]byte(c.input), &dec); err != nil { if c.output != nil { @@ -95,6 +101,8 @@ func TestGenesisAlloc(t *testing.T) { } func TestGenesisX(t *testing.T) { + t.Parallel() + cases := []struct { input string output *Genesis @@ -128,7 +136,11 @@ func TestGenesisX(t *testing.T) { } for _, c := range cases { + c := c + t.Run("", func(t *testing.T) { + t.Parallel() + var dec *Genesis if err := json.Unmarshal([]byte(c.input), &dec); err != nil { if c.output != nil { diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go index 0d067fa08d..25ac9a95c5 100644 --- a/crypto/crypto_test.go +++ b/crypto/crypto_test.go @@ -37,6 +37,8 @@ func TestKeyEncoding(t *testing.T) { } func TestCreate2(t *testing.T) { + t.Parallel() + cases := []struct { address string salt string @@ -88,7 +90,11 @@ func TestCreate2(t *testing.T) { } for _, c := range cases { + c := c + t.Run("", func(t *testing.T) { + t.Parallel() + address := types.StringToAddress(c.address) initCode := hex.MustDecodeHex(c.initCode) @@ -157,6 +163,8 @@ func TestValidateSignatureValues(t *testing.T) { } func TestPrivateKeyRead(t *testing.T) { + t.Parallel() + // Write private keys to disk, check if read is ok testTable := []struct { name string @@ -192,7 +200,10 @@ func TestPrivateKeyRead(t *testing.T) { } for _, testCase := range testTable { + testCase := testCase t.Run(testCase.name, func(t *testing.T) { + t.Parallel() + privateKey, err := BytesToPrivateKey([]byte(testCase.privateKeyHex)) if err != nil && !testCase.shouldFail { t.Fatalf("Unable to parse private key, %v", err) diff --git a/crypto/txsigner_test.go b/crypto/txsigner_test.go index 50ad4590ce..1141893dbe 100644 --- a/crypto/txsigner_test.go +++ b/crypto/txsigner_test.go @@ -29,6 +29,8 @@ func TestFrontierSigner(t *testing.T) { } func TestEIP155Signer_Sender(t *testing.T) { + t.Parallel() + toAddress := types.StringToAddress("1") testTable := []struct { @@ -70,7 +72,10 @@ func TestEIP155Signer_Sender(t *testing.T) { } for _, testCase := range testTable { + testCase := testCase t.Run(testCase.name, func(t *testing.T) { + t.Parallel() + key, keyGenError := GenerateKey() if keyGenError != nil { t.Fatalf("Unable to generate key") diff --git a/e2e/broadcast_test.go b/e2e/broadcast_test.go index 50bfcc3a31..aad6bc1172 100644 --- a/e2e/broadcast_test.go +++ b/e2e/broadcast_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "math/big" + "sync" "testing" "time" @@ -44,12 +45,21 @@ func TestBroadcast(t *testing.T) { } for _, tt := range testCases { + tt := tt + t.Run(tt.name, func(t *testing.T) { srvs := framework.NewTestServers(t, tt.numNodes, conf) + framework.MultiJoinSerial(t, srvs[0:tt.numConnectedNodes]) // Check the connections + connectionErrors := framework.NewAtomicErrors(len(srvs)) + + var wgForConnections sync.WaitGroup + for i, srv := range srvs { + srv := srv + // Required number of connections numRequiredConnections := 0 if i < tt.numConnectedNodes { @@ -59,12 +69,29 @@ func TestBroadcast(t *testing.T) { numRequiredConnections = 2 } } - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - _, err := framework.WaitUntilPeerConnects(ctx, srv, numRequiredConnections) - if err != nil { - t.Fatal(err) - } + + wgForConnections.Add(1) + go func() { + defer wgForConnections.Done() + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + + _, err := framework.WaitUntilPeerConnects(ctx, srv, numRequiredConnections) + if err != nil { + connectionErrors.Append(err) + } + }() + } + + wgForConnections.Wait() + + for _, err := range connectionErrors.Errors() { + t.Error(err) + } + + if len(connectionErrors.Errors()) > 0 { + t.Fail() } // wait until gossip protocol build mesh network @@ -90,6 +117,8 @@ func TestBroadcast(t *testing.T) { } for i, srv := range srvs { + srv := srv + shouldHaveTxPool := false subTestName := fmt.Sprintf("node %d shouldn't have tx in txpool", i) if i < tt.numConnectedNodes { @@ -98,7 +127,9 @@ func TestBroadcast(t *testing.T) { } t.Run(subTestName, func(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + t.Parallel() + + ctx, cancel := context.WithTimeout(context.Background(), framework.DefaultTimeout) defer cancel() res, err := framework.WaitUntilTxPoolFilled(ctx, srv, 1) diff --git a/e2e/encoding_test.go b/e2e/encoding_test.go deleted file mode 100644 index 6b67373e3e..0000000000 --- a/e2e/encoding_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package e2e - -import ( - "context" - "testing" - "time" - - "github.com/0xPolygon/polygon-edge/types" - - "github.com/0xPolygon/polygon-edge/e2e/framework" - "github.com/0xPolygon/polygon-edge/helper/tests" - "github.com/stretchr/testify/assert" -) - -func TestEncoding(t *testing.T) { - key, from := tests.GenerateKeyAndAddr(t) - - srvs := framework.NewTestServers(t, 1, func(config *framework.TestServerConfig) { - config.SetConsensus(framework.ConsensusDev) - config.SetSeal(true) - config.Premine(from, framework.EthToWei(10)) - }) - srv := srvs[0] - - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - contractAddr, err := srv.DeployContract(ctx, sampleByteCode, key) - - if err != nil { - t.Fatal(err) - } - - ctx, cancel = context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - receipt := srv.InvokeMethod(ctx, types.Address(contractAddr), "setA1", key) - - // try to get the transaction - client := srv.JSONRPC().Eth() - - _, err = client.GetTransactionByHash(receipt.TransactionHash) - assert.NoError(t, err) - - _, err = client.GetBlockByHash(receipt.BlockHash, true) - assert.NoError(t, err) -} diff --git a/e2e/framework/helper.go b/e2e/framework/helper.go index 5de29da6e6..b3161e5783 100644 --- a/e2e/framework/helper.go +++ b/e2e/framework/helper.go @@ -29,6 +29,35 @@ import ( empty "google.golang.org/protobuf/types/known/emptypb" ) +var ( + DefaultTimeout = time.Second * 10 +) + +type AtomicErrors struct { + sync.RWMutex + errors []error +} + +func NewAtomicErrors(capacity int) AtomicErrors { + return AtomicErrors{ + errors: make([]error, 0, capacity), + } +} + +func (a *AtomicErrors) Append(err error) { + a.Lock() + defer a.Unlock() + + a.errors = append(a.errors, err) +} + +func (a *AtomicErrors) Errors() []error { + a.RLock() + defer a.RUnlock() + + return a.errors +} + func EthToWei(ethValue int64) *big.Int { return EthToWeiPrecise(ethValue, 18) } @@ -102,7 +131,7 @@ func StakeAmount( Input: MethodSig("stake"), } - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout) defer cancel() _, err := srv.SendRawTx(ctx, txn, senderKey) @@ -130,7 +159,7 @@ func UnstakeAmount( Input: MethodSig("unstake"), } - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout) defer cancel() receipt, err := srv.SendRawTx(ctx, txn, senderKey) @@ -202,41 +231,53 @@ func MultiJoin(t *testing.T, srvs ...*TestServer) { t.Fatal("not an even number") } - errCh := make(chan error, len(srvs)/2) + errors := NewAtomicErrors(len(srvs) / 2) + + var wg sync.WaitGroup for i := 0; i < len(srvs); i += 2 { src, dst := srvs[i], srvs[i+1] + srcIndex, dstIndex := i, i+1 + + wg.Add(1) go func() { + defer wg.Done() + srcClient, dstClient := src.Operator(), dst.Operator() - dstStatus, err := dstClient.GetStatus(context.Background(), &empty.Empty{}) + ctxFotStatus, cancelForStatus := context.WithTimeout(context.Background(), DefaultTimeout) + defer cancelForStatus() + + dstStatus, err := dstClient.GetStatus(ctxFotStatus, &empty.Empty{}) if err != nil { - errCh <- err + errors.Append(fmt.Errorf("failed to get status from server %d, error=%w", dstIndex, err)) return } dstAddr := strings.Split(dstStatus.P2PAddr, ",")[0] - _, err = srcClient.PeersAdd(context.Background(), &proto.PeersAddRequest{ + ctxForConnecting, cancelForConnecting := context.WithTimeout(context.Background(), DefaultTimeout) + + defer cancelForConnecting() + + _, err = srcClient.PeersAdd(ctxForConnecting, &proto.PeersAddRequest{ Id: dstAddr, }) - errCh <- err + if err != nil { + errors.Append(fmt.Errorf("failed to connect from %d to %d, error=%w", srcIndex, dstIndex, err)) + } }() } - errCount := 0 - - for i := 0; i < len(srvs)/2; i++ { - if err := <-errCh; err != nil { - errCount++ + wg.Wait() - t.Errorf("failed to connect from %d to %d, error=%+v ", 2*i, 2*i+1, err) - } + for _, err := range errors.Errors() { + t.Error(err) } - if errCount > 0 { + if len(errors.Errors()) > 0 { t.Fail() } } @@ -326,8 +367,13 @@ func WaitUntilBlockMined(ctx context.Context, srv *TestServer, desiredHeight uin // MethodSig returns the signature of a non-parametrized function func MethodSig(name string) []byte { + return MethodSigWithParams(fmt.Sprintf("%s()", name)) +} + +// MethodSigWithParams returns the signature of a function +func MethodSigWithParams(nameWithParams string) []byte { h := sha3.NewLegacyKeccak256() - h.Write([]byte(name + "()")) + h.Write([]byte(nameWithParams)) b := h.Sum(nil) return b[:4] @@ -429,18 +475,45 @@ func NewTestServers(t *testing.T, num int, conf func(*TestServerConfig)) []*Test srv := NewTestServer(t, dataDir, conf) srv.Config.SetBootnodes(bootnodes) - if genesisErr := srv.GenerateGenesis(); genesisErr != nil { - t.Fatal(genesisErr) - } + srvs = append(srvs, srv) + } - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() + errors := NewAtomicErrors(len(srvs)) - if err := srv.Start(ctx); err != nil { - t.Fatal(err) - } + var wg sync.WaitGroup - srvs = append(srvs, srv) + for i, srv := range srvs { + wg.Add(1) + + i, srv := i, srv + + go func() { + defer wg.Done() + + if err := srv.GenerateGenesis(); err != nil { + errors.Append(fmt.Errorf("server %d failed genesis command, error=%w", i, err)) + + return + } + + ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout) + defer cancel() + + err := srv.Start(ctx) + if err != nil { + errors.Append(fmt.Errorf("server %d failed to start, error=%w", i, err)) + } + }() + } + + wg.Wait() + + for _, err := range errors.Errors() { + t.Error(err) + } + + if len(errors.Errors()) > 0 { + t.Fail() } return srvs diff --git a/e2e/framework/testserver.go b/e2e/framework/testserver.go index 953b86b4d7..279a3afe2b 100644 --- a/e2e/framework/testserver.go +++ b/e2e/framework/testserver.go @@ -569,7 +569,7 @@ func (t *TestServer) GetGasTotal(txHashes []web3.Hash) uint64 { go func(txHash web3.Hash) { defer wg.Done() - ctx, cancelFn := context.WithTimeout(context.Background(), 10*time.Second) + ctx, cancelFn := context.WithTimeout(context.Background(), DefaultTimeout) defer cancelFn() receipt, receiptErr := tests.WaitForReceipt(ctx, t.JSONRPC().Eth(), txHash) diff --git a/e2e/genesis_test.go b/e2e/genesis_test.go index c4f1289566..6fda5398f0 100644 --- a/e2e/genesis_test.go +++ b/e2e/genesis_test.go @@ -3,124 +3,65 @@ package e2e import ( "context" "github.com/0xPolygon/polygon-edge/command" - "math/big" "testing" "time" - "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/e2e/framework" "github.com/0xPolygon/polygon-edge/helper/tests" - txpoolOp "github.com/0xPolygon/polygon-edge/txpool/proto" - "github.com/0xPolygon/polygon-edge/types" - "github.com/golang/protobuf/ptypes/any" "github.com/stretchr/testify/assert" ) -// Test if the custom block gas limit is properly set -func TestGenesisCustomBlockGasLimit(t *testing.T) { - var blockGasLimit uint64 = 5000000000 - - srvs := framework.NewTestServers(t, 1, func(config *framework.TestServerConfig) { - config.SetConsensus(framework.ConsensusDev) - config.SetBlockLimit(blockGasLimit) - }) - srv := srvs[0] - - client := srv.JSONRPC() - - block, err := client.Eth().GetBlockByNumber(0, true) - if err != nil { - t.Fatalf("failed to retrieve block: %v", err) - } - - if block.GasLimit != blockGasLimit { - t.Fatalf("invalid block gas limit, expected [%d] but got [%d]", blockGasLimit, block.GasLimit) - } -} - -// Test if the default gas limit is properly set -func TestGenesisDefaultBlockGasLimit(t *testing.T) { - var blockGasLimit uint64 = command.DefaultGenesisGasLimit - - srvs := framework.NewTestServers(t, 1, func(config *framework.TestServerConfig) { - config.SetConsensus(framework.ConsensusDev) - }) - srv := srvs[0] - - client := srv.JSONRPC() - - block, err := client.Eth().GetBlockByNumber(0, true) - if err != nil { - t.Fatalf("failed to retrieve block: %v", err) +// TestGenesisBlockGasLimit tests the genesis block limit setting +func TestGenesisBlockGasLimit(t *testing.T) { + testTable := []struct { + name string + blockGasLimit uint64 + expectedBlockGasLimit uint64 + }{ + { + "Custom block gas limit", + 5000000000, + 5000000000, + }, + { + "Default block gas limit", + 0, + command.DefaultGenesisGasLimit, + }, } - if block.GasLimit != blockGasLimit { - t.Fatalf("invalid block gas limit, expected [%d] but got [%d]", blockGasLimit, block.GasLimit) - } -} - -// Test if the custom block gas limit is propagated to the subsequent blocks -func TestCustomBlockGasLimitPropagation(t *testing.T) { - var blockGasLimit uint64 = 5000000000 + for _, testCase := range testTable { + t.Run(testCase.name, func(t *testing.T) { + _, addr := tests.GenerateKeyAndAddr(t) - senderKey, senderAddress := tests.GenerateKeyAndAddr(t) - _, receiverAddress := tests.GenerateKeyAndAddr(t) + ibftManager := framework.NewIBFTServersManager( + t, + 1, + IBFTDirPrefix, + func(i int, config *framework.TestServerConfig) { + config.Premine(addr, framework.EthToWei(10)) + config.SetBlockTime(1) - srvs := framework.NewTestServers(t, 1, func(config *framework.TestServerConfig) { - config.SetConsensus(framework.ConsensusDev) - config.SetBlockLimit(blockGasLimit) - config.Premine(senderAddress, framework.EthToWei(100)) - config.SetBlockGasTarget(blockGasLimit) - }) - srv := srvs[0] + if testCase.blockGasLimit != 0 { + config.SetBlockLimit(testCase.blockGasLimit) + } + }, + ) - client := srv.JSONRPC() + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() - block, err := client.Eth().GetBlockByNumber(0, true) - if err != nil { - t.Fatalf("failed to retrieve block %d: %v", 0, err) - } - - if block.GasLimit != blockGasLimit { - t.Fatalf("invalid block gas limit, expected [%d] but got [%d]", blockGasLimit, block.GasLimit) - } + ibftManager.StartServers(ctx) + srv := ibftManager.GetServer(0) - signer := crypto.NewEIP155Signer(100) + client := srv.JSONRPC() - for i := 0; i < 20; i++ { - signedTx, err := signer.SignTx(&types.Transaction{ - Nonce: uint64(i), - GasPrice: big.NewInt(framework.DefaultGasPrice), - Gas: blockGasLimit, - To: &receiverAddress, - Value: framework.EthToWei(1), - V: big.NewInt(1), - From: senderAddress, - }, senderKey) - if err != nil { - t.Fatalf("failed to sign txn: %v", err) - } + block, err := client.Eth().GetBlockByNumber(0, true) + if err != nil { + t.Fatalf("failed to retrieve block: %v", err) + } - _, err = srv.TxnPoolOperator().AddTxn(context.Background(), &txpoolOp.AddTxnReq{ - Raw: &any.Any{ - Value: signedTx.MarshalRLP(), - }, - From: types.ZeroAddress.String(), + assert.Equal(t, testCase.expectedBlockGasLimit, block.GasLimit) }) - assert.NoError(t, err) - } - - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - _, err = framework.WaitUntilBlockMined(ctx, srv, 1) - assert.NoError(t, err) - - block, err = client.Eth().GetBlockByNumber(1, true) - assert.NoError(t, err, "failed to retrieve block %d: %v", 1, err) - assert.NotNil(t, block) - - if block.GasLimit != blockGasLimit { - t.Fatalf("invalid block gas limit, expected [%d] but got [%d]", blockGasLimit, block.GasLimit) } } diff --git a/e2e/ibft_test.go b/e2e/ibft_test.go index f45cd0418a..a71b8b4fac 100644 --- a/e2e/ibft_test.go +++ b/e2e/ibft_test.go @@ -15,43 +15,49 @@ import ( "github.com/stretchr/testify/assert" ) +/** + TestIbft_Transfer sends a transfer transaction (EOA -> EOA) + and verifies it was mined +**/ func TestIbft_Transfer(t *testing.T) { - senderKey, senderAddr := tests.GenerateKeyAndAddr(t) - _, receiverAddr := tests.GenerateKeyAndAddr(t) + var ( + senderKey, senderAddr = tests.GenerateKeyAndAddr(t) + _, receiverAddr = tests.GenerateKeyAndAddr(t) + ) - ibftManager := framework.NewIBFTServersManager( - t, + ibftManager := framework.NewIBFTServersManager(t, IBFTMinNodes, IBFTDirPrefix, func(i int, config *framework.TestServerConfig) { config.Premine(senderAddr, framework.EthToWei(10)) config.SetSeal(true) - }) + }, + ) ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() - ibftManager.StartServers(ctx) - srv := ibftManager.GetServer(0) + ibftManager.StartServers(ctx) - for i := 0; i < IBFTMinNodes-1; i++ { - txn := &framework.PreparedTransaction{ - From: senderAddr, - To: &receiverAddr, - GasPrice: big.NewInt(10000), - Gas: 1000000, - Value: framework.EthToWei(1), - } + txn := &framework.PreparedTransaction{ + From: senderAddr, + To: &receiverAddr, + GasPrice: big.NewInt(10000), + Gas: 1000000, + Value: framework.EthToWei(1), + } - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() + ctx, cancel = context.WithTimeout(context.Background(), framework.DefaultTimeout) + defer cancel() - receipt, err := srv.SendRawTx(ctx, txn, senderKey) + // send tx and wait for receipt + receipt, err := ibftManager. + GetServer(0). + SendRawTx(ctx, txn, senderKey) - assert.NoError(t, err) - assert.NotNil(t, receipt) - assert.NotNil(t, receipt.TransactionHash) - } + assert.NoError(t, err) + assert.NotNil(t, receipt) + assert.NotNil(t, receipt.TransactionHash) } func TestIbft_TransactionFeeRecipient(t *testing.T) { @@ -110,7 +116,7 @@ func TestIbft_TransactionFeeRecipient(t *testing.T) { Value: big.NewInt(0), Input: framework.MethodSig("setA1"), } - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), framework.DefaultTimeout) defer cancel() receipt, err := srv.SendRawTx(ctx, deployTx, senderKey) assert.NoError(t, err) @@ -121,7 +127,7 @@ func TestIbft_TransactionFeeRecipient(t *testing.T) { txn.Input = framework.MethodSig("setA1") } - ctx1, cancel1 := context.WithTimeout(context.Background(), 10*time.Second) + ctx1, cancel1 := context.WithTimeout(context.Background(), framework.DefaultTimeout) defer cancel1() receipt, err := srv.SendRawTx(ctx1, txn, senderKey) assert.NoError(t, err) diff --git a/e2e/logs_test.go b/e2e/logs_test.go index 05200788d8..c01bbd9f29 100644 --- a/e2e/logs_test.go +++ b/e2e/logs_test.go @@ -3,6 +3,7 @@ package e2e import ( "context" "math/big" + "sync" "testing" "time" @@ -18,36 +19,86 @@ import ( func TestNewFilter_Logs(t *testing.T) { key, addr := tests.GenerateKeyAndAddr(t) - srvs := framework.NewTestServers(t, 1, func(config *framework.TestServerConfig) { - config.SetConsensus(framework.ConsensusDev) - config.Premine(addr, framework.EthToWei(10)) - config.SetSeal(true) - }) - srv := srvs[0] - ctx1, cancel1 := context.WithTimeout(context.Background(), 10*time.Second) + ibftManager := framework.NewIBFTServersManager( + t, + 1, + IBFTDirPrefix, + func(i int, config *framework.TestServerConfig) { + config.Premine(addr, framework.EthToWei(10)) + config.SetBlockTime(1) + }, + ) + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + ibftManager.StartServers(ctx) + srv := ibftManager.GetServer(0) + + ctx1, cancel1 := context.WithTimeout(context.Background(), framework.DefaultTimeout) defer cancel1() contractAddr, err := srv.DeployContract(ctx1, sampleByteCode, key) + castedContractAddr := types.Address(contractAddr) if err != nil { t.Fatal(err) } - client := srv.JSONRPC() - id, err := client.Eth().NewFilter(&web3.LogFilter{}) + txpoolClient := srv.TxnPoolOperator() + jsonRPCClient := srv.JSONRPC() + id, err := jsonRPCClient.Eth().NewFilter(&web3.LogFilter{}) assert.NoError(t, err) numCalls := 10 - for i := 0; i < numCalls; i++ { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - srv.InvokeMethod(ctx, types.Address(contractAddr), "setA1", key) + + var ( + wg sync.WaitGroup + ) + + for i := 1; i <= numCalls; i++ { + wg.Add(1) + + go func(nonce uint64) { + defer wg.Done() + + txn, err := tests.GenerateAddTxnReq(tests.GenerateTxReqParams{ + Nonce: nonce, + ReferenceAddr: addr, + ReferenceKey: key, + ToAddress: castedContractAddr, + GasPrice: big.NewInt(framework.DefaultGasPrice), + Input: framework.MethodSig("setA1"), + }) + if err != nil { + return + } + + addTxnContext, cancelFn := context.WithTimeout(context.Background(), framework.DefaultTimeout) + defer cancelFn() + + addResp, addErr := txpoolClient.AddTxn(addTxnContext, txn) + if addErr != nil { + return + } + + receiptContext, cancelFn := context.WithTimeout(context.Background(), framework.DefaultTimeout) + defer cancelFn() + + txHash := web3.Hash(types.StringToHash(addResp.TxHash)) + if _, receiptErr := srv.WaitForReceipt(receiptContext, txHash); receiptErr != nil { + return + } + }(uint64(i)) } - res, err := client.Eth().GetFilterChanges(id) + wg.Wait() + + res, err := jsonRPCClient.Eth().GetFilterChanges(id) + assert.NoError(t, err) - assert.Equal(t, len(res), numCalls) + assert.Equal(t, numCalls, len(res)) } func TestNewFilter_Block(t *testing.T) { @@ -66,7 +117,7 @@ func TestNewFilter_Block(t *testing.T) { assert.NoError(t, err) for i := 0; i < 3; i++ { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), framework.DefaultTimeout) _, err := srv.SendRawTx(ctx, &framework.PreparedTransaction{ From: from, To: &to, @@ -100,23 +151,34 @@ func TestFilterValue(t *testing.T) { // 3. Query the block's bloom filter to make sure the data has been properly inserted. // key, addr := tests.GenerateKeyAndAddr(t) - srvs := framework.NewTestServers(t, 1, func(config *framework.TestServerConfig) { - config.SetConsensus(framework.ConsensusDev) - config.Premine(addr, framework.EthToWei(10)) - config.SetSeal(true) - }) - srv := srvs[0] - ctx1, cancel1 := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel1() + ibftManager := framework.NewIBFTServersManager( + t, + 1, + IBFTDirPrefix, + func(i int, config *framework.TestServerConfig) { + config.Premine(addr, framework.EthToWei(10)) + config.SetBlockTime(1) + }, + ) - contractAddr, err := srv.DeployContract(ctx1, bloomFilterTestBytecode, key) + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + ibftManager.StartServers(ctx) + srv := ibftManager.GetServer(0) + + deployCtx, deployCancel := context.WithTimeout(context.Background(), time.Minute) + defer deployCancel() + + contractAddr, err := srv.DeployContract(deployCtx, bloomFilterTestBytecode, key) if err != nil { t.Fatal(err) } - client := srv.JSONRPC() + txpoolClient := srv.TxnPoolOperator() + jsonRPCClient := srv.JSONRPC() // Encode event signature hash := sha3.NewLegacyKeccak256() @@ -129,33 +191,60 @@ func TestFilterValue(t *testing.T) { var ( placeholderWrapper []*web3.Hash placeholder web3.Hash + filterEventHashes [][]*web3.Hash + filterAddresses []web3.Address ) copy(placeholder[:], buf) placeholderWrapper = append(placeholderWrapper, &placeholder) - var filterEventHashes [][]*web3.Hash - filterEventHashes = append(filterEventHashes, placeholderWrapper) - - var filterAddresses []web3.Address - filterAddresses = append(filterAddresses, contractAddr) - id, err := client.Eth().NewFilter(&web3.LogFilter{ + filterID, err := jsonRPCClient.Eth().NewFilter(&web3.LogFilter{ Address: filterAddresses, Topics: filterEventHashes, }) + assert.NoError(t, err) - numCalls := 1 - for i := 0; i < numCalls; i++ { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - srv.InvokeMethod(ctx, types.Address(contractAddr), "TriggerMyEvent", key) + castedContractAddr := types.Address(contractAddr) + + if err != nil { + t.Fatal(err) } - res, err := client.Eth().GetFilterChanges(id) + txn, err := tests.GenerateAddTxnReq(tests.GenerateTxReqParams{ + Nonce: 1, + ReferenceAddr: addr, + ReferenceKey: key, + ToAddress: castedContractAddr, + GasPrice: big.NewInt(framework.DefaultGasPrice), + Input: framework.MethodSig("TriggerMyEvent"), + }) + + if err != nil { + return + } + + addTxnContext, cancelFn := context.WithTimeout(context.Background(), framework.DefaultTimeout) + defer cancelFn() + + addResp, addErr := txpoolClient.AddTxn(addTxnContext, txn) + if addErr != nil { + return + } + + receiptContext, cancelFn := context.WithTimeout(context.Background(), framework.DefaultTimeout) + defer cancelFn() + + txHash := web3.Hash(types.StringToHash(addResp.TxHash)) + if _, receiptErr := srv.WaitForReceipt(receiptContext, txHash); receiptErr != nil { + return + } + + res, err := jsonRPCClient.Eth().GetFilterChanges(filterID) + assert.NoError(t, err) assert.Len(t, res, 1) assert.Equal(t, "0x000000000000000000000000000000000000000000000000000000000000002a", hex.EncodeToHex(res[0].Data)) diff --git a/e2e/pos_poa_switch_test.go b/e2e/pos_poa_switch_test.go index 3bad021cee..63aecf8cee 100644 --- a/e2e/pos_poa_switch_test.go +++ b/e2e/pos_poa_switch_test.go @@ -98,7 +98,7 @@ func TestPoAPoSSwitch(t *testing.T) { go func(srv *framework.TestServer) { defer wg.Done() - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), framework.DefaultTimeout) defer cancel() // every validator should have 4 validators in validator set @@ -157,7 +157,7 @@ func TestPoAPoSSwitch(t *testing.T) { go func(srv *framework.TestServer) { defer wg.Done() - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), framework.DefaultTimeout) defer cancel() // every validator should have only 3 validators in validator set diff --git a/e2e/pos_test.go b/e2e/pos_test.go index f3b5287c05..3d67b077f3 100644 --- a/e2e/pos_test.go +++ b/e2e/pos_test.go @@ -390,7 +390,7 @@ func TestPoS_UnstakeExploit(t *testing.T) { From: types.ZeroAddress.String(), } - addCtx, addCtxCn := context.WithTimeout(context.Background(), time.Second*10) + addCtx, addCtxCn := context.WithTimeout(context.Background(), framework.DefaultTimeout) addResp, addErr := clt.AddTxn(addCtx, msg) if addErr != nil { diff --git a/e2e/transaction_test.go b/e2e/transaction_test.go index d4475fd4df..206efe24cb 100644 --- a/e2e/transaction_test.go +++ b/e2e/transaction_test.go @@ -16,59 +16,12 @@ import ( "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/e2e/framework" "github.com/0xPolygon/polygon-edge/helper/tests" - txpoolOp "github.com/0xPolygon/polygon-edge/txpool/proto" "github.com/0xPolygon/polygon-edge/types" - "github.com/golang/protobuf/ptypes/any" "github.com/stretchr/testify/assert" "github.com/umbracle/go-web3" "github.com/umbracle/go-web3/jsonrpc" ) -func TestSignedTransaction(t *testing.T) { - senderKey, senderAddr := tests.GenerateKeyAndAddr(t) - _, receiverAddr := tests.GenerateKeyAndAddr(t) - - preminedAmount := framework.EthToWei(10) - ibftManager := framework.NewIBFTServersManager( - t, - IBFTMinNodes, - IBFTDirPrefix, - func(i int, config *framework.TestServerConfig) { - config.Premine(senderAddr, preminedAmount) - config.SetSeal(true) - }) - - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) - defer cancel() - ibftManager.StartServers(ctx) - - srv := ibftManager.GetServer(0) - clt := srv.JSONRPC() - - // check there is enough balance - balance, err := clt.Eth().GetBalance(web3.Address(senderAddr), web3.Latest) - assert.NoError(t, err) - assert.Equal(t, preminedAmount, balance) - - for i := 0; i < 5; i++ { - txn := &framework.PreparedTransaction{ - From: senderAddr, - To: &receiverAddr, - GasPrice: big.NewInt(10000), - Gas: 1000000, - Value: big.NewInt(10000), - } - - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - receipt, err := srv.SendRawTx(ctx, txn, senderKey) - assert.NoError(t, err) - assert.NotNil(t, receipt) - assert.NotNil(t, receipt.TransactionHash) - } -} - func TestPreminedBalance(t *testing.T) { preminedAccounts := []struct { address types.Address @@ -207,7 +160,7 @@ func TestEthTransfer(t *testing.T) { previousReceiverBalance := balanceReceiver // Do the transfer - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), framework.DefaultTimeout) defer cancel() txn := &framework.PreparedTransaction{ @@ -313,114 +266,6 @@ func getCount( return bigResponse, nil } -// addStressTestTxns adds numTransactions that call the -// passed in StressTest smart contract method -func addStressTestTxns( - t *testing.T, - srv *framework.TestServer, - numTransactions int, - contractAddr types.Address, - senderKey *ecdsa.PrivateKey, -) { - t.Helper() - - currentNonce := 1 // 1 because the first transaction was deployment - clt := srv.TxnPoolOperator() - - for i := 0; i < numTransactions; i++ { - var msg *txpoolOp.AddTxnReq - - setNameTxn := generateStressTestTx( - t, - uint64(currentNonce), - contractAddr, - senderKey, - ) - currentNonce++ - - msg = &txpoolOp.AddTxnReq{ - Raw: &any.Any{ - Value: setNameTxn.MarshalRLP(), - }, - From: types.ZeroAddress.String(), - } - - _, addErr := clt.AddTxn(context.Background(), msg) - if addErr != nil { - t.Fatalf("Unable to add txn #%d, %v", i, addErr) - } - } -} - -// Test scenario (Dev mode): -// Deploy the StressTest smart contract and send ~50 transactions -// that modify it's state, and make sure that all -// transactions were correctly executed -func Test_TransactionDevLoop(t *testing.T) { - senderKey, sender := tests.GenerateKeyAndAddr(t) - defaultBalance := framework.EthToWei(100) - - // Set up the test server - srvs := framework.NewTestServers(t, 1, func(config *framework.TestServerConfig) { - config.SetConsensus(framework.ConsensusDev) - config.SetSeal(true) - config.Premine(sender, defaultBalance) - config.SetBlockLimit(20000000) - }) - srv := srvs[0] - client := srv.JSONRPC() - - // Deploy the stress test contract - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - contractAddr, err := srv.DeployContract(ctx, stressTestBytecode, senderKey) - - if err != nil { - t.Fatal(err) - } - - count, countErr := getCount(sender, contractAddr, client) - if countErr != nil { - t.Fatalf("Unable to call count method, %v", countErr) - } - - // Check that the count is 0 before running the test - assert.Equalf(t, "0", count.String(), "Count doesn't match") - - // Send ~50 transactions - numTransactions := 50 - - // Add stress test transactions - addStressTestTxns( - t, - srv, - numTransactions, - types.StringToAddress(contractAddr.String()), - senderKey, - ) - - // Wait for the final tx to be mined - retryCtx, retryCancel := context.WithTimeout(context.Background(), 5*time.Second) - defer retryCancel() - - _, err = tests.WaitForNonce( - retryCtx, - client.Eth(), - web3.BytesToAddress(sender.Bytes()), - 1+uint64(numTransactions), // contract nonce is 1 (EIP-161) - ) - assert.NoError(t, err) - - count, countErr = getCount(sender, contractAddr, client) - if countErr != nil { - t.Fatalf("Unable to call count method, %v", countErr) - } - - // Check that the count is 0 before running the test - assert.Equalf(t, strconv.Itoa(numTransactions), count.String(), "Count doesn't match") -} - // generateStressTestTx generates a transaction for the // IBFT_Loop and Dev_Loop stress tests func generateStressTestTx( @@ -526,7 +371,7 @@ func Test_TransactionIBFTLoop(t *testing.T) { client := srv.JSONRPC() // Deploy the stress test contract - deployCtx, deployCancel := context.WithTimeout(context.Background(), 10*time.Second) + deployCtx, deployCancel := context.WithTimeout(context.Background(), framework.DefaultTimeout) defer deployCancel() buf, err := hex.DecodeString(stressTestBytecode) diff --git a/e2e/txpool_test.go b/e2e/txpool_test.go index 6e8aaa8fe1..9f9f48b73d 100644 --- a/e2e/txpool_test.go +++ b/e2e/txpool_test.go @@ -4,16 +4,14 @@ import ( "context" "crypto/ecdsa" "errors" - "fmt" + "github.com/0xPolygon/polygon-edge/txpool" "math/big" - "sync" "testing" "time" "github.com/0xPolygon/polygon-edge/crypto" "github.com/0xPolygon/polygon-edge/e2e/framework" "github.com/0xPolygon/polygon-edge/helper/tests" - "github.com/0xPolygon/polygon-edge/txpool" txpoolOp "github.com/0xPolygon/polygon-edge/txpool/proto" "github.com/0xPolygon/polygon-edge/types" "github.com/golang/protobuf/ptypes/any" @@ -240,7 +238,7 @@ func TestTxPool_TransactionCoalescing(t *testing.T) { for i := 0; i < len(nonces); i++ { addReq := generateReq(nonces[i]) - addCtx, addCtxCn := context.WithTimeout(context.Background(), time.Second*10) + addCtx, addCtxCn := context.WithTimeout(context.Background(), framework.DefaultTimeout) addResp, addErr := clt.AddTxn(addCtx, addReq) if addErr != nil { @@ -255,7 +253,7 @@ func TestTxPool_TransactionCoalescing(t *testing.T) { } // Wait for the first transaction to go through - ctx, cancelFn := context.WithTimeout(context.Background(), 10*time.Second) + ctx, cancelFn := context.WithTimeout(context.Background(), framework.DefaultTimeout) defer cancelFn() receipt, receiptErr := tests.WaitForReceipt(ctx, client.Eth(), testTransactions[0].txHash) @@ -277,7 +275,7 @@ func TestTxPool_TransactionCoalescing(t *testing.T) { // Add the transaction with the gap nonce value addReq := generateReq(1) - addCtx, addCtxCn := context.WithTimeout(context.Background(), time.Second*10) + addCtx, addCtxCn := context.WithTimeout(context.Background(), framework.DefaultTimeout) defer addCtxCn() addResp, addErr := clt.AddTxn(addCtx, addReq) @@ -292,7 +290,7 @@ func TestTxPool_TransactionCoalescing(t *testing.T) { // Start from 1 since there was previously a txn with nonce 0 for i := 1; i < len(testTransactions); i++ { // Wait for the first transaction to go through - ctx, cancelFn := context.WithTimeout(context.Background(), 10*time.Second) + ctx, cancelFn := context.WithTimeout(context.Background(), framework.DefaultTimeout) receipt, receiptErr := tests.WaitForReceipt(ctx, client.Eth(), testTransactions[i].txHash) if receiptErr != nil { @@ -336,138 +334,6 @@ func generateTestAccounts(t *testing.T, numAccounts int) []*testAccount { return testAccounts } -func TestTxPool_StressAddition(t *testing.T) { - // Test scenario: - // Add a large number of txns to the txpool concurrently - // Predefined values - defaultBalance := framework.EthToWei(10000) - - // Each account should add 50 transactions - numAccounts := 10 - numTxPerAccount := 50 - - testAccounts := generateTestAccounts(t, numAccounts) - - // Set up the test server - srv := framework.NewTestServers(t, 1, func(config *framework.TestServerConfig) { - config.SetConsensus(framework.ConsensusDev) - config.SetSeal(true) - config.SetBlockLimit(20000000) - for _, testAccount := range testAccounts { - config.Premine(testAccount.address, defaultBalance) - } - })[0] - client := srv.JSONRPC() - - // Required default values - signer := crypto.NewEIP155Signer(100) - - // TxPool client - toAddress := types.StringToAddress("1") - defaultValue := framework.EthToWeiPrecise(1, 15) // 0.001 ETH - - generateTx := func(account *testAccount, nonce uint64) *types.Transaction { - signedTx, signErr := signer.SignTx(&types.Transaction{ - Nonce: nonce, - From: account.address, - To: &toAddress, - GasPrice: big.NewInt(10), - Gas: framework.DefaultGasLimit, - Value: defaultValue, - V: big.NewInt(27), // it is necessary to encode in rlp - }, account.key) - - if signErr != nil { - t.Fatalf("Unable to sign transaction, %v", signErr) - } - - return signedTx - } - - // Spawn numAccounts threads to act as sender workers that will send transactions. - // The sender worker forwards the transaction hash to the receipt worker. - // The numAccounts receipt worker threads wait for tx hashes to arrive and wait for their receipts - - var ( - wg sync.WaitGroup - errorsLock sync.Mutex - workerErrors = make([]error, 0) - ) - - wg.Add(numAccounts) - - appendError := func(err error) { - errorsLock.Lock() - defer errorsLock.Unlock() - - workerErrors = append(workerErrors, err) - } - - sendWorker := func(account *testAccount, receiptsChan chan web3.Hash) { - defer close(receiptsChan) - - nonce := uint64(0) - - for i := 0; i < numTxPerAccount; i++ { - tx := generateTx(account, nonce) - - txHash, err := client.Eth().SendRawTransaction(tx.MarshalRLP()) - if err != nil { - appendError(fmt.Errorf("unable to send txn, %w", err)) - - return - } - - receiptsChan <- txHash - - nonce++ - } - } - - receiptWorker := func(receiptsChan chan web3.Hash) { - defer wg.Done() - - for txHash := range receiptsChan { - waitCtx, waitCancel := context.WithTimeout(context.Background(), time.Second*30) - - if _, err := tests.WaitForReceipt(waitCtx, srv.JSONRPC().Eth(), txHash); err != nil { - appendError(fmt.Errorf("unable to wait for receipt, %w", err)) - waitCancel() - - return - } - - waitCancel() - } - } - - for _, testAccount := range testAccounts { - receiptsCh := make(chan web3.Hash, numTxPerAccount) - go sendWorker( - testAccount, - receiptsCh, - ) - - go receiptWorker(receiptsCh) - } - - wg.Wait() - - if len(workerErrors) != 0 { - t.Fatalf("%v", workerErrors) - } - - // Make sure the transactions went through - for _, account := range testAccounts { - nonce, err := client.Eth().GetNonce(web3.Address(account.address), web3.Latest) - if err != nil { - t.Fatalf("Unable to fetch block") - } - - assert.Equal(t, uint64(numTxPerAccount), nonce) - } -} - func TestTxPool_RecoverableError(t *testing.T) { // Test scenario : // @@ -570,93 +436,6 @@ func TestTxPool_RecoverableError(t *testing.T) { assert.NotEqual(t, secondTx.BlockNumber, receipt.BlockNumber) } -func TestTxPool_ZeroPriceDev(t *testing.T) { - senderKey, senderAddress := tests.GenerateKeyAndAddr(t) - _, receiverAddress := tests.GenerateKeyAndAddr(t) - // Test scenario: - // The sender account should send funds to the receiver account. - // Each transaction should have a gas price set do 0 and be treated - // as a non-local transaction - - var zeroPriceLimit uint64 = 0 - - startingBalance := framework.EthToWei(100) - - servers := framework.NewTestServers(t, 1, func(config *framework.TestServerConfig) { - config.SetConsensus(framework.ConsensusDev) - config.SetSeal(true) - config.SetPriceLimit(&zeroPriceLimit) - config.SetBlockLimit(20000000) - config.Premine(senderAddress, startingBalance) - }) - - server := servers[0] - client := server.JSONRPC() - operator := server.TxnPoolOperator() - ctx := context.Background() - - var ( - nonce uint64 = 0 - nonceMux sync.Mutex - wg sync.WaitGroup - ) - - sendTx := func() { - nonceMux.Lock() - tx, err := signer.SignTx(&types.Transaction{ - Nonce: nonce, - GasPrice: big.NewInt(0), - Gas: framework.DefaultGasLimit - 1, - To: &receiverAddress, - Value: oneEth, - V: big.NewInt(27), - From: types.ZeroAddress, - }, senderKey) - assert.NoError(t, err, "failed to sign transaction") - - _, err = operator.AddTxn(ctx, &txpoolOp.AddTxnReq{ - Raw: &any.Any{ - Value: tx.MarshalRLP(), - }, - From: types.ZeroAddress.String(), - }) - assert.NoError(t, err, "failed to add txn using operator") - - nonce++ - nonceMux.Unlock() - - wg.Done() - } - - numIterations := 100 - numIterationsBig := big.NewInt(int64(numIterations)) - - for i := 0; i < numIterations; i++ { - wg.Add(1) - - go sendTx() - } - - wg.Wait() - - waitCtx, waitCancel := context.WithTimeout(context.Background(), 3*time.Second) - defer waitCancel() - - _, err := tests.WaitForNonce(waitCtx, client.Eth(), web3.BytesToAddress(senderAddress.Bytes()), nonce) - assert.NoError(t, err) - - receiverBalance, err := client.Eth().GetBalance(web3.Address(receiverAddress), web3.Latest) - assert.NoError(t, err, "failed to retrieve receiver account balance") - - sentFunds := big.NewInt(0).Mul(numIterationsBig, oneEth) - assert.Equal(t, sentFunds.String(), receiverBalance.String()) - - senderBalance, err := client.Eth().GetBalance(web3.Address(senderAddress), web3.Latest) - assert.NoError(t, err, "failed to retrieve sender account balance") - - assert.Equal(t, big.NewInt(0).Sub(startingBalance, sentFunds).String(), senderBalance.String()) -} - func TestTxPool_GetPendingTx(t *testing.T) { senderKey, senderAddress := tests.GenerateKeyAndAddr(t) _, receiverAddress := tests.GenerateKeyAndAddr(t) diff --git a/e2e/websocket_test.go b/e2e/websocket_test.go index bcb430ca58..bdc521939e 100644 --- a/e2e/websocket_test.go +++ b/e2e/websocket_test.go @@ -3,15 +3,13 @@ package e2e import ( "context" "encoding/json" - "math/big" - "testing" - "time" - "github.com/0xPolygon/polygon-edge/e2e/framework" "github.com/0xPolygon/polygon-edge/jsonrpc" "github.com/0xPolygon/polygon-edge/types" "github.com/gorilla/websocket" "github.com/stretchr/testify/assert" + "math/big" + "testing" ) type testWSRequest struct { @@ -110,7 +108,7 @@ func TestWS_Response(t *testing.T) { }) t.Run("Valid block number after transfer", func(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), framework.DefaultTimeout) defer cancel() _, err = srv.SendRawTx(ctx, &framework.PreparedTransaction{ diff --git a/helper/tests/testing.go b/helper/tests/testing.go index 23ad4502e8..4727fb38f4 100644 --- a/helper/tests/testing.go +++ b/helper/tests/testing.go @@ -5,9 +5,11 @@ import ( "crypto/ecdsa" "errors" "fmt" + "github.com/golang/protobuf/ptypes/any" libp2pCrypto "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/peer" "github.com/multiformats/go-multiaddr" + "math/big" "net" "testing" "time" @@ -221,3 +223,50 @@ func GetFreePort() (port int, err error) { return } + +type GenerateTxReqParams struct { + Nonce uint64 + ReferenceAddr types.Address + ReferenceKey *ecdsa.PrivateKey + ToAddress types.Address + GasPrice *big.Int + Value *big.Int + Input []byte +} + +func generateTx(params GenerateTxReqParams) (*types.Transaction, error) { + signer := crypto.NewEIP155Signer(100) + + signedTx, signErr := signer.SignTx(&types.Transaction{ + Nonce: params.Nonce, + From: params.ReferenceAddr, + To: ¶ms.ToAddress, + GasPrice: params.GasPrice, + Gas: 1000000, + Value: params.Value, + Input: params.Input, + V: big.NewInt(27), // it is necessary to encode in rlp + }, params.ReferenceKey) + + if signErr != nil { + return nil, fmt.Errorf("unable to sign transaction, %w", signErr) + } + + return signedTx, nil +} + +func GenerateAddTxnReq(params GenerateTxReqParams) (*txpoolOp.AddTxnReq, error) { + txn, err := generateTx(params) + if err != nil { + return nil, err + } + + msg := &txpoolOp.AddTxnReq{ + Raw: &any.Any{ + Value: txn.MarshalRLP(), + }, + From: types.ZeroAddress.String(), + } + + return msg, nil +} diff --git a/jsonrpc/codec_test.go b/jsonrpc/codec_test.go index 92018ae3c0..ddcc2c0078 100644 --- a/jsonrpc/codec_test.go +++ b/jsonrpc/codec_test.go @@ -7,6 +7,8 @@ import ( ) func TestBlockNumberOrHash_UnmarshalJSON(t *testing.T) { + t.Parallel() + var blockHash types.Hash err := blockHash.UnmarshalText([]byte("0xe0ee62fd4a39a6988e24df0b406b90af71932e1b01d5561400a8eab943a33d68")) assert.NoError(t, err) @@ -82,7 +84,10 @@ func TestBlockNumberOrHash_UnmarshalJSON(t *testing.T) { } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + bnh := BlockNumberOrHash{} err := bnh.UnmarshalJSON([]byte(tt.rawRequest)) diff --git a/jsonrpc/dispatcher_test.go b/jsonrpc/dispatcher_test.go index 0172ecdc4d..58b0b75480 100644 --- a/jsonrpc/dispatcher_test.go +++ b/jsonrpc/dispatcher_test.go @@ -56,7 +56,11 @@ func expectBatchJSONResult(data []byte, v interface{}) error { } func TestDispatcher_HandleWebsocketConnection_EthSubscribe(t *testing.T) { + t.Parallel() + t.Run("clients should be able to receive \"newHeads\" event thru eth_subscribe", func(t *testing.T) { + t.Parallel() + store := newMockStore() dispatcher := newDispatcher(hclog.NewNullLogger(), store, 0) diff --git a/jsonrpc/eth_blockchain_test.go b/jsonrpc/eth_blockchain_test.go index 1db17d939c..04e75e2f6f 100644 --- a/jsonrpc/eth_blockchain_test.go +++ b/jsonrpc/eth_blockchain_test.go @@ -100,6 +100,8 @@ func TestEth_Block_GetBlockTransactionCountByNumber(t *testing.T) { } func TestEth_Block_GetLogs(t *testing.T) { + t.Parallel() + blockHash := types.StringToHash("1") // Topics we're searching for @@ -175,7 +177,10 @@ func TestEth_Block_GetLogs(t *testing.T) { eth := newTestEthEndpoint(store) for _, testCase := range testTable { + testCase := testCase t.Run(testCase.name, func(t *testing.T) { + t.Parallel() + foundLogs, logError := eth.GetLogs(testCase.query) if logError != nil && !testCase.shouldFail { @@ -191,7 +196,11 @@ func TestEth_Block_GetLogs(t *testing.T) { } func TestEth_GetTransactionByHash(t *testing.T) { + t.Parallel() + t.Run("returns correct transaction data if transaction is found in a sealed block", func(t *testing.T) { + t.Parallel() + store := &mockBlockStore{} eth := newTestEthEndpoint(store) block := newTestBlock(1, hash1) @@ -218,6 +227,8 @@ func TestEth_GetTransactionByHash(t *testing.T) { }) t.Run("returns correct transaction data if transaction is found in tx pool (pending)", func(t *testing.T) { + t.Parallel() + store := &mockBlockStore{} eth := newTestEthEndpoint(store) @@ -241,6 +252,8 @@ func TestEth_GetTransactionByHash(t *testing.T) { }) t.Run("returns nil if transaction is nowhere to be found", func(t *testing.T) { + t.Parallel() + eth := newTestEthEndpoint(&mockBlockStore{}) res, err := eth.GetTransactionByHash(types.StringToHash("abcdef")) @@ -251,7 +264,11 @@ func TestEth_GetTransactionByHash(t *testing.T) { } func TestEth_GetTransactionReceipt(t *testing.T) { + t.Parallel() + t.Run("returns nil if transaction with same hash not found", func(t *testing.T) { + t.Parallel() + store := &mockBlockStore{} eth := newTestEthEndpoint(store) @@ -262,6 +279,8 @@ func TestEth_GetTransactionReceipt(t *testing.T) { }) t.Run("returns correct receipt data for found transaction", func(t *testing.T) { + t.Parallel() + store := newMockBlockStore() eth := newTestEthEndpoint(store) block := newTestBlock(1, hash4) @@ -339,7 +358,11 @@ func TestEth_GasPrice(t *testing.T) { } func TestEth_Call(t *testing.T) { + t.Parallel() + t.Run("returns error if transaction execution fails", func(t *testing.T) { + t.Parallel() + store := newMockBlockStore() store.add(newTestBlock(100, hash1)) store.ethCallError = errors.New("an arbitrary error") @@ -362,6 +385,8 @@ func TestEth_Call(t *testing.T) { }) t.Run("returns a value representing result of the successful transaction execution", func(t *testing.T) { + t.Parallel() + store := newMockBlockStore() store.add(newTestBlock(100, hash1)) store.ethCallError = nil diff --git a/jsonrpc/eth_endpoint_test.go b/jsonrpc/eth_endpoint_test.go index 1fbb04bd3a..dee87c92fb 100644 --- a/jsonrpc/eth_endpoint_test.go +++ b/jsonrpc/eth_endpoint_test.go @@ -12,6 +12,8 @@ import ( ) func TestEth_DecodeTxn(t *testing.T) { + t.Parallel() + tests := []struct { name string accounts map[types.Address]*state.Account @@ -143,7 +145,10 @@ func TestEth_DecodeTxn(t *testing.T) { } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + if tt.res != nil { tt.res.ComputeHash() } @@ -161,6 +166,8 @@ func TestEth_DecodeTxn(t *testing.T) { } func TestEth_GetNextNonce(t *testing.T) { + t.Parallel() + // Set up the mock accounts accounts := []struct { address types.Address @@ -209,7 +216,10 @@ func TestEth_GetNextNonce(t *testing.T) { } for _, testCase := range testTable { + testCase := testCase t.Run(testCase.name, func(t *testing.T) { + t.Parallel() + // Grab the nonce nonce, err := eth.getNextNonce(testCase.account, testCase.number) diff --git a/jsonrpc/eth_state_test.go b/jsonrpc/eth_state_test.go index f4885b168f..6de758165b 100644 --- a/jsonrpc/eth_state_test.go +++ b/jsonrpc/eth_state_test.go @@ -619,6 +619,8 @@ func getExampleStore() *mockSpecialStore { // the latest block gas limit for the upper bound, or the specified // gas limit in the transaction func TestEth_EstimateGas_GasLimit(t *testing.T) { + // TODO Make this test run in parallel when the race + // condition is fixed in gas estimation store := getExampleStore() ethEndpoint := newTestEthEndpoint(store) diff --git a/jsonrpc/txpool_endpoint_test.go b/jsonrpc/txpool_endpoint_test.go index 0fe28699ac..e45b383f5f 100644 --- a/jsonrpc/txpool_endpoint_test.go +++ b/jsonrpc/txpool_endpoint_test.go @@ -10,7 +10,11 @@ import ( ) func TestContentEndpoint(t *testing.T) { + t.Parallel() + t.Run("returns empty ContentResponse if tx pool has no transactions", func(t *testing.T) { + t.Parallel() + mockStore := newMockTxPoolStore() txPoolEndpoint := &TxPool{mockStore} @@ -25,6 +29,8 @@ func TestContentEndpoint(t *testing.T) { // nolint:dupl t.Run("returns correct data for pending transaction", func(t *testing.T) { + t.Parallel() + mockStore := newMockTxPoolStore() address1 := types.Address{0x1} testTx := newTestTransaction(2, address1) @@ -53,6 +59,8 @@ func TestContentEndpoint(t *testing.T) { // nolint:dupl t.Run("returns correct data for queued transaction", func(t *testing.T) { + t.Parallel() + mockStore := newMockTxPoolStore() address1 := types.Address{0x1} testTx := newTestTransaction(2, address1) @@ -80,6 +88,8 @@ func TestContentEndpoint(t *testing.T) { }) t.Run("returns correct ContentResponse data for multiple transactions", func(t *testing.T) { + t.Parallel() + mockStore := newMockTxPoolStore() address1 := types.Address{0x1} testTx1 := newTestTransaction(2, address1) @@ -107,7 +117,11 @@ func TestContentEndpoint(t *testing.T) { } func TestInspectEndpoint(t *testing.T) { + t.Parallel() + t.Run("returns empty InspectResponse if tx pool has no transactions", func(t *testing.T) { + t.Parallel() + mockStore := newMockTxPoolStore() mockStore.maxSlots = 1024 txPoolEndpoint := &TxPool{mockStore} @@ -124,6 +138,8 @@ func TestInspectEndpoint(t *testing.T) { }) t.Run("returns correct data for queued transactions", func(t *testing.T) { + t.Parallel() + mockStore := newMockTxPoolStore() mockStore.capacity = 1 address1 := types.Address{0x1} @@ -144,6 +160,8 @@ func TestInspectEndpoint(t *testing.T) { }) t.Run("returns correct data for pending transactions", func(t *testing.T) { + t.Parallel() + mockStore := newMockTxPoolStore() mockStore.capacity = 2 address1 := types.Address{0x1} @@ -167,7 +185,11 @@ func TestInspectEndpoint(t *testing.T) { } func TestStatusEndpoint(t *testing.T) { + t.Parallel() + t.Run("returns empty StatusResponse if tx pool has no transactions", func(t *testing.T) { + t.Parallel() + mockStore := newMockTxPoolStore() txPoolEndpoint := &TxPool{mockStore} @@ -180,6 +202,8 @@ func TestStatusEndpoint(t *testing.T) { }) t.Run("returns correct count of pending/queued transactions", func(t *testing.T) { + t.Parallel() + mockStore := newMockTxPoolStore() address1 := types.Address{0x1} testTx1 := newTestTransaction(2, address1) diff --git a/protocol/syncer_test.go b/protocol/syncer_test.go index b6ac8cc1c2..17066c7387 100644 --- a/protocol/syncer_test.go +++ b/protocol/syncer_test.go @@ -16,6 +16,8 @@ import ( ) func TestHandleNewPeer(t *testing.T) { + t.Parallel() + tests := []struct { name string chain blockchainShim @@ -33,7 +35,10 @@ func TestHandleNewPeer(t *testing.T) { } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + syncer, peerSyncers := SetupSyncerNetwork(t, tt.chain, tt.peerChains) // Check peer's status in Syncer's peer list @@ -50,6 +55,8 @@ func TestHandleNewPeer(t *testing.T) { } func TestDeletePeer(t *testing.T) { + t.Parallel() + tests := []struct { name string chain blockchainShim @@ -69,7 +76,10 @@ func TestDeletePeer(t *testing.T) { } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + syncer, peerSyncers := SetupSyncerNetwork(t, tt.chain, tt.peerChains) // disconnects from syncer @@ -92,6 +102,8 @@ func TestDeletePeer(t *testing.T) { } func TestBroadcast(t *testing.T) { + t.Parallel() + tests := []struct { name string syncerHeaders []*types.Header @@ -107,7 +119,10 @@ func TestBroadcast(t *testing.T) { } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + chain, peerChain := NewMockBlockchain(tt.syncerHeaders), NewMockBlockchain(tt.peerHeaders) syncer, peerSyncers := SetupSyncerNetwork(t, chain, []blockchainShim{peerChain}) peerSyncer := peerSyncers[0] @@ -141,6 +156,8 @@ func TestBroadcast(t *testing.T) { } func TestBestPeer(t *testing.T) { + t.Parallel() + tests := []struct { name string chain blockchainShim @@ -173,7 +190,10 @@ func TestBestPeer(t *testing.T) { } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + syncer, peerSyncers := SetupSyncerNetwork(t, tt.chain, tt.peersChain) bestPeer := syncer.BestPeer() @@ -192,6 +212,8 @@ func TestBestPeer(t *testing.T) { } func TestFindCommonAncestor(t *testing.T) { + t.Parallel() + tests := []struct { name string syncerHeaders []*types.Header @@ -221,7 +243,10 @@ func TestFindCommonAncestor(t *testing.T) { } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + chain, peerChain := blockchain.NewTestBlockchain( t, tt.syncerHeaders, @@ -247,6 +272,8 @@ func TestFindCommonAncestor(t *testing.T) { } func TestWatchSyncWithPeer(t *testing.T) { + t.Parallel() + tests := []struct { name string headers []*types.Header @@ -274,7 +301,10 @@ func TestWatchSyncWithPeer(t *testing.T) { } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + chain, peerChain := NewMockBlockchain(tt.headers), NewMockBlockchain(tt.peerHeaders) syncer, peerSyncers := SetupSyncerNetwork(t, chain, []blockchainShim{peerChain}) @@ -315,6 +345,8 @@ func TestWatchSyncWithPeer(t *testing.T) { } func TestBulkSyncWithPeer(t *testing.T) { + t.Parallel() + tests := []struct { name string headers []*types.Header @@ -343,7 +375,10 @@ func TestBulkSyncWithPeer(t *testing.T) { } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + chain, peerChain := NewMockBlockchain(tt.headers), NewMockBlockchain(tt.peerHeaders) syncer, peerSyncers := SetupSyncerNetwork(t, chain, []blockchainShim{peerChain}) peerSyncer := peerSyncers[0] diff --git a/state/immutable-trie/encoding_test.go b/state/immutable-trie/encoding_test.go index 3a771af4f9..a7ba9bf540 100644 --- a/state/immutable-trie/encoding_test.go +++ b/state/immutable-trie/encoding_test.go @@ -6,6 +6,8 @@ import ( ) func TestEncoding_HasTermSymbol(t *testing.T) { + t.Parallel() + testTable := []struct { name string value []byte @@ -39,7 +41,10 @@ func TestEncoding_HasTermSymbol(t *testing.T) { } for _, testCase := range testTable { + testCase := testCase t.Run(testCase.name, func(t *testing.T) { + t.Parallel() + assert.Equal(t, testCase.shouldHaveTerm, hasTerminator(testCase.value)) }) } @@ -50,6 +55,8 @@ const ( ) func TestEncoding_KeyBytesToHexNibbles(t *testing.T) { + t.Parallel() + testTable := []struct { name string inputString []byte @@ -100,7 +107,10 @@ func TestEncoding_KeyBytesToHexNibbles(t *testing.T) { } for _, testCase := range testTable { + testCase := testCase t.Run(testCase.name, func(t *testing.T) { + t.Parallel() + output := bytesToHexNibbles(testCase.inputString) assert.Len(t, output, len(testCase.expectedOutput)) @@ -119,6 +129,8 @@ func TestEncoding_HexCompact(t *testing.T) { // 1 0001 | extension odd // 2 0010 | terminating (leaf) even // 3 0011 | terminating (leaf) odd + t.Parallel() + testTable := []struct { name string inputHex []byte @@ -147,7 +159,10 @@ func TestEncoding_HexCompact(t *testing.T) { } for _, testCase := range testTable { + testCase := testCase t.Run(testCase.name, func(t *testing.T) { + t.Parallel() + compactOutput := encodeCompact(testCase.inputHex) // Check if the compact outputs match diff --git a/state/runtime/evm/evm_test.go b/state/runtime/evm/evm_test.go index 796830b13c..71aaaba33b 100644 --- a/state/runtime/evm/evm_test.go +++ b/state/runtime/evm/evm_test.go @@ -88,6 +88,8 @@ func (m *mockHost) GetNonce(addr types.Address) uint64 { } func TestRun(t *testing.T) { + t.Parallel() + tests := []struct { name string value *big.Int @@ -151,7 +153,10 @@ func TestRun(t *testing.T) { } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + evm := NewEVM() contract := newMockContract(tt.value, tt.gas, tt.code) host := &mockHost{} diff --git a/state/runtime/precompiled/testing.go b/state/runtime/precompiled/testing.go index fbe2a89db8..8bd9c22314 100644 --- a/state/runtime/precompiled/testing.go +++ b/state/runtime/precompiled/testing.go @@ -31,6 +31,7 @@ func decodeHex(t *testing.T, input string) []byte { func ReadTestCase(t *testing.T, path string, f func(t *testing.T, c *TestCase)) { t.Helper() + t.Parallel() data, err := ioutil.ReadFile(filepath.Join("./fixtures", path)) if err != nil { @@ -51,6 +52,8 @@ func ReadTestCase(t *testing.T, path string, f func(t *testing.T, c *TestCase)) } for _, i := range cases { + i := i + inputDecode := decodeHex(t, fmt.Sprintf("0x%s", i.Input)) expectedDecode := decodeHex(t, fmt.Sprintf("0x%s", i.Expected)) @@ -62,6 +65,8 @@ func ReadTestCase(t *testing.T, path string, f func(t *testing.T, c *TestCase)) } t.Run(i.Name, func(t *testing.T) { + t.Parallel() + f(t, c) }) } diff --git a/state/testing.go b/state/testing.go index 194d6222cd..d622cee09e 100644 --- a/state/testing.go +++ b/state/testing.go @@ -39,41 +39,66 @@ type buildPreState func(p PreStates) (State, Snapshot) // TestState tests a set of tests on a state func TestState(t *testing.T, buildPreState buildPreState) { t.Helper() + t.Parallel() t.Run("", func(t *testing.T) { + t.Parallel() + testWriteState(t, buildPreState) }) t.Run("", func(t *testing.T) { + t.Parallel() + testWriteEmptyState(t, buildPreState) }) t.Run("", func(t *testing.T) { + t.Parallel() + testUpdateStateWithEmpty(t, buildPreState) }) t.Run("", func(t *testing.T) { + t.Parallel() + testSuicideAccountInPreState(t, buildPreState) }) t.Run("", func(t *testing.T) { + t.Parallel() + testSuicideAccount(t, buildPreState) }) t.Run("", func(t *testing.T) { + t.Parallel() + testSuicideAccountWithData(t, buildPreState) }) t.Run("", func(t *testing.T) { + t.Parallel() + testSuicideCoinbase(t, buildPreState) }) t.Run("", func(t *testing.T) { + t.Parallel() + testSuicideWithIntermediateCommit(t, buildPreState) }) t.Run("", func(t *testing.T) { + t.Parallel() + testRestartRefunds(t, buildPreState) }) t.Run("", func(t *testing.T) { + t.Parallel() + testChangePrestateAccountBalanceToZero(t, buildPreState) }) t.Run("", func(t *testing.T) { + t.Parallel() + testChangeAccountBalanceToZero(t, buildPreState) }) t.Run("", func(t *testing.T) { + t.Parallel() + testDeleteCommonStateRoot(t, buildPreState) }) } diff --git a/state/transition_test.go b/state/transition_test.go index 2080113fea..87ae04568a 100644 --- a/state/transition_test.go +++ b/state/transition_test.go @@ -22,6 +22,8 @@ func newTestTransition(preState map[types.Address]*PreState) *Transition { } func TestSubGasLimitPrice(t *testing.T) { + t.Parallel() + tests := []struct { name string preState map[types.Address]*PreState @@ -61,7 +63,10 @@ func TestSubGasLimitPrice(t *testing.T) { } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + transition := newTestTransition(tt.preState) msg := &types.Transaction{ From: tt.from, @@ -84,6 +89,8 @@ func TestSubGasLimitPrice(t *testing.T) { } func TestTransfer(t *testing.T) { + t.Parallel() + tests := []struct { name string preState map[types.Address]*PreState @@ -127,7 +134,10 @@ func TestTransfer(t *testing.T) { } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + transition := newTestTransition(tt.preState) amount := big.NewInt(tt.amount) diff --git a/tests/evm_test.go b/tests/evm_test.go index f3eeffca53..d79c3063fe 100644 --- a/tests/evm_test.go +++ b/tests/evm_test.go @@ -139,6 +139,8 @@ func rlpHashLogs(logs []*types.Log) (res types.Hash) { } func TestEVM(t *testing.T) { + t.Parallel() + folders, err := listFolders(vmTests) if err != nil { t.Fatal(err) @@ -157,7 +159,10 @@ func TestEVM(t *testing.T) { } for _, file := range files { + file := file t.Run(file, func(t *testing.T) { + t.Parallel() + if !strings.HasSuffix(file, ".json") { return } diff --git a/tests/state_test.go b/tests/state_test.go index 9ce1cd8e1e..4cc239a261 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -101,6 +101,8 @@ func RunSpecificTest(t *testing.T, file string, c stateCase, name, fork string, } func TestState(t *testing.T) { + t.Parallel() + long := []string{ "static_Call50000", "static_Return50000", @@ -121,7 +123,10 @@ func TestState(t *testing.T) { } for _, folder := range folders { + folder := folder t.Run(folder, func(t *testing.T) { + t.Parallel() + files, err := listFiles(folder) if err != nil { t.Fatal(err) diff --git a/txpool/event_subscription_test.go b/txpool/event_subscription_test.go index e9f6c3110e..3633f44079 100644 --- a/txpool/event_subscription_test.go +++ b/txpool/event_subscription_test.go @@ -156,6 +156,8 @@ func TestEventSubscription_ProcessedEvents(t *testing.T) { } func TestEventSubscription_EventSupported(t *testing.T) { + t.Parallel() + supportedEvents := []proto.EventType{ proto.EventType_ADDED, proto.EventType_PROMOTED, @@ -187,7 +189,10 @@ func TestEventSubscription_EventSupported(t *testing.T) { } for _, testCase := range testTable { + testCase := testCase t.Run(testCase.name, func(t *testing.T) { + t.Parallel() + for _, eventType := range testCase.events { assert.Equal(t, testCase.supported, subscription.eventSupported(eventType)) } diff --git a/txpool/txpool_test.go b/txpool/txpool_test.go index c673d4380b..650f354c19 100644 --- a/txpool/txpool_test.go +++ b/txpool/txpool_test.go @@ -106,6 +106,8 @@ type result struct { /* Single account cases (unit tests) */ func TestAddTxErrors(t *testing.T) { + t.Parallel() + poolSigner := crypto.NewEIP155Signer(100) // Generate a private key and address @@ -132,6 +134,7 @@ func TestAddTxErrors(t *testing.T) { } t.Run("ErrNegativeValue", func(t *testing.T) { + t.Parallel() pool := setupPool() tx := newTx(defaultAddr, 0, 1) @@ -144,6 +147,7 @@ func TestAddTxErrors(t *testing.T) { }) t.Run("ErrBlockLimitExceeded", func(t *testing.T) { + t.Parallel() pool := setupPool() tx := newTx(defaultAddr, 0, 1) @@ -159,6 +163,7 @@ func TestAddTxErrors(t *testing.T) { }) t.Run("ErrNonSignedTx", func(t *testing.T) { + t.Parallel() pool := setupPool() tx := newTx(defaultAddr, 0, 1) @@ -170,6 +175,7 @@ func TestAddTxErrors(t *testing.T) { }) t.Run("ErrInvalidSender", func(t *testing.T) { + t.Parallel() pool := setupPool() tx := newTx(addr1, 0, 1) @@ -185,6 +191,7 @@ func TestAddTxErrors(t *testing.T) { }) t.Run("ErrUnderpriced", func(t *testing.T) { + t.Parallel() pool := setupPool() pool.priceLimit = 1000000 @@ -198,6 +205,7 @@ func TestAddTxErrors(t *testing.T) { }) t.Run("ErrInvalidAccountState", func(t *testing.T) { + t.Parallel() pool := setupPool() pool.store = faultyMockStore{} @@ -213,6 +221,7 @@ func TestAddTxErrors(t *testing.T) { }) t.Run("ErrTxPoolOverflow", func(t *testing.T) { + t.Parallel() pool := setupPool() // fill the pool @@ -228,6 +237,7 @@ func TestAddTxErrors(t *testing.T) { }) t.Run("ErrIntrinsicGas", func(t *testing.T) { + t.Parallel() pool := setupPool() tx := newTx(defaultAddr, 0, 1) @@ -241,6 +251,7 @@ func TestAddTxErrors(t *testing.T) { }) t.Run("ErrAlreadyKnown", func(t *testing.T) { + t.Parallel() pool := setupPool() tx := newTx(defaultAddr, 0, 1) @@ -262,6 +273,7 @@ func TestAddTxErrors(t *testing.T) { }) t.Run("ErrOversizedData", func(t *testing.T) { + t.Parallel() pool := setupPool() tx := newTx(defaultAddr, 0, 1) @@ -281,6 +293,7 @@ func TestAddTxErrors(t *testing.T) { }) t.Run("ErrNonceTooLow", func(t *testing.T) { + t.Parallel() pool := setupPool() // faultyMockStore.GetNonce() == 99999 @@ -295,6 +308,7 @@ func TestAddTxErrors(t *testing.T) { }) t.Run("ErrInsufficientFunds", func(t *testing.T) { + t.Parallel() pool := setupPool() tx := newTx(defaultAddr, 0, 1) @@ -309,11 +323,15 @@ func TestAddTxErrors(t *testing.T) { } func TestAddGossipTx(t *testing.T) { + t.Parallel() + key, sender := tests.GenerateKeyAndAddr(t) signer := crypto.NewEIP155Signer(uint64(100)) tx := newTx(types.ZeroAddress, 1, 1) t.Run("node is a validator", func(t *testing.T) { + t.Parallel() + pool, err := newTestPool() assert.NoError(t, err) pool.SetSigner(signer) @@ -340,6 +358,8 @@ func TestAddGossipTx(t *testing.T) { }) t.Run("node is a non validator", func(t *testing.T) { + t.Parallel() + pool, err := newTestPool() assert.NoError(t, err) pool.SetSigner(signer) @@ -389,7 +409,11 @@ func TestDropKnownGossipTx(t *testing.T) { } func TestAddHandler(t *testing.T) { + t.Parallel() + t.Run("enqueue new tx with higher nonce", func(t *testing.T) { + t.Parallel() + pool, err := newTestPool() assert.NoError(t, err) pool.SetSigner(&mockSigner{}) @@ -406,6 +430,8 @@ func TestAddHandler(t *testing.T) { }) t.Run("reject new tx with low nonce", func(t *testing.T) { + t.Parallel() + pool, err := newTestPool() assert.NoError(t, err) pool.SetSigner(&mockSigner{}) @@ -426,6 +452,8 @@ func TestAddHandler(t *testing.T) { }) t.Run("signal promotion for new tx with expected nonce", func(t *testing.T) { + t.Parallel() + pool, err := newTestPool() assert.NoError(t, err) pool.SetSigner(&mockSigner{}) @@ -447,10 +475,14 @@ func TestAddHandler(t *testing.T) { } func TestPromoteHandler(t *testing.T) { + t.Parallel() + t.Run("nothing to promote", func(t *testing.T) { /* This test demonstrates that if some promotion handler got its job done by a previous one, it will not perform any logic by doing an early return. */ + t.Parallel() + pool, err := newTestPool() assert.NoError(t, err) pool.SetSigner(&mockSigner{}) @@ -487,6 +519,8 @@ func TestPromoteHandler(t *testing.T) { }) t.Run("promote one tx", func(t *testing.T) { + t.Parallel() + pool, err := newTestPool() assert.NoError(t, err) pool.SetSigner(&mockSigner{}) @@ -508,10 +542,12 @@ func TestPromoteHandler(t *testing.T) { }) t.Run("promote several txs", func(t *testing.T) { + t.Parallel() /* This example illustrates the flexibility of the handlers: One promotion handler can be executed at any time after it was invoked (when the runtime decides), resulting in promotion of several enqueued txs. */ + pool, err := newTestPool() assert.NoError(t, err) pool.SetSigner(&mockSigner{}) @@ -552,6 +588,8 @@ func TestPromoteHandler(t *testing.T) { t.Run("one tx -> one promotion", func(t *testing.T) { /* In this scenario, each received tx will be instantly promoted. All txs are sent in the order of expected nonce. */ + t.Parallel() + pool, err := newTestPool() assert.NoError(t, err) pool.SetSigner(&mockSigner{}) @@ -1019,11 +1057,6 @@ func TestDrop(t *testing.T) { assert.Equal(t, uint64(0), pool.accounts.get(addr1).promoted.length()) } -func TestDemote(t *testing.T) { - // TODO dbrajovic - t.SkipNow() -} - /* "Integrated" tests */ // The following tests ensure that the pool's inner event loop @@ -1078,10 +1111,6 @@ func TestAddTxns(t *testing.T) { "send 100k txns", 100000, }, - { - "send 1m txns", - 1000000, - }, } for _, testCase := range testTable { diff --git a/types/types_test.go b/types/types_test.go index 8288bca4b6..82d6ae3ed6 100644 --- a/types/types_test.go +++ b/types/types_test.go @@ -9,6 +9,8 @@ import ( ) func TestEIP55(t *testing.T) { + t.Parallel() + cases := []struct { address string expected string @@ -52,7 +54,11 @@ func TestEIP55(t *testing.T) { } for _, c := range cases { + c := c + t.Run("", func(t *testing.T) { + t.Parallel() + addr := StringToAddress(c.address) assert.Equal(t, c.expected, addr.String()) })