github.com/theQRL/go-zond@v0.1.1/trie/preimages.go (about) 1 // Copyright 2022 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 trie 18 19 import ( 20 "sync" 21 22 "github.com/theQRL/go-zond/common" 23 "github.com/theQRL/go-zond/core/rawdb" 24 "github.com/theQRL/go-zond/zonddb" 25 ) 26 27 // preimageStore is the store for caching preimages of node key. 28 type preimageStore struct { 29 lock sync.RWMutex 30 disk zonddb.KeyValueStore 31 preimages map[common.Hash][]byte // Preimages of nodes from the secure trie 32 preimagesSize common.StorageSize // Storage size of the preimages cache 33 } 34 35 // newPreimageStore initializes the store for caching preimages. 36 func newPreimageStore(disk zonddb.KeyValueStore) *preimageStore { 37 return &preimageStore{ 38 disk: disk, 39 preimages: make(map[common.Hash][]byte), 40 } 41 } 42 43 // insertPreimage writes a new trie node pre-image to the memory database if it's 44 // yet unknown. The method will NOT make a copy of the slice, only use if the 45 // preimage will NOT be changed later on. 46 func (store *preimageStore) insertPreimage(preimages map[common.Hash][]byte) { 47 store.lock.Lock() 48 defer store.lock.Unlock() 49 50 for hash, preimage := range preimages { 51 if _, ok := store.preimages[hash]; ok { 52 continue 53 } 54 store.preimages[hash] = preimage 55 store.preimagesSize += common.StorageSize(common.HashLength + len(preimage)) 56 } 57 } 58 59 // preimage retrieves a cached trie node pre-image from memory. If it cannot be 60 // found cached, the method queries the persistent database for the content. 61 func (store *preimageStore) preimage(hash common.Hash) []byte { 62 store.lock.RLock() 63 preimage := store.preimages[hash] 64 store.lock.RUnlock() 65 66 if preimage != nil { 67 return preimage 68 } 69 return rawdb.ReadPreimage(store.disk, hash) 70 } 71 72 // commit flushes the cached preimages into the disk. 73 func (store *preimageStore) commit(force bool) error { 74 store.lock.Lock() 75 defer store.lock.Unlock() 76 77 if store.preimagesSize <= 4*1024*1024 && !force { 78 return nil 79 } 80 batch := store.disk.NewBatch() 81 rawdb.WritePreimages(batch, store.preimages) 82 if err := batch.Write(); err != nil { 83 return err 84 } 85 store.preimages, store.preimagesSize = make(map[common.Hash][]byte), 0 86 return nil 87 } 88 89 // size returns the current storage size of accumulated preimages. 90 func (store *preimageStore) size() common.StorageSize { 91 store.lock.RLock() 92 defer store.lock.RUnlock() 93 94 return store.preimagesSize 95 }