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