github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/core/tx_pool_test.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:35</date> 10 //</624450080962777088> 11 12 13 package core 14 15 import ( 16 "crypto/ecdsa" 17 "fmt" 18 "io/ioutil" 19 "math/big" 20 "math/rand" 21 "os" 22 "testing" 23 "time" 24 25 "github.com/ethereum/go-ethereum/common" 26 "github.com/ethereum/go-ethereum/core/state" 27 "github.com/ethereum/go-ethereum/core/types" 28 "github.com/ethereum/go-ethereum/crypto" 29 "github.com/ethereum/go-ethereum/ethdb" 30 "github.com/ethereum/go-ethereum/event" 31 "github.com/ethereum/go-ethereum/params" 32 ) 33 34 //testxtpoolconfig是没有状态磁盘的事务池配置 35 //测试中使用的副作用。 36 var testTxPoolConfig TxPoolConfig 37 38 func init() { 39 testTxPoolConfig = DefaultTxPoolConfig 40 testTxPoolConfig.Journal = "" 41 } 42 43 type testBlockChain struct { 44 statedb *state.StateDB 45 gasLimit uint64 46 chainHeadFeed *event.Feed 47 } 48 49 func (bc *testBlockChain) CurrentBlock() *types.Block { 50 return types.NewBlock(&types.Header{ 51 GasLimit: bc.gasLimit, 52 }, nil, nil, nil) 53 } 54 55 func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { 56 return bc.CurrentBlock() 57 } 58 59 func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) { 60 return bc.statedb, nil 61 } 62 63 func (bc *testBlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription { 64 return bc.chainHeadFeed.Subscribe(ch) 65 } 66 67 func transaction(nonce uint64, gaslimit uint64, key *ecdsa.PrivateKey) *types.Transaction { 68 return pricedTransaction(nonce, gaslimit, big.NewInt(1), key) 69 } 70 71 func pricedTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey) *types.Transaction { 72 tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(100), gaslimit, gasprice, nil), types.HomesteadSigner{}, key) 73 return tx 74 } 75 76 func setupTxPool() (*TxPool, *ecdsa.PrivateKey) { 77 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 78 blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} 79 80 key, _ := crypto.GenerateKey() 81 pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 82 83 return pool, key 84 } 85 86 //validatexpoolinternals检查池中的各种一致性不变量。 87 func validateTxPoolInternals(pool *TxPool) error { 88 pool.mu.RLock() 89 defer pool.mu.RUnlock() 90 91 //确保总事务集与挂起+排队一致 92 pending, queued := pool.stats() 93 if total := pool.all.Count(); total != pending+queued { 94 return fmt.Errorf("total transaction count %d != %d pending + %d queued", total, pending, queued) 95 } 96 if priced := pool.priced.items.Len() - pool.priced.stales; priced != pending+queued { 97 return fmt.Errorf("total priced transaction count %d != %d pending + %d queued", priced, pending, queued) 98 } 99 //确保要分配的下一个nonce是正确的nonce 100 for addr, txs := range pool.pending { 101 //查找最后一个事务 102 var last uint64 103 for nonce := range txs.txs.items { 104 if last < nonce { 105 last = nonce 106 } 107 } 108 if nonce := pool.pendingState.GetNonce(addr); nonce != last+1 { 109 return fmt.Errorf("pending nonce mismatch: have %v, want %v", nonce, last+1) 110 } 111 } 112 return nil 113 } 114 115 //validateEvents检查事务添加事件的正确数量 116 //在池的事件源上被激发。 117 func validateEvents(events chan NewTxsEvent, count int) error { 118 var received []*types.Transaction 119 120 for len(received) < count { 121 select { 122 case ev := <-events: 123 received = append(received, ev.Txs...) 124 case <-time.After(time.Second): 125 return fmt.Errorf("event #%d not fired", received) 126 } 127 } 128 if len(received) > count { 129 return fmt.Errorf("more than %d events fired: %v", count, received[count:]) 130 } 131 select { 132 case ev := <-events: 133 return fmt.Errorf("more than %d events fired: %v", count, ev.Txs) 134 135 case <-time.After(50 * time.Millisecond): 136 //这个分支应该是“默认”的,但它是Goroutines之间的数据竞争, 137 //读取事件通道并将其推入,因此最好等待一点以确保 138 //真的什么都没有注射。 139 } 140 return nil 141 } 142 143 func deriveSender(tx *types.Transaction) (common.Address, error) { 144 return types.Sender(types.HomesteadSigner{}, tx) 145 } 146 147 type testChain struct { 148 *testBlockChain 149 address common.Address 150 trigger *bool 151 } 152 153 //testchain.state()多次用于重置挂起状态。 154 //当Simulate为true时,它将创建一个指示 155 //TX0和TX1包含在链条中。 156 func (c *testChain) State() (*state.StateDB, error) { 157 //将“状态更改”延迟一次。Tx池获取 158 //状态多次,通过稍微延迟,我们模拟 159 //这些回迁之间的状态变化。 160 stdb := c.statedb 161 if *c.trigger { 162 c.statedb, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 163 //模拟新的头部模块包括TX0和TX1 164 c.statedb.SetNonce(c.address, 2) 165 c.statedb.SetBalance(c.address, new(big.Int).SetUint64(params.Ether)) 166 *c.trigger = false 167 } 168 return stdb, nil 169 } 170 171 //此测试模拟在 172 //状态重置并测试挂起状态是否与 173 //启动ResetState()的块头事件。 174 func TestStateChangeDuringTransactionPoolReset(t *testing.T) { 175 t.Parallel() 176 177 var ( 178 key, _ = crypto.GenerateKey() 179 address = crypto.PubkeyToAddress(key.PublicKey) 180 statedb, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 181 trigger = false 182 ) 183 184 //设置包含2个事务的池 185 statedb.SetBalance(address, new(big.Int).SetUint64(params.Ether)) 186 blockchain := &testChain{&testBlockChain{statedb, 1000000000, new(event.Feed)}, address, &trigger} 187 188 tx0 := transaction(0, 100000, key) 189 tx1 := transaction(1, 100000, key) 190 191 pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 192 defer pool.Stop() 193 194 nonce := pool.State().GetNonce(address) 195 if nonce != 0 { 196 t.Fatalf("Invalid nonce, want 0, got %d", nonce) 197 } 198 199 pool.AddRemotes(types.Transactions{tx0, tx1}) 200 201 nonce = pool.State().GetNonce(address) 202 if nonce != 2 { 203 t.Fatalf("Invalid nonce, want 2, got %d", nonce) 204 } 205 206 //后台触发状态更改 207 trigger = true 208 209 pool.lockedReset(nil, nil) 210 211 _, err := pool.Pending() 212 if err != nil { 213 t.Fatalf("Could not fetch pending transactions: %v", err) 214 } 215 nonce = pool.State().GetNonce(address) 216 if nonce != 2 { 217 t.Fatalf("Invalid nonce, want 2, got %d", nonce) 218 } 219 } 220 221 func TestInvalidTransactions(t *testing.T) { 222 t.Parallel() 223 224 pool, key := setupTxPool() 225 defer pool.Stop() 226 227 tx := transaction(0, 100, key) 228 from, _ := deriveSender(tx) 229 230 pool.currentState.AddBalance(from, big.NewInt(1)) 231 if err := pool.AddRemote(tx); err != ErrInsufficientFunds { 232 t.Error("expected", ErrInsufficientFunds) 233 } 234 235 balance := new(big.Int).Add(tx.Value(), new(big.Int).Mul(new(big.Int).SetUint64(tx.Gas()), tx.GasPrice())) 236 pool.currentState.AddBalance(from, balance) 237 if err := pool.AddRemote(tx); err != ErrIntrinsicGas { 238 t.Error("expected", ErrIntrinsicGas, "got", err) 239 } 240 241 pool.currentState.SetNonce(from, 1) 242 pool.currentState.AddBalance(from, big.NewInt(0xffffffffffffff)) 243 tx = transaction(0, 100000, key) 244 if err := pool.AddRemote(tx); err != ErrNonceTooLow { 245 t.Error("expected", ErrNonceTooLow) 246 } 247 248 tx = transaction(1, 100000, key) 249 pool.gasPrice = big.NewInt(1000) 250 if err := pool.AddRemote(tx); err != ErrUnderpriced { 251 t.Error("expected", ErrUnderpriced, "got", err) 252 } 253 if err := pool.AddLocal(tx); err != nil { 254 t.Error("expected", nil, "got", err) 255 } 256 } 257 258 func TestTransactionQueue(t *testing.T) { 259 t.Parallel() 260 261 pool, key := setupTxPool() 262 defer pool.Stop() 263 264 tx := transaction(0, 100, key) 265 from, _ := deriveSender(tx) 266 pool.currentState.AddBalance(from, big.NewInt(1000)) 267 pool.lockedReset(nil, nil) 268 pool.enqueueTx(tx.Hash(), tx) 269 270 pool.promoteExecutables([]common.Address{from}) 271 if len(pool.pending) != 1 { 272 t.Error("expected valid txs to be 1 is", len(pool.pending)) 273 } 274 275 tx = transaction(1, 100, key) 276 from, _ = deriveSender(tx) 277 pool.currentState.SetNonce(from, 2) 278 pool.enqueueTx(tx.Hash(), tx) 279 pool.promoteExecutables([]common.Address{from}) 280 if _, ok := pool.pending[from].txs.items[tx.Nonce()]; ok { 281 t.Error("expected transaction to be in tx pool") 282 } 283 284 if len(pool.queue) > 0 { 285 t.Error("expected transaction queue to be empty. is", len(pool.queue)) 286 } 287 288 pool, key = setupTxPool() 289 defer pool.Stop() 290 291 tx1 := transaction(0, 100, key) 292 tx2 := transaction(10, 100, key) 293 tx3 := transaction(11, 100, key) 294 from, _ = deriveSender(tx1) 295 pool.currentState.AddBalance(from, big.NewInt(1000)) 296 pool.lockedReset(nil, nil) 297 298 pool.enqueueTx(tx1.Hash(), tx1) 299 pool.enqueueTx(tx2.Hash(), tx2) 300 pool.enqueueTx(tx3.Hash(), tx3) 301 302 pool.promoteExecutables([]common.Address{from}) 303 304 if len(pool.pending) != 1 { 305 t.Error("expected tx pool to be 1, got", len(pool.pending)) 306 } 307 if pool.queue[from].Len() != 2 { 308 t.Error("expected len(queue) == 2, got", pool.queue[from].Len()) 309 } 310 } 311 312 func TestTransactionNegativeValue(t *testing.T) { 313 t.Parallel() 314 315 pool, key := setupTxPool() 316 defer pool.Stop() 317 318 tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(-1), 100, big.NewInt(1), nil), types.HomesteadSigner{}, key) 319 from, _ := deriveSender(tx) 320 pool.currentState.AddBalance(from, big.NewInt(1)) 321 if err := pool.AddRemote(tx); err != ErrNegativeValue { 322 t.Error("expected", ErrNegativeValue, "got", err) 323 } 324 } 325 326 func TestTransactionChainFork(t *testing.T) { 327 t.Parallel() 328 329 pool, key := setupTxPool() 330 defer pool.Stop() 331 332 addr := crypto.PubkeyToAddress(key.PublicKey) 333 resetState := func() { 334 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 335 statedb.AddBalance(addr, big.NewInt(100000000000000)) 336 337 pool.chain = &testBlockChain{statedb, 1000000, new(event.Feed)} 338 pool.lockedReset(nil, nil) 339 } 340 resetState() 341 342 tx := transaction(0, 100000, key) 343 if _, err := pool.add(tx, false); err != nil { 344 t.Error("didn't expect error", err) 345 } 346 pool.removeTx(tx.Hash(), true) 347 348 //重置池的内部状态 349 resetState() 350 if _, err := pool.add(tx, false); err != nil { 351 t.Error("didn't expect error", err) 352 } 353 } 354 355 func TestTransactionDoubleNonce(t *testing.T) { 356 t.Parallel() 357 358 pool, key := setupTxPool() 359 defer pool.Stop() 360 361 addr := crypto.PubkeyToAddress(key.PublicKey) 362 resetState := func() { 363 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 364 statedb.AddBalance(addr, big.NewInt(100000000000000)) 365 366 pool.chain = &testBlockChain{statedb, 1000000, new(event.Feed)} 367 pool.lockedReset(nil, nil) 368 } 369 resetState() 370 371 signer := types.HomesteadSigner{} 372 tx1, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 100000, big.NewInt(1), nil), signer, key) 373 tx2, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 1000000, big.NewInt(2), nil), signer, key) 374 tx3, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 1000000, big.NewInt(1), nil), signer, key) 375 376 //添加前两个事务,确保只保留较高的价格 377 if replace, err := pool.add(tx1, false); err != nil || replace { 378 t.Errorf("first transaction insert failed (%v) or reported replacement (%v)", err, replace) 379 } 380 if replace, err := pool.add(tx2, false); err != nil || !replace { 381 t.Errorf("second transaction insert failed (%v) or not reported replacement (%v)", err, replace) 382 } 383 pool.promoteExecutables([]common.Address{addr}) 384 if pool.pending[addr].Len() != 1 { 385 t.Error("expected 1 pending transactions, got", pool.pending[addr].Len()) 386 } 387 if tx := pool.pending[addr].txs.items[0]; tx.Hash() != tx2.Hash() { 388 t.Errorf("transaction mismatch: have %x, want %x", tx.Hash(), tx2.Hash()) 389 } 390 //添加第三个交易并确保它不被保存(较小的价格) 391 pool.add(tx3, false) 392 pool.promoteExecutables([]common.Address{addr}) 393 if pool.pending[addr].Len() != 1 { 394 t.Error("expected 1 pending transactions, got", pool.pending[addr].Len()) 395 } 396 if tx := pool.pending[addr].txs.items[0]; tx.Hash() != tx2.Hash() { 397 t.Errorf("transaction mismatch: have %x, want %x", tx.Hash(), tx2.Hash()) 398 } 399 //确保事务总数正确 400 if pool.all.Count() != 1 { 401 t.Error("expected 1 total transactions, got", pool.all.Count()) 402 } 403 } 404 405 func TestTransactionMissingNonce(t *testing.T) { 406 t.Parallel() 407 408 pool, key := setupTxPool() 409 defer pool.Stop() 410 411 addr := crypto.PubkeyToAddress(key.PublicKey) 412 pool.currentState.AddBalance(addr, big.NewInt(100000000000000)) 413 tx := transaction(1, 100000, key) 414 if _, err := pool.add(tx, false); err != nil { 415 t.Error("didn't expect error", err) 416 } 417 if len(pool.pending) != 0 { 418 t.Error("expected 0 pending transactions, got", len(pool.pending)) 419 } 420 if pool.queue[addr].Len() != 1 { 421 t.Error("expected 1 queued transaction, got", pool.queue[addr].Len()) 422 } 423 if pool.all.Count() != 1 { 424 t.Error("expected 1 total transactions, got", pool.all.Count()) 425 } 426 } 427 428 func TestTransactionNonceRecovery(t *testing.T) { 429 t.Parallel() 430 431 const n = 10 432 pool, key := setupTxPool() 433 defer pool.Stop() 434 435 addr := crypto.PubkeyToAddress(key.PublicKey) 436 pool.currentState.SetNonce(addr, n) 437 pool.currentState.AddBalance(addr, big.NewInt(100000000000000)) 438 pool.lockedReset(nil, nil) 439 440 tx := transaction(n, 100000, key) 441 if err := pool.AddRemote(tx); err != nil { 442 t.Error(err) 443 } 444 //模拟一些奇怪的事务重新排序和丢失的nonce 445 pool.currentState.SetNonce(addr, n-1) 446 pool.lockedReset(nil, nil) 447 if fn := pool.pendingState.GetNonce(addr); fn != n-1 { 448 t.Errorf("expected nonce to be %d, got %d", n-1, fn) 449 } 450 } 451 452 //测试如果帐户用完资金,任何挂起和排队的事务 453 //被丢弃。 454 func TestTransactionDropping(t *testing.T) { 455 t.Parallel() 456 457 //创建测试帐户并为其提供资金 458 pool, key := setupTxPool() 459 defer pool.Stop() 460 461 account, _ := deriveSender(transaction(0, 0, key)) 462 pool.currentState.AddBalance(account, big.NewInt(1000)) 463 464 //添加一些挂起的事务和一些排队的事务 465 var ( 466 tx0 = transaction(0, 100, key) 467 tx1 = transaction(1, 200, key) 468 tx2 = transaction(2, 300, key) 469 tx10 = transaction(10, 100, key) 470 tx11 = transaction(11, 200, key) 471 tx12 = transaction(12, 300, key) 472 ) 473 pool.promoteTx(account, tx0.Hash(), tx0) 474 pool.promoteTx(account, tx1.Hash(), tx1) 475 pool.promoteTx(account, tx2.Hash(), tx2) 476 pool.enqueueTx(tx10.Hash(), tx10) 477 pool.enqueueTx(tx11.Hash(), tx11) 478 pool.enqueueTx(tx12.Hash(), tx12) 479 480 //检查验证前和验证后是否按原样离开池 481 if pool.pending[account].Len() != 3 { 482 t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), 3) 483 } 484 if pool.queue[account].Len() != 3 { 485 t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 3) 486 } 487 if pool.all.Count() != 6 { 488 t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 6) 489 } 490 pool.lockedReset(nil, nil) 491 if pool.pending[account].Len() != 3 { 492 t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), 3) 493 } 494 if pool.queue[account].Len() != 3 { 495 t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 3) 496 } 497 if pool.all.Count() != 6 { 498 t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 6) 499 } 500 //减少账户余额,并检查失效的交易记录是否已删除。 501 pool.currentState.AddBalance(account, big.NewInt(-650)) 502 pool.lockedReset(nil, nil) 503 504 if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok { 505 t.Errorf("funded pending transaction missing: %v", tx0) 506 } 507 if _, ok := pool.pending[account].txs.items[tx1.Nonce()]; !ok { 508 t.Errorf("funded pending transaction missing: %v", tx0) 509 } 510 if _, ok := pool.pending[account].txs.items[tx2.Nonce()]; ok { 511 t.Errorf("out-of-fund pending transaction present: %v", tx1) 512 } 513 if _, ok := pool.queue[account].txs.items[tx10.Nonce()]; !ok { 514 t.Errorf("funded queued transaction missing: %v", tx10) 515 } 516 if _, ok := pool.queue[account].txs.items[tx11.Nonce()]; !ok { 517 t.Errorf("funded queued transaction missing: %v", tx10) 518 } 519 if _, ok := pool.queue[account].txs.items[tx12.Nonce()]; ok { 520 t.Errorf("out-of-fund queued transaction present: %v", tx11) 521 } 522 if pool.all.Count() != 4 { 523 t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 4) 524 } 525 //降低区块气限额,检查失效的交易是否被取消。 526 pool.chain.(*testBlockChain).gasLimit = 100 527 pool.lockedReset(nil, nil) 528 529 if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok { 530 t.Errorf("funded pending transaction missing: %v", tx0) 531 } 532 if _, ok := pool.pending[account].txs.items[tx1.Nonce()]; ok { 533 t.Errorf("over-gased pending transaction present: %v", tx1) 534 } 535 if _, ok := pool.queue[account].txs.items[tx10.Nonce()]; !ok { 536 t.Errorf("funded queued transaction missing: %v", tx10) 537 } 538 if _, ok := pool.queue[account].txs.items[tx11.Nonce()]; ok { 539 t.Errorf("over-gased queued transaction present: %v", tx11) 540 } 541 if pool.all.Count() != 2 { 542 t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 2) 543 } 544 } 545 546 //测试事务是否从当前挂起池中删除(例如out 547 //所有连续(仍然有效,但不可执行)交易 548 //推迟到将来的队列中,以防止广播它们。 549 func TestTransactionPostponing(t *testing.T) { 550 t.Parallel() 551 552 //创建用于测试延迟的池 553 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 554 blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} 555 556 pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 557 defer pool.Stop() 558 559 //创建两个测试帐户以生成不同的间隙配置文件 560 keys := make([]*ecdsa.PrivateKey, 2) 561 accs := make([]common.Address, len(keys)) 562 563 for i := 0; i < len(keys); i++ { 564 keys[i], _ = crypto.GenerateKey() 565 accs[i] = crypto.PubkeyToAddress(keys[i].PublicKey) 566 567 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(50100)) 568 } 569 //添加批处理连续挂起事务以进行验证 570 txs := []*types.Transaction{} 571 for i, key := range keys { 572 573 for j := 0; j < 100; j++ { 574 var tx *types.Transaction 575 if (i+j)%2 == 0 { 576 tx = transaction(uint64(j), 25000, key) 577 } else { 578 tx = transaction(uint64(j), 50000, key) 579 } 580 txs = append(txs, tx) 581 } 582 } 583 for i, err := range pool.AddRemotes(txs) { 584 if err != nil { 585 t.Fatalf("tx %d: failed to add transactions: %v", i, err) 586 } 587 } 588 //检查验证前和验证后是否按原样离开池 589 if pending := pool.pending[accs[0]].Len() + pool.pending[accs[1]].Len(); pending != len(txs) { 590 t.Errorf("pending transaction mismatch: have %d, want %d", pending, len(txs)) 591 } 592 if len(pool.queue) != 0 { 593 t.Errorf("queued accounts mismatch: have %d, want %d", len(pool.queue), 0) 594 } 595 if pool.all.Count() != len(txs) { 596 t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs)) 597 } 598 pool.lockedReset(nil, nil) 599 if pending := pool.pending[accs[0]].Len() + pool.pending[accs[1]].Len(); pending != len(txs) { 600 t.Errorf("pending transaction mismatch: have %d, want %d", pending, len(txs)) 601 } 602 if len(pool.queue) != 0 { 603 t.Errorf("queued accounts mismatch: have %d, want %d", len(pool.queue), 0) 604 } 605 if pool.all.Count() != len(txs) { 606 t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs)) 607 } 608 //减少账户余额,并检查交易是否被重组。 609 for _, addr := range accs { 610 pool.currentState.AddBalance(addr, big.NewInt(-1)) 611 } 612 pool.lockedReset(nil, nil) 613 614 //第一个帐户的第一个交易仍然有效,请检查后面的 615 //它们要么被过滤掉,要么排队等待稍后。 616 if _, ok := pool.pending[accs[0]].txs.items[txs[0].Nonce()]; !ok { 617 t.Errorf("tx %d: valid and funded transaction missing from pending pool: %v", 0, txs[0]) 618 } 619 if _, ok := pool.queue[accs[0]].txs.items[txs[0].Nonce()]; ok { 620 t.Errorf("tx %d: valid and funded transaction present in future queue: %v", 0, txs[0]) 621 } 622 for i, tx := range txs[1:100] { 623 if i%2 == 1 { 624 if _, ok := pool.pending[accs[0]].txs.items[tx.Nonce()]; ok { 625 t.Errorf("tx %d: valid but future transaction present in pending pool: %v", i+1, tx) 626 } 627 if _, ok := pool.queue[accs[0]].txs.items[tx.Nonce()]; !ok { 628 t.Errorf("tx %d: valid but future transaction missing from future queue: %v", i+1, tx) 629 } 630 } else { 631 if _, ok := pool.pending[accs[0]].txs.items[tx.Nonce()]; ok { 632 t.Errorf("tx %d: out-of-fund transaction present in pending pool: %v", i+1, tx) 633 } 634 if _, ok := pool.queue[accs[0]].txs.items[tx.Nonce()]; ok { 635 t.Errorf("tx %d: out-of-fund transaction present in future queue: %v", i+1, tx) 636 } 637 } 638 } 639 //第二个帐户的第一个事务无效,请检查所有事务 640 //或者被筛选出,或者排队等待稍后。 641 if pool.pending[accs[1]] != nil { 642 t.Errorf("invalidated account still has pending transactions") 643 } 644 for i, tx := range txs[100:] { 645 if i%2 == 1 { 646 if _, ok := pool.queue[accs[1]].txs.items[tx.Nonce()]; !ok { 647 t.Errorf("tx %d: valid but future transaction missing from future queue: %v", 100+i, tx) 648 } 649 } else { 650 if _, ok := pool.queue[accs[1]].txs.items[tx.Nonce()]; ok { 651 t.Errorf("tx %d: out-of-fund transaction present in future queue: %v", 100+i, tx) 652 } 653 } 654 } 655 if pool.all.Count() != len(txs)/2 { 656 t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs)/2) 657 } 658 } 659 660 //测试事务池是否同时具有可执行和不可执行 661 //来自原始帐户的事务,填充nonce间隙将所有事务移动到队列中 662 //一个进入待处理池。 663 func TestTransactionGapFilling(t *testing.T) { 664 t.Parallel() 665 666 //创建测试帐户并为其提供资金 667 pool, key := setupTxPool() 668 defer pool.Stop() 669 670 account, _ := deriveSender(transaction(0, 0, key)) 671 pool.currentState.AddBalance(account, big.NewInt(1000000)) 672 673 //跟踪事务事件以确保公布所有可执行文件 674 events := make(chan NewTxsEvent, testTxPoolConfig.AccountQueue+5) 675 sub := pool.txFeed.Subscribe(events) 676 defer sub.Unsubscribe() 677 678 //创建一个挂起事务和一个排队事务,中间有一个非ce间隙 679 if err := pool.AddRemote(transaction(0, 100000, key)); err != nil { 680 t.Fatalf("failed to add pending transaction: %v", err) 681 } 682 if err := pool.AddRemote(transaction(2, 100000, key)); err != nil { 683 t.Fatalf("failed to add queued transaction: %v", err) 684 } 685 pending, queued := pool.Stats() 686 if pending != 1 { 687 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 1) 688 } 689 if queued != 1 { 690 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) 691 } 692 if err := validateEvents(events, 1); err != nil { 693 t.Fatalf("original event firing failed: %v", err) 694 } 695 if err := validateTxPoolInternals(pool); err != nil { 696 t.Fatalf("pool internal state corrupted: %v", err) 697 } 698 //填补当前空白,确保所有事务都处于挂起状态 699 if err := pool.AddRemote(transaction(1, 100000, key)); err != nil { 700 t.Fatalf("failed to add gapped transaction: %v", err) 701 } 702 pending, queued = pool.Stats() 703 if pending != 3 { 704 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) 705 } 706 if queued != 0 { 707 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) 708 } 709 if err := validateEvents(events, 2); err != nil { 710 t.Fatalf("gap-filling event firing failed: %v", err) 711 } 712 if err := validateTxPoolInternals(pool); err != nil { 713 t.Fatalf("pool internal state corrupted: %v", err) 714 } 715 } 716 717 //测试属于单个帐户的交易计数是否高于 718 //一些阈值,更高的事务被丢弃以防止DoS攻击。 719 func TestTransactionQueueAccountLimiting(t *testing.T) { 720 t.Parallel() 721 722 //创建测试帐户并为其提供资金 723 pool, key := setupTxPool() 724 defer pool.Stop() 725 726 account, _ := deriveSender(transaction(0, 0, key)) 727 pool.currentState.AddBalance(account, big.NewInt(1000000)) 728 729 //Keep queuing up transactions and make sure all above a limit are dropped 730 for i := uint64(1); i <= testTxPoolConfig.AccountQueue+5; i++ { 731 if err := pool.AddRemote(transaction(i, 100000, key)); err != nil { 732 t.Fatalf("tx %d: failed to add transaction: %v", i, err) 733 } 734 if len(pool.pending) != 0 { 735 t.Errorf("tx %d: pending pool size mismatch: have %d, want %d", i, len(pool.pending), 0) 736 } 737 if i <= testTxPoolConfig.AccountQueue { 738 if pool.queue[account].Len() != int(i) { 739 t.Errorf("tx %d: queue size mismatch: have %d, want %d", i, pool.queue[account].Len(), i) 740 } 741 } else { 742 if pool.queue[account].Len() != int(testTxPoolConfig.AccountQueue) { 743 t.Errorf("tx %d: queue limit mismatch: have %d, want %d", i, pool.queue[account].Len(), testTxPoolConfig.AccountQueue) 744 } 745 } 746 } 747 if pool.all.Count() != int(testTxPoolConfig.AccountQueue) { 748 t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), testTxPoolConfig.AccountQueue) 749 } 750 } 751 752 //测试属于多个帐户的事务计数是否高于 753 //一些阈值,更高的事务被丢弃以防止DoS攻击。 754 // 755 //除非本地跟踪,否则此逻辑不应适用于本地事务 756 //机制被禁用。 757 func TestTransactionQueueGlobalLimiting(t *testing.T) { 758 testTransactionQueueGlobalLimiting(t, false) 759 } 760 func TestTransactionQueueGlobalLimitingNoLocals(t *testing.T) { 761 testTransactionQueueGlobalLimiting(t, true) 762 } 763 764 func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) { 765 t.Parallel() 766 767 //创建池以测试限制强制 768 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 769 blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} 770 771 config := testTxPoolConfig 772 config.NoLocals = nolocals 773 config.GlobalQueue = config.AccountQueue*3 - 1 //减少队列限制以缩短测试时间(-1以使其不可分割) 774 775 pool := NewTxPool(config, params.TestChainConfig, blockchain) 776 defer pool.Stop() 777 778 //创建多个测试帐户并为其提供资金(最后一个帐户将是本地帐户) 779 keys := make([]*ecdsa.PrivateKey, 5) 780 for i := 0; i < len(keys); i++ { 781 keys[i], _ = crypto.GenerateKey() 782 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) 783 } 784 local := keys[len(keys)-1] 785 786 //生成和排队一批事务 787 nonces := make(map[common.Address]uint64) 788 789 txs := make(types.Transactions, 0, 3*config.GlobalQueue) 790 for len(txs) < cap(txs) { 791 key := keys[rand.Intn(len(keys)-1)] //跳过添加本地帐户的交易记录 792 addr := crypto.PubkeyToAddress(key.PublicKey) 793 794 txs = append(txs, transaction(nonces[addr]+1, 100000, key)) 795 nonces[addr]++ 796 } 797 //导入批并验证是否已强制执行限制 798 pool.AddRemotes(txs) 799 800 queued := 0 801 for addr, list := range pool.queue { 802 if list.Len() > int(config.AccountQueue) { 803 t.Errorf("addr %x: queued accounts overflown allowance: %d > %d", addr, list.Len(), config.AccountQueue) 804 } 805 queued += list.Len() 806 } 807 if queued > int(config.GlobalQueue) { 808 t.Fatalf("total transactions overflow allowance: %d > %d", queued, config.GlobalQueue) 809 } 810 //从本地帐户生成一批交易并导入它们 811 txs = txs[:0] 812 for i := uint64(0); i < 3*config.GlobalQueue; i++ { 813 txs = append(txs, transaction(i+1, 100000, local)) 814 } 815 pool.AddLocals(txs) 816 817 //如果禁用局部变量,则以前的逐出算法也应在此应用 818 if nolocals { 819 queued := 0 820 for addr, list := range pool.queue { 821 if list.Len() > int(config.AccountQueue) { 822 t.Errorf("addr %x: queued accounts overflown allowance: %d > %d", addr, list.Len(), config.AccountQueue) 823 } 824 queued += list.Len() 825 } 826 if queued > int(config.GlobalQueue) { 827 t.Fatalf("total transactions overflow allowance: %d > %d", queued, config.GlobalQueue) 828 } 829 } else { 830 //已启用本地免除,请确保本地帐户拥有队列 831 if len(pool.queue) != 1 { 832 t.Errorf("multiple accounts in queue: have %v, want %v", len(pool.queue), 1) 833 } 834 //此外,即使高于全球限额,也要确保没有任何本地交易被取消。 835 if queued := pool.queue[crypto.PubkeyToAddress(local.PublicKey)].Len(); uint64(queued) != 3*config.GlobalQueue { 836 t.Fatalf("local account queued transaction count mismatch: have %v, want %v", queued, 3*config.GlobalQueue) 837 } 838 } 839 } 840 841 //测试如果帐户长时间处于空闲状态, 842 //排队的不可执行事务将被删除,以防止浪费资源 843 //把它们绕来绕去。 844 // 845 //除非本地跟踪,否则此逻辑不应适用于本地事务 846 //机制被禁用。 847 func TestTransactionQueueTimeLimiting(t *testing.T) { testTransactionQueueTimeLimiting(t, false) } 848 func TestTransactionQueueTimeLimitingNoLocals(t *testing.T) { testTransactionQueueTimeLimiting(t, true) } 849 850 func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { 851 //将驱逐间隔减少到可测试的数量 852 defer func(old time.Duration) { evictionInterval = old }(evictionInterval) 853 evictionInterval = time.Second 854 855 //创建池以测试非过期强制 856 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 857 blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} 858 859 config := testTxPoolConfig 860 config.Lifetime = time.Second 861 config.NoLocals = nolocals 862 863 pool := NewTxPool(config, params.TestChainConfig, blockchain) 864 defer pool.Stop() 865 866 //创建两个测试帐户以确保远程计算机过期,但本地计算机不过期 867 local, _ := crypto.GenerateKey() 868 remote, _ := crypto.GenerateKey() 869 870 pool.currentState.AddBalance(crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000)) 871 pool.currentState.AddBalance(crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000)) 872 873 //添加这两个事务并确保它们都排队 874 if err := pool.AddLocal(pricedTransaction(1, 100000, big.NewInt(1), local)); err != nil { 875 t.Fatalf("failed to add local transaction: %v", err) 876 } 877 if err := pool.AddRemote(pricedTransaction(1, 100000, big.NewInt(1), remote)); err != nil { 878 t.Fatalf("failed to add remote transaction: %v", err) 879 } 880 pending, queued := pool.Stats() 881 if pending != 0 { 882 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) 883 } 884 if queued != 2 { 885 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) 886 } 887 if err := validateTxPoolInternals(pool); err != nil { 888 t.Fatalf("pool internal state corrupted: %v", err) 889 } 890 //稍等一点,把剩菜运走,清理干净,只留下本地菜。 891 time.Sleep(2 * config.Lifetime) 892 893 pending, queued = pool.Stats() 894 if pending != 0 { 895 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) 896 } 897 if nolocals { 898 if queued != 0 { 899 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) 900 } 901 } else { 902 if queued != 1 { 903 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) 904 } 905 } 906 if err := validateTxPoolInternals(pool); err != nil { 907 t.Fatalf("pool internal state corrupted: %v", err) 908 } 909 } 910 911 //测试即使属于单个帐户的交易计数变为 912 //高于某个阈值,只要事务是可执行的,它们就是 913 //认可的。 914 func TestTransactionPendingLimiting(t *testing.T) { 915 t.Parallel() 916 917 //创建测试帐户并为其提供资金 918 pool, key := setupTxPool() 919 defer pool.Stop() 920 921 account, _ := deriveSender(transaction(0, 0, key)) 922 pool.currentState.AddBalance(account, big.NewInt(1000000)) 923 924 //跟踪事务事件以确保公布所有可执行文件 925 events := make(chan NewTxsEvent, testTxPoolConfig.AccountQueue+5) 926 sub := pool.txFeed.Subscribe(events) 927 defer sub.Unsubscribe() 928 929 //继续排队处理事务,并确保删除所有超过限制的事务 930 for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ { 931 if err := pool.AddRemote(transaction(i, 100000, key)); err != nil { 932 t.Fatalf("tx %d: failed to add transaction: %v", i, err) 933 } 934 if pool.pending[account].Len() != int(i)+1 { 935 t.Errorf("tx %d: pending pool size mismatch: have %d, want %d", i, pool.pending[account].Len(), i+1) 936 } 937 if len(pool.queue) != 0 { 938 t.Errorf("tx %d: queue size mismatch: have %d, want %d", i, pool.queue[account].Len(), 0) 939 } 940 } 941 if pool.all.Count() != int(testTxPoolConfig.AccountQueue+5) { 942 t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), testTxPoolConfig.AccountQueue+5) 943 } 944 if err := validateEvents(events, int(testTxPoolConfig.AccountQueue+5)); err != nil { 945 t.Fatalf("event firing failed: %v", err) 946 } 947 if err := validateTxPoolInternals(pool); err != nil { 948 t.Fatalf("pool internal state corrupted: %v", err) 949 } 950 } 951 952 //测试是否以同样的方式强制执行事务限制 953 //事务将逐个添加或分批添加。 954 func TestTransactionQueueLimitingEquivalency(t *testing.T) { testTransactionLimitingEquivalency(t, 1) } 955 func TestTransactionPendingLimitingEquivalency(t *testing.T) { testTransactionLimitingEquivalency(t, 0) } 956 957 func testTransactionLimitingEquivalency(t *testing.T, origin uint64) { 958 t.Parallel() 959 960 //将一批事务逐个添加到池中 961 pool1, key1 := setupTxPool() 962 defer pool1.Stop() 963 964 account1, _ := deriveSender(transaction(0, 0, key1)) 965 pool1.currentState.AddBalance(account1, big.NewInt(1000000)) 966 967 for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ { 968 if err := pool1.AddRemote(transaction(origin+i, 100000, key1)); err != nil { 969 t.Fatalf("tx %d: failed to add transaction: %v", i, err) 970 } 971 } 972 //在一个大批量中向池中添加一批事务 973 pool2, key2 := setupTxPool() 974 defer pool2.Stop() 975 976 account2, _ := deriveSender(transaction(0, 0, key2)) 977 pool2.currentState.AddBalance(account2, big.NewInt(1000000)) 978 979 txs := []*types.Transaction{} 980 for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ { 981 txs = append(txs, transaction(origin+i, 100000, key2)) 982 } 983 pool2.AddRemotes(txs) 984 985 //确保批量优化符合相同的池机制 986 if len(pool1.pending) != len(pool2.pending) { 987 t.Errorf("pending transaction count mismatch: one-by-one algo: %d, batch algo: %d", len(pool1.pending), len(pool2.pending)) 988 } 989 if len(pool1.queue) != len(pool2.queue) { 990 t.Errorf("queued transaction count mismatch: one-by-one algo: %d, batch algo: %d", len(pool1.queue), len(pool2.queue)) 991 } 992 if pool1.all.Count() != pool2.all.Count() { 993 t.Errorf("total transaction count mismatch: one-by-one algo %d, batch algo %d", pool1.all.Count(), pool2.all.Count()) 994 } 995 if err := validateTxPoolInternals(pool1); err != nil { 996 t.Errorf("pool 1 internal state corrupted: %v", err) 997 } 998 if err := validateTxPoolInternals(pool2); err != nil { 999 t.Errorf("pool 2 internal state corrupted: %v", err) 1000 } 1001 } 1002 1003 //测试属于多个帐户的事务计数是否高于 1004 //一些硬阈值,更高的事务被丢弃以防止DoS 1005 //攻击。 1006 func TestTransactionPendingGlobalLimiting(t *testing.T) { 1007 t.Parallel() 1008 1009 //创建池以测试限制强制 1010 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1011 blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} 1012 1013 config := testTxPoolConfig 1014 config.GlobalSlots = config.AccountSlots * 10 1015 1016 pool := NewTxPool(config, params.TestChainConfig, blockchain) 1017 defer pool.Stop() 1018 1019 //创建多个测试帐户并为其提供资金 1020 keys := make([]*ecdsa.PrivateKey, 5) 1021 for i := 0; i < len(keys); i++ { 1022 keys[i], _ = crypto.GenerateKey() 1023 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) 1024 } 1025 //生成和排队一批事务 1026 nonces := make(map[common.Address]uint64) 1027 1028 txs := types.Transactions{} 1029 for _, key := range keys { 1030 addr := crypto.PubkeyToAddress(key.PublicKey) 1031 for j := 0; j < int(config.GlobalSlots)/len(keys)*2; j++ { 1032 txs = append(txs, transaction(nonces[addr], 100000, key)) 1033 nonces[addr]++ 1034 } 1035 } 1036 //导入批并验证是否已强制执行限制 1037 pool.AddRemotes(txs) 1038 1039 pending := 0 1040 for _, list := range pool.pending { 1041 pending += list.Len() 1042 } 1043 if pending > int(config.GlobalSlots) { 1044 t.Fatalf("total pending transactions overflow allowance: %d > %d", pending, config.GlobalSlots) 1045 } 1046 if err := validateTxPoolInternals(pool); err != nil { 1047 t.Fatalf("pool internal state corrupted: %v", err) 1048 } 1049 } 1050 1051 //测试如果事务开始被限制,事务也将从“全部”中删除 1052 func TestTransactionCapClearsFromAll(t *testing.T) { 1053 t.Parallel() 1054 1055 //创建池以测试限制强制 1056 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1057 blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} 1058 1059 config := testTxPoolConfig 1060 config.AccountSlots = 2 1061 config.AccountQueue = 2 1062 config.GlobalSlots = 8 1063 1064 pool := NewTxPool(config, params.TestChainConfig, blockchain) 1065 defer pool.Stop() 1066 1067 //创建多个测试帐户并为其提供资金 1068 key, _ := crypto.GenerateKey() 1069 addr := crypto.PubkeyToAddress(key.PublicKey) 1070 pool.currentState.AddBalance(addr, big.NewInt(1000000)) 1071 1072 txs := types.Transactions{} 1073 for j := 0; j < int(config.GlobalSlots)*2; j++ { 1074 txs = append(txs, transaction(uint64(j), 100000, key)) 1075 } 1076 //导入批并验证是否已强制执行限制 1077 pool.AddRemotes(txs) 1078 if err := validateTxPoolInternals(pool); err != nil { 1079 t.Fatalf("pool internal state corrupted: %v", err) 1080 } 1081 } 1082 1083 //测试属于多个帐户的事务计数是否高于 1084 //一些硬阈值,如果它们低于最小保证插槽计数,则 1085 //交易仍然保留。 1086 func TestTransactionPendingMinimumAllowance(t *testing.T) { 1087 t.Parallel() 1088 1089 //创建池以测试限制强制 1090 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1091 blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} 1092 1093 config := testTxPoolConfig 1094 config.GlobalSlots = 1 1095 1096 pool := NewTxPool(config, params.TestChainConfig, blockchain) 1097 defer pool.Stop() 1098 1099 //创建多个测试帐户并为其提供资金 1100 keys := make([]*ecdsa.PrivateKey, 5) 1101 for i := 0; i < len(keys); i++ { 1102 keys[i], _ = crypto.GenerateKey() 1103 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) 1104 } 1105 //生成和排队一批事务 1106 nonces := make(map[common.Address]uint64) 1107 1108 txs := types.Transactions{} 1109 for _, key := range keys { 1110 addr := crypto.PubkeyToAddress(key.PublicKey) 1111 for j := 0; j < int(config.AccountSlots)*2; j++ { 1112 txs = append(txs, transaction(nonces[addr], 100000, key)) 1113 nonces[addr]++ 1114 } 1115 } 1116 //导入批并验证是否已强制执行限制 1117 pool.AddRemotes(txs) 1118 1119 for addr, list := range pool.pending { 1120 if list.Len() != int(config.AccountSlots) { 1121 t.Errorf("addr %x: total pending transactions mismatch: have %d, want %d", addr, list.Len(), config.AccountSlots) 1122 } 1123 } 1124 if err := validateTxPoolInternals(pool); err != nil { 1125 t.Fatalf("pool internal state corrupted: %v", err) 1126 } 1127 } 1128 1129 //将交易池天然气价格正确设置为较高值的测试 1130 //丢弃所有比这便宜的东西,并将所有有间隙的事务移回 1131 //从挂起的池到队列。 1132 // 1133 //注意,不允许删除本地事务。 1134 func TestTransactionPoolRepricing(t *testing.T) { 1135 t.Parallel() 1136 1137 //创建池以测试定价强制 1138 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1139 blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} 1140 1141 pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 1142 defer pool.Stop() 1143 1144 //跟踪事务事件以确保公布所有可执行文件 1145 events := make(chan NewTxsEvent, 32) 1146 sub := pool.txFeed.Subscribe(events) 1147 defer sub.Unsubscribe() 1148 1149 //创建多个测试帐户并为其提供资金 1150 keys := make([]*ecdsa.PrivateKey, 4) 1151 for i := 0; i < len(keys); i++ { 1152 keys[i], _ = crypto.GenerateKey() 1153 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) 1154 } 1155 //生成并排队一批事务,包括挂起和排队事务 1156 txs := types.Transactions{} 1157 1158 txs = append(txs, pricedTransaction(0, 100000, big.NewInt(2), keys[0])) 1159 txs = append(txs, pricedTransaction(1, 100000, big.NewInt(1), keys[0])) 1160 txs = append(txs, pricedTransaction(2, 100000, big.NewInt(2), keys[0])) 1161 1162 txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[1])) 1163 txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[1])) 1164 txs = append(txs, pricedTransaction(2, 100000, big.NewInt(2), keys[1])) 1165 1166 txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[2])) 1167 txs = append(txs, pricedTransaction(2, 100000, big.NewInt(1), keys[2])) 1168 txs = append(txs, pricedTransaction(3, 100000, big.NewInt(2), keys[2])) 1169 1170 ltx := pricedTransaction(0, 100000, big.NewInt(1), keys[3]) 1171 1172 //导入批处理,并且挂起事务和排队事务都匹配 1173 pool.AddRemotes(txs) 1174 pool.AddLocal(ltx) 1175 1176 pending, queued := pool.Stats() 1177 if pending != 7 { 1178 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 7) 1179 } 1180 if queued != 3 { 1181 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 3) 1182 } 1183 if err := validateEvents(events, 7); err != nil { 1184 t.Fatalf("original event firing failed: %v", err) 1185 } 1186 if err := validateTxPoolInternals(pool); err != nil { 1187 t.Fatalf("pool internal state corrupted: %v", err) 1188 } 1189 //重新定价池并检查定价过低的交易是否被删除 1190 pool.SetGasPrice(big.NewInt(2)) 1191 1192 pending, queued = pool.Stats() 1193 if pending != 2 { 1194 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) 1195 } 1196 if queued != 5 { 1197 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 5) 1198 } 1199 if err := validateEvents(events, 0); err != nil { 1200 t.Fatalf("reprice event firing failed: %v", err) 1201 } 1202 if err := validateTxPoolInternals(pool); err != nil { 1203 t.Fatalf("pool internal state corrupted: %v", err) 1204 } 1205 //检查是否无法重新添加旧事务 1206 if err := pool.AddRemote(pricedTransaction(1, 100000, big.NewInt(1), keys[0])); err != ErrUnderpriced { 1207 t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced) 1208 } 1209 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(1), keys[1])); err != ErrUnderpriced { 1210 t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced) 1211 } 1212 if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(1), keys[2])); err != ErrUnderpriced { 1213 t.Fatalf("adding underpriced queued transaction error mismatch: have %v, want %v", err, ErrUnderpriced) 1214 } 1215 if err := validateEvents(events, 0); err != nil { 1216 t.Fatalf("post-reprice event firing failed: %v", err) 1217 } 1218 if err := validateTxPoolInternals(pool); err != nil { 1219 t.Fatalf("pool internal state corrupted: %v", err) 1220 } 1221 //但是,我们可以添加本地定价过低的交易 1222 tx := pricedTransaction(1, 100000, big.NewInt(1), keys[3]) 1223 if err := pool.AddLocal(tx); err != nil { 1224 t.Fatalf("failed to add underpriced local transaction: %v", err) 1225 } 1226 if pending, _ = pool.Stats(); pending != 3 { 1227 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) 1228 } 1229 if err := validateEvents(events, 1); err != nil { 1230 t.Fatalf("post-reprice local event firing failed: %v", err) 1231 } 1232 if err := validateTxPoolInternals(pool); err != nil { 1233 t.Fatalf("pool internal state corrupted: %v", err) 1234 } 1235 //我们可以用适当定价的交易来填补缺口 1236 if err := pool.AddRemote(pricedTransaction(1, 100000, big.NewInt(2), keys[0])); err != nil { 1237 t.Fatalf("failed to add pending transaction: %v", err) 1238 } 1239 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(2), keys[1])); err != nil { 1240 t.Fatalf("failed to add pending transaction: %v", err) 1241 } 1242 if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(2), keys[2])); err != nil { 1243 t.Fatalf("failed to add queued transaction: %v", err) 1244 } 1245 if err := validateEvents(events, 5); err != nil { 1246 t.Fatalf("post-reprice event firing failed: %v", err) 1247 } 1248 if err := validateTxPoolInternals(pool); err != nil { 1249 t.Fatalf("pool internal state corrupted: %v", err) 1250 } 1251 } 1252 1253 //将交易池天然气价格设置为较高值的测试没有 1254 //删除本地事务。 1255 func TestTransactionPoolRepricingKeepsLocals(t *testing.T) { 1256 t.Parallel() 1257 1258 //创建池以测试定价强制 1259 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1260 blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} 1261 1262 pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 1263 defer pool.Stop() 1264 1265 //创建多个测试帐户并为其提供资金 1266 keys := make([]*ecdsa.PrivateKey, 3) 1267 for i := 0; i < len(keys); i++ { 1268 keys[i], _ = crypto.GenerateKey() 1269 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000*1000000)) 1270 } 1271 //用线性增长的喘息创建事务(包括挂起和排队) 1272 for i := uint64(0); i < 500; i++ { 1273 //添加待定 1274 p_tx := pricedTransaction(i, 100000, big.NewInt(int64(i)), keys[2]) 1275 if err := pool.AddLocal(p_tx); err != nil { 1276 t.Fatal(err) 1277 } 1278 //添加队列 1279 q_tx := pricedTransaction(i+501, 100000, big.NewInt(int64(i)), keys[2]) 1280 if err := pool.AddLocal(q_tx); err != nil { 1281 t.Fatal(err) 1282 } 1283 } 1284 pending, queued := pool.Stats() 1285 expPending, expQueued := 500, 500 1286 validate := func() { 1287 pending, queued = pool.Stats() 1288 if pending != expPending { 1289 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, expPending) 1290 } 1291 if queued != expQueued { 1292 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, expQueued) 1293 } 1294 1295 if err := validateTxPoolInternals(pool); err != nil { 1296 t.Fatalf("pool internal state corrupted: %v", err) 1297 } 1298 } 1299 validate() 1300 1301 //重装游泳池并检查是否没有任何东西掉下。 1302 pool.SetGasPrice(big.NewInt(2)) 1303 validate() 1304 1305 pool.SetGasPrice(big.NewInt(2)) 1306 pool.SetGasPrice(big.NewInt(4)) 1307 pool.SetGasPrice(big.NewInt(8)) 1308 pool.SetGasPrice(big.NewInt(100)) 1309 validate() 1310 } 1311 1312 //测试当池达到其全球交易限额时,定价过低 1313 //交易逐渐转移到更昂贵的交易和任何有缺口的交易上。 1314 //挂起的事务将移动到队列中。 1315 // 1316 //注意,不允许删除本地事务。 1317 func TestTransactionPoolUnderpricing(t *testing.T) { 1318 t.Parallel() 1319 1320 //创建池以测试定价强制 1321 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1322 blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} 1323 1324 config := testTxPoolConfig 1325 config.GlobalSlots = 2 1326 config.GlobalQueue = 2 1327 1328 pool := NewTxPool(config, params.TestChainConfig, blockchain) 1329 defer pool.Stop() 1330 1331 //跟踪事务事件以确保公布所有可执行文件 1332 events := make(chan NewTxsEvent, 32) 1333 sub := pool.txFeed.Subscribe(events) 1334 defer sub.Unsubscribe() 1335 1336 //创建多个测试帐户并为其提供资金 1337 keys := make([]*ecdsa.PrivateKey, 4) 1338 for i := 0; i < len(keys); i++ { 1339 keys[i], _ = crypto.GenerateKey() 1340 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) 1341 } 1342 //生成并排队一批事务,包括挂起和排队事务 1343 txs := types.Transactions{} 1344 1345 txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[0])) 1346 txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[0])) 1347 1348 txs = append(txs, pricedTransaction(1, 100000, big.NewInt(1), keys[1])) 1349 1350 ltx := pricedTransaction(0, 100000, big.NewInt(1), keys[2]) 1351 1352 //导入批处理,并且挂起事务和排队事务都匹配 1353 pool.AddRemotes(txs) 1354 pool.AddLocal(ltx) 1355 1356 pending, queued := pool.Stats() 1357 if pending != 3 { 1358 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) 1359 } 1360 if queued != 1 { 1361 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) 1362 } 1363 if err := validateEvents(events, 3); err != nil { 1364 t.Fatalf("original event firing failed: %v", err) 1365 } 1366 if err := validateTxPoolInternals(pool); err != nil { 1367 t.Fatalf("pool internal state corrupted: %v", err) 1368 } 1369 //确保在块限制上添加定价过低的事务失败 1370 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(1), keys[1])); err != ErrUnderpriced { 1371 t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced) 1372 } 1373 //确保增加高价交易会降低廉价交易,但不会降低自有交易。 1374 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(3), keys[1])); err != nil { //+k1:0=>-k1:1=>悬垂k0:0,k0:1,k1:0,k2:0;力矩- 1375 t.Fatalf("failed to add well priced transaction: %v", err) 1376 } 1377 if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(4), keys[1])); err != nil { //+K1:2 => -K0:0 => Pend K1:0, K2:0; Que K0:1 K1:2 1378 t.Fatalf("failed to add well priced transaction: %v", err) 1379 } 1380 if err := pool.AddRemote(pricedTransaction(3, 100000, big.NewInt(5), keys[1])); err != nil { //+k1:3=>-k0:1=>悬垂k1:0,k2:0;力矩k1:2 k1:3 1381 t.Fatalf("failed to add well priced transaction: %v", err) 1382 } 1383 pending, queued = pool.Stats() 1384 if pending != 2 { 1385 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) 1386 } 1387 if queued != 2 { 1388 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) 1389 } 1390 if err := validateEvents(events, 1); err != nil { 1391 t.Fatalf("additional event firing failed: %v", err) 1392 } 1393 if err := validateTxPoolInternals(pool); err != nil { 1394 t.Fatalf("pool internal state corrupted: %v", err) 1395 } 1396 //确保增加本地交易可以推出价格更高的交易。 1397 ltx = pricedTransaction(1, 100000, big.NewInt(0), keys[2]) 1398 if err := pool.AddLocal(ltx); err != nil { 1399 t.Fatalf("failed to append underpriced local transaction: %v", err) 1400 } 1401 ltx = pricedTransaction(0, 100000, big.NewInt(0), keys[3]) 1402 if err := pool.AddLocal(ltx); err != nil { 1403 t.Fatalf("failed to add new underpriced local transaction: %v", err) 1404 } 1405 pending, queued = pool.Stats() 1406 if pending != 3 { 1407 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) 1408 } 1409 if queued != 1 { 1410 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) 1411 } 1412 if err := validateEvents(events, 2); err != nil { 1413 t.Fatalf("local event firing failed: %v", err) 1414 } 1415 if err := validateTxPoolInternals(pool); err != nil { 1416 t.Fatalf("pool internal state corrupted: %v", err) 1417 } 1418 } 1419 1420 //测试更昂贵的交易将廉价的交易从池中推出,但是 1421 //不产生不稳定,通过创建开始跳跃事务的间隙 1422 //在排队/等待之间来回。 1423 func TestTransactionPoolStableUnderpricing(t *testing.T) { 1424 t.Parallel() 1425 1426 //创建池以测试定价强制 1427 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1428 blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} 1429 1430 config := testTxPoolConfig 1431 config.GlobalSlots = 128 1432 config.GlobalQueue = 0 1433 1434 pool := NewTxPool(config, params.TestChainConfig, blockchain) 1435 defer pool.Stop() 1436 1437 //跟踪事务事件以确保公布所有可执行文件 1438 events := make(chan NewTxsEvent, 32) 1439 sub := pool.txFeed.Subscribe(events) 1440 defer sub.Unsubscribe() 1441 1442 //创建多个测试帐户并为其提供资金 1443 keys := make([]*ecdsa.PrivateKey, 2) 1444 for i := 0; i < len(keys); i++ { 1445 keys[i], _ = crypto.GenerateKey() 1446 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) 1447 } 1448 //用相同的交易价格点填充整个队列 1449 txs := types.Transactions{} 1450 for i := uint64(0); i < config.GlobalSlots; i++ { 1451 txs = append(txs, pricedTransaction(i, 100000, big.NewInt(1), keys[0])) 1452 } 1453 pool.AddRemotes(txs) 1454 1455 pending, queued := pool.Stats() 1456 if pending != int(config.GlobalSlots) { 1457 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, config.GlobalSlots) 1458 } 1459 if queued != 0 { 1460 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) 1461 } 1462 if err := validateEvents(events, int(config.GlobalSlots)); err != nil { 1463 t.Fatalf("original event firing failed: %v", err) 1464 } 1465 if err := validateTxPoolInternals(pool); err != nil { 1466 t.Fatalf("pool internal state corrupted: %v", err) 1467 } 1468 //确保增加高价交易会降低成本,但不会产生缺口。 1469 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(3), keys[1])); err != nil { 1470 t.Fatalf("failed to add well priced transaction: %v", err) 1471 } 1472 pending, queued = pool.Stats() 1473 if pending != int(config.GlobalSlots) { 1474 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, config.GlobalSlots) 1475 } 1476 if queued != 0 { 1477 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) 1478 } 1479 if err := validateEvents(events, 1); err != nil { 1480 t.Fatalf("additional event firing failed: %v", err) 1481 } 1482 if err := validateTxPoolInternals(pool); err != nil { 1483 t.Fatalf("pool internal state corrupted: %v", err) 1484 } 1485 } 1486 1487 //测试池拒绝不满足最小值的替换事务 1488 //需要涨价。 1489 func TestTransactionReplacement(t *testing.T) { 1490 t.Parallel() 1491 1492 //创建池以测试定价强制 1493 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1494 blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} 1495 1496 pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 1497 defer pool.Stop() 1498 1499 //跟踪事务事件以确保公布所有可执行文件 1500 events := make(chan NewTxsEvent, 32) 1501 sub := pool.txFeed.Subscribe(events) 1502 defer sub.Unsubscribe() 1503 1504 //创建测试帐户以添加交易记录 1505 key, _ := crypto.GenerateKey() 1506 pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000)) 1507 1508 //添加待定交易,确保强制执行最低价格上涨以进行替换(对于超低价格也是如此) 1509 price := int64(100) 1510 threshold := (price * (100 + int64(testTxPoolConfig.PriceBump))) / 100 1511 1512 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(1), key)); err != nil { 1513 t.Fatalf("failed to add original cheap pending transaction: %v", err) 1514 } 1515 if err := pool.AddRemote(pricedTransaction(0, 100001, big.NewInt(1), key)); err != ErrReplaceUnderpriced { 1516 t.Fatalf("original cheap pending transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) 1517 } 1518 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(2), key)); err != nil { 1519 t.Fatalf("failed to replace original cheap pending transaction: %v", err) 1520 } 1521 if err := validateEvents(events, 2); err != nil { 1522 t.Fatalf("cheap replacement event firing failed: %v", err) 1523 } 1524 1525 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(price), key)); err != nil { 1526 t.Fatalf("failed to add original proper pending transaction: %v", err) 1527 } 1528 if err := pool.AddRemote(pricedTransaction(0, 100001, big.NewInt(threshold-1), key)); err != ErrReplaceUnderpriced { 1529 t.Fatalf("original proper pending transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) 1530 } 1531 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(threshold), key)); err != nil { 1532 t.Fatalf("failed to replace original proper pending transaction: %v", err) 1533 } 1534 if err := validateEvents(events, 2); err != nil { 1535 t.Fatalf("proper replacement event firing failed: %v", err) 1536 } 1537 //添加排队事务,确保强制执行最低价格上涨以进行替换(对于超低价格也是如此) 1538 if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(1), key)); err != nil { 1539 t.Fatalf("failed to add original cheap queued transaction: %v", err) 1540 } 1541 if err := pool.AddRemote(pricedTransaction(2, 100001, big.NewInt(1), key)); err != ErrReplaceUnderpriced { 1542 t.Fatalf("original cheap queued transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) 1543 } 1544 if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(2), key)); err != nil { 1545 t.Fatalf("failed to replace original cheap queued transaction: %v", err) 1546 } 1547 1548 if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(price), key)); err != nil { 1549 t.Fatalf("failed to add original proper queued transaction: %v", err) 1550 } 1551 if err := pool.AddRemote(pricedTransaction(2, 100001, big.NewInt(threshold-1), key)); err != ErrReplaceUnderpriced { 1552 t.Fatalf("original proper queued transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) 1553 } 1554 if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(threshold), key)); err != nil { 1555 t.Fatalf("failed to replace original proper queued transaction: %v", err) 1556 } 1557 1558 if err := validateEvents(events, 0); err != nil { 1559 t.Fatalf("queued replacement event firing failed: %v", err) 1560 } 1561 if err := validateTxPoolInternals(pool); err != nil { 1562 t.Fatalf("pool internal state corrupted: %v", err) 1563 } 1564 } 1565 1566 //测试本地事务是否记录到磁盘,但远程事务 1567 //在重新启动之间被丢弃。 1568 func TestTransactionJournaling(t *testing.T) { testTransactionJournaling(t, false) } 1569 func TestTransactionJournalingNoLocals(t *testing.T) { testTransactionJournaling(t, true) } 1570 1571 func testTransactionJournaling(t *testing.T, nolocals bool) { 1572 t.Parallel() 1573 1574 //为日志创建临时文件 1575 file, err := ioutil.TempFile("", "") 1576 if err != nil { 1577 t.Fatalf("failed to create temporary journal: %v", err) 1578 } 1579 journal := file.Name() 1580 defer os.Remove(journal) 1581 1582 //清理临时文件,我们现在只需要路径 1583 file.Close() 1584 os.Remove(journal) 1585 1586 //创建原始池以将事务注入日记帐 1587 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1588 blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} 1589 1590 config := testTxPoolConfig 1591 config.NoLocals = nolocals 1592 config.Journal = journal 1593 config.Rejournal = time.Second 1594 1595 pool := NewTxPool(config, params.TestChainConfig, blockchain) 1596 1597 //创建两个测试帐户以确保远程计算机过期,但本地计算机不过期 1598 local, _ := crypto.GenerateKey() 1599 remote, _ := crypto.GenerateKey() 1600 1601 pool.currentState.AddBalance(crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000)) 1602 pool.currentState.AddBalance(crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000)) 1603 1604 //添加三个本地和一个远程事务,并确保它们排队 1605 if err := pool.AddLocal(pricedTransaction(0, 100000, big.NewInt(1), local)); err != nil { 1606 t.Fatalf("failed to add local transaction: %v", err) 1607 } 1608 if err := pool.AddLocal(pricedTransaction(1, 100000, big.NewInt(1), local)); err != nil { 1609 t.Fatalf("failed to add local transaction: %v", err) 1610 } 1611 if err := pool.AddLocal(pricedTransaction(2, 100000, big.NewInt(1), local)); err != nil { 1612 t.Fatalf("failed to add local transaction: %v", err) 1613 } 1614 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(1), remote)); err != nil { 1615 t.Fatalf("failed to add remote transaction: %v", err) 1616 } 1617 pending, queued := pool.Stats() 1618 if pending != 4 { 1619 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 4) 1620 } 1621 if queued != 0 { 1622 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) 1623 } 1624 if err := validateTxPoolInternals(pool); err != nil { 1625 t.Fatalf("pool internal state corrupted: %v", err) 1626 } 1627 //终止旧池,触发本地nonce,创建新池并确保相关事务继续存在 1628 pool.Stop() 1629 statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) 1630 blockchain = &testBlockChain{statedb, 1000000, new(event.Feed)} 1631 1632 pool = NewTxPool(config, params.TestChainConfig, blockchain) 1633 1634 pending, queued = pool.Stats() 1635 if queued != 0 { 1636 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) 1637 } 1638 if nolocals { 1639 if pending != 0 { 1640 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) 1641 } 1642 } else { 1643 if pending != 2 { 1644 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) 1645 } 1646 } 1647 if err := validateTxPoolInternals(pool); err != nil { 1648 t.Fatalf("pool internal state corrupted: %v", err) 1649 } 1650 //临时触发nonce并确保删除新失效的事务 1651 statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 2) 1652 pool.lockedReset(nil, nil) 1653 time.Sleep(2 * config.Rejournal) 1654 pool.Stop() 1655 1656 statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) 1657 blockchain = &testBlockChain{statedb, 1000000, new(event.Feed)} 1658 pool = NewTxPool(config, params.TestChainConfig, blockchain) 1659 1660 pending, queued = pool.Stats() 1661 if pending != 0 { 1662 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) 1663 } 1664 if nolocals { 1665 if queued != 0 { 1666 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) 1667 } 1668 } else { 1669 if queued != 1 { 1670 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) 1671 } 1672 } 1673 if err := validateTxPoolInternals(pool); err != nil { 1674 t.Fatalf("pool internal state corrupted: %v", err) 1675 } 1676 pool.Stop() 1677 } 1678 1679 //TestTransactionStatusCheck测试池是否可以正确检索 1680 //单个交易的挂起状态。 1681 func TestTransactionStatusCheck(t *testing.T) { 1682 t.Parallel() 1683 1684 //创建池以测试状态检索 1685 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1686 blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} 1687 1688 pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 1689 defer pool.Stop() 1690 1691 //创建用于检查各种交易状态的测试帐户 1692 keys := make([]*ecdsa.PrivateKey, 3) 1693 for i := 0; i < len(keys); i++ { 1694 keys[i], _ = crypto.GenerateKey() 1695 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) 1696 } 1697 //生成并排队一批事务,包括挂起和排队事务 1698 txs := types.Transactions{} 1699 1700 txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[0])) //未决 1701 txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[1])) //挂起并排队 1702 txs = append(txs, pricedTransaction(2, 100000, big.NewInt(1), keys[1])) 1703 txs = append(txs, pricedTransaction(2, 100000, big.NewInt(1), keys[2])) //仅排队 1704 1705 //导入事务并确保正确添加它们 1706 pool.AddRemotes(txs) 1707 1708 pending, queued := pool.Stats() 1709 if pending != 2 { 1710 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) 1711 } 1712 if queued != 2 { 1713 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) 1714 } 1715 if err := validateTxPoolInternals(pool); err != nil { 1716 t.Fatalf("pool internal state corrupted: %v", err) 1717 } 1718 //检索每个事务的状态并验证它们 1719 hashes := make([]common.Hash, len(txs)) 1720 for i, tx := range txs { 1721 hashes[i] = tx.Hash() 1722 } 1723 hashes = append(hashes, common.Hash{}) 1724 1725 statuses := pool.Status(hashes) 1726 expect := []TxStatus{TxStatusPending, TxStatusPending, TxStatusQueued, TxStatusQueued, TxStatusUnknown} 1727 1728 for i := 0; i < len(statuses); i++ { 1729 if statuses[i] != expect[i] { 1730 t.Errorf("transaction %d: status mismatch: have %v, want %v", i, statuses[i], expect[i]) 1731 } 1732 } 1733 } 1734 1735 //基准测试验证挂起队列的内容的速度 1736 //事务池。 1737 func BenchmarkPendingDemotion100(b *testing.B) { benchmarkPendingDemotion(b, 100) } 1738 func BenchmarkPendingDemotion1000(b *testing.B) { benchmarkPendingDemotion(b, 1000) } 1739 func BenchmarkPendingDemotion10000(b *testing.B) { benchmarkPendingDemotion(b, 10000) } 1740 1741 func benchmarkPendingDemotion(b *testing.B, size int) { 1742 //将一批事务逐个添加到池中 1743 pool, key := setupTxPool() 1744 defer pool.Stop() 1745 1746 account, _ := deriveSender(transaction(0, 0, key)) 1747 pool.currentState.AddBalance(account, big.NewInt(1000000)) 1748 1749 for i := 0; i < size; i++ { 1750 tx := transaction(uint64(i), 100000, key) 1751 pool.promoteTx(account, tx.Hash(), tx) 1752 } 1753 //基准池验证速度 1754 b.ResetTimer() 1755 for i := 0; i < b.N; i++ { 1756 pool.demoteUnexecutables() 1757 } 1758 } 1759 1760 //基准调度未来队列内容的速度 1761 //事务池。 1762 func BenchmarkFuturePromotion100(b *testing.B) { benchmarkFuturePromotion(b, 100) } 1763 func BenchmarkFuturePromotion1000(b *testing.B) { benchmarkFuturePromotion(b, 1000) } 1764 func BenchmarkFuturePromotion10000(b *testing.B) { benchmarkFuturePromotion(b, 10000) } 1765 1766 func benchmarkFuturePromotion(b *testing.B, size int) { 1767 //将一批事务逐个添加到池中 1768 pool, key := setupTxPool() 1769 defer pool.Stop() 1770 1771 account, _ := deriveSender(transaction(0, 0, key)) 1772 pool.currentState.AddBalance(account, big.NewInt(1000000)) 1773 1774 for i := 0; i < size; i++ { 1775 tx := transaction(uint64(1+i), 100000, key) 1776 pool.enqueueTx(tx.Hash(), tx) 1777 } 1778 //基准池验证速度 1779 b.ResetTimer() 1780 for i := 0; i < b.N; i++ { 1781 pool.promoteExecutables(nil) 1782 } 1783 } 1784 1785 //测试迭代事务插入的速度。 1786 func BenchmarkPoolInsert(b *testing.B) { 1787 //生成一批要排队进入池的事务 1788 pool, key := setupTxPool() 1789 defer pool.Stop() 1790 1791 account, _ := deriveSender(transaction(0, 0, key)) 1792 pool.currentState.AddBalance(account, big.NewInt(1000000)) 1793 1794 txs := make(types.Transactions, b.N) 1795 for i := 0; i < b.N; i++ { 1796 txs[i] = transaction(uint64(i), 100000, key) 1797 } 1798 //将事务导入队列的基准 1799 b.ResetTimer() 1800 for _, tx := range txs { 1801 pool.AddRemote(tx) 1802 } 1803 } 1804 1805 //对批量事务插入的速度进行基准测试。 1806 func BenchmarkPoolBatchInsert100(b *testing.B) { benchmarkPoolBatchInsert(b, 100) } 1807 func BenchmarkPoolBatchInsert1000(b *testing.B) { benchmarkPoolBatchInsert(b, 1000) } 1808 func BenchmarkPoolBatchInsert10000(b *testing.B) { benchmarkPoolBatchInsert(b, 10000) } 1809 1810 func benchmarkPoolBatchInsert(b *testing.B, size int) { 1811 //生成一批要排队进入池的事务 1812 pool, key := setupTxPool() 1813 defer pool.Stop() 1814 1815 account, _ := deriveSender(transaction(0, 0, key)) 1816 pool.currentState.AddBalance(account, big.NewInt(1000000)) 1817 1818 batches := make([]types.Transactions, b.N) 1819 for i := 0; i < b.N; i++ { 1820 batches[i] = make(types.Transactions, size) 1821 for j := 0; j < size; j++ { 1822 batches[i][j] = transaction(uint64(size*i+j), 100000, key) 1823 } 1824 } 1825 //将事务导入队列的基准 1826 b.ResetTimer() 1827 for _, batch := range batches { 1828 pool.AddRemotes(batch) 1829 } 1830 } 1831