github.com/iotexproject/iotex-core@v1.14.1-rc1/e2etest/local_actpool_test.go (about)

     1  // Copyright (c) 2019 IoTeX Foundation
     2  // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability
     3  // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed.
     4  // This source code is governed by Apache License 2.0 that can be found in the LICENSE file.
     5  
     6  package e2etest
     7  
     8  import (
     9  	"context"
    10  	"fmt"
    11  	"math/big"
    12  	"testing"
    13  	"time"
    14  
    15  	"github.com/libp2p/go-libp2p-core/peer"
    16  	"github.com/stretchr/testify/require"
    17  	"google.golang.org/protobuf/proto"
    18  
    19  	"github.com/iotexproject/go-pkgs/crypto"
    20  
    21  	"github.com/iotexproject/iotex-core/action"
    22  	"github.com/iotexproject/iotex-core/config"
    23  	"github.com/iotexproject/iotex-core/p2p"
    24  	"github.com/iotexproject/iotex-core/server/itx"
    25  	"github.com/iotexproject/iotex-core/test/identityset"
    26  	"github.com/iotexproject/iotex-core/testutil"
    27  )
    28  
    29  func TestLocalActPool(t *testing.T) {
    30  	require := require.New(t)
    31  
    32  	cfg, err := newActPoolConfig(t)
    33  	require.NoError(err)
    34  
    35  	// create server
    36  	ctx := context.Background()
    37  	svr, err := itx.NewServer(cfg)
    38  	require.NoError(err)
    39  
    40  	chainID := cfg.Chain.ID
    41  	fmt.Println("server start")
    42  	require.NoError(svr.Start(ctx))
    43  	fmt.Println("server started")
    44  	require.NotNil(svr.ChainService(chainID).ActionPool())
    45  
    46  	// create client
    47  	cfg, err = newActPoolConfig(t)
    48  	require.NoError(err)
    49  	addrs, err := svr.P2PAgent().Self()
    50  	require.NoError(err)
    51  	cfg.Network.BootstrapNodes = []string{validNetworkAddr(addrs)}
    52  	cli := p2p.NewAgent(
    53  		cfg.Network,
    54  		cfg.Chain.ID,
    55  		cfg.Genesis.Hash(),
    56  		func(_ context.Context, _ uint32, _ string, _ proto.Message) {
    57  
    58  		},
    59  		func(_ context.Context, _ uint32, _ peer.AddrInfo, _ proto.Message) {
    60  
    61  		},
    62  	)
    63  	require.NotNil(cli)
    64  	require.NoError(cli.Start(ctx))
    65  	fmt.Println("p2p agent started")
    66  
    67  	defer func() {
    68  		require.NoError(cli.Stop(ctx))
    69  		require.NoError(svr.Stop(ctx))
    70  	}()
    71  
    72  	// Create three valid actions from "from" to "to"
    73  	tsf1, err := action.SignedTransfer(identityset.Address(0).String(), identityset.PrivateKey(1), 1, big.NewInt(1), []byte{}, uint64(100000), big.NewInt(0))
    74  	require.NoError(err)
    75  	// Wait until server receives the 1st action
    76  	require.NoError(testutil.WaitUntil(100*time.Millisecond, 60*time.Second, func() (bool, error) {
    77  		require.NoError(cli.BroadcastOutbound(ctx, tsf1.Proto()))
    78  		acts := svr.ChainService(chainID).ActionPool().PendingActionMap()
    79  		return lenPendingActionMap(acts) == 1, nil
    80  	}))
    81  	fmt.Println("1")
    82  
    83  	tsf2, err := action.SignedTransfer(identityset.Address(1).String(), identityset.PrivateKey(1), 2, big.NewInt(3), []byte{}, uint64(100000), big.NewInt(0))
    84  	require.NoError(err)
    85  	tsf3, err := action.SignedTransfer(identityset.Address(0).String(), identityset.PrivateKey(1), 3, big.NewInt(3), []byte{}, uint64(100000), big.NewInt(0))
    86  	require.NoError(err)
    87  	// Create contract
    88  	exec4, err := action.SignedExecution(action.EmptyAddress, identityset.PrivateKey(1), 4, big.NewInt(0), uint64(120000), big.NewInt(10), []byte{})
    89  	require.NoError(err)
    90  	// Create three invalid actions from "from" to "to"
    91  	tsf5, err := action.SignedTransfer(identityset.Address(0).String(), identityset.PrivateKey(1), 2, big.NewInt(3), []byte{}, uint64(100000), big.NewInt(0))
    92  	require.NoError(err)
    93  
    94  	require.NoError(cli.BroadcastOutbound(ctx, tsf2.Proto()))
    95  	require.NoError(cli.BroadcastOutbound(ctx, tsf3.Proto()))
    96  	require.NoError(cli.BroadcastOutbound(ctx, exec4.Proto()))
    97  	require.NoError(cli.BroadcastOutbound(ctx, tsf5.Proto()))
    98  
    99  	fmt.Println("2")
   100  	// Wait until server receives all the transfers
   101  	require.NoError(testutil.WaitUntil(100*time.Millisecond, 60*time.Second, func() (bool, error) {
   102  		acts := svr.ChainService(chainID).ActionPool().PendingActionMap()
   103  		// 3 valid transfers and 1 valid execution
   104  		return lenPendingActionMap(acts) == 4, nil
   105  	}))
   106  	fmt.Println("3")
   107  
   108  }
   109  
   110  func TestPressureActPool(t *testing.T) {
   111  	require := require.New(t)
   112  
   113  	cfg, err := newActPoolConfig(t)
   114  	require.NoError(err)
   115  
   116  	// create server
   117  	ctx := context.Background()
   118  	svr, err := itx.NewServer(cfg)
   119  	require.NoError(err)
   120  	require.NoError(svr.Start(ctx))
   121  	chainID := cfg.Chain.ID
   122  	require.NotNil(svr.ChainService(chainID).ActionPool())
   123  
   124  	// create client
   125  	cfg, err = newActPoolConfig(t)
   126  	require.NoError(err)
   127  	addrs, err := svr.P2PAgent().Self()
   128  	require.NoError(err)
   129  	cfg.Network.BootstrapNodes = []string{validNetworkAddr(addrs)}
   130  	cli := p2p.NewAgent(
   131  		cfg.Network,
   132  		cfg.Chain.ID,
   133  		cfg.Genesis.Hash(),
   134  		func(_ context.Context, _ uint32, _ string, _ proto.Message) {
   135  
   136  		},
   137  		func(_ context.Context, _ uint32, _ peer.AddrInfo, _ proto.Message) {
   138  
   139  		},
   140  	)
   141  	require.NotNil(cli)
   142  	require.NoError(cli.Start(ctx))
   143  
   144  	defer func() {
   145  		require.NoError(cli.Stop(ctx))
   146  		require.NoError(svr.Stop(ctx))
   147  	}()
   148  
   149  	tsf, err := action.SignedTransfer(identityset.Address(0).String(), identityset.PrivateKey(1), 1, big.NewInt(int64(0)), []byte{}, uint64(100000), big.NewInt(0))
   150  	require.NoError(err)
   151  	// Wait until server receives the 1st action
   152  	require.NoError(testutil.WaitUntil(100*time.Millisecond, 60*time.Second, func() (bool, error) {
   153  		require.NoError(cli.BroadcastOutbound(ctx, tsf.Proto()))
   154  		acts := svr.ChainService(chainID).ActionPool().PendingActionMap()
   155  		return lenPendingActionMap(acts) == 1, nil
   156  	}))
   157  
   158  	// Broadcast has rate limit at 300
   159  	for i := 2; i <= 250; i++ {
   160  		tsf, err := action.SignedTransfer(identityset.Address(0).String(), identityset.PrivateKey(1), uint64(i), big.NewInt(int64(i)), []byte{}, uint64(100000), big.NewInt(0))
   161  		require.NoError(err)
   162  		require.NoError(cli.BroadcastOutbound(ctx, tsf.Proto()))
   163  	}
   164  
   165  	// Wait until committed blocks contain all broadcasted actions
   166  	err = testutil.WaitUntil(100*time.Millisecond, 60*time.Second, func() (bool, error) {
   167  		acts := svr.ChainService(chainID).ActionPool().PendingActionMap()
   168  		return lenPendingActionMap(acts) == 250, nil
   169  	})
   170  	require.NoError(err)
   171  }
   172  
   173  func newActPoolConfig(t *testing.T) (config.Config, error) {
   174  	r := require.New(t)
   175  
   176  	cfg := config.Default
   177  
   178  	testTriePath, err := testutil.PathOfTempFile("trie")
   179  	r.NoError(err)
   180  	testDBPath, err := testutil.PathOfTempFile("db")
   181  	r.NoError(err)
   182  	testIndexPath, err := testutil.PathOfTempFile("index")
   183  	r.NoError(err)
   184  	testContractIndexPath, err := testutil.PathOfTempFile("contractindex")
   185  	r.NoError(err)
   186  	testSGDIndexPath, err := testutil.PathOfTempFile("sgdindex")
   187  	r.NoError(err)
   188  	defer func() {
   189  		testutil.CleanupPath(testTriePath)
   190  		testutil.CleanupPath(testDBPath)
   191  		testutil.CleanupPath(testIndexPath)
   192  		testutil.CleanupPath(testContractIndexPath)
   193  		testutil.CleanupPath(testSGDIndexPath)
   194  	}()
   195  
   196  	cfg.Chain.TrieDBPatchFile = ""
   197  	cfg.Chain.TrieDBPath = testTriePath
   198  	cfg.Chain.ChainDBPath = testDBPath
   199  	cfg.Chain.IndexDBPath = testIndexPath
   200  	cfg.Chain.ContractStakingIndexDBPath = testContractIndexPath
   201  	cfg.Chain.SGDIndexDBPath = testSGDIndexPath
   202  	cfg.ActPool.MinGasPriceStr = "0"
   203  	cfg.Consensus.Scheme = config.NOOPScheme
   204  	cfg.Network.Port = testutil.RandomPort()
   205  
   206  	sk, err := crypto.GenerateKey()
   207  	if err != nil {
   208  		return config.Config{}, err
   209  	}
   210  	cfg.Chain.ProducerPrivKey = sk.HexString()
   211  	return cfg, nil
   212  }