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  }