github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/storage/feed/request.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:44</date> 10 //</624450119328075776> 11 12 13 package feed 14 15 import ( 16 "bytes" 17 "encoding/json" 18 "hash" 19 20 "github.com/ethereum/go-ethereum/common" 21 "github.com/ethereum/go-ethereum/common/hexutil" 22 "github.com/ethereum/go-ethereum/swarm/storage" 23 "github.com/ethereum/go-ethereum/swarm/storage/feed/lookup" 24 ) 25 26 //请求表示对订阅源更新消息进行签名或签名的请求 27 type Request struct { 28 Update //将放在块上的实际内容,较少签名 29 Signature *Signature 30 idAddr storage.Address //更新的缓存块地址(未序列化,供内部使用) 31 binaryData []byte //缓存的序列化数据(不再序列化!,用于效率/内部使用) 32 } 33 34 //updateRequestJSON表示JSON序列化的updateRequest 35 type updateRequestJSON struct { 36 ID 37 ProtocolVersion uint8 `json:"protocolVersion"` 38 Data string `json:"data,omitempty"` 39 Signature string `json:"signature,omitempty"` 40 } 41 42 //请求布局 43 //更新字节 44 //签名长度字节 45 const minimumSignedUpdateLength = minimumUpdateDataLength + signatureLength 46 47 //newfirstrequest返回准备好签名的请求以发布第一个源更新 48 func NewFirstRequest(topic Topic) *Request { 49 50 request := new(Request) 51 52 //获取当前时间 53 now := TimestampProvider.Now().Time 54 request.Epoch = lookup.GetFirstEpoch(now) 55 request.Feed.Topic = topic 56 request.Header.Version = ProtocolVersion 57 58 return request 59 } 60 61 //setdata存储提要更新将使用的有效负载数据 62 func (r *Request) SetData(data []byte) { 63 r.data = data 64 r.Signature = nil 65 } 66 67 //如果此请求为签名更新建模,或者为签名请求,则is update返回true 68 func (r *Request) IsUpdate() bool { 69 return r.Signature != nil 70 } 71 72 //验证签名是否有效 73 func (r *Request) Verify() (err error) { 74 if len(r.data) == 0 { 75 return NewError(ErrInvalidValue, "Update does not contain data") 76 } 77 if r.Signature == nil { 78 return NewError(ErrInvalidSignature, "Missing signature field") 79 } 80 81 digest, err := r.GetDigest() 82 if err != nil { 83 return err 84 } 85 86 //获取签名者的地址(它还检查签名是否有效) 87 r.Feed.User, err = getUserAddr(digest, *r.Signature) 88 if err != nil { 89 return err 90 } 91 92 //检查块中包含的查找信息是否与updateaddr(块搜索键)匹配。 93 //用于检索此块的 94 //如果验证失败,则有人伪造了块。 95 if !bytes.Equal(r.idAddr, r.Addr()) { 96 return NewError(ErrInvalidSignature, "Signature address does not match with update user address") 97 } 98 99 return nil 100 } 101 102 //签名执行签名以验证更新消息 103 func (r *Request) Sign(signer Signer) error { 104 r.Feed.User = signer.Address() 105 r.binaryData = nil //使序列化数据无效 106 digest, err := r.GetDigest() //计算摘要并序列化为.BinaryData 107 if err != nil { 108 return err 109 } 110 111 signature, err := signer.Sign(digest) 112 if err != nil { 113 return err 114 } 115 116 //尽管签名者接口返回签名者的公共地址, 117 //从签名中恢复它以查看它们是否匹配 118 userAddr, err := getUserAddr(digest, signature) 119 if err != nil { 120 return NewError(ErrInvalidSignature, "Error verifying signature") 121 } 122 123 if userAddr != signer.Address() { //健全性检查以确保签名者声明的地址与用于签名的地址相同! 124 return NewError(ErrInvalidSignature, "Signer address does not match update user address") 125 } 126 127 r.Signature = &signature 128 r.idAddr = r.Addr() 129 return nil 130 } 131 132 //GetDigest创建用于签名的源更新摘要 133 //序列化的负载缓存在.BinaryData中 134 func (r *Request) GetDigest() (result common.Hash, err error) { 135 hasher := hashPool.Get().(hash.Hash) 136 defer hashPool.Put(hasher) 137 hasher.Reset() 138 dataLength := r.Update.binaryLength() 139 if r.binaryData == nil { 140 r.binaryData = make([]byte, dataLength+signatureLength) 141 if err := r.Update.binaryPut(r.binaryData[:dataLength]); err != nil { 142 return result, err 143 } 144 } 145 hasher.Write(r.binaryData[:dataLength]) //除了签名以外的一切。 146 147 return common.BytesToHash(hasher.Sum(nil)), nil 148 } 149 150 //创建更新块。 151 func (r *Request) toChunk() (storage.Chunk, error) { 152 153 //检查更新是否已签名和序列化 154 //为了提高效率,数据在签名期间序列化并缓存在 155 //在.getDigest()中计算签名摘要时的BinaryData字段 156 if r.Signature == nil || r.binaryData == nil { 157 return nil, NewError(ErrInvalidSignature, "toChunk called without a valid signature or payload data. Call .Sign() first.") 158 } 159 160 updateLength := r.Update.binaryLength() 161 162 //签名是块数据中的最后一项 163 copy(r.binaryData[updateLength:], r.Signature[:]) 164 165 chunk := storage.NewChunk(r.idAddr, r.binaryData) 166 return chunk, nil 167 } 168 169 //FromChunk从块数据填充此结构。它不验证签名是否有效。 170 func (r *Request) fromChunk(chunk storage.Chunk) error { 171 //有关更新块布局,请参见请求定义 172 173 chunkdata := chunk.Data() 174 175 //反序列化源更新部分 176 if err := r.Update.binaryGet(chunkdata[:len(chunkdata)-signatureLength]); err != nil { 177 return err 178 } 179 180 //提取签名 181 var signature *Signature 182 cursor := r.Update.binaryLength() 183 sigdata := chunkdata[cursor : cursor+signatureLength] 184 if len(sigdata) > 0 { 185 signature = &Signature{} 186 copy(signature[:], sigdata) 187 } 188 189 r.Signature = signature 190 r.idAddr = chunk.Address() 191 r.binaryData = chunkdata 192 193 return nil 194 195 } 196 197 //FromValues从字符串键值存储中反序列化此实例 198 //用于分析查询字符串 199 func (r *Request) FromValues(values Values, data []byte) error { 200 signatureBytes, err := hexutil.Decode(values.Get("signature")) 201 if err != nil { 202 r.Signature = nil 203 } else { 204 if len(signatureBytes) != signatureLength { 205 return NewError(ErrInvalidSignature, "Incorrect signature length") 206 } 207 r.Signature = new(Signature) 208 copy(r.Signature[:], signatureBytes) 209 } 210 err = r.Update.FromValues(values, data) 211 if err != nil { 212 return err 213 } 214 r.idAddr = r.Addr() 215 return err 216 } 217 218 //AppendValues将此结构序列化到提供的字符串键值存储区中 219 //用于生成查询字符串 220 func (r *Request) AppendValues(values Values) []byte { 221 if r.Signature != nil { 222 values.Set("signature", hexutil.Encode(r.Signature[:])) 223 } 224 return r.Update.AppendValues(values) 225 } 226 227 //fromjson接受更新请求json并填充更新请求 228 func (r *Request) fromJSON(j *updateRequestJSON) error { 229 230 r.ID = j.ID 231 r.Header.Version = j.ProtocolVersion 232 233 var err error 234 if j.Data != "" { 235 r.data, err = hexutil.Decode(j.Data) 236 if err != nil { 237 return NewError(ErrInvalidValue, "Cannot decode data") 238 } 239 } 240 241 if j.Signature != "" { 242 sigBytes, err := hexutil.Decode(j.Signature) 243 if err != nil || len(sigBytes) != signatureLength { 244 return NewError(ErrInvalidSignature, "Cannot decode signature") 245 } 246 r.Signature = new(Signature) 247 r.idAddr = r.Addr() 248 copy(r.Signature[:], sigBytes) 249 } 250 return nil 251 } 252 253 //unmarshaljson接受存储在字节数组中的json结构并填充请求对象 254 //实现json.unmasheler接口 255 func (r *Request) UnmarshalJSON(rawData []byte) error { 256 var requestJSON updateRequestJSON 257 if err := json.Unmarshal(rawData, &requestJSON); err != nil { 258 return err 259 } 260 return r.fromJSON(&requestJSON) 261 } 262 263 //marshaljson接受更新请求并将其作为json结构编码到字节数组中 264 //实现json.Marshaler接口 265 func (r *Request) MarshalJSON() (rawData []byte, err error) { 266 var signatureString, dataString string 267 if r.Signature != nil { 268 signatureString = hexutil.Encode(r.Signature[:]) 269 } 270 if r.data != nil { 271 dataString = hexutil.Encode(r.data) 272 } 273 274 requestJSON := &updateRequestJSON{ 275 ID: r.ID, 276 ProtocolVersion: r.Header.Version, 277 Data: dataString, 278 Signature: signatureString, 279 } 280 281 return json.Marshal(requestJSON) 282 } 283