github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/core/state/iterator.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  //版权所有2015 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  	"bytes"
    29  	"fmt"
    30  
    31  	"github.com/ethereum/go-ethereum/common"
    32  	"github.com/ethereum/go-ethereum/rlp"
    33  	"github.com/ethereum/go-ethereum/trie"
    34  )
    35  
    36  //nodeiterator是遍历整个状态trie post顺序的迭代器,
    37  //包括所有合同代码和合同状态尝试。
    38  type NodeIterator struct {
    39  state *StateDB //正在迭代的状态
    40  
    41  stateIt trie.NodeIterator //全局状态trie的主迭代器
    42  dataIt  trie.NodeIterator //合同数据检索的辅助迭代器
    43  
    44  accountHash common.Hash //包含帐户的节点的哈希
    45  codeHash    common.Hash //合同源代码的哈希
    46  code        []byte      //与合同相关的源代码
    47  
    48  Hash   common.Hash //正在迭代的当前条目的哈希(如果不是独立的,则为零)
    49  Parent common.Hash //第一个完整祖先节点的哈希(如果当前是根节点,则为零)
    50  
    51  Error error //迭代器中出现内部错误时的故障集
    52  }
    53  
    54  //newnodeiterator创建一个后序状态节点迭代器。
    55  func NewNodeIterator(state *StateDB) *NodeIterator {
    56  	return &NodeIterator{
    57  		state: state,
    58  	}
    59  }
    60  
    61  //next将迭代器移动到下一个节点,返回是否存在
    62  //进一步的节点。如果出现内部错误,此方法将返回false,并且
    63  //将错误字段设置为遇到的故障。
    64  func (it *NodeIterator) Next() bool {
    65  //如果迭代器以前失败,则不要执行任何操作
    66  	if it.Error != nil {
    67  		return false
    68  	}
    69  //否则,使用迭代器前进并报告任何错误
    70  	if err := it.step(); err != nil {
    71  		it.Error = err
    72  		return false
    73  	}
    74  	return it.retrieve()
    75  }
    76  
    77  //步骤将迭代器移动到状态trie的下一个条目。
    78  func (it *NodeIterator) step() error {
    79  //如果到达迭代结束,则中止
    80  	if it.state == nil {
    81  		return nil
    82  	}
    83  //如果我们刚开始初始化迭代器
    84  	if it.stateIt == nil {
    85  		it.stateIt = it.state.trie.NodeIterator(nil)
    86  	}
    87  //如果我们以前有数据节点,那么我们肯定至少有状态节点
    88  	if it.dataIt != nil {
    89  		if cont := it.dataIt.Next(true); !cont {
    90  			if it.dataIt.Error() != nil {
    91  				return it.dataIt.Error()
    92  			}
    93  			it.dataIt = nil
    94  		}
    95  		return nil
    96  	}
    97  //如果我们以前有源代码,就放弃它
    98  	if it.code != nil {
    99  		it.code = nil
   100  		return nil
   101  	}
   102  //进入下一个状态trie节点,如果节点用完则终止
   103  	if cont := it.stateIt.Next(true); !cont {
   104  		if it.stateIt.Error() != nil {
   105  			return it.stateIt.Error()
   106  		}
   107  		it.state, it.stateIt = nil, nil
   108  		return nil
   109  	}
   110  //如果状态trie节点是内部条目,则保持原样
   111  	if !it.stateIt.Leaf() {
   112  		return nil
   113  	}
   114  //否则,我们将到达一个帐户节点,开始数据迭代
   115  	var account Account
   116  	if err := rlp.Decode(bytes.NewReader(it.stateIt.LeafBlob()), &account); err != nil {
   117  		return err
   118  	}
   119  	dataTrie, err := it.state.db.OpenStorageTrie(common.BytesToHash(it.stateIt.LeafKey()), account.Root)
   120  	if err != nil {
   121  		return err
   122  	}
   123  	it.dataIt = dataTrie.NodeIterator(nil)
   124  	if !it.dataIt.Next(true) {
   125  		it.dataIt = nil
   126  	}
   127  	if !bytes.Equal(account.CodeHash, emptyCodeHash) {
   128  		it.codeHash = common.BytesToHash(account.CodeHash)
   129  		addrHash := common.BytesToHash(it.stateIt.LeafKey())
   130  		it.code, err = it.state.db.ContractCode(addrHash, common.BytesToHash(account.CodeHash))
   131  		if err != nil {
   132  			return fmt.Errorf("code %x: %v", account.CodeHash, err)
   133  		}
   134  	}
   135  	it.accountHash = it.stateIt.Parent()
   136  	return nil
   137  }
   138  
   139  //检索拉取和缓存迭代器正在遍历的当前状态条目。
   140  //该方法返回是否还有其他数据要检查。
   141  func (it *NodeIterator) retrieve() bool {
   142  //清除任何预先设置的值
   143  	it.Hash = common.Hash{}
   144  
   145  //如果迭代完成,则不返回可用数据
   146  	if it.state == nil {
   147  		return false
   148  	}
   149  //否则检索当前条目
   150  	switch {
   151  	case it.dataIt != nil:
   152  		it.Hash, it.Parent = it.dataIt.Hash(), it.dataIt.Parent()
   153  		if it.Parent == (common.Hash{}) {
   154  			it.Parent = it.accountHash
   155  		}
   156  	case it.code != nil:
   157  		it.Hash, it.Parent = it.codeHash, it.accountHash
   158  	case it.stateIt != nil:
   159  		it.Hash, it.Parent = it.stateIt.Hash(), it.stateIt.Parent()
   160  	}
   161  	return true
   162  }