github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/core/state/database.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2017 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package state 26 27 import ( 28 "fmt" 29 "sync" 30 31 "github.com/ethereum/go-ethereum/common" 32 "github.com/ethereum/go-ethereum/ethdb" 33 "github.com/ethereum/go-ethereum/trie" 34 lru "github.com/hashicorp/golang-lru" 35 ) 36 37 //trie缓存生成限制,在此之后将trie节点从内存中逐出。 38 var MaxTrieCacheGen = uint16(120) 39 40 const ( 41 //要保留的过去尝试次数。此值的选择方式如下: 42 //合理的链条重铺深度将达到现有的三重。 43 maxPastTries = 12 44 45 //要保留的codehash->大小关联数。 46 codeSizeCacheSize = 100000 47 ) 48 49 //数据库将访问权限包装为“尝试”和“合同代码”。 50 type Database interface { 51 //opentrie打开主帐户trie。 52 OpenTrie(root common.Hash) (Trie, error) 53 54 //openstoragetrie打开帐户的存储trie。 55 OpenStorageTrie(addrHash, root common.Hash) (Trie, error) 56 57 //copy trie返回给定trie的独立副本。 58 CopyTrie(Trie) Trie 59 60 //ContractCode检索特定合同的代码。 61 ContractCode(addrHash, codeHash common.Hash) ([]byte, error) 62 63 //ContractCodeSize检索特定合同代码的大小。 64 ContractCodeSize(addrHash, codeHash common.Hash) (int, error) 65 66 //triedb检索用于数据存储的低级trie数据库。 67 TrieDB() *trie.Database 68 } 69 70 //特里亚是以太梅克尔特里亚。 71 type Trie interface { 72 TryGet(key []byte) ([]byte, error) 73 TryUpdate(key, value []byte) error 74 TryDelete(key []byte) error 75 Commit(onleaf trie.LeafCallback) (common.Hash, error) 76 Hash() common.Hash 77 NodeIterator(startKey []byte) trie.NodeIterator 78 GetKey([]byte) []byte //TODO(FJL):移除SecureTrie时移除此项 79 Prove(key []byte, fromLevel uint, proofDb ethdb.Putter) error 80 } 81 82 //NeXDATA为状态创建后备存储。返回的数据库是安全的 83 //同时使用并将缓存的trie节点保留在内存中。游泳池是可选的 84 //在低级存储层和 85 //高级Trie抽象。 86 func NewDatabase(db ethdb.Database) Database { 87 csc, _ := lru.New(codeSizeCacheSize) 88 return &cachingDB{ 89 db: trie.NewDatabase(db), 90 codeSizeCache: csc, 91 } 92 } 93 94 type cachingDB struct { 95 db *trie.Database 96 mu sync.Mutex 97 pastTries []*trie.SecureTrie 98 codeSizeCache *lru.Cache 99 } 100 101 //opentrie打开主帐户trie。 102 func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) { 103 db.mu.Lock() 104 defer db.mu.Unlock() 105 106 for i := len(db.pastTries) - 1; i >= 0; i-- { 107 if db.pastTries[i].Hash() == root { 108 return cachedTrie{db.pastTries[i].Copy(), db}, nil 109 } 110 } 111 tr, err := trie.NewSecure(root, db.db, MaxTrieCacheGen) 112 if err != nil { 113 return nil, err 114 } 115 return cachedTrie{tr, db}, nil 116 } 117 118 func (db *cachingDB) pushTrie(t *trie.SecureTrie) { 119 db.mu.Lock() 120 defer db.mu.Unlock() 121 122 if len(db.pastTries) >= maxPastTries { 123 copy(db.pastTries, db.pastTries[1:]) 124 db.pastTries[len(db.pastTries)-1] = t 125 } else { 126 db.pastTries = append(db.pastTries, t) 127 } 128 } 129 130 //openstoragetrie打开帐户的存储trie。 131 func (db *cachingDB) OpenStorageTrie(addrHash, root common.Hash) (Trie, error) { 132 return trie.NewSecure(root, db.db, 0) 133 } 134 135 //copy trie返回给定trie的独立副本。 136 func (db *cachingDB) CopyTrie(t Trie) Trie { 137 switch t := t.(type) { 138 case cachedTrie: 139 return cachedTrie{t.SecureTrie.Copy(), db} 140 case *trie.SecureTrie: 141 return t.Copy() 142 default: 143 panic(fmt.Errorf("unknown trie type %T", t)) 144 } 145 } 146 147 //ContractCode检索特定合同的代码。 148 func (db *cachingDB) ContractCode(addrHash, codeHash common.Hash) ([]byte, error) { 149 code, err := db.db.Node(codeHash) 150 if err == nil { 151 db.codeSizeCache.Add(codeHash, len(code)) 152 } 153 return code, err 154 } 155 156 //ContractCodeSize检索特定合同代码的大小。 157 func (db *cachingDB) ContractCodeSize(addrHash, codeHash common.Hash) (int, error) { 158 if cached, ok := db.codeSizeCache.Get(codeHash); ok { 159 return cached.(int), nil 160 } 161 code, err := db.ContractCode(addrHash, codeHash) 162 return len(code), err 163 } 164 165 //triedb检索任何中间trie节点缓存层。 166 func (db *cachingDB) TrieDB() *trie.Database { 167 return db.db 168 } 169 170 //cachedtrie在提交时将其trie插入cachingdb。 171 type cachedTrie struct { 172 *trie.SecureTrie 173 db *cachingDB 174 } 175 176 func (m cachedTrie) Commit(onleaf trie.LeafCallback) (common.Hash, error) { 177 root, err := m.SecureTrie.Commit(onleaf) 178 if err == nil { 179 m.db.pushTrie(m.SecureTrie) 180 } 181 return root, err 182 } 183 184 func (m cachedTrie) Prove(key []byte, fromLevel uint, proofDb ethdb.Putter) error { 185 return m.SecureTrie.Prove(key, fromLevel, proofDb) 186 }