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