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