github.com/etherite/go-etherite@v0.0.0-20171015192807-5f4dd87b2f6e/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 "math/big" 24 25 "github.com/etherite/go-etherite/common" 26 "github.com/etherite/go-etherite/core" 27 "github.com/etherite/go-etherite/core/types" 28 "github.com/etherite/go-etherite/crypto" 29 "github.com/etherite/go-etherite/ethdb" 30 "github.com/etherite/go-etherite/rlp" 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 // OdrBackend is an interface to a backend service that handles ODR retrievals type 38 type OdrBackend interface { 39 Database() ethdb.Database 40 Retrieve(ctx context.Context, req OdrRequest) error 41 } 42 43 // OdrRequest is an interface for retrieval requests 44 type OdrRequest interface { 45 StoreResult(db ethdb.Database) 46 } 47 48 // TrieID identifies a state or account storage trie 49 type TrieID struct { 50 BlockHash, Root common.Hash 51 BlockNumber uint64 52 AccKey []byte 53 } 54 55 // StateTrieID returns a TrieID for a state trie belonging to a certain block 56 // header. 57 func StateTrieID(header *types.Header) *TrieID { 58 return &TrieID{ 59 BlockHash: header.Hash(), 60 BlockNumber: header.Number.Uint64(), 61 AccKey: nil, 62 Root: header.Root, 63 } 64 } 65 66 // StorageTrieID returns a TrieID for a contract storage trie at a given account 67 // of a given state trie. It also requires the root hash of the trie for 68 // checking Merkle proofs. 69 func StorageTrieID(state *TrieID, addrHash, root common.Hash) *TrieID { 70 return &TrieID{ 71 BlockHash: state.BlockHash, 72 BlockNumber: state.BlockNumber, 73 AccKey: addrHash[:], 74 Root: root, 75 } 76 } 77 78 // TrieRequest is the ODR request type for state/storage trie entries 79 type TrieRequest struct { 80 OdrRequest 81 Id *TrieID 82 Key []byte 83 Proof []rlp.RawValue 84 } 85 86 // StoreResult stores the retrieved data in local database 87 func (req *TrieRequest) StoreResult(db ethdb.Database) { 88 storeProof(db, req.Proof) 89 } 90 91 // storeProof stores the new trie nodes obtained from a merkle proof in the database 92 func storeProof(db ethdb.Database, proof []rlp.RawValue) { 93 for _, buf := range proof { 94 hash := crypto.Keccak256(buf) 95 val, _ := db.Get(hash) 96 if val == nil { 97 db.Put(hash, buf) 98 } 99 } 100 } 101 102 // CodeRequest is the ODR request type for retrieving contract code 103 type CodeRequest struct { 104 OdrRequest 105 Id *TrieID // references storage trie of the account 106 Hash common.Hash 107 Data []byte 108 } 109 110 // StoreResult stores the retrieved data in local database 111 func (req *CodeRequest) StoreResult(db ethdb.Database) { 112 db.Put(req.Hash[:], req.Data) 113 } 114 115 // BlockRequest is the ODR request type for retrieving block bodies 116 type BlockRequest struct { 117 OdrRequest 118 Hash common.Hash 119 Number uint64 120 Rlp []byte 121 } 122 123 // StoreResult stores the retrieved data in local database 124 func (req *BlockRequest) StoreResult(db ethdb.Database) { 125 core.WriteBodyRLP(db, req.Hash, req.Number, req.Rlp) 126 } 127 128 // ReceiptsRequest is the ODR request type for retrieving block bodies 129 type ReceiptsRequest struct { 130 OdrRequest 131 Hash common.Hash 132 Number uint64 133 Receipts types.Receipts 134 } 135 136 // StoreResult stores the retrieved data in local database 137 func (req *ReceiptsRequest) StoreResult(db ethdb.Database) { 138 core.WriteBlockReceipts(db, req.Hash, req.Number, req.Receipts) 139 } 140 141 // TrieRequest is the ODR request type for state/storage trie entries 142 type ChtRequest struct { 143 OdrRequest 144 ChtNum, BlockNum uint64 145 ChtRoot common.Hash 146 Header *types.Header 147 Td *big.Int 148 Proof []rlp.RawValue 149 } 150 151 // StoreResult stores the retrieved data in local database 152 func (req *ChtRequest) StoreResult(db ethdb.Database) { 153 // if there is a canonical hash, there is a header too 154 core.WriteHeader(db, req.Header) 155 hash, num := req.Header.Hash(), req.Header.Number.Uint64() 156 core.WriteTd(db, hash, num, req.Td) 157 core.WriteCanonicalHash(db, hash, num) 158 //storeProof(db, req.Proof) 159 }