github.com/aigarnetwork/aigar@v0.0.0-20191115204914-d59a6eb70f8e/eth/downloader/fakepeer.go (about) 1 // Copyright 2018 The go-ethereum Authors 2 // Copyright 2019 The go-aigar Authors 3 // This file is part of the go-aigar library. 4 // 5 // The go-aigar 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-aigar 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-aigar library. If not, see <http://www.gnu.org/licenses/>. 17 18 package downloader 19 20 import ( 21 "math/big" 22 23 "github.com/AigarNetwork/aigar/common" 24 "github.com/AigarNetwork/aigar/core" 25 "github.com/AigarNetwork/aigar/core/rawdb" 26 "github.com/AigarNetwork/aigar/core/types" 27 "github.com/AigarNetwork/aigar/ethdb" 28 ) 29 30 // FakePeer is a mock downloader peer that operates on a local database instance 31 // instead of being an actual live node. It's useful for testing and to implement 32 // sync commands from an existing local database. 33 type FakePeer struct { 34 id string 35 db ethdb.Database 36 hc *core.HeaderChain 37 dl *Downloader 38 } 39 40 // NewFakePeer creates a new mock downloader peer with the given data sources. 41 func NewFakePeer(id string, db ethdb.Database, hc *core.HeaderChain, dl *Downloader) *FakePeer { 42 return &FakePeer{id: id, db: db, hc: hc, dl: dl} 43 } 44 45 // Head implements downloader.Peer, returning the current head hash and number 46 // of the best known header. 47 func (p *FakePeer) Head() (common.Hash, *big.Int) { 48 header := p.hc.CurrentHeader() 49 return header.Hash(), header.Number 50 } 51 52 // RequestHeadersByHash implements downloader.Peer, returning a batch of headers 53 // defined by the origin hash and the associated query parameters. 54 func (p *FakePeer) RequestHeadersByHash(hash common.Hash, amount int, skip int, reverse bool) error { 55 var ( 56 headers []*types.Header 57 unknown bool 58 ) 59 for !unknown && len(headers) < amount { 60 origin := p.hc.GetHeaderByHash(hash) 61 if origin == nil { 62 break 63 } 64 number := origin.Number.Uint64() 65 headers = append(headers, origin) 66 if reverse { 67 for i := 0; i <= skip; i++ { 68 if header := p.hc.GetHeader(hash, number); header != nil { 69 hash = header.ParentHash 70 number-- 71 } else { 72 unknown = true 73 break 74 } 75 } 76 } else { 77 var ( 78 current = origin.Number.Uint64() 79 next = current + uint64(skip) + 1 80 ) 81 if header := p.hc.GetHeaderByNumber(next); header != nil { 82 if p.hc.GetBlockHashesFromHash(header.Hash(), uint64(skip+1))[skip] == hash { 83 hash = header.Hash() 84 } else { 85 unknown = true 86 } 87 } else { 88 unknown = true 89 } 90 } 91 } 92 p.dl.DeliverHeaders(p.id, headers) 93 return nil 94 } 95 96 // RequestHeadersByNumber implements downloader.Peer, returning a batch of headers 97 // defined by the origin number and the associated query parameters. 98 func (p *FakePeer) RequestHeadersByNumber(number uint64, amount int, skip int, reverse bool) error { 99 var ( 100 headers []*types.Header 101 unknown bool 102 ) 103 for !unknown && len(headers) < amount { 104 origin := p.hc.GetHeaderByNumber(number) 105 if origin == nil { 106 break 107 } 108 if reverse { 109 if number >= uint64(skip+1) { 110 number -= uint64(skip + 1) 111 } else { 112 unknown = true 113 } 114 } else { 115 number += uint64(skip + 1) 116 } 117 headers = append(headers, origin) 118 } 119 p.dl.DeliverHeaders(p.id, headers) 120 return nil 121 } 122 123 // RequestBodies implements downloader.Peer, returning a batch of block bodies 124 // corresponding to the specified block hashes. 125 func (p *FakePeer) RequestBodies(hashes []common.Hash) error { 126 var ( 127 txs [][]*types.Transaction 128 uncles [][]*types.Header 129 ) 130 for _, hash := range hashes { 131 block := rawdb.ReadBlock(p.db, hash, *p.hc.GetBlockNumber(hash)) 132 133 txs = append(txs, block.Transactions()) 134 uncles = append(uncles, block.Uncles()) 135 } 136 p.dl.DeliverBodies(p.id, txs, uncles) 137 return nil 138 } 139 140 // RequestReceipts implements downloader.Peer, returning a batch of transaction 141 // receipts corresponding to the specified block hashes. 142 func (p *FakePeer) RequestReceipts(hashes []common.Hash) error { 143 var receipts [][]*types.Receipt 144 for _, hash := range hashes { 145 receipts = append(receipts, rawdb.ReadRawReceipts(p.db, hash, *p.hc.GetBlockNumber(hash))) 146 } 147 p.dl.DeliverReceipts(p.id, receipts) 148 return nil 149 } 150 151 // RequestNodeData implements downloader.Peer, returning a batch of state trie 152 // nodes corresponding to the specified trie hashes. 153 func (p *FakePeer) RequestNodeData(hashes []common.Hash) error { 154 var data [][]byte 155 for _, hash := range hashes { 156 if entry, err := p.db.Get(hash.Bytes()); err == nil { 157 data = append(data, entry) 158 } 159 } 160 p.dl.DeliverNodeData(p.id, data) 161 return nil 162 }