github.com/abschain-develop/go-abs@v2.0.3+incompatible/light/odr.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 light implements on-demand retrieval capable state and chain objects 18 // for the Ethereum Light Client. 19 package light 20 21 import ( 22 "context" 23 "errors" 24 "math/big" 25 26 "github.com/abschain-develop/go-abs/common" 27 "github.com/abschain-develop/go-abs/core" 28 "github.com/abschain-develop/go-abs/core/rawdb" 29 "github.com/abschain-develop/go-abs/core/types" 30 "github.com/abschain-develop/go-abs/ethdb" 31 ) 32 33 // NoOdr is the default context passed to an ODR capable function when the ODR 34 // service is not required. 35 var NoOdr = context.Background() 36 37 // ErrNoPeers is returned if no peers capable of serving a queued request are available 38 var ErrNoPeers = errors.New("no suitable peers available") 39 40 // OdrBackend is an interface to a backend service that handles ODR retrievals type 41 type OdrBackend interface { 42 Database() ethdb.Database 43 ChtIndexer() *core.ChainIndexer 44 BloomTrieIndexer() *core.ChainIndexer 45 BloomIndexer() *core.ChainIndexer 46 Retrieve(ctx context.Context, req OdrRequest) error 47 IndexerConfig() *IndexerConfig 48 } 49 50 // OdrRequest is an interface for retrieval requests 51 type OdrRequest interface { 52 StoreResult(db ethdb.Database) 53 } 54 55 // TrieID identifies a state or account storage trie 56 type TrieID struct { 57 BlockHash, Root common.Hash 58 BlockNumber uint64 59 AccKey []byte 60 } 61 62 // StateTrieID returns a TrieID for a state trie belonging to a certain block 63 // header. 64 func StateTrieID(header *types.Header) *TrieID { 65 return &TrieID{ 66 BlockHash: header.Hash(), 67 BlockNumber: header.Number.Uint64(), 68 AccKey: nil, 69 Root: header.Root, 70 } 71 } 72 73 // StorageTrieID returns a TrieID for a contract storage trie at a given account 74 // of a given state trie. It also requires the root hash of the trie for 75 // checking Merkle proofs. 76 func StorageTrieID(state *TrieID, addrHash, root common.Hash) *TrieID { 77 return &TrieID{ 78 BlockHash: state.BlockHash, 79 BlockNumber: state.BlockNumber, 80 AccKey: addrHash[:], 81 Root: root, 82 } 83 } 84 85 // TrieRequest is the ODR request type for state/storage trie entries 86 type TrieRequest struct { 87 OdrRequest 88 Id *TrieID 89 Key []byte 90 Proof *NodeSet 91 } 92 93 // StoreResult stores the retrieved data in local database 94 func (req *TrieRequest) StoreResult(db ethdb.Database) { 95 req.Proof.Store(db) 96 } 97 98 // CodeRequest is the ODR request type for retrieving contract code 99 type CodeRequest struct { 100 OdrRequest 101 Id *TrieID // references storage trie of the account 102 Hash common.Hash 103 Data []byte 104 } 105 106 // StoreResult stores the retrieved data in local database 107 func (req *CodeRequest) StoreResult(db ethdb.Database) { 108 db.Put(req.Hash[:], req.Data) 109 } 110 111 // BlockRequest is the ODR request type for retrieving block bodies 112 type BlockRequest struct { 113 OdrRequest 114 Hash common.Hash 115 Number uint64 116 Rlp []byte 117 } 118 119 // StoreResult stores the retrieved data in local database 120 func (req *BlockRequest) StoreResult(db ethdb.Database) { 121 rawdb.WriteBodyRLP(db, req.Hash, req.Number, req.Rlp) 122 } 123 124 // ReceiptsRequest is the ODR request type for retrieving block bodies 125 type ReceiptsRequest struct { 126 OdrRequest 127 Hash common.Hash 128 Number uint64 129 Receipts types.Receipts 130 } 131 132 // StoreResult stores the retrieved data in local database 133 func (req *ReceiptsRequest) StoreResult(db ethdb.Database) { 134 rawdb.WriteReceipts(db, req.Hash, req.Number, req.Receipts) 135 } 136 137 // ChtRequest is the ODR request type for state/storage trie entries 138 type ChtRequest struct { 139 OdrRequest 140 Config *IndexerConfig 141 ChtNum, BlockNum uint64 142 ChtRoot common.Hash 143 Header *types.Header 144 Td *big.Int 145 Proof *NodeSet 146 } 147 148 // StoreResult stores the retrieved data in local database 149 func (req *ChtRequest) StoreResult(db ethdb.Database) { 150 hash, num := req.Header.Hash(), req.Header.Number.Uint64() 151 152 rawdb.WriteHeader(db, req.Header) 153 rawdb.WriteTd(db, hash, num, req.Td) 154 rawdb.WriteCanonicalHash(db, hash, num) 155 } 156 157 // BloomRequest is the ODR request type for retrieving bloom filters from a CHT structure 158 type BloomRequest struct { 159 OdrRequest 160 Config *IndexerConfig 161 BloomTrieNum uint64 162 BitIdx uint 163 SectionIndexList []uint64 164 BloomTrieRoot common.Hash 165 BloomBits [][]byte 166 Proofs *NodeSet 167 } 168 169 // StoreResult stores the retrieved data in local database 170 func (req *BloomRequest) StoreResult(db ethdb.Database) { 171 for i, sectionIdx := range req.SectionIndexList { 172 sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*req.Config.BloomTrieSize-1) 173 // if we don't have the canonical hash stored for this section head number, we'll still store it under 174 // a key with a zero sectionHead. GetBloomBits will look there too if we still don't have the canonical 175 // hash. In the unlikely case we've retrieved the section head hash since then, we'll just retrieve the 176 // bit vector again from the network. 177 rawdb.WriteBloomBits(db, req.BitIdx, sectionIdx, sectionHead, req.BloomBits[i]) 178 } 179 }