github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/consensus/clique/snapshot.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 clique
    26  
    27  import (
    28  	"bytes"
    29  	"encoding/json"
    30  	"sort"
    31  
    32  	"github.com/ethereum/go-ethereum/common"
    33  	"github.com/ethereum/go-ethereum/core/types"
    34  	"github.com/ethereum/go-ethereum/ethdb"
    35  	"github.com/ethereum/go-ethereum/params"
    36  	lru "github.com/hashicorp/golang-lru"
    37  )
    38  
    39  //投票代表授权签名人修改
    40  //授权列表。
    41  type Vote struct {
    42  Signer    common.Address `json:"signer"`    //投票的授权签署人
    43  Block     uint64         `json:"block"`     //投票所投的区号(过期旧票)
    44  Address   common.Address `json:"address"`   //正在投票更改其授权的帐户
    45  Authorize bool           `json:"authorize"` //是否授权或取消对投票帐户的授权
    46  }
    47  
    48  //计票是一种简单的计票方式,用来保持当前的计票结果。投票赞成
    49  //反对这项提议并不算在内,因为它等同于不投票。
    50  type Tally struct {
    51  Authorize bool `json:"authorize"` //投票是授权还是踢某人
    52  Votes     int  `json:"votes"`     //到目前为止想要通过提案的票数
    53  }
    54  
    55  //快照是在给定时间点上投票的授权状态。
    56  type Snapshot struct {
    57  config   *params.CliqueConfig //微调行为的一致引擎参数
    58  sigcache *lru.ARCCache        //缓存最近的块签名以加快ecrecover
    59  
    60  Number  uint64                      `json:"number"`  //创建快照的块号
    61  Hash    common.Hash                 `json:"hash"`    //创建快照的块哈希
    62  Signers map[common.Address]struct{} `json:"signers"` //此时的授权签名人集合
    63  Recents map[uint64]common.Address   `json:"recents"` //垃圾邮件保护的最近签名者集
    64  Votes   []*Vote                     `json:"votes"`   //按时间顺序投票的名单
    65  Tally   map[common.Address]Tally    `json:"tally"`   //当前投票计数以避免重新计算
    66  }
    67  
    68  //签名者实现排序接口以允许对地址列表进行排序
    69  type signers []common.Address
    70  
    71  func (s signers) Len() int           { return len(s) }
    72  func (s signers) Less(i, j int) bool { return bytes.Compare(s[i][:], s[j][:]) < 0 }
    73  func (s signers) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
    74  
    75  //
    76  //方法不初始化最近的签名者集,因此仅当用于
    77  //
    78  func newSnapshot(config *params.CliqueConfig, sigcache *lru.ARCCache, number uint64, hash common.Hash, signers []common.Address) *Snapshot {
    79  	snap := &Snapshot{
    80  		config:   config,
    81  		sigcache: sigcache,
    82  		Number:   number,
    83  		Hash:     hash,
    84  		Signers:  make(map[common.Address]struct{}),
    85  		Recents:  make(map[uint64]common.Address),
    86  		Tally:    make(map[common.Address]Tally),
    87  	}
    88  	for _, signer := range signers {
    89  		snap.Signers[signer] = struct{}{}
    90  	}
    91  	return snap
    92  }
    93  
    94  //LoadSnapshot从数据库加载现有快照。
    95  func loadSnapshot(config *params.CliqueConfig, sigcache *lru.ARCCache, db ethdb.Database, hash common.Hash) (*Snapshot, error) {
    96  	blob, err := db.Get(append([]byte("clique-"), hash[:]...))
    97  	if err != nil {
    98  		return nil, err
    99  	}
   100  	snap := new(Snapshot)
   101  	if err := json.Unmarshal(blob, snap); err != nil {
   102  		return nil, err
   103  	}
   104  	snap.config = config
   105  	snap.sigcache = sigcache
   106  
   107  	return snap, nil
   108  }
   109  
   110  //存储将快照插入数据库。
   111  func (s *Snapshot) store(db ethdb.Database) error {
   112  	blob, err := json.Marshal(s)
   113  	if err != nil {
   114  		return err
   115  	}
   116  	return db.Put(append([]byte("clique-"), s.Hash[:]...), blob)
   117  }
   118  
   119  //
   120  func (s *Snapshot) copy() *Snapshot {
   121  	cpy := &Snapshot{
   122  		config:   s.config,
   123  		sigcache: s.sigcache,
   124  		Number:   s.Number,
   125  		Hash:     s.Hash,
   126  		Signers:  make(map[common.Address]struct{}),
   127  		Recents:  make(map[uint64]common.Address),
   128  		Votes:    make([]*Vote, len(s.Votes)),
   129  		Tally:    make(map[common.Address]Tally),
   130  	}
   131  	for signer := range s.Signers {
   132  		cpy.Signers[signer] = struct{}{}
   133  	}
   134  	for block, signer := range s.Recents {
   135  		cpy.Recents[block] = signer
   136  	}
   137  	for address, tally := range s.Tally {
   138  		cpy.Tally[address] = tally
   139  	}
   140  	copy(cpy.Votes, s.Votes)
   141  
   142  	return cpy
   143  }
   144  
   145  //validvote返回在
   146  //给定快照上下文(例如,不要尝试添加已授权的签名者)。
   147  func (s *Snapshot) validVote(address common.Address, authorize bool) bool {
   148  	_, signer := s.Signers[address]
   149  	return (signer && !authorize) || (!signer && authorize)
   150  }
   151  
   152  //Cast在计票中添加了新的选票。
   153  func (s *Snapshot) cast(address common.Address, authorize bool) bool {
   154  //确保投票有意义
   155  	if !s.validVote(address, authorize) {
   156  		return false
   157  	}
   158  //将投票投到现有或新的计票中
   159  	if old, ok := s.Tally[address]; ok {
   160  		old.Votes++
   161  		s.Tally[address] = old
   162  	} else {
   163  		s.Tally[address] = Tally{Authorize: authorize, Votes: 1}
   164  	}
   165  	return true
   166  }
   167  
   168  //
   169  func (s *Snapshot) uncast(address common.Address, authorize bool) bool {
   170  //如果没有计票结果,那是悬而未决的投票,就投吧。
   171  	tally, ok := s.Tally[address]
   172  	if !ok {
   173  		return false
   174  	}
   175  //确保我们只还原已计数的投票
   176  	if tally.Authorize != authorize {
   177  		return false
   178  	}
   179  //否则恢复投票
   180  	if tally.Votes > 1 {
   181  		tally.Votes--
   182  		s.Tally[address] = tally
   183  	} else {
   184  		delete(s.Tally, address)
   185  	}
   186  	return true
   187  }
   188  
   189  //应用通过将给定的头应用于创建新的授权快照
   190  //原来的那个。
   191  func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) {
   192  //不允许传入清除器代码的头
   193  	if len(headers) == 0 {
   194  		return s, nil
   195  	}
   196  //
   197  	for i := 0; i < len(headers)-1; i++ {
   198  		if headers[i+1].Number.Uint64() != headers[i].Number.Uint64()+1 {
   199  			return nil, errInvalidVotingChain
   200  		}
   201  	}
   202  	if headers[0].Number.Uint64() != s.Number+1 {
   203  		return nil, errInvalidVotingChain
   204  	}
   205  //遍历头并创建新快照
   206  	snap := s.copy()
   207  
   208  	for _, header := range headers {
   209  //删除检查点块上的所有投票
   210  		number := header.Number.Uint64()
   211  		if number%s.config.Epoch == 0 {
   212  			snap.Votes = nil
   213  			snap.Tally = make(map[common.Address]Tally)
   214  		}
   215  //从最近列表中删除最早的签名者,以允许其再次签名。
   216  		if limit := uint64(len(snap.Signers)/2 + 1); number >= limit {
   217  			delete(snap.Recents, number-limit)
   218  		}
   219  //解析授权密钥并检查签名者
   220  		signer, err := ecrecover(header, s.sigcache)
   221  		if err != nil {
   222  			return nil, err
   223  		}
   224  		if _, ok := snap.Signers[signer]; !ok {
   225  			return nil, errUnauthorized
   226  		}
   227  		for _, recent := range snap.Recents {
   228  			if recent == signer {
   229  				return nil, errUnauthorized
   230  			}
   231  		}
   232  		snap.Recents[number] = signer
   233  
   234  //
   235  		for i, vote := range snap.Votes {
   236  			if vote.Signer == signer && vote.Address == header.Coinbase {
   237  //从缓存的计数中取消投票
   238  				snap.uncast(vote.Address, vote.Authorize)
   239  
   240  //取消按时间顺序排列的投票
   241  				snap.Votes = append(snap.Votes[:i], snap.Votes[i+1:]...)
   242  break //
   243  			}
   244  		}
   245  //统计签名者的新投票
   246  		var authorize bool
   247  		switch {
   248  		case bytes.Equal(header.Nonce[:], nonceAuthVote):
   249  			authorize = true
   250  		case bytes.Equal(header.Nonce[:], nonceDropVote):
   251  			authorize = false
   252  		default:
   253  			return nil, errInvalidVote
   254  		}
   255  		if snap.cast(header.Coinbase, authorize) {
   256  			snap.Votes = append(snap.Votes, &Vote{
   257  				Signer:    signer,
   258  				Block:     number,
   259  				Address:   header.Coinbase,
   260  				Authorize: authorize,
   261  			})
   262  		}
   263  //如果投票通过,则更新签名者列表
   264  		if tally := snap.Tally[header.Coinbase]; tally.Votes > len(snap.Signers)/2 {
   265  			if tally.Authorize {
   266  				snap.Signers[header.Coinbase] = struct{}{}
   267  			} else {
   268  				delete(snap.Signers, header.Coinbase)
   269  
   270  //签名者列表收缩,删除所有剩余的最近缓存
   271  				if limit := uint64(len(snap.Signers)/2 + 1); number >= limit {
   272  					delete(snap.Recents, number-limit)
   273  				}
   274  //放弃取消授权签名者所投的任何以前的票
   275  				for i := 0; i < len(snap.Votes); i++ {
   276  					if snap.Votes[i].Signer == header.Coinbase {
   277  //从缓存的计数中取消投票
   278  						snap.uncast(snap.Votes[i].Address, snap.Votes[i].Authorize)
   279  
   280  //取消按时间顺序排列的投票
   281  						snap.Votes = append(snap.Votes[:i], snap.Votes[i+1:]...)
   282  
   283  						i--
   284  					}
   285  				}
   286  			}
   287  //放弃对刚刚更改的帐户的任何以前的投票
   288  			for i := 0; i < len(snap.Votes); i++ {
   289  				if snap.Votes[i].Address == header.Coinbase {
   290  					snap.Votes = append(snap.Votes[:i], snap.Votes[i+1:]...)
   291  					i--
   292  				}
   293  			}
   294  			delete(snap.Tally, header.Coinbase)
   295  		}
   296  	}
   297  	snap.Number += uint64(len(headers))
   298  	snap.Hash = headers[len(headers)-1].Hash()
   299  
   300  	return snap, nil
   301  }
   302  
   303  //签名者按升序检索授权签名者列表。
   304  func (s *Snapshot) signers() []common.Address {
   305  	sigs := make([]common.Address, 0, len(s.Signers))
   306  	for sig := range s.Signers {
   307  		sigs = append(sigs, sig)
   308  	}
   309  	sort.Sort(signers(sigs))
   310  	return sigs
   311  }
   312  
   313  //如果给定块高度的签名者依次是或不是,则Inturn返回。
   314  func (s *Snapshot) inturn(number uint64, signer common.Address) bool {
   315  	signers, offset := s.signers(), 0
   316  	for offset < len(signers) && signers[offset] != signer {
   317  		offset++
   318  	}
   319  	return (number % uint64(len(signers))) == uint64(offset)
   320  }