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 }