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  }