github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/storage/mru/request.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 // 10 // 11 // 12 // 13 // 14 // 15 // 16 // 17 // 18 // 19 // 20 // 21 // 22 // 23 // 24 25 package mru 26 27 import ( 28 "bytes" 29 "encoding/json" 30 31 "github.com/ethereum/go-ethereum/common" 32 "github.com/ethereum/go-ethereum/common/hexutil" 33 "github.com/ethereum/go-ethereum/swarm/storage" 34 ) 35 36 // 37 type updateRequestJSON struct { 38 Name string `json:"name,omitempty"` 39 Frequency uint64 `json:"frequency,omitempty"` 40 StartTime uint64 `json:"startTime,omitempty"` 41 Owner string `json:"ownerAddr,omitempty"` 42 RootAddr string `json:"rootAddr,omitempty"` 43 MetaHash string `json:"metaHash,omitempty"` 44 Version uint32 `json:"version,omitempty"` 45 Period uint32 `json:"period,omitempty"` 46 Data string `json:"data,omitempty"` 47 Multihash bool `json:"multiHash"` 48 Signature string `json:"signature,omitempty"` 49 } 50 51 // 52 type Request struct { 53 SignedResourceUpdate 54 metadata ResourceMetadata 55 isNew bool 56 } 57 58 var zeroAddr = common.Address{} 59 60 // 61 func NewCreateUpdateRequest(metadata *ResourceMetadata) (*Request, error) { 62 63 request, err := NewCreateRequest(metadata) 64 if err != nil { 65 return nil, err 66 } 67 68 // 69 now := TimestampProvider.Now().Time 70 71 request.version = 1 72 request.period, err = getNextPeriod(metadata.StartTime.Time, now, metadata.Frequency) 73 if err != nil { 74 return nil, err 75 } 76 return request, nil 77 } 78 79 // 80 func NewCreateRequest(metadata *ResourceMetadata) (request *Request, err error) { 81 if metadata.StartTime.Time == 0 { // 82 metadata.StartTime = TimestampProvider.Now() 83 } 84 85 if metadata.Owner == zeroAddr { 86 return nil, NewError(ErrInvalidValue, "OwnerAddr is not set") 87 } 88 89 request = &Request{ 90 metadata: *metadata, 91 } 92 request.rootAddr, request.metaHash, _, err = request.metadata.serializeAndHash() 93 request.isNew = true 94 return request, nil 95 } 96 97 // 98 func (r *Request) Frequency() uint64 { 99 return r.metadata.Frequency 100 } 101 102 // 103 func (r *Request) Name() string { 104 return r.metadata.Name 105 } 106 107 // 108 func (r *Request) Multihash() bool { 109 return r.multihash 110 } 111 112 // 113 func (r *Request) Period() uint32 { 114 return r.period 115 } 116 117 // 118 func (r *Request) Version() uint32 { 119 return r.version 120 } 121 122 // 123 func (r *Request) RootAddr() storage.Address { 124 return r.rootAddr 125 } 126 127 // 128 func (r *Request) StartTime() Timestamp { 129 return r.metadata.StartTime 130 } 131 132 // 133 func (r *Request) Owner() common.Address { 134 return r.metadata.Owner 135 } 136 137 // 138 func (r *Request) Sign(signer Signer) error { 139 if r.metadata.Owner != zeroAddr && r.metadata.Owner != signer.Address() { 140 return NewError(ErrInvalidSignature, "Signer does not match current owner of the resource") 141 } 142 143 if err := r.SignedResourceUpdate.Sign(signer); err != nil { 144 return err 145 } 146 r.metadata.Owner = signer.Address() 147 return nil 148 } 149 150 // 151 func (r *Request) SetData(data []byte, multihash bool) { 152 r.data = data 153 r.multihash = multihash 154 r.signature = nil 155 if !r.isNew { 156 r.metadata.Frequency = 0 // 157 } 158 } 159 160 func (r *Request) IsNew() bool { 161 return r.metadata.Frequency > 0 && (r.period <= 1 || r.version <= 1) 162 } 163 164 func (r *Request) IsUpdate() bool { 165 return r.signature != nil 166 } 167 168 // 169 func (r *Request) fromJSON(j *updateRequestJSON) error { 170 171 r.version = j.Version 172 r.period = j.Period 173 r.multihash = j.Multihash 174 r.metadata.Name = j.Name 175 r.metadata.Frequency = j.Frequency 176 r.metadata.StartTime.Time = j.StartTime 177 178 if err := decodeHexArray(r.metadata.Owner[:], j.Owner, "ownerAddr"); err != nil { 179 return err 180 } 181 182 var err error 183 if j.Data != "" { 184 r.data, err = hexutil.Decode(j.Data) 185 if err != nil { 186 return NewError(ErrInvalidValue, "Cannot decode data") 187 } 188 } 189 190 var declaredRootAddr storage.Address 191 var declaredMetaHash []byte 192 193 declaredRootAddr, err = decodeHexSlice(j.RootAddr, storage.KeyLength, "rootAddr") 194 if err != nil { 195 return err 196 } 197 declaredMetaHash, err = decodeHexSlice(j.MetaHash, 32, "metaHash") 198 if err != nil { 199 return err 200 } 201 202 if r.IsNew() { 203 // 204 // 205 // 206 207 r.rootAddr, r.metaHash, _, err = r.metadata.serializeAndHash() 208 if err != nil { 209 return err 210 } 211 if j.RootAddr != "" && !bytes.Equal(declaredRootAddr, r.rootAddr) { 212 return NewError(ErrInvalidValue, "rootAddr does not match resource metadata") 213 } 214 if j.MetaHash != "" && !bytes.Equal(declaredMetaHash, r.metaHash) { 215 return NewError(ErrInvalidValue, "metaHash does not match resource metadata") 216 } 217 218 } else { 219 // 220 r.rootAddr = declaredRootAddr 221 r.metaHash = declaredMetaHash 222 } 223 224 if j.Signature != "" { 225 sigBytes, err := hexutil.Decode(j.Signature) 226 if err != nil || len(sigBytes) != signatureLength { 227 return NewError(ErrInvalidSignature, "Cannot decode signature") 228 } 229 r.signature = new(Signature) 230 r.updateAddr = r.UpdateAddr() 231 copy(r.signature[:], sigBytes) 232 } 233 return nil 234 } 235 236 func decodeHexArray(dst []byte, src, name string) error { 237 bytes, err := decodeHexSlice(src, len(dst), name) 238 if err != nil { 239 return err 240 } 241 if bytes != nil { 242 copy(dst, bytes) 243 } 244 return nil 245 } 246 247 func decodeHexSlice(src string, expectedLength int, name string) (bytes []byte, err error) { 248 if src != "" { 249 bytes, err = hexutil.Decode(src) 250 if err != nil || len(bytes) != expectedLength { 251 return nil, NewErrorf(ErrInvalidValue, "Cannot decode %s", name) 252 } 253 } 254 return bytes, nil 255 } 256 257 // 258 // 259 func (r *Request) UnmarshalJSON(rawData []byte) error { 260 var requestJSON updateRequestJSON 261 if err := json.Unmarshal(rawData, &requestJSON); err != nil { 262 return err 263 } 264 return r.fromJSON(&requestJSON) 265 } 266 267 // 268 // 269 func (r *Request) MarshalJSON() (rawData []byte, err error) { 270 var signatureString, dataHashString, rootAddrString, metaHashString string 271 if r.signature != nil { 272 signatureString = hexutil.Encode(r.signature[:]) 273 } 274 if r.data != nil { 275 dataHashString = hexutil.Encode(r.data) 276 } 277 if r.rootAddr != nil { 278 rootAddrString = hexutil.Encode(r.rootAddr) 279 } 280 if r.metaHash != nil { 281 metaHashString = hexutil.Encode(r.metaHash) 282 } 283 var ownerAddrString string 284 if r.metadata.Frequency == 0 { 285 ownerAddrString = "" 286 } else { 287 ownerAddrString = hexutil.Encode(r.metadata.Owner[:]) 288 } 289 290 requestJSON := &updateRequestJSON{ 291 Name: r.metadata.Name, 292 Frequency: r.metadata.Frequency, 293 StartTime: r.metadata.StartTime.Time, 294 Version: r.version, 295 Period: r.period, 296 Owner: ownerAddrString, 297 Data: dataHashString, 298 Multihash: r.multihash, 299 Signature: signatureString, 300 RootAddr: rootAddrString, 301 MetaHash: metaHashString, 302 } 303 304 return json.Marshal(requestJSON) 305 }