github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/core/state/iterator.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:35</date>
    10  //</624450079884840960>
    11  
    12  
    13  package state
    14  
    15  import (
    16  	"bytes"
    17  	"fmt"
    18  
    19  	"github.com/ethereum/go-ethereum/common"
    20  	"github.com/ethereum/go-ethereum/rlp"
    21  	"github.com/ethereum/go-ethereum/trie"
    22  )
    23  
    24  //nodeiterator是遍历整个状态trie post顺序的迭代器,
    25  //including all of the contract code and contract state tries.
    26  type NodeIterator struct {
    27  state *StateDB //正在迭代的状态
    28  
    29  stateIt trie.NodeIterator //全局状态trie的主迭代器
    30  dataIt  trie.NodeIterator //Secondary iterator for the data trie of a contract
    31  
    32  accountHash common.Hash //包含帐户的节点的哈希
    33  codeHash    common.Hash //合同源代码的哈希
    34  code        []byte      //与合同相关的源代码
    35  
    36  Hash   common.Hash //正在迭代的当前条目的哈希(如果不是独立的,则为零)
    37  Parent common.Hash //第一个完整祖先节点的哈希(如果当前是根节点,则为零)
    38  
    39  Error error //迭代器中出现内部错误时的故障集
    40  }
    41  
    42  //newnodeiterator创建一个后序状态节点迭代器。
    43  func NewNodeIterator(state *StateDB) *NodeIterator {
    44  	return &NodeIterator{
    45  		state: state,
    46  	}
    47  }
    48  
    49  //next将迭代器移动到下一个节点,返回是否存在
    50  //进一步的节点。如果出现内部错误,此方法将返回false,并且
    51  //将错误字段设置为遇到的故障。
    52  func (it *NodeIterator) Next() bool {
    53  //如果迭代器以前失败,则不要执行任何操作
    54  	if it.Error != nil {
    55  		return false
    56  	}
    57  //否则,使用迭代器前进并报告任何错误
    58  	if err := it.step(); err != nil {
    59  		it.Error = err
    60  		return false
    61  	}
    62  	return it.retrieve()
    63  }
    64  
    65  //步骤将迭代器移动到状态trie的下一个条目。
    66  func (it *NodeIterator) step() error {
    67  //如果到达迭代结束,则中止
    68  	if it.state == nil {
    69  		return nil
    70  	}
    71  //如果我们刚开始初始化迭代器
    72  	if it.stateIt == nil {
    73  		it.stateIt = it.state.trie.NodeIterator(nil)
    74  	}
    75  //如果我们以前有数据节点,那么我们肯定至少有状态节点
    76  	if it.dataIt != nil {
    77  		if cont := it.dataIt.Next(true); !cont {
    78  			if it.dataIt.Error() != nil {
    79  				return it.dataIt.Error()
    80  			}
    81  			it.dataIt = nil
    82  		}
    83  		return nil
    84  	}
    85  //If we had source code previously, discard that
    86  	if it.code != nil {
    87  		it.code = nil
    88  		return nil
    89  	}
    90  //进入下一个状态trie节点,如果节点用完则终止
    91  	if cont := it.stateIt.Next(true); !cont {
    92  		if it.stateIt.Error() != nil {
    93  			return it.stateIt.Error()
    94  		}
    95  		it.state, it.stateIt = nil, nil
    96  		return nil
    97  	}
    98  //如果状态trie节点是内部条目,则保持原样
    99  	if !it.stateIt.Leaf() {
   100  		return nil
   101  	}
   102  //否则,我们将到达一个帐户节点,开始数据迭代
   103  	var account Account
   104  	if err := rlp.Decode(bytes.NewReader(it.stateIt.LeafBlob()), &account); err != nil {
   105  		return err
   106  	}
   107  	dataTrie, err := it.state.db.OpenStorageTrie(common.BytesToHash(it.stateIt.LeafKey()), account.Root)
   108  	if err != nil {
   109  		return err
   110  	}
   111  	it.dataIt = dataTrie.NodeIterator(nil)
   112  	if !it.dataIt.Next(true) {
   113  		it.dataIt = nil
   114  	}
   115  	if !bytes.Equal(account.CodeHash, emptyCodeHash) {
   116  		it.codeHash = common.BytesToHash(account.CodeHash)
   117  		addrHash := common.BytesToHash(it.stateIt.LeafKey())
   118  		it.code, err = it.state.db.ContractCode(addrHash, common.BytesToHash(account.CodeHash))
   119  		if err != nil {
   120  			return fmt.Errorf("code %x: %v", account.CodeHash, err)
   121  		}
   122  	}
   123  	it.accountHash = it.stateIt.Parent()
   124  	return nil
   125  }
   126  
   127  //检索拉取和缓存迭代器正在遍历的当前状态条目。
   128  //该方法返回是否还有其他数据要检查。
   129  func (it *NodeIterator) retrieve() bool {
   130  //清除任何预先设置的值
   131  	it.Hash = common.Hash{}
   132  
   133  //如果迭代完成,则不返回可用数据
   134  	if it.state == nil {
   135  		return false
   136  	}
   137  //否则检索当前条目
   138  	switch {
   139  	case it.dataIt != nil:
   140  		it.Hash, it.Parent = it.dataIt.Hash(), it.dataIt.Parent()
   141  		if it.Parent == (common.Hash{}) {
   142  			it.Parent = it.accountHash
   143  		}
   144  	case it.code != nil:
   145  		it.Hash, it.Parent = it.codeHash, it.accountHash
   146  	case it.stateIt != nil:
   147  		it.Hash, it.Parent = it.stateIt.Hash(), it.stateIt.Parent()
   148  	}
   149  	return true
   150  }
   151