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 }