| 
									
										
										
										
											2016-11-09 02:01:56 +01:00
										 |  |  | // Copyright 2016 The go-ethereum Authors | 
					
						
							| 
									
										
										
										
											2016-10-14 05:47:09 +02:00
										 |  |  | // This file is part of the go-ethereum library. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							|  |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							|  |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package light | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2017-03-22 18:20:33 +01:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2016-10-14 05:47:09 +02:00
										 |  |  | 	"math" | 
					
						
							|  |  |  | 	"math/big" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							| 
									
										
										
										
											2017-04-05 01:16:29 +03:00
										 |  |  | 	"github.com/ethereum/go-ethereum/consensus/ethash" | 
					
						
							| 
									
										
										
										
											2016-10-14 05:47:09 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/core" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/core/types" | 
					
						
							| 
									
										
										
										
											2017-01-17 11:19:50 +00:00
										 |  |  | 	"github.com/ethereum/go-ethereum/core/vm" | 
					
						
							| 
									
										
										
										
											2016-10-14 05:47:09 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/ethdb" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/params" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type testTxRelay struct { | 
					
						
							| 
									
										
										
										
											2017-01-06 03:44:58 +01:00
										 |  |  | 	send, discard, mined chan int | 
					
						
							| 
									
										
										
										
											2016-10-14 05:47:09 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *testTxRelay) Send(txs types.Transactions) { | 
					
						
							| 
									
										
										
										
											2017-01-06 03:44:58 +01:00
										 |  |  | 	self.send <- len(txs) | 
					
						
							| 
									
										
										
										
											2016-10-14 05:47:09 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *testTxRelay) NewHead(head common.Hash, mined []common.Hash, rollback []common.Hash) { | 
					
						
							| 
									
										
										
										
											2017-01-06 03:44:58 +01:00
										 |  |  | 	m := len(mined) | 
					
						
							|  |  |  | 	if m != 0 { | 
					
						
							|  |  |  | 		self.mined <- m | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-10-14 05:47:09 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *testTxRelay) Discard(hashes []common.Hash) { | 
					
						
							| 
									
										
										
										
											2017-01-06 03:44:58 +01:00
										 |  |  | 	self.discard <- len(hashes) | 
					
						
							| 
									
										
										
										
											2016-10-14 05:47:09 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const poolTestTxs = 1000 | 
					
						
							|  |  |  | const poolTestBlocks = 100 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // test tx 0..n-1 | 
					
						
							|  |  |  | var testTx [poolTestTxs]*types.Transaction | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // txs sent before block i | 
					
						
							|  |  |  | func sentTx(i int) int { | 
					
						
							|  |  |  | 	return int(math.Pow(float64(i)/float64(poolTestBlocks), 0.9) * poolTestTxs) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // txs included in block i or before that (minedTx(i) <= sentTx(i)) | 
					
						
							|  |  |  | func minedTx(i int) int { | 
					
						
							|  |  |  | 	return int(math.Pow(float64(i)/float64(poolTestBlocks), 1.1) * poolTestTxs) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func txPoolTestChainGen(i int, block *core.BlockGen) { | 
					
						
							|  |  |  | 	s := minedTx(i) | 
					
						
							|  |  |  | 	e := minedTx(i + 1) | 
					
						
							|  |  |  | 	for i := s; i < e; i++ { | 
					
						
							|  |  |  | 		block.AddTx(testTx[i]) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestTxPool(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2017-01-06 15:52:03 +01:00
										 |  |  | 	for i := range testTx { | 
					
						
							| 
									
										
										
										
											2017-01-04 20:17:24 +01:00
										 |  |  | 		testTx[i], _ = types.SignTx(types.NewTransaction(uint64(i), acc1Addr, big.NewInt(10000), bigTxGas, nil, nil), types.HomesteadSigner{}, testBankKey) | 
					
						
							| 
									
										
										
										
											2016-10-14 05:47:09 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var ( | 
					
						
							|  |  |  | 		sdb, _  = ethdb.NewMemDatabase() | 
					
						
							|  |  |  | 		ldb, _  = ethdb.NewMemDatabase() | 
					
						
							| 
									
										
										
										
											2017-03-02 14:03:33 +01:00
										 |  |  | 		gspec   = core.Genesis{Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}} | 
					
						
							|  |  |  | 		genesis = gspec.MustCommit(sdb) | 
					
						
							| 
									
										
										
										
											2016-10-14 05:47:09 +02:00
										 |  |  | 	) | 
					
						
							| 
									
										
										
										
											2017-03-02 14:03:33 +01:00
										 |  |  | 	gspec.MustCommit(ldb) | 
					
						
							| 
									
										
										
										
											2016-10-14 05:47:09 +02:00
										 |  |  | 	// Assemble the test environment | 
					
						
							| 
									
										
										
										
											2017-08-18 18:58:36 +08:00
										 |  |  | 	blockchain, _ := core.NewBlockChain(sdb, params.TestChainConfig, ethash.NewFullFaker(), vm.Config{}) | 
					
						
							| 
									
										
										
										
											2017-04-05 01:16:29 +03:00
										 |  |  | 	gchain, _ := core.GenerateChain(params.TestChainConfig, genesis, sdb, poolTestBlocks, txPoolTestChainGen) | 
					
						
							| 
									
										
										
										
											2016-10-14 05:47:09 +02:00
										 |  |  | 	if _, err := blockchain.InsertChain(gchain); err != nil { | 
					
						
							|  |  |  | 		panic(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	odr := &testOdr{sdb: sdb, ldb: ldb} | 
					
						
							| 
									
										
										
										
											2017-01-06 03:44:58 +01:00
										 |  |  | 	relay := &testTxRelay{ | 
					
						
							|  |  |  | 		send:    make(chan int, 1), | 
					
						
							|  |  |  | 		discard: make(chan int, 1), | 
					
						
							|  |  |  | 		mined:   make(chan int, 1), | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-08-18 18:58:36 +08:00
										 |  |  | 	lightchain, _ := NewLightChain(odr, params.TestChainConfig, ethash.NewFullFaker()) | 
					
						
							| 
									
										
										
										
											2016-10-14 05:47:09 +02:00
										 |  |  | 	txPermanent = 50 | 
					
						
							| 
									
										
										
										
											2017-08-18 18:58:36 +08:00
										 |  |  | 	pool := NewTxPool(params.TestChainConfig, lightchain, relay) | 
					
						
							| 
									
										
										
										
											2017-03-22 18:20:33 +01:00
										 |  |  | 	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) | 
					
						
							|  |  |  | 	defer cancel() | 
					
						
							| 
									
										
										
										
											2016-10-14 05:47:09 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for ii, block := range gchain { | 
					
						
							|  |  |  | 		i := ii + 1 | 
					
						
							|  |  |  | 		s := sentTx(i - 1) | 
					
						
							|  |  |  | 		e := sentTx(i) | 
					
						
							|  |  |  | 		for i := s; i < e; i++ { | 
					
						
							|  |  |  | 			pool.Add(ctx, testTx[i]) | 
					
						
							| 
									
										
										
										
											2017-01-06 03:44:58 +01:00
										 |  |  | 			got := <-relay.send | 
					
						
							| 
									
										
										
										
											2016-10-14 05:47:09 +02:00
										 |  |  | 			exp := 1 | 
					
						
							|  |  |  | 			if got != exp { | 
					
						
							|  |  |  | 				t.Errorf("relay.Send expected len = %d, got %d", exp, got) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if _, err := lightchain.InsertHeaderChain([]*types.Header{block.Header()}, 1); err != nil { | 
					
						
							|  |  |  | 			panic(err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 03:44:58 +01:00
										 |  |  | 		got := <-relay.mined | 
					
						
							| 
									
										
										
										
											2016-10-14 05:47:09 +02:00
										 |  |  | 		exp := minedTx(i) - minedTx(i-1) | 
					
						
							|  |  |  | 		if got != exp { | 
					
						
							|  |  |  | 			t.Errorf("relay.NewHead expected len(mined) = %d, got %d", exp, got) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		exp = 0 | 
					
						
							|  |  |  | 		if i > int(txPermanent)+1 { | 
					
						
							|  |  |  | 			exp = minedTx(i-int(txPermanent)-1) - minedTx(i-int(txPermanent)-2) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-06 03:44:58 +01:00
										 |  |  | 		if exp != 0 { | 
					
						
							|  |  |  | 			got = <-relay.discard | 
					
						
							|  |  |  | 			if got != exp { | 
					
						
							|  |  |  | 				t.Errorf("relay.Discard expected len = %d, got %d", exp, got) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-10-14 05:47:09 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |