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