github.com/halybang/go-ethereum@v1.0.5-0.20180325041310-3b262bc1367c/core/tx_pool_test.go (about) 1 // Copyright 2018 Wanchain Foundation Ltd 2 // Copyright 2015 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 18 package core 19 20 import ( 21 "crypto/ecdsa" 22 "fmt" 23 "io/ioutil" 24 "math/big" 25 "math/rand" 26 "os" 27 "testing" 28 "time" 29 30 "bytes" 31 32 "github.com/wanchain/go-wanchain/common" 33 "github.com/wanchain/go-wanchain/core/state" 34 "github.com/wanchain/go-wanchain/core/types" 35 "github.com/wanchain/go-wanchain/core/vm" 36 "github.com/wanchain/go-wanchain/crypto" 37 "github.com/wanchain/go-wanchain/ethdb" 38 "github.com/wanchain/go-wanchain/event" 39 "github.com/wanchain/go-wanchain/params" 40 ) 41 42 // testTxPoolConfig is a transaction pool configuration without stateful disk 43 // sideeffects used during testing. 44 var testTxPoolConfig TxPoolConfig 45 46 func init() { 47 testTxPoolConfig = DefaultTxPoolConfig 48 testTxPoolConfig.Journal = "" 49 } 50 51 type testBlockChain struct { 52 statedb *state.StateDB 53 gasLimit *big.Int 54 chainHeadFeed *event.Feed 55 } 56 57 func (bc *testBlockChain) CurrentBlock() *types.Block { 58 return types.NewBlock(&types.Header{ 59 GasLimit: bc.gasLimit, 60 }, nil, nil, nil) 61 } 62 63 func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { 64 return bc.CurrentBlock() 65 } 66 67 func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) { 68 return bc.statedb, nil 69 } 70 71 func (bc *testBlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription { 72 return bc.chainHeadFeed.Subscribe(ch) 73 } 74 75 func transaction(nonce uint64, gaslimit *big.Int, key *ecdsa.PrivateKey) *types.Transaction { 76 return pricedTransaction(nonce, gaslimit, big.NewInt(1), key) 77 } 78 79 func pricedTransaction(nonce uint64, gaslimit, gasprice *big.Int, key *ecdsa.PrivateKey) *types.Transaction { 80 tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(100), gaslimit, gasprice, nil), types.HomesteadSigner{}, key) 81 return tx 82 } 83 84 func setupTxPool() (*TxPool, *ecdsa.PrivateKey) { 85 db, _ := ethdb.NewMemDatabase() 86 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 87 blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} 88 89 key, _ := crypto.GenerateKey() 90 pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 91 92 return pool, key 93 } 94 95 // validateTxPoolInternals checks various consistency invariants within the pool. 96 func validateTxPoolInternals(pool *TxPool) error { 97 pool.mu.RLock() 98 defer pool.mu.RUnlock() 99 100 // Ensure the total transaction set is consistent with pending + queued 101 pending, queued := pool.stats() 102 if total := len(pool.all); total != pending+queued { 103 return fmt.Errorf("total transaction count %d != %d pending + %d queued", total, pending, queued) 104 } 105 if priced := pool.priced.items.Len() - pool.priced.stales; priced != pending+queued { 106 return fmt.Errorf("total priced transaction count %d != %d pending + %d queued", priced, pending, queued) 107 } 108 // Ensure the next nonce to assign is the correct one 109 for addr, txs := range pool.pending { 110 // Find the last transaction 111 var last uint64 112 for nonce, _ := range txs.txs.items { 113 if last < nonce { 114 last = nonce 115 } 116 } 117 if nonce := pool.pendingState.GetNonce(addr); nonce != last+1 { 118 return fmt.Errorf("pending nonce mismatch: have %v, want %v", nonce, last+1) 119 } 120 } 121 return nil 122 } 123 124 func deriveSender(tx *types.Transaction) (common.Address, error) { 125 return types.Sender(types.HomesteadSigner{}, tx) 126 } 127 128 type testChain struct { 129 *testBlockChain 130 address common.Address 131 trigger *bool 132 } 133 134 // testChain.State() is used multiple times to reset the pending state. 135 // when simulate is true it will create a state that indicates 136 // that tx0 and tx1 are included in the chain. 137 func (c *testChain) State() (*state.StateDB, error) { 138 // delay "state change" by one. The tx pool fetches the 139 // state multiple times and by delaying it a bit we simulate 140 // a state change between those fetches. 141 stdb := c.statedb 142 if *c.trigger { 143 db, _ := ethdb.NewMemDatabase() 144 c.statedb, _ = state.New(common.Hash{}, state.NewDatabase(db)) 145 // simulate that the new head block included tx0 and tx1 146 c.statedb.SetNonce(c.address, 2) 147 c.statedb.SetBalance(c.address, new(big.Int).SetUint64(params.Wan)) 148 *c.trigger = false 149 } 150 return stdb, nil 151 } 152 153 // This test simulates a scenario where a new block is imported during a 154 // state reset and tests whether the pending state is in sync with the 155 // block head event that initiated the resetState(). 156 func TestStateChangeDuringPoolReset(t *testing.T) { 157 var ( 158 db, _ = ethdb.NewMemDatabase() 159 key, _ = crypto.GenerateKey() 160 address = crypto.PubkeyToAddress(key.PublicKey) 161 statedb, _ = state.New(common.Hash{}, state.NewDatabase(db)) 162 trigger = false 163 ) 164 165 // setup pool with 2 transaction in it 166 statedb.SetBalance(address, new(big.Int).SetUint64(params.Wan)) 167 blockchain := &testChain{&testBlockChain{statedb, big.NewInt(1000000000), new(event.Feed)}, address, &trigger} 168 169 tx0 := transaction(0, big.NewInt(100000), key) 170 tx1 := transaction(1, big.NewInt(100000), key) 171 172 pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 173 defer pool.Stop() 174 175 nonce := pool.State().GetNonce(address) 176 if nonce != 0 { 177 t.Fatalf("Invalid nonce, want 0, got %d", nonce) 178 } 179 180 pool.AddRemotes(types.Transactions{tx0, tx1}) 181 182 nonce = pool.State().GetNonce(address) 183 if nonce != 2 { 184 t.Fatalf("Invalid nonce, want 2, got %d", nonce) 185 } 186 187 // trigger state change in the background 188 trigger = true 189 190 pool.lockedReset(nil, nil) 191 192 pendingTx, err := pool.Pending() 193 if err != nil { 194 t.Fatalf("Could not fetch pending transactions: %v", err) 195 } 196 197 for addr, txs := range pendingTx { 198 t.Logf("%0x: %d\n", addr, len(txs)) 199 } 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 func TestInvalidTransactions(t *testing.T) { 208 pool, key := setupTxPool() 209 defer pool.Stop() 210 211 tx := transaction(0, big.NewInt(100), key) 212 from, _ := deriveSender(tx) 213 214 pool.currentState.AddBalance(from, big.NewInt(1)) 215 if err := pool.AddRemote(tx); err != ErrInsufficientFunds { 216 t.Error("expected", ErrInsufficientFunds) 217 } 218 219 balance := new(big.Int).Add(tx.Value(), new(big.Int).Mul(tx.Gas(), tx.GasPrice())) 220 pool.currentState.AddBalance(from, balance) 221 if err := pool.AddRemote(tx); err != ErrIntrinsicGas { 222 t.Error("expected", ErrIntrinsicGas, "got", err) 223 } 224 225 pool.currentState.SetNonce(from, 1) 226 pool.currentState.AddBalance(from, big.NewInt(0xffffffffffffff)) 227 tx = transaction(0, big.NewInt(100000), key) 228 if err := pool.AddRemote(tx); err != ErrNonceTooLow { 229 t.Error("expected", ErrNonceTooLow) 230 } 231 232 tx = transaction(1, big.NewInt(100000), key) 233 pool.gasPrice = big.NewInt(1000) 234 if err := pool.AddRemote(tx); err != ErrUnderpriced { 235 t.Error("expected", ErrUnderpriced, "got", err) 236 } 237 if err := pool.AddLocal(tx); err != nil { 238 t.Error("expected", nil, "got", err) 239 } 240 } 241 242 func TestTransactionQueue(t *testing.T) { 243 pool, key := setupTxPool() 244 defer pool.Stop() 245 246 tx := transaction(0, big.NewInt(100), key) 247 from, _ := deriveSender(tx) 248 pool.currentState.AddBalance(from, big.NewInt(1000)) 249 pool.lockedReset(nil, nil) 250 pool.enqueueTx(tx.Hash(), tx) 251 252 pool.promoteExecutables([]common.Address{from}) 253 if len(pool.pending) != 1 { 254 t.Error("expected valid txs to be 1 is", len(pool.pending)) 255 } 256 257 tx = transaction(1, big.NewInt(100), key) 258 from, _ = deriveSender(tx) 259 pool.currentState.SetNonce(from, 2) 260 pool.enqueueTx(tx.Hash(), tx) 261 pool.promoteExecutables([]common.Address{from}) 262 if _, ok := pool.pending[from].txs.items[tx.Nonce()]; ok { 263 t.Error("expected transaction to be in tx pool") 264 } 265 266 if len(pool.queue) > 0 { 267 t.Error("expected transaction queue to be empty. is", len(pool.queue)) 268 } 269 270 pool, key = setupTxPool() 271 defer pool.Stop() 272 273 tx1 := transaction(0, big.NewInt(100), key) 274 tx2 := transaction(10, big.NewInt(100), key) 275 tx3 := transaction(11, big.NewInt(100), key) 276 from, _ = deriveSender(tx1) 277 pool.currentState.AddBalance(from, big.NewInt(1000)) 278 pool.lockedReset(nil, nil) 279 280 pool.enqueueTx(tx1.Hash(), tx1) 281 pool.enqueueTx(tx2.Hash(), tx2) 282 pool.enqueueTx(tx3.Hash(), tx3) 283 284 pool.promoteExecutables([]common.Address{from}) 285 286 if len(pool.pending) != 1 { 287 t.Error("expected tx pool to be 1, got", len(pool.pending)) 288 } 289 if pool.queue[from].Len() != 2 { 290 t.Error("expected len(queue) == 2, got", pool.queue[from].Len()) 291 } 292 } 293 294 func TestNegativeValue(t *testing.T) { 295 pool, key := setupTxPool() 296 defer pool.Stop() 297 298 tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(-1), big.NewInt(100), big.NewInt(1), nil), types.HomesteadSigner{}, key) 299 from, _ := deriveSender(tx) 300 pool.currentState.AddBalance(from, big.NewInt(1)) 301 if err := pool.AddRemote(tx); err != ErrNegativeValue { 302 t.Error("expected", ErrNegativeValue, "got", err) 303 } 304 } 305 306 func TestTransactionChainFork(t *testing.T) { 307 pool, key := setupTxPool() 308 defer pool.Stop() 309 310 addr := crypto.PubkeyToAddress(key.PublicKey) 311 resetState := func() { 312 db, _ := ethdb.NewMemDatabase() 313 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 314 statedb.AddBalance(addr, big.NewInt(100000000000000)) 315 316 pool.chain = &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} 317 pool.lockedReset(nil, nil) 318 } 319 resetState() 320 321 tx := transaction(0, big.NewInt(100000), key) 322 if _, err := pool.add(tx, false); err != nil { 323 t.Error("didn't expect error", err) 324 } 325 pool.removeTx(tx.Hash()) 326 327 // reset the pool's internal state 328 resetState() 329 if _, err := pool.add(tx, false); err != nil { 330 t.Error("didn't expect error", err) 331 } 332 } 333 334 func TestTransactionDoubleNonce(t *testing.T) { 335 pool, key := setupTxPool() 336 defer pool.Stop() 337 338 addr := crypto.PubkeyToAddress(key.PublicKey) 339 resetState := func() { 340 db, _ := ethdb.NewMemDatabase() 341 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 342 statedb.AddBalance(addr, big.NewInt(100000000000000)) 343 344 pool.chain = &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} 345 pool.lockedReset(nil, nil) 346 } 347 resetState() 348 349 signer := types.HomesteadSigner{} 350 tx1, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), big.NewInt(100000), big.NewInt(1), nil), signer, key) 351 tx2, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), big.NewInt(1000000), big.NewInt(2), nil), signer, key) 352 tx3, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), big.NewInt(1000000), big.NewInt(1), nil), signer, key) 353 354 // Add the first two transaction, ensure higher priced stays only 355 if replace, err := pool.add(tx1, false); err != nil || replace { 356 t.Errorf("first transaction insert failed (%v) or reported replacement (%v)", err, replace) 357 } 358 if replace, err := pool.add(tx2, false); err != nil || !replace { 359 t.Errorf("second transaction insert failed (%v) or not reported replacement (%v)", err, replace) 360 } 361 pool.promoteExecutables([]common.Address{addr}) 362 if pool.pending[addr].Len() != 1 { 363 t.Error("expected 1 pending transactions, got", pool.pending[addr].Len()) 364 } 365 if tx := pool.pending[addr].txs.items[0]; tx.Hash() != tx2.Hash() { 366 t.Errorf("transaction mismatch: have %x, want %x", tx.Hash(), tx2.Hash()) 367 } 368 // Add the third transaction and ensure it's not saved (smaller price) 369 pool.add(tx3, false) 370 pool.promoteExecutables([]common.Address{addr}) 371 if pool.pending[addr].Len() != 1 { 372 t.Error("expected 1 pending transactions, got", pool.pending[addr].Len()) 373 } 374 if tx := pool.pending[addr].txs.items[0]; tx.Hash() != tx2.Hash() { 375 t.Errorf("transaction mismatch: have %x, want %x", tx.Hash(), tx2.Hash()) 376 } 377 // Ensure the total transaction count is correct 378 if len(pool.all) != 1 { 379 t.Error("expected 1 total transactions, got", len(pool.all)) 380 } 381 } 382 383 func TestMissingNonce(t *testing.T) { 384 pool, key := setupTxPool() 385 defer pool.Stop() 386 387 addr := crypto.PubkeyToAddress(key.PublicKey) 388 pool.currentState.AddBalance(addr, big.NewInt(100000000000000)) 389 tx := transaction(1, big.NewInt(100000), key) 390 if _, err := pool.add(tx, false); err != nil { 391 t.Error("didn't expect error", err) 392 } 393 if len(pool.pending) != 0 { 394 t.Error("expected 0 pending transactions, got", len(pool.pending)) 395 } 396 if pool.queue[addr].Len() != 1 { 397 t.Error("expected 1 queued transaction, got", pool.queue[addr].Len()) 398 } 399 if len(pool.all) != 1 { 400 t.Error("expected 1 total transactions, got", len(pool.all)) 401 } 402 } 403 404 func TestTransactionNonceRecovery(t *testing.T) { 405 const n = 10 406 pool, key := setupTxPool() 407 defer pool.Stop() 408 409 addr := crypto.PubkeyToAddress(key.PublicKey) 410 pool.currentState.SetNonce(addr, n) 411 pool.currentState.AddBalance(addr, big.NewInt(100000000000000)) 412 pool.lockedReset(nil, nil) 413 414 tx := transaction(n, big.NewInt(100000), key) 415 if err := pool.AddRemote(tx); err != nil { 416 t.Error(err) 417 } 418 // simulate some weird re-order of transactions and missing nonce(s) 419 pool.currentState.SetNonce(addr, n-1) 420 pool.lockedReset(nil, nil) 421 if fn := pool.pendingState.GetNonce(addr); fn != n-1 { 422 t.Errorf("expected nonce to be %d, got %d", n-1, fn) 423 } 424 } 425 426 // Tests that if an account runs out of funds, any pending and queued transactions 427 // are dropped. 428 func TestTransactionDropping(t *testing.T) { 429 // Create a test account and fund it 430 pool, key := setupTxPool() 431 defer pool.Stop() 432 433 account, _ := deriveSender(transaction(0, big.NewInt(0), key)) 434 pool.currentState.AddBalance(account, big.NewInt(1000)) 435 436 // Add some pending and some queued transactions 437 var ( 438 tx0 = transaction(0, big.NewInt(100), key) 439 tx1 = transaction(1, big.NewInt(200), key) 440 tx2 = transaction(2, big.NewInt(300), key) 441 tx10 = transaction(10, big.NewInt(100), key) 442 tx11 = transaction(11, big.NewInt(200), key) 443 tx12 = transaction(12, big.NewInt(300), key) 444 ) 445 pool.promoteTx(account, tx0.Hash(), tx0) 446 pool.promoteTx(account, tx1.Hash(), tx1) 447 pool.promoteTx(account, tx2.Hash(), tx2) 448 pool.enqueueTx(tx10.Hash(), tx10) 449 pool.enqueueTx(tx11.Hash(), tx11) 450 pool.enqueueTx(tx12.Hash(), tx12) 451 452 // Check that pre and post validations leave the pool as is 453 if pool.pending[account].Len() != 3 { 454 t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), 3) 455 } 456 if pool.queue[account].Len() != 3 { 457 t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 3) 458 } 459 if len(pool.all) != 6 { 460 t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 6) 461 } 462 pool.lockedReset(nil, nil) 463 if pool.pending[account].Len() != 3 { 464 t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), 3) 465 } 466 if pool.queue[account].Len() != 3 { 467 t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 3) 468 } 469 if len(pool.all) != 6 { 470 t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 6) 471 } 472 // Reduce the balance of the account, and check that invalidated transactions are dropped 473 pool.currentState.SubBalance(account, big.NewInt(650)) 474 pool.lockedReset(nil, nil) 475 476 if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok { 477 t.Errorf("funded pending transaction missing: %v", tx0) 478 } 479 if _, ok := pool.pending[account].txs.items[tx1.Nonce()]; !ok { 480 t.Errorf("funded pending transaction missing: %v", tx0) 481 } 482 if _, ok := pool.pending[account].txs.items[tx2.Nonce()]; ok { 483 t.Errorf("out-of-fund pending transaction present: %v", tx1) 484 } 485 if _, ok := pool.queue[account].txs.items[tx10.Nonce()]; !ok { 486 t.Errorf("funded queued transaction missing: %v", tx10) 487 } 488 if _, ok := pool.queue[account].txs.items[tx11.Nonce()]; !ok { 489 t.Errorf("funded queued transaction missing: %v", tx10) 490 } 491 if _, ok := pool.queue[account].txs.items[tx12.Nonce()]; ok { 492 t.Errorf("out-of-fund queued transaction present: %v", tx11) 493 } 494 if len(pool.all) != 4 { 495 t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 4) 496 } 497 // Reduce the block gas limit, check that invalidated transactions are dropped 498 pool.chain.(*testBlockChain).gasLimit = big.NewInt(100) 499 pool.lockedReset(nil, nil) 500 501 if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok { 502 t.Errorf("funded pending transaction missing: %v", tx0) 503 } 504 if _, ok := pool.pending[account].txs.items[tx1.Nonce()]; ok { 505 t.Errorf("over-gased pending transaction present: %v", tx1) 506 } 507 if _, ok := pool.queue[account].txs.items[tx10.Nonce()]; !ok { 508 t.Errorf("funded queued transaction missing: %v", tx10) 509 } 510 if _, ok := pool.queue[account].txs.items[tx11.Nonce()]; ok { 511 t.Errorf("over-gased queued transaction present: %v", tx11) 512 } 513 if len(pool.all) != 2 { 514 t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 2) 515 } 516 } 517 518 // Tests that if a transaction is dropped from the current pending pool (e.g. out 519 // of fund), all consecutive (still valid, but not executable) transactions are 520 // postponed back into the future queue to prevent broadcasting them. 521 func TestTransactionPostponing(t *testing.T) { 522 // Create a test account and fund it 523 pool, key := setupTxPool() 524 defer pool.Stop() 525 526 account, _ := deriveSender(transaction(0, big.NewInt(0), key)) 527 pool.currentState.AddBalance(account, big.NewInt(1000)) 528 529 // Add a batch consecutive pending transactions for validation 530 txns := []*types.Transaction{} 531 for i := 0; i < 100; i++ { 532 var tx *types.Transaction 533 if i%2 == 0 { 534 tx = transaction(uint64(i), big.NewInt(100), key) 535 } else { 536 tx = transaction(uint64(i), big.NewInt(500), key) 537 } 538 pool.promoteTx(account, tx.Hash(), tx) 539 txns = append(txns, tx) 540 } 541 // Check that pre and post validations leave the pool as is 542 if pool.pending[account].Len() != len(txns) { 543 t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), len(txns)) 544 } 545 if len(pool.queue) != 0 { 546 t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 0) 547 } 548 if len(pool.all) != len(txns) { 549 t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), len(txns)) 550 } 551 pool.lockedReset(nil, nil) 552 if pool.pending[account].Len() != len(txns) { 553 t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), len(txns)) 554 } 555 if len(pool.queue) != 0 { 556 t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 0) 557 } 558 if len(pool.all) != len(txns) { 559 t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), len(txns)) 560 } 561 // Reduce the balance of the account, and check that transactions are reorganised 562 pool.currentState.SubBalance(account, big.NewInt(750)) 563 pool.lockedReset(nil, nil) 564 565 if _, ok := pool.pending[account].txs.items[txns[0].Nonce()]; !ok { 566 t.Errorf("tx %d: valid and funded transaction missing from pending pool: %v", 0, txns[0]) 567 } 568 if _, ok := pool.queue[account].txs.items[txns[0].Nonce()]; ok { 569 t.Errorf("tx %d: valid and funded transaction present in future queue: %v", 0, txns[0]) 570 } 571 for i, tx := range txns[1:] { 572 if i%2 == 1 { 573 if _, ok := pool.pending[account].txs.items[tx.Nonce()]; ok { 574 t.Errorf("tx %d: valid but future transaction present in pending pool: %v", i+1, tx) 575 } 576 if _, ok := pool.queue[account].txs.items[tx.Nonce()]; !ok { 577 t.Errorf("tx %d: valid but future transaction missing from future queue: %v", i+1, tx) 578 } 579 } else { 580 if _, ok := pool.pending[account].txs.items[tx.Nonce()]; ok { 581 t.Errorf("tx %d: out-of-fund transaction present in pending pool: %v", i+1, tx) 582 } 583 if _, ok := pool.queue[account].txs.items[tx.Nonce()]; ok { 584 t.Errorf("tx %d: out-of-fund transaction present in future queue: %v", i+1, tx) 585 } 586 } 587 } 588 if len(pool.all) != len(txns)/2 { 589 t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), len(txns)/2) 590 } 591 } 592 593 // Tests that if the transaction count belonging to a single account goes above 594 // some threshold, the higher transactions are dropped to prevent DOS attacks. 595 func TestTransactionQueueAccountLimiting(t *testing.T) { 596 // Create a test account and fund it 597 pool, key := setupTxPool() 598 defer pool.Stop() 599 600 account, _ := deriveSender(transaction(0, big.NewInt(0), key)) 601 pool.currentState.AddBalance(account, big.NewInt(1000000)) 602 603 // Keep queuing up transactions and make sure all above a limit are dropped 604 for i := uint64(1); i <= testTxPoolConfig.AccountQueue+5; i++ { 605 if err := pool.AddRemote(transaction(i, big.NewInt(100000), key)); err != nil { 606 t.Fatalf("tx %d: failed to add transaction: %v", i, err) 607 } 608 if len(pool.pending) != 0 { 609 t.Errorf("tx %d: pending pool size mismatch: have %d, want %d", i, len(pool.pending), 0) 610 } 611 if i <= testTxPoolConfig.AccountQueue { 612 if pool.queue[account].Len() != int(i) { 613 t.Errorf("tx %d: queue size mismatch: have %d, want %d", i, pool.queue[account].Len(), i) 614 } 615 } else { 616 if pool.queue[account].Len() != int(testTxPoolConfig.AccountQueue) { 617 t.Errorf("tx %d: queue limit mismatch: have %d, want %d", i, pool.queue[account].Len(), testTxPoolConfig.AccountQueue) 618 } 619 } 620 } 621 if len(pool.all) != int(testTxPoolConfig.AccountQueue) { 622 t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), testTxPoolConfig.AccountQueue) 623 } 624 } 625 626 // Tests that if the transaction count belonging to multiple accounts go above 627 // some threshold, the higher transactions are dropped to prevent DOS attacks. 628 // 629 // This logic should not hold for local transactions, unless the local tracking 630 // mechanism is disabled. 631 func TestTransactionQueueGlobalLimiting(t *testing.T) { 632 testTransactionQueueGlobalLimiting(t, false) 633 } 634 func TestTransactionQueueGlobalLimitingNoLocals(t *testing.T) { 635 testTransactionQueueGlobalLimiting(t, true) 636 } 637 638 func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) { 639 // Create the pool to test the limit enforcement with 640 db, _ := ethdb.NewMemDatabase() 641 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 642 blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} 643 644 config := testTxPoolConfig 645 config.NoLocals = nolocals 646 config.GlobalQueue = config.AccountQueue*3 - 1 // reduce the queue limits to shorten test time (-1 to make it non divisible) 647 648 pool := NewTxPool(config, params.TestChainConfig, blockchain) 649 defer pool.Stop() 650 651 // Create a number of test accounts and fund them (last one will be the local) 652 keys := make([]*ecdsa.PrivateKey, 5) 653 for i := 0; i < len(keys); i++ { 654 keys[i], _ = crypto.GenerateKey() 655 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) 656 } 657 local := keys[len(keys)-1] 658 659 // Generate and queue a batch of transactions 660 nonces := make(map[common.Address]uint64) 661 662 txs := make(types.Transactions, 0, 3*config.GlobalQueue) 663 for len(txs) < cap(txs) { 664 key := keys[rand.Intn(len(keys)-1)] // skip adding transactions with the local account 665 addr := crypto.PubkeyToAddress(key.PublicKey) 666 667 txs = append(txs, transaction(nonces[addr]+1, big.NewInt(100000), key)) 668 nonces[addr]++ 669 } 670 // Import the batch and verify that limits have been enforced 671 pool.AddRemotes(txs) 672 673 queued := 0 674 for addr, list := range pool.queue { 675 if list.Len() > int(config.AccountQueue) { 676 t.Errorf("addr %x: queued accounts overflown allowance: %d > %d", addr, list.Len(), config.AccountQueue) 677 } 678 queued += list.Len() 679 } 680 if queued > int(config.GlobalQueue) { 681 t.Fatalf("total transactions overflow allowance: %d > %d", queued, config.GlobalQueue) 682 } 683 // Generate a batch of transactions from the local account and import them 684 txs = txs[:0] 685 for i := uint64(0); i < 3*config.GlobalQueue; i++ { 686 txs = append(txs, transaction(i+1, big.NewInt(100000), local)) 687 } 688 pool.AddLocals(txs) 689 690 // If locals are disabled, the previous eviction algorithm should apply here too 691 if nolocals { 692 queued := 0 693 for addr, list := range pool.queue { 694 if list.Len() > int(config.AccountQueue) { 695 t.Errorf("addr %x: queued accounts overflown allowance: %d > %d", addr, list.Len(), config.AccountQueue) 696 } 697 queued += list.Len() 698 } 699 if queued > int(config.GlobalQueue) { 700 t.Fatalf("total transactions overflow allowance: %d > %d", queued, config.GlobalQueue) 701 } 702 } else { 703 // Local exemptions are enabled, make sure the local account owned the queue 704 if len(pool.queue) != 1 { 705 t.Errorf("multiple accounts in queue: have %v, want %v", len(pool.queue), 1) 706 } 707 // Also ensure no local transactions are ever dropped, even if above global limits 708 if queued := pool.queue[crypto.PubkeyToAddress(local.PublicKey)].Len(); uint64(queued) != 3*config.GlobalQueue { 709 t.Fatalf("local account queued transaction count mismatch: have %v, want %v", queued, 3*config.GlobalQueue) 710 } 711 } 712 } 713 714 // Tests that if an account remains idle for a prolonged amount of time, any 715 // non-executable transactions queued up are dropped to prevent wasting resources 716 // on shuffling them around. 717 // 718 // This logic should not hold for local transactions, unless the local tracking 719 // mechanism is disabled. 720 func TestTransactionQueueTimeLimiting(t *testing.T) { testTransactionQueueTimeLimiting(t, false) } 721 func TestTransactionQueueTimeLimitingNoLocals(t *testing.T) { testTransactionQueueTimeLimiting(t, true) } 722 723 func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { 724 // Reduce the eviction interval to a testable amount 725 defer func(old time.Duration) { evictionInterval = old }(evictionInterval) 726 evictionInterval = time.Second 727 728 // Create the pool to test the non-expiration enforcement 729 db, _ := ethdb.NewMemDatabase() 730 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 731 blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} 732 733 config := testTxPoolConfig 734 config.Lifetime = time.Second 735 config.NoLocals = nolocals 736 737 pool := NewTxPool(config, params.TestChainConfig, blockchain) 738 defer pool.Stop() 739 740 // Create two test accounts to ensure remotes expire but locals do not 741 local, _ := crypto.GenerateKey() 742 remote, _ := crypto.GenerateKey() 743 744 pool.currentState.AddBalance(crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000)) 745 pool.currentState.AddBalance(crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000)) 746 747 // Add the two transactions and ensure they both are queued up 748 if err := pool.AddLocal(pricedTransaction(1, big.NewInt(100000), big.NewInt(1), local)); err != nil { 749 t.Fatalf("failed to add local transaction: %v", err) 750 } 751 if err := pool.AddRemote(pricedTransaction(1, big.NewInt(100000), big.NewInt(1), remote)); err != nil { 752 t.Fatalf("failed to add remote transaction: %v", err) 753 } 754 pending, queued := pool.Stats() 755 if pending != 0 { 756 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) 757 } 758 if queued != 2 { 759 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) 760 } 761 if err := validateTxPoolInternals(pool); err != nil { 762 t.Fatalf("pool internal state corrupted: %v", err) 763 } 764 // Wait a bit for eviction to run and clean up any leftovers, and ensure only the local remains 765 time.Sleep(2 * config.Lifetime) 766 767 pending, queued = pool.Stats() 768 if pending != 0 { 769 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) 770 } 771 if nolocals { 772 if queued != 0 { 773 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) 774 } 775 } else { 776 if queued != 1 { 777 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) 778 } 779 } 780 if err := validateTxPoolInternals(pool); err != nil { 781 t.Fatalf("pool internal state corrupted: %v", err) 782 } 783 } 784 785 // Tests that even if the transaction count belonging to a single account goes 786 // above some threshold, as long as the transactions are executable, they are 787 // accepted. 788 func TestTransactionPendingLimiting(t *testing.T) { 789 // Create a test account and fund it 790 pool, key := setupTxPool() 791 defer pool.Stop() 792 793 account, _ := deriveSender(transaction(0, big.NewInt(0), key)) 794 pool.currentState.AddBalance(account, big.NewInt(1000000)) 795 796 // Keep queuing up transactions and make sure all above a limit are dropped 797 for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ { 798 if err := pool.AddRemote(transaction(i, big.NewInt(100000), key)); err != nil { 799 t.Fatalf("tx %d: failed to add transaction: %v", i, err) 800 } 801 if pool.pending[account].Len() != int(i)+1 { 802 t.Errorf("tx %d: pending pool size mismatch: have %d, want %d", i, pool.pending[account].Len(), i+1) 803 } 804 if len(pool.queue) != 0 { 805 t.Errorf("tx %d: queue size mismatch: have %d, want %d", i, pool.queue[account].Len(), 0) 806 } 807 } 808 if len(pool.all) != int(testTxPoolConfig.AccountQueue+5) { 809 t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), testTxPoolConfig.AccountQueue+5) 810 } 811 } 812 813 // Tests that the transaction limits are enforced the same way irrelevant whether 814 // the transactions are added one by one or in batches. 815 func TestTransactionQueueLimitingEquivalency(t *testing.T) { testTransactionLimitingEquivalency(t, 1) } 816 func TestTransactionPendingLimitingEquivalency(t *testing.T) { testTransactionLimitingEquivalency(t, 0) } 817 818 func testTransactionLimitingEquivalency(t *testing.T, origin uint64) { 819 // Add a batch of transactions to a pool one by one 820 pool1, key1 := setupTxPool() 821 defer pool1.Stop() 822 823 account1, _ := deriveSender(transaction(0, big.NewInt(0), key1)) 824 pool1.currentState.AddBalance(account1, big.NewInt(1000000)) 825 826 for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ { 827 if err := pool1.AddRemote(transaction(origin+i, big.NewInt(100000), key1)); err != nil { 828 t.Fatalf("tx %d: failed to add transaction: %v", i, err) 829 } 830 } 831 // Add a batch of transactions to a pool in one big batch 832 pool2, key2 := setupTxPool() 833 defer pool2.Stop() 834 835 account2, _ := deriveSender(transaction(0, big.NewInt(0), key2)) 836 pool2.currentState.AddBalance(account2, big.NewInt(1000000)) 837 838 txns := []*types.Transaction{} 839 for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ { 840 txns = append(txns, transaction(origin+i, big.NewInt(100000), key2)) 841 } 842 pool2.AddRemotes(txns) 843 844 // Ensure the batch optimization honors the same pool mechanics 845 if len(pool1.pending) != len(pool2.pending) { 846 t.Errorf("pending transaction count mismatch: one-by-one algo: %d, batch algo: %d", len(pool1.pending), len(pool2.pending)) 847 } 848 if len(pool1.queue) != len(pool2.queue) { 849 t.Errorf("queued transaction count mismatch: one-by-one algo: %d, batch algo: %d", len(pool1.queue), len(pool2.queue)) 850 } 851 if len(pool1.all) != len(pool2.all) { 852 t.Errorf("total transaction count mismatch: one-by-one algo %d, batch algo %d", len(pool1.all), len(pool2.all)) 853 } 854 if err := validateTxPoolInternals(pool1); err != nil { 855 t.Errorf("pool 1 internal state corrupted: %v", err) 856 } 857 if err := validateTxPoolInternals(pool2); err != nil { 858 t.Errorf("pool 2 internal state corrupted: %v", err) 859 } 860 } 861 862 // Tests that if the transaction count belonging to multiple accounts go above 863 // some hard threshold, the higher transactions are dropped to prevent DOS 864 // attacks. 865 func TestTransactionPendingGlobalLimiting(t *testing.T) { 866 // Create the pool to test the limit enforcement with 867 db, _ := ethdb.NewMemDatabase() 868 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 869 blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} 870 871 config := testTxPoolConfig 872 config.GlobalSlots = config.AccountSlots * 10 873 874 pool := NewTxPool(config, params.TestChainConfig, blockchain) 875 defer pool.Stop() 876 877 // Create a number of test accounts and fund them 878 keys := make([]*ecdsa.PrivateKey, 5) 879 for i := 0; i < len(keys); i++ { 880 keys[i], _ = crypto.GenerateKey() 881 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) 882 } 883 // Generate and queue a batch of transactions 884 nonces := make(map[common.Address]uint64) 885 886 txs := types.Transactions{} 887 for _, key := range keys { 888 addr := crypto.PubkeyToAddress(key.PublicKey) 889 for j := 0; j < int(config.GlobalSlots)/len(keys)*2; j++ { 890 txs = append(txs, transaction(nonces[addr], big.NewInt(100000), key)) 891 nonces[addr]++ 892 } 893 } 894 // Import the batch and verify that limits have been enforced 895 pool.AddRemotes(txs) 896 897 pending := 0 898 for _, list := range pool.pending { 899 pending += list.Len() 900 } 901 if pending > int(config.GlobalSlots) { 902 t.Fatalf("total pending transactions overflow allowance: %d > %d", pending, config.GlobalSlots) 903 } 904 if err := validateTxPoolInternals(pool); err != nil { 905 t.Fatalf("pool internal state corrupted: %v", err) 906 } 907 } 908 909 // Tests that if transactions start being capped, transactions are also removed from 'all' 910 func TestTransactionCapClearsFromAll(t *testing.T) { 911 // Create the pool to test the limit enforcement with 912 db, _ := ethdb.NewMemDatabase() 913 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 914 blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} 915 916 config := testTxPoolConfig 917 config.AccountSlots = 2 918 config.AccountQueue = 2 919 config.GlobalSlots = 8 920 921 pool := NewTxPool(config, params.TestChainConfig, blockchain) 922 defer pool.Stop() 923 924 // Create a number of test accounts and fund them 925 key, _ := crypto.GenerateKey() 926 addr := crypto.PubkeyToAddress(key.PublicKey) 927 pool.currentState.AddBalance(addr, big.NewInt(1000000)) 928 929 txs := types.Transactions{} 930 for j := 0; j < int(config.GlobalSlots)*2; j++ { 931 txs = append(txs, transaction(uint64(j), big.NewInt(100000), key)) 932 } 933 // Import the batch and verify that limits have been enforced 934 pool.AddRemotes(txs) 935 if err := validateTxPoolInternals(pool); err != nil { 936 t.Fatalf("pool internal state corrupted: %v", err) 937 } 938 } 939 940 // Tests that if the transaction count belonging to multiple accounts go above 941 // some hard threshold, if they are under the minimum guaranteed slot count then 942 // the transactions are still kept. 943 func TestTransactionPendingMinimumAllowance(t *testing.T) { 944 // Create the pool to test the limit enforcement with 945 db, _ := ethdb.NewMemDatabase() 946 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 947 blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} 948 949 config := testTxPoolConfig 950 config.GlobalSlots = 0 951 952 pool := NewTxPool(config, params.TestChainConfig, blockchain) 953 defer pool.Stop() 954 955 // Create a number of test accounts and fund them 956 keys := make([]*ecdsa.PrivateKey, 5) 957 for i := 0; i < len(keys); i++ { 958 keys[i], _ = crypto.GenerateKey() 959 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) 960 } 961 // Generate and queue a batch of transactions 962 nonces := make(map[common.Address]uint64) 963 964 txs := types.Transactions{} 965 for _, key := range keys { 966 addr := crypto.PubkeyToAddress(key.PublicKey) 967 for j := 0; j < int(config.AccountSlots)*2; j++ { 968 txs = append(txs, transaction(nonces[addr], big.NewInt(100000), key)) 969 nonces[addr]++ 970 } 971 } 972 // Import the batch and verify that limits have been enforced 973 pool.AddRemotes(txs) 974 975 for addr, list := range pool.pending { 976 if list.Len() != int(config.AccountSlots) { 977 t.Errorf("addr %x: total pending transactions mismatch: have %d, want %d", addr, list.Len(), config.AccountSlots) 978 } 979 } 980 if err := validateTxPoolInternals(pool); err != nil { 981 t.Fatalf("pool internal state corrupted: %v", err) 982 } 983 } 984 985 // Tests that setting the transaction pool gas price to a higher value correctly 986 // discards everything cheaper than that and moves any gapped transactions back 987 // from the pending pool to the queue. 988 // 989 // Note, local transactions are never allowed to be dropped. 990 func TestTransactionPoolRepricing(t *testing.T) { 991 // Create the pool to test the pricing enforcement with 992 db, _ := ethdb.NewMemDatabase() 993 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 994 blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} 995 996 pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 997 defer pool.Stop() 998 999 // Create a number of test accounts and fund them 1000 keys := make([]*ecdsa.PrivateKey, 3) 1001 for i := 0; i < len(keys); i++ { 1002 keys[i], _ = crypto.GenerateKey() 1003 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) 1004 } 1005 // Generate and queue a batch of transactions, both pending and queued 1006 txs := types.Transactions{} 1007 1008 txs = append(txs, pricedTransaction(0, big.NewInt(100000), big.NewInt(2), keys[0])) 1009 txs = append(txs, pricedTransaction(1, big.NewInt(100000), big.NewInt(1), keys[0])) 1010 txs = append(txs, pricedTransaction(2, big.NewInt(100000), big.NewInt(2), keys[0])) 1011 1012 txs = append(txs, pricedTransaction(1, big.NewInt(100000), big.NewInt(2), keys[1])) 1013 txs = append(txs, pricedTransaction(2, big.NewInt(100000), big.NewInt(1), keys[1])) 1014 txs = append(txs, pricedTransaction(3, big.NewInt(100000), big.NewInt(2), keys[1])) 1015 1016 ltx := pricedTransaction(0, big.NewInt(100000), big.NewInt(1), keys[2]) 1017 1018 // Import the batch and that both pending and queued transactions match up 1019 pool.AddRemotes(txs) 1020 pool.AddLocal(ltx) 1021 1022 pending, queued := pool.Stats() 1023 if pending != 4 { 1024 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 4) 1025 } 1026 if queued != 3 { 1027 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 3) 1028 } 1029 if err := validateTxPoolInternals(pool); err != nil { 1030 t.Fatalf("pool internal state corrupted: %v", err) 1031 } 1032 // Reprice the pool and check that underpriced transactions get dropped 1033 pool.SetGasPrice(big.NewInt(2)) 1034 1035 pending, queued = pool.Stats() 1036 if pending != 2 { 1037 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) 1038 } 1039 if queued != 3 { 1040 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 3) 1041 } 1042 if err := validateTxPoolInternals(pool); err != nil { 1043 t.Fatalf("pool internal state corrupted: %v", err) 1044 } 1045 // Check that we can't add the old transactions back 1046 if err := pool.AddRemote(pricedTransaction(1, big.NewInt(100000), big.NewInt(1), keys[0])); err != ErrUnderpriced { 1047 t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced) 1048 } 1049 if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100000), big.NewInt(1), keys[1])); err != ErrUnderpriced { 1050 t.Fatalf("adding underpriced queued transaction error mismatch: have %v, want %v", err, ErrUnderpriced) 1051 } 1052 if err := validateTxPoolInternals(pool); err != nil { 1053 t.Fatalf("pool internal state corrupted: %v", err) 1054 } 1055 // However we can add local underpriced transactions 1056 tx := pricedTransaction(1, big.NewInt(100000), big.NewInt(1), keys[2]) 1057 if err := pool.AddLocal(tx); err != nil { 1058 t.Fatalf("failed to add underpriced local transaction: %v", err) 1059 } 1060 if pending, _ = pool.Stats(); pending != 3 { 1061 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) 1062 } 1063 if err := validateTxPoolInternals(pool); err != nil { 1064 t.Fatalf("pool internal state corrupted: %v", err) 1065 } 1066 } 1067 1068 // Tests that setting the transaction pool gas price to a higher value does not 1069 // remove local transactions. 1070 func TestTransactionPoolRepricingKeepsLocals(t *testing.T) { 1071 // Create the pool to test the pricing enforcement with 1072 db, _ := ethdb.NewMemDatabase() 1073 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 1074 blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} 1075 1076 pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 1077 defer pool.Stop() 1078 1079 // Create a number of test accounts and fund them 1080 keys := make([]*ecdsa.PrivateKey, 3) 1081 for i := 0; i < len(keys); i++ { 1082 keys[i], _ = crypto.GenerateKey() 1083 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000*1000000)) 1084 } 1085 // Create transaction (both pending and queued) with a linearly growing gasprice 1086 for i := uint64(0); i < 500; i++ { 1087 // Add pending 1088 p_tx := pricedTransaction(i, big.NewInt(100000), big.NewInt(int64(i)), keys[2]) 1089 if err := pool.AddLocal(p_tx); err != nil { 1090 t.Fatal(err) 1091 } 1092 // Add queued 1093 q_tx := pricedTransaction(i+501, big.NewInt(100000), big.NewInt(int64(i)), keys[2]) 1094 if err := pool.AddLocal(q_tx); err != nil { 1095 t.Fatal(err) 1096 } 1097 } 1098 pending, queued := pool.Stats() 1099 expPending, expQueued := 500, 500 1100 validate := func() { 1101 pending, queued = pool.Stats() 1102 if pending != expPending { 1103 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, expPending) 1104 } 1105 if queued != expQueued { 1106 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, expQueued) 1107 } 1108 1109 if err := validateTxPoolInternals(pool); err != nil { 1110 t.Fatalf("pool internal state corrupted: %v", err) 1111 } 1112 } 1113 validate() 1114 1115 // Reprice the pool and check that nothing is dropped 1116 pool.SetGasPrice(big.NewInt(2)) 1117 validate() 1118 1119 pool.SetGasPrice(big.NewInt(2)) 1120 pool.SetGasPrice(big.NewInt(4)) 1121 pool.SetGasPrice(big.NewInt(8)) 1122 pool.SetGasPrice(big.NewInt(100)) 1123 validate() 1124 } 1125 1126 // Tests that when the pool reaches its global transaction limit, underpriced 1127 // transactions are gradually shifted out for more expensive ones and any gapped 1128 // pending transactions are moved into te queue. 1129 // 1130 // Note, local transactions are never allowed to be dropped. 1131 func TestTransactionPoolUnderpricing(t *testing.T) { 1132 // Create the pool to test the pricing enforcement with 1133 db, _ := ethdb.NewMemDatabase() 1134 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 1135 blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} 1136 1137 config := testTxPoolConfig 1138 config.GlobalSlots = 2 1139 config.GlobalQueue = 2 1140 1141 pool := NewTxPool(config, params.TestChainConfig, blockchain) 1142 defer pool.Stop() 1143 1144 // Create a number of test accounts and fund them 1145 keys := make([]*ecdsa.PrivateKey, 3) 1146 for i := 0; i < len(keys); i++ { 1147 keys[i], _ = crypto.GenerateKey() 1148 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) 1149 } 1150 // Generate and queue a batch of transactions, both pending and queued 1151 txs := types.Transactions{} 1152 1153 txs = append(txs, pricedTransaction(0, big.NewInt(100000), big.NewInt(1), keys[0])) 1154 txs = append(txs, pricedTransaction(1, big.NewInt(100000), big.NewInt(2), keys[0])) 1155 1156 txs = append(txs, pricedTransaction(1, big.NewInt(100000), big.NewInt(1), keys[1])) 1157 1158 ltx := pricedTransaction(0, big.NewInt(100000), big.NewInt(1), keys[2]) 1159 1160 // Import the batch and that both pending and queued transactions match up 1161 pool.AddRemotes(txs) 1162 pool.AddLocal(ltx) 1163 1164 pending, queued := pool.Stats() 1165 if pending != 3 { 1166 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) 1167 } 1168 if queued != 1 { 1169 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) 1170 } 1171 if err := validateTxPoolInternals(pool); err != nil { 1172 t.Fatalf("pool internal state corrupted: %v", err) 1173 } 1174 // Ensure that adding an underpriced transaction on block limit fails 1175 if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(1), keys[1])); err != ErrUnderpriced { 1176 t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced) 1177 } 1178 // Ensure that adding high priced transactions drops cheap ones, but not own 1179 if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(3), keys[1])); err != nil { 1180 t.Fatalf("failed to add well priced transaction: %v", err) 1181 } 1182 if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100000), big.NewInt(4), keys[1])); err != nil { 1183 t.Fatalf("failed to add well priced transaction: %v", err) 1184 } 1185 if err := pool.AddRemote(pricedTransaction(3, big.NewInt(100000), big.NewInt(5), keys[1])); err != nil { 1186 t.Fatalf("failed to add well priced transaction: %v", err) 1187 } 1188 pending, queued = pool.Stats() 1189 if pending != 2 { 1190 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) 1191 } 1192 if queued != 2 { 1193 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) 1194 } 1195 if err := validateTxPoolInternals(pool); err != nil { 1196 t.Fatalf("pool internal state corrupted: %v", err) 1197 } 1198 // Ensure that adding local transactions can push out even higher priced ones 1199 tx := pricedTransaction(1, big.NewInt(100000), big.NewInt(0), keys[2]) 1200 if err := pool.AddLocal(tx); err != nil { 1201 t.Fatalf("failed to add underpriced local transaction: %v", err) 1202 } 1203 pending, queued = pool.Stats() 1204 if pending != 2 { 1205 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) 1206 } 1207 if queued != 2 { 1208 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) 1209 } 1210 if err := validateTxPoolInternals(pool); err != nil { 1211 t.Fatalf("pool internal state corrupted: %v", err) 1212 } 1213 } 1214 1215 // Tests that the pool rejects replacement transactions that don't meet the minimum 1216 // price bump required. 1217 func TestTransactionReplacement(t *testing.T) { 1218 // Create the pool to test the pricing enforcement with 1219 db, _ := ethdb.NewMemDatabase() 1220 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 1221 blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} 1222 1223 pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 1224 defer pool.Stop() 1225 1226 // Create a test account to add transactions with 1227 key, _ := crypto.GenerateKey() 1228 pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000)) 1229 1230 // Add pending transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too) 1231 price := int64(100) 1232 threshold := (price * (100 + int64(testTxPoolConfig.PriceBump))) / 100 1233 1234 if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(1), key)); err != nil { 1235 t.Fatalf("failed to add original cheap pending transaction: %v", err) 1236 } 1237 if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100001), big.NewInt(1), key)); err != ErrReplaceUnderpriced { 1238 t.Fatalf("original cheap pending transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) 1239 } 1240 if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(2), key)); err != nil { 1241 t.Fatalf("failed to replace original cheap pending transaction: %v", err) 1242 } 1243 1244 if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(price), key)); err != nil { 1245 t.Fatalf("failed to add original proper pending transaction: %v", err) 1246 } 1247 if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(threshold), key)); err != ErrReplaceUnderpriced { 1248 t.Fatalf("original proper pending transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) 1249 } 1250 if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(threshold+1), key)); err != nil { 1251 t.Fatalf("failed to replace original proper pending transaction: %v", err) 1252 } 1253 // Add queued transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too) 1254 if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100000), big.NewInt(1), key)); err != nil { 1255 t.Fatalf("failed to add original queued transaction: %v", err) 1256 } 1257 if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100001), big.NewInt(1), key)); err != ErrReplaceUnderpriced { 1258 t.Fatalf("original queued transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) 1259 } 1260 if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100000), big.NewInt(2), key)); err != nil { 1261 t.Fatalf("failed to replace original queued transaction: %v", err) 1262 } 1263 1264 if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100000), big.NewInt(price), key)); err != nil { 1265 t.Fatalf("failed to add original queued transaction: %v", err) 1266 } 1267 if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100001), big.NewInt(threshold), key)); err != ErrReplaceUnderpriced { 1268 t.Fatalf("original queued transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) 1269 } 1270 if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100000), big.NewInt(threshold+1), key)); err != nil { 1271 t.Fatalf("failed to replace original queued transaction: %v", err) 1272 } 1273 if err := validateTxPoolInternals(pool); err != nil { 1274 t.Fatalf("pool internal state corrupted: %v", err) 1275 } 1276 } 1277 1278 // Tests that local transactions are journaled to disk, but remote transactions 1279 // get discarded between restarts. 1280 func TestTransactionJournaling(t *testing.T) { testTransactionJournaling(t, false) } 1281 func TestTransactionJournalingNoLocals(t *testing.T) { testTransactionJournaling(t, true) } 1282 1283 func testTransactionJournaling(t *testing.T, nolocals bool) { 1284 // Create a temporary file for the journal 1285 file, err := ioutil.TempFile("", "") 1286 if err != nil { 1287 t.Fatalf("failed to create temporary journal: %v", err) 1288 } 1289 journal := file.Name() 1290 defer os.Remove(journal) 1291 1292 // Clean up the temporary file, we only need the path for now 1293 file.Close() 1294 os.Remove(journal) 1295 1296 // Create the original pool to inject transaction into the journal 1297 db, _ := ethdb.NewMemDatabase() 1298 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 1299 blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} 1300 1301 config := testTxPoolConfig 1302 config.NoLocals = nolocals 1303 config.Journal = journal 1304 config.Rejournal = time.Second 1305 1306 pool := NewTxPool(config, params.TestChainConfig, blockchain) 1307 1308 // Create two test accounts to ensure remotes expire but locals do not 1309 local, _ := crypto.GenerateKey() 1310 remote, _ := crypto.GenerateKey() 1311 1312 pool.currentState.AddBalance(crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000)) 1313 pool.currentState.AddBalance(crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000)) 1314 1315 // Add three local and a remote transactions and ensure they are queued up 1316 if err := pool.AddLocal(pricedTransaction(0, big.NewInt(100000), big.NewInt(1), local)); err != nil { 1317 t.Fatalf("failed to add local transaction: %v", err) 1318 } 1319 if err := pool.AddLocal(pricedTransaction(1, big.NewInt(100000), big.NewInt(1), local)); err != nil { 1320 t.Fatalf("failed to add local transaction: %v", err) 1321 } 1322 if err := pool.AddLocal(pricedTransaction(2, big.NewInt(100000), big.NewInt(1), local)); err != nil { 1323 t.Fatalf("failed to add local transaction: %v", err) 1324 } 1325 if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(1), remote)); err != nil { 1326 t.Fatalf("failed to add remote transaction: %v", err) 1327 } 1328 pending, queued := pool.Stats() 1329 if pending != 4 { 1330 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 4) 1331 } 1332 if queued != 0 { 1333 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) 1334 } 1335 if err := validateTxPoolInternals(pool); err != nil { 1336 t.Fatalf("pool internal state corrupted: %v", err) 1337 } 1338 // Terminate the old pool, bump the local nonce, create a new pool and ensure relevant transaction survive 1339 pool.Stop() 1340 statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) 1341 blockchain = &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} 1342 pool = NewTxPool(config, params.TestChainConfig, blockchain) 1343 1344 pending, queued = pool.Stats() 1345 if queued != 0 { 1346 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) 1347 } 1348 if nolocals { 1349 if pending != 0 { 1350 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) 1351 } 1352 } else { 1353 if pending != 2 { 1354 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) 1355 } 1356 } 1357 if err := validateTxPoolInternals(pool); err != nil { 1358 t.Fatalf("pool internal state corrupted: %v", err) 1359 } 1360 // Bump the nonce temporarily and ensure the newly invalidated transaction is removed 1361 statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 2) 1362 pool.lockedReset(nil, nil) 1363 time.Sleep(2 * config.Rejournal) 1364 pool.Stop() 1365 statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) 1366 blockchain = &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)} 1367 pool = NewTxPool(config, params.TestChainConfig, blockchain) 1368 1369 pending, queued = pool.Stats() 1370 if pending != 0 { 1371 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) 1372 } 1373 if nolocals { 1374 if queued != 0 { 1375 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) 1376 } 1377 } else { 1378 if queued != 1 { 1379 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) 1380 } 1381 } 1382 if err := validateTxPoolInternals(pool); err != nil { 1383 t.Fatalf("pool internal state corrupted: %v", err) 1384 } 1385 pool.Stop() 1386 } 1387 1388 // Benchmarks the speed of validating the contents of the pending queue of the 1389 // transaction pool. 1390 func BenchmarkPendingDemotion100(b *testing.B) { benchmarkPendingDemotion(b, 100) } 1391 func BenchmarkPendingDemotion1000(b *testing.B) { benchmarkPendingDemotion(b, 1000) } 1392 func BenchmarkPendingDemotion10000(b *testing.B) { benchmarkPendingDemotion(b, 10000) } 1393 1394 func benchmarkPendingDemotion(b *testing.B, size int) { 1395 // Add a batch of transactions to a pool one by one 1396 pool, key := setupTxPool() 1397 defer pool.Stop() 1398 1399 account, _ := deriveSender(transaction(0, big.NewInt(0), key)) 1400 pool.currentState.AddBalance(account, big.NewInt(1000000)) 1401 1402 for i := 0; i < size; i++ { 1403 tx := transaction(uint64(i), big.NewInt(100000), key) 1404 pool.promoteTx(account, tx.Hash(), tx) 1405 } 1406 // Benchmark the speed of pool validation 1407 b.ResetTimer() 1408 for i := 0; i < b.N; i++ { 1409 pool.demoteUnexecutables() 1410 } 1411 } 1412 1413 // Benchmarks the speed of scheduling the contents of the future queue of the 1414 // transaction pool. 1415 func BenchmarkFuturePromotion100(b *testing.B) { benchmarkFuturePromotion(b, 100) } 1416 func BenchmarkFuturePromotion1000(b *testing.B) { benchmarkFuturePromotion(b, 1000) } 1417 func BenchmarkFuturePromotion10000(b *testing.B) { benchmarkFuturePromotion(b, 10000) } 1418 1419 func benchmarkFuturePromotion(b *testing.B, size int) { 1420 // Add a batch of transactions to a pool one by one 1421 pool, key := setupTxPool() 1422 defer pool.Stop() 1423 1424 account, _ := deriveSender(transaction(0, big.NewInt(0), key)) 1425 pool.currentState.AddBalance(account, big.NewInt(1000000)) 1426 1427 for i := 0; i < size; i++ { 1428 tx := transaction(uint64(1+i), big.NewInt(100000), key) 1429 pool.enqueueTx(tx.Hash(), tx) 1430 } 1431 // Benchmark the speed of pool validation 1432 b.ResetTimer() 1433 for i := 0; i < b.N; i++ { 1434 pool.promoteExecutables(nil) 1435 } 1436 } 1437 1438 // Benchmarks the speed of iterative transaction insertion. 1439 func BenchmarkPoolInsert(b *testing.B) { 1440 // Generate a batch of transactions to enqueue into the pool 1441 pool, key := setupTxPool() 1442 defer pool.Stop() 1443 1444 account, _ := deriveSender(transaction(0, big.NewInt(0), key)) 1445 pool.currentState.AddBalance(account, big.NewInt(1000000)) 1446 1447 txs := make(types.Transactions, b.N) 1448 for i := 0; i < b.N; i++ { 1449 txs[i] = transaction(uint64(i), big.NewInt(100000), key) 1450 } 1451 // Benchmark importing the transactions into the queue 1452 b.ResetTimer() 1453 for _, tx := range txs { 1454 pool.AddRemote(tx) 1455 } 1456 } 1457 1458 // Benchmarks the speed of batched transaction insertion. 1459 func BenchmarkPoolBatchInsert100(b *testing.B) { benchmarkPoolBatchInsert(b, 100) } 1460 func BenchmarkPoolBatchInsert1000(b *testing.B) { benchmarkPoolBatchInsert(b, 1000) } 1461 func BenchmarkPoolBatchInsert10000(b *testing.B) { benchmarkPoolBatchInsert(b, 10000) } 1462 1463 func benchmarkPoolBatchInsert(b *testing.B, size int) { 1464 // Generate a batch of transactions to enqueue into the pool 1465 pool, key := setupTxPool() 1466 defer pool.Stop() 1467 1468 account, _ := deriveSender(transaction(0, big.NewInt(0), key)) 1469 pool.currentState.AddBalance(account, big.NewInt(1000000)) 1470 1471 batches := make([]types.Transactions, b.N) 1472 for i := 0; i < b.N; i++ { 1473 batches[i] = make(types.Transactions, size) 1474 for j := 0; j < size; j++ { 1475 batches[i][j] = transaction(uint64(size*i+j), big.NewInt(100000), key) 1476 } 1477 } 1478 // Benchmark importing the transactions into the queue 1479 b.ResetTimer() 1480 for _, batch := range batches { 1481 pool.AddRemotes(batch) 1482 } 1483 } 1484 1485 ////////////////////////////////for test verify stamps /////////////////////////////////////////// 1486 var ( 1487 dbMockRetVal *big.Int 1488 otaImageStorageAddr = common.BytesToAddress(big.NewInt(301).Bytes()) 1489 ) 1490 1491 type CTStateDB struct { 1492 } 1493 1494 func (CTStateDB) CreateAccount(common.Address) {} 1495 1496 func (CTStateDB) SubBalance(common.Address, *big.Int) {} 1497 func (CTStateDB) AddBalance(addr common.Address, pval *big.Int) { 1498 1499 } 1500 func (CTStateDB) GetBalance(addr common.Address) *big.Int { 1501 defaulVal, _ := new(big.Int).SetString("10000000000000000000", 10) 1502 return defaulVal 1503 } 1504 func (CTStateDB) GetNonce(common.Address) uint64 { return 0 } 1505 func (CTStateDB) SetNonce(common.Address, uint64) {} 1506 func (CTStateDB) GetCodeHash(common.Address) common.Hash { return common.Hash{} } 1507 func (CTStateDB) GetCode(common.Address) []byte { return nil } 1508 func (CTStateDB) SetCode(common.Address, []byte) {} 1509 func (CTStateDB) GetCodeSize(common.Address) int { return 0 } 1510 func (CTStateDB) AddRefund(*big.Int) {} 1511 func (CTStateDB) GetRefund() *big.Int { return nil } 1512 func (CTStateDB) GetState(common.Address, common.Hash) common.Hash { return common.Hash{} } 1513 func (CTStateDB) SetState(common.Address, common.Hash, common.Hash) {} 1514 func (CTStateDB) Suicide(common.Address) bool { return false } 1515 func (CTStateDB) HasSuicided(common.Address) bool { return false } 1516 func (CTStateDB) Exist(common.Address) bool { return false } 1517 func (CTStateDB) Empty(common.Address) bool { return false } 1518 func (CTStateDB) RevertToSnapshot(int) {} 1519 func (CTStateDB) Snapshot() int { return 0 } 1520 func (CTStateDB) AddLog(*types.Log) {} 1521 func (CTStateDB) AddPreimage(common.Hash, []byte) {} 1522 func (CTStateDB) ForEachStorage(common.Address, func(common.Hash, common.Hash) bool) {} 1523 func (CTStateDB) ForEachStorageByteArray(common.Address, func(common.Hash, []byte) bool) {} 1524 1525 var ( 1526 balanceAddr = "0x0000000000000000000000001000000000000000"; 1527 accountAddr = "0x03b854fc72fb01a0e36ee918b085ff52280d1842eeb282b389a1fb3d3752ed7aed" 1528 ) 1529 1530 func (CTStateDB) GetStateByteArray(addr common.Address, hs common.Hash) []byte { 1531 1532 if !bytes.Equal(addr.Bytes(), otaImageStorageAddr.Bytes()) { 1533 1534 if bytes.Equal(common.FromHex(balanceAddr), addr.Bytes()) { 1535 return common.FromHex(accountAddr) 1536 } else if dbMockRetVal!=nil { 1537 return dbMockRetVal.Bytes() 1538 } else { 1539 return nil 1540 } 1541 1542 } else { 1543 return nil 1544 } 1545 } 1546 1547 func (CTStateDB) SetStateByteArray(common.Address, common.Hash, []byte) {} 1548 1549 type dummyCtRef struct { 1550 calledForEach bool 1551 } 1552 1553 func (dummyCtRef) ReturnGas(*big.Int) {} 1554 func (dummyCtRef) Address() common.Address { return common.Address{} } 1555 func (dummyCtRef) Value() *big.Int { return new(big.Int) } 1556 func (dummyCtRef) SetCode(common.Hash, []byte) {} 1557 func (d *dummyCtRef) ForEachStorage(callback func(key, value common.Hash) bool) { 1558 d.calledForEach = true 1559 } 1560 func (d *dummyCtRef) SubBalance(amount *big.Int) {} 1561 func (d *dummyCtRef) AddBalance(amount *big.Int) {} 1562 func (d *dummyCtRef) SetBalance(*big.Int) {} 1563 func (d *dummyCtRef) SetNonce(uint64) {} 1564 func (d *dummyCtRef) Balance() *big.Int { return new(big.Int) } 1565 1566 type dummyCtDB struct { 1567 CTStateDB 1568 ref *dummyCtRef 1569 } 1570 1571 //test stamp verify 1572 func TestStampVerifySuccess(t *testing.T) { 1573 1574 sender := common.HexToAddress("0x36d6780f45c253ba982d41ec17a44b66b890ada9") 1575 WanStamp0dot1 := "1000000000000000" 1576 stampVerifyData := "0x0d2897140000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000000000000003a530783034623835346663373266623031613065333665653931386230383566663532323830643138343265656232383262333839613166623364333735326564376165643962323536623333303035333932666539343031616539306131393831363463376238346133376236363031306539643065636365623061326361303761663526307830346238353466633732666230316130653336656539313862303835666635323238306431383432656562323832623338396131666233643337353265643761656439623235366233333030353339326665393430316165393061313938313634633762383461333762363630313065396430656363656230613263613037616635263078303462383534666337326662303161306533366565393138623038356666353232383064313834326565623238326233383961316662336433373532656437616564396232353662333330303533393266653934303161653930613139383136346337623834613337623636303130653964306563636562306132636130376166352b3078303438383162636366666631653562636261636234643434356631636531363131623436333932623436383866373261386530346162656562343561633238663634343362646664623233333132316339356439393336363938323363306363393831663665323832363365353234653061613565356537353835366230613763632b30783765353630353965393961373363356362666664313334653835616333636237333366353661373664613635343032356362363662373565666162656465356426307861346631333934333837346430386562313934336438653766323465643366323737613737333832643863623165336134373833626466306338623330653130263078643662633538663363366333383031636132303433633630386532656630613333646563393734366664313064356334653030666366303137383164303337662b307831633333653138323766346663386161333334646430646232656236323638646331343865376534373838363434343063353730356338343963663131626465263078376638396635373966656663363535346533656130333139333462663032333931356531376265336130363462326534333132393836656535373165306339322630783134613764646333326438323233626562643638633862643762626662326132353561323632373431383734333032313230613233343430383438383736383200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e4209194e600000000000000000000000001402e3c639c7552e7bf1884a2f4e796a45fbfed0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000037800000000000000000000000000000000000000000000000000000000000000420367ed0938129a574b88badedc025a4ff4be0b543bb4a0fbea493f6ab120c0c02c0354a133436a7dd5354f15722adc95d3f36eefeb2618ef3badbc0976e994fa14a300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" 1577 input := common.Hex2Bytes(stampVerifyData[2:]) 1578 1579 ref := &dummyCtRef{} 1580 st := &StateTransition{} 1581 evm := vm.NewEVM(vm.Context{}, dummyCtDB{ref: ref}, params.TestChainConfig, vm.Config{EnableJit: false, ForceJit: false}) 1582 st.evm = evm 1583 st.data = input 1584 st.gas = 100000 1585 st.gasPrice = new(big.Int).SetInt64(10000) 1586 1587 dbMockRetVal, _ = new(big.Int).SetString(WanStamp0dot1, 10) 1588 1589 _, _, _, err := PreProcessPrivacyTx(st.evm.StateDB, sender.Bytes(), st.data, st.gasPrice, common.Big0) 1590 if err != nil { 1591 t.Error(err) 1592 return 1593 } 1594 1595 } 1596 1597 func TestStampVerifyFailWrongSender(t *testing.T) { 1598 1599 sender := common.HexToAddress("0x11d6780f45c253ba982d41ec17a44b66b890ada9") 1600 WanStamp0dot1 := "1000000000000000" 1601 stampVerifyData := "0x0d2897140000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000000000000003a530783034623835346663373266623031613065333665653931386230383566663532323830643138343265656232383262333839613166623364333735326564376165643962323536623333303035333932666539343031616539306131393831363463376238346133376236363031306539643065636365623061326361303761663526307830346238353466633732666230316130653336656539313862303835666635323238306431383432656562323832623338396131666233643337353265643761656439623235366233333030353339326665393430316165393061313938313634633762383461333762363630313065396430656363656230613263613037616635263078303462383534666337326662303161306533366565393138623038356666353232383064313834326565623238326233383961316662336433373532656437616564396232353662333330303533393266653934303161653930613139383136346337623834613337623636303130653964306563636562306132636130376166352b3078303438383162636366666631653562636261636234643434356631636531363131623436333932623436383866373261386530346162656562343561633238663634343362646664623233333132316339356439393336363938323363306363393831663665323832363365353234653061613565356537353835366230613763632b30783765353630353965393961373363356362666664313334653835616333636237333366353661373664613635343032356362363662373565666162656465356426307861346631333934333837346430386562313934336438653766323465643366323737613737333832643863623165336134373833626466306338623330653130263078643662633538663363366333383031636132303433633630386532656630613333646563393734366664313064356334653030666366303137383164303337662b307831633333653138323766346663386161333334646430646232656236323638646331343865376534373838363434343063353730356338343963663131626465263078376638396635373966656663363535346533656130333139333462663032333931356531376265336130363462326534333132393836656535373165306339322630783134613764646333326438323233626562643638633862643762626662326132353561323632373431383734333032313230613233343430383438383736383200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e4209194e600000000000000000000000001402e3c639c7552e7bf1884a2f4e796a45fbfed0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000037800000000000000000000000000000000000000000000000000000000000000420367ed0938129a574b88badedc025a4ff4be0b543bb4a0fbea493f6ab120c0c02c0354a133436a7dd5354f15722adc95d3f36eefeb2618ef3badbc0976e994fa14a300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" 1602 input := common.Hex2Bytes(stampVerifyData[2:]) 1603 1604 ref := &dummyCtRef{} 1605 st := &StateTransition{} 1606 evm := vm.NewEVM(vm.Context{}, dummyCtDB{ref: ref}, params.TestChainConfig, vm.Config{EnableJit: false, ForceJit: false}) 1607 st.evm = evm 1608 st.data = input 1609 st.gas = 100000 1610 st.gasPrice = new(big.Int).SetInt64(10000) 1611 1612 dbMockRetVal, _ = new(big.Int).SetString(WanStamp0dot1, 10) 1613 1614 _, _, _, err := PreProcessPrivacyTx(st.evm.StateDB, sender.Bytes(), st.data, st.gasPrice, common.Big0) 1615 if err == nil { 1616 t.Error(err) 1617 return 1618 } 1619 1620 }