github.com/theQRL/go-zond@v0.2.1/zond/handler_test.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package zond 18 19 import ( 20 "math/big" 21 "sort" 22 "sync" 23 24 "github.com/theQRL/go-zond/common" 25 "github.com/theQRL/go-zond/consensus/beacon" 26 "github.com/theQRL/go-zond/core" 27 "github.com/theQRL/go-zond/core/rawdb" 28 "github.com/theQRL/go-zond/core/txpool" 29 "github.com/theQRL/go-zond/core/types" 30 "github.com/theQRL/go-zond/core/vm" 31 "github.com/theQRL/go-zond/crypto/pqcrypto" 32 "github.com/theQRL/go-zond/event" 33 "github.com/theQRL/go-zond/params" 34 "github.com/theQRL/go-zond/zond/downloader" 35 "github.com/theQRL/go-zond/zonddb" 36 ) 37 38 var ( 39 // testKey is a private key to use for funding a tester account. 40 testKey, _ = pqcrypto.HexToDilithium("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 41 42 // testAddr is the Zond address of the tester account. 43 testAddr = testKey.GetAddress() 44 ) 45 46 // testTxPool is a mock transaction pool that blindly accepts all transactions. 47 // Its goal is to get around setting up a valid statedb for the balance and nonce 48 // checks. 49 type testTxPool struct { 50 pool map[common.Hash]*types.Transaction // Hash map of collected transactions 51 52 txFeed event.Feed // Notification feed to allow waiting for inclusion 53 lock sync.RWMutex // Protects the transaction pool 54 } 55 56 // newTestTxPool creates a mock transaction pool. 57 func newTestTxPool() *testTxPool { 58 return &testTxPool{ 59 pool: make(map[common.Hash]*types.Transaction), 60 } 61 } 62 63 // Has returns an indicator whether txpool has a transaction 64 // cached with the given hash. 65 func (p *testTxPool) Has(hash common.Hash) bool { 66 p.lock.Lock() 67 defer p.lock.Unlock() 68 69 return p.pool[hash] != nil 70 } 71 72 // Get retrieves the transaction from local txpool with given 73 // tx hash. 74 func (p *testTxPool) Get(hash common.Hash) *types.Transaction { 75 p.lock.Lock() 76 defer p.lock.Unlock() 77 return p.pool[hash] 78 } 79 80 // Add appends a batch of transactions to the pool, and notifies any 81 // listeners if the addition channel is non nil 82 func (p *testTxPool) Add(txs []*types.Transaction, local bool, sync bool) []error { 83 p.lock.Lock() 84 defer p.lock.Unlock() 85 86 for _, tx := range txs { 87 p.pool[tx.Hash()] = tx 88 } 89 p.txFeed.Send(core.NewTxsEvent{Txs: txs}) 90 return make([]error, len(txs)) 91 } 92 93 // Pending returns all the transactions known to the pool 94 func (p *testTxPool) Pending(filter txpool.PendingFilter) map[common.Address][]*txpool.LazyTransaction { 95 p.lock.RLock() 96 defer p.lock.RUnlock() 97 98 batches := make(map[common.Address][]*types.Transaction) 99 for _, tx := range p.pool { 100 from, _ := types.Sender(types.ShanghaiSigner{ChainId: big.NewInt(0)}, tx) 101 batches[from] = append(batches[from], tx) 102 } 103 for _, batch := range batches { 104 sort.Sort(types.TxByNonce(batch)) 105 } 106 pending := make(map[common.Address][]*txpool.LazyTransaction) 107 for addr, batch := range batches { 108 for _, tx := range batch { 109 pending[addr] = append(pending[addr], &txpool.LazyTransaction{ 110 Hash: tx.Hash(), 111 Tx: tx, 112 Time: tx.Time(), 113 GasFeeCap: tx.GasFeeCap(), 114 GasTipCap: tx.GasTipCap(), 115 Gas: tx.Gas(), 116 }) 117 } 118 } 119 return pending 120 } 121 122 // SubscribeTransactions should return an event subscription of NewTxsEvent and 123 // send events to the given channel. 124 func (p *testTxPool) SubscribeTransactions(ch chan<- core.NewTxsEvent) event.Subscription { 125 return p.txFeed.Subscribe(ch) 126 } 127 128 // testHandler is a live implementation of the Zond protocol handler, just 129 // preinitialized with some sane testing defaults and the transaction pool mocked 130 // out. 131 type testHandler struct { 132 db zonddb.Database 133 chain *core.BlockChain 134 txpool *testTxPool 135 handler *handler 136 } 137 138 // newTestHandler creates a new handler for testing purposes with no blocks. 139 func newTestHandler() *testHandler { 140 return newTestHandlerWithBlocks(0) 141 } 142 143 // newTestHandlerWithBlocks creates a new handler for testing purposes, with a 144 // given number of initial blocks. 145 func newTestHandlerWithBlocks(blocks int) *testHandler { 146 // Create a database pre-initialize with a genesis block 147 db := rawdb.NewMemoryDatabase() 148 gspec := &core.Genesis{ 149 Config: params.TestChainConfig, 150 Alloc: core.GenesisAlloc{testAddr: {Balance: big.NewInt(1000000)}}, 151 } 152 chain, _ := core.NewBlockChain(db, nil, gspec, beacon.NewFaker(), vm.Config{}, nil) 153 154 _, bs, _ := core.GenerateChainWithGenesis(gspec, beacon.NewFaker(), blocks, nil) 155 if _, err := chain.InsertChain(bs); err != nil { 156 panic(err) 157 } 158 txpool := newTestTxPool() 159 160 handler, _ := newHandler(&handlerConfig{ 161 Database: db, 162 Chain: chain, 163 TxPool: txpool, 164 Network: 1, 165 Sync: downloader.SnapSync, 166 BloomCache: 1, 167 }) 168 handler.Start(1000) 169 170 return &testHandler{ 171 db: db, 172 chain: chain, 173 txpool: txpool, 174 handler: handler, 175 } 176 } 177 178 // close tears down the handler and all its internal constructs. 179 func (b *testHandler) close() { 180 b.handler.Stop() 181 b.chain.Stop() 182 }