github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/core/state/managed_state.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  	"sync"
    29  
    30  	"github.com/ethereum/go-ethereum/common"
    31  )
    32  
    33  type account struct {
    34  	stateObject *stateObject
    35  	nstart      uint64
    36  	nonces      []bool
    37  }
    38  
    39  type ManagedState struct {
    40  	*StateDB
    41  
    42  	mu sync.RWMutex
    43  
    44  	accounts map[common.Address]*account
    45  }
    46  
    47  //managedState返回一个新的托管状态,statedb作为它的支持层。
    48  func ManageState(statedb *StateDB) *ManagedState {
    49  	return &ManagedState{
    50  		StateDB:  statedb.Copy(),
    51  		accounts: make(map[common.Address]*account),
    52  	}
    53  }
    54  
    55  //setstate设置托管状态的底层
    56  func (ms *ManagedState) SetState(statedb *StateDB) {
    57  	ms.mu.Lock()
    58  	defer ms.mu.Unlock()
    59  	ms.StateDB = statedb
    60  }
    61  
    62  //removenonce从托管状态中删除了nonce以及所有将来挂起的nonce
    63  func (ms *ManagedState) RemoveNonce(addr common.Address, n uint64) {
    64  	if ms.hasAccount(addr) {
    65  		ms.mu.Lock()
    66  		defer ms.mu.Unlock()
    67  
    68  		account := ms.getAccount(addr)
    69  		if n-account.nstart <= uint64(len(account.nonces)) {
    70  			reslice := make([]bool, n-account.nstart)
    71  			copy(reslice, account.nonces[:n-account.nstart])
    72  			account.nonces = reslice
    73  		}
    74  	}
    75  }
    76  
    77  //new nonce返回托管帐户的新规范nonce
    78  func (ms *ManagedState) NewNonce(addr common.Address) uint64 {
    79  	ms.mu.Lock()
    80  	defer ms.mu.Unlock()
    81  
    82  	account := ms.getAccount(addr)
    83  	for i, nonce := range account.nonces {
    84  		if !nonce {
    85  			return account.nstart + uint64(i)
    86  		}
    87  	}
    88  	account.nonces = append(account.nonces, true)
    89  
    90  	return uint64(len(account.nonces)-1) + account.nstart
    91  }
    92  
    93  //GETNONCE返回托管或非托管帐户的规范NoCE。
    94  //
    95  //因为getnonce改变了db,所以我们必须获得一个写锁。
    96  func (ms *ManagedState) GetNonce(addr common.Address) uint64 {
    97  	ms.mu.Lock()
    98  	defer ms.mu.Unlock()
    99  
   100  	if ms.hasAccount(addr) {
   101  		account := ms.getAccount(addr)
   102  		return uint64(len(account.nonces)) + account.nstart
   103  	} else {
   104  		return ms.StateDB.GetNonce(addr)
   105  	}
   106  }
   107  
   108  //setnonce为托管状态设置新的规范nonce
   109  func (ms *ManagedState) SetNonce(addr common.Address, nonce uint64) {
   110  	ms.mu.Lock()
   111  	defer ms.mu.Unlock()
   112  
   113  	so := ms.GetOrNewStateObject(addr)
   114  	so.SetNonce(nonce)
   115  
   116  	ms.accounts[addr] = newAccount(so)
   117  }
   118  
   119  //hasAccount返回给定地址是否被管理
   120  func (ms *ManagedState) HasAccount(addr common.Address) bool {
   121  	ms.mu.RLock()
   122  	defer ms.mu.RUnlock()
   123  	return ms.hasAccount(addr)
   124  }
   125  
   126  func (ms *ManagedState) hasAccount(addr common.Address) bool {
   127  	_, ok := ms.accounts[addr]
   128  	return ok
   129  }
   130  
   131  //填充托管状态
   132  func (ms *ManagedState) getAccount(addr common.Address) *account {
   133  	if account, ok := ms.accounts[addr]; !ok {
   134  		so := ms.GetOrNewStateObject(addr)
   135  		ms.accounts[addr] = newAccount(so)
   136  	} else {
   137  //始终确保状态帐户nonce实际上不高于
   138  //比跟踪的那个。
   139  		so := ms.StateDB.getStateObject(addr)
   140  		if so != nil && uint64(len(account.nonces))+account.nstart < so.Nonce() {
   141  			ms.accounts[addr] = newAccount(so)
   142  		}
   143  
   144  	}
   145  
   146  	return ms.accounts[addr]
   147  }
   148  
   149  func newAccount(so *stateObject) *account {
   150  	return &account{so, so.Nonce(), nil}
   151  }