github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/p2p/enr/enr.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 //包ENR实现EIP-778中定义的以太坊节点记录。节点记录保留 26 //有关对等网络上节点的任意信息。 27 // 28 //记录包含命名键。要在记录中存储和检索键/值,请使用条目 29 //接口。 30 // 31 //在将记录传输到另一个节点之前,必须对它们进行签名。解码记录验证 32 //它的签名。创建记录时,设置所需条目,然后调用sign添加 33 //签名。修改记录会使签名失效。 34 // 35 //ENR包支持“secp256k1 keccak”身份方案。 36 package enr 37 38 import ( 39 "bytes" 40 "errors" 41 "fmt" 42 "io" 43 "sort" 44 45 "github.com/ethereum/go-ethereum/rlp" 46 ) 47 48 const SizeLimit = 300 //节点记录的最大编码大小(字节) 49 50 var ( 51 errNoID = errors.New("unknown or unspecified identity scheme") 52 errInvalidSig = errors.New("invalid signature") 53 errNotSorted = errors.New("record key/value pairs are not sorted by key") 54 errDuplicateKey = errors.New("record contains duplicate key") 55 errIncompletePair = errors.New("record contains incomplete k/v pair") 56 errTooBig = fmt.Errorf("record bigger than %d bytes", SizeLimit) 57 errEncodeUnsigned = errors.New("can't encode unsigned record") 58 errNotFound = errors.New("no such key in record") 59 ) 60 61 //记录表示节点记录。零值是一个空记录。 62 type Record struct { 63 seq uint64 //序列号 64 signature []byte //签名 65 raw []byte //RLP编码记录 66 pairs []pair //所有键/值对的排序列表 67 } 68 69 //对是记录中的键/值对。 70 type pair struct { 71 k string 72 v rlp.RawValue 73 } 74 75 //签名报告记录是否具有有效签名。 76 func (r *Record) Signed() bool { 77 return r.signature != nil 78 } 79 80 //seq返回序列号。 81 func (r *Record) Seq() uint64 { 82 return r.seq 83 } 84 85 //setseq更新记录序列号。这将使记录上的任何签名失效。 86 //通常不需要调用setseq,因为在签名记录中设置了任何键 87 //增加序列号。 88 func (r *Record) SetSeq(s uint64) { 89 r.signature = nil 90 r.raw = nil 91 r.seq = s 92 } 93 94 //LOAD检索键/值对的值。给定的项必须是指针,并且将 95 //设置为记录中条目的值。 96 // 97 //加载返回的错误被包装在keyError中。您可以区分解码错误 98 //使用isNotFound函数来消除丢失的键。 99 func (r *Record) Load(e Entry) error { 100 i := sort.Search(len(r.pairs), func(i int) bool { return r.pairs[i].k >= e.ENRKey() }) 101 if i < len(r.pairs) && r.pairs[i].k == e.ENRKey() { 102 if err := rlp.DecodeBytes(r.pairs[i].v, e); err != nil { 103 return &KeyError{Key: e.ENRKey(), Err: err} 104 } 105 return nil 106 } 107 return &KeyError{Key: e.ENRKey(), Err: errNotFound} 108 } 109 110 //set添加或更新记录中的给定项。如果值不能 111 //编码的。如果记录已签名,则set将递增序列号并使其失效。 112 //序列号。 113 func (r *Record) Set(e Entry) { 114 blob, err := rlp.EncodeToBytes(e) 115 if err != nil { 116 panic(fmt.Errorf("enr: can't encode %s: %v", e.ENRKey(), err)) 117 } 118 r.invalidate() 119 120 pairs := make([]pair, len(r.pairs)) 121 copy(pairs, r.pairs) 122 i := sort.Search(len(pairs), func(i int) bool { return pairs[i].k >= e.ENRKey() }) 123 switch { 124 case i < len(pairs) && pairs[i].k == e.ENRKey(): 125 //元素存在于r.pairs[i] 126 pairs[i].v = blob 127 case i < len(r.pairs): 128 //在第i个元素之前插入对 129 el := pair{e.ENRKey(), blob} 130 pairs = append(pairs, pair{}) 131 copy(pairs[i+1:], pairs[i:]) 132 pairs[i] = el 133 default: 134 //元素应放置在r.pairs的末尾 135 pairs = append(pairs, pair{e.ENRKey(), blob}) 136 } 137 r.pairs = pairs 138 } 139 140 func (r *Record) invalidate() { 141 if r.signature == nil { 142 r.seq++ 143 } 144 r.signature = nil 145 r.raw = nil 146 } 147 148 //encoderlp实现rlp.encoder。编码失败,如果 149 //记录未签名。 150 func (r Record) EncodeRLP(w io.Writer) error { 151 if !r.Signed() { 152 return errEncodeUnsigned 153 } 154 _, err := w.Write(r.raw) 155 return err 156 } 157 158 //decoderlp实现rlp.decoder。解码验证签名。 159 func (r *Record) DecodeRLP(s *rlp.Stream) error { 160 raw, err := s.Raw() 161 if err != nil { 162 return err 163 } 164 if len(raw) > SizeLimit { 165 return errTooBig 166 } 167 168 //解码RLP容器。 169 dec := Record{raw: raw} 170 s = rlp.NewStream(bytes.NewReader(raw), 0) 171 if _, err := s.List(); err != nil { 172 return err 173 } 174 if err = s.Decode(&dec.signature); err != nil { 175 return err 176 } 177 if err = s.Decode(&dec.seq); err != nil { 178 return err 179 } 180 //记录的其余部分包含已排序的k/v对。 181 var prevkey string 182 for i := 0; ; i++ { 183 var kv pair 184 if err := s.Decode(&kv.k); err != nil { 185 if err == rlp.EOL { 186 break 187 } 188 return err 189 } 190 if err := s.Decode(&kv.v); err != nil { 191 if err == rlp.EOL { 192 return errIncompletePair 193 } 194 return err 195 } 196 if i > 0 { 197 if kv.k == prevkey { 198 return errDuplicateKey 199 } 200 if kv.k < prevkey { 201 return errNotSorted 202 } 203 } 204 dec.pairs = append(dec.pairs, kv) 205 prevkey = kv.k 206 } 207 if err := s.ListEnd(); err != nil { 208 return err 209 } 210 211 _, scheme := dec.idScheme() 212 if scheme == nil { 213 return errNoID 214 } 215 if err := scheme.Verify(&dec, dec.signature); err != nil { 216 return err 217 } 218 *r = dec 219 return nil 220 } 221 222 //nodeadr返回节点地址。如果记录是 223 //未签名或使用未知的标识方案。 224 func (r *Record) NodeAddr() []byte { 225 _, scheme := r.idScheme() 226 if scheme == nil { 227 return nil 228 } 229 return scheme.NodeAddr(r) 230 } 231 232 //setsig设置记录签名。如果编码的记录较大,则返回错误 233 //大于大小限制或根据传递的方案签名无效。 234 func (r *Record) SetSig(idscheme string, sig []byte) error { 235 //检查“id”是否已设置并与给定方案匹配。这种恐慌是因为 236 //这里的不一致始终是签名函数调用中的实现错误 237 //这种方法。 238 id, s := r.idScheme() 239 if s == nil { 240 panic(errNoID) 241 } 242 if id != idscheme { 243 panic(fmt.Errorf("identity scheme mismatch in Sign: record has %s, want %s", id, idscheme)) 244 } 245 246 //对照方案进行验证。 247 if err := s.Verify(r, sig); err != nil { 248 return err 249 } 250 raw, err := r.encode(sig) 251 if err != nil { 252 return err 253 } 254 r.signature, r.raw = sig, raw 255 return nil 256 } 257 258 //AppendElements将序列号和条目追加到给定切片。 259 func (r *Record) AppendElements(list []interface{}) []interface{} { 260 list = append(list, r.seq) 261 for _, p := range r.pairs { 262 list = append(list, p.k, p.v) 263 } 264 return list 265 } 266 267 func (r *Record) encode(sig []byte) (raw []byte, err error) { 268 list := make([]interface{}, 1, 2*len(r.pairs)+1) 269 list[0] = sig 270 list = r.AppendElements(list) 271 if raw, err = rlp.EncodeToBytes(list); err != nil { 272 return nil, err 273 } 274 if len(raw) > SizeLimit { 275 return nil, errTooBig 276 } 277 return raw, nil 278 } 279 280 func (r *Record) idScheme() (string, IdentityScheme) { 281 var id ID 282 if err := r.Load(&id); err != nil { 283 return "", nil 284 } 285 return string(id), FindIdentityScheme(string(id)) 286 }