swarm/storage/mru: Add version / header for future use

This commit is contained in:
Javier Peletier 2018-09-16 23:11:00 +02:00
parent c3897268cc
commit 2d212ed246
6 changed files with 60 additions and 31 deletions

View file

@ -33,12 +33,12 @@ Structure Summary:
Request: Resource update with signature
ResourceUpdate: headers + data
UpdateHeader: (placeholder, to be deleted)
ID: Information about how to locate a specific update
View: Author of the update and what is updating
Topic: Item that the updates are about
User: User who updates the resource
Epoch: time slot where the update is stored
Header: Protocol version and reserved for future use placeholders
ID: Information about how to locate a specific update
View: Author of the update and what is updating
Topic: Item that the updates are about
User: User who updates the resource
Epoch: time slot where the update is stored
*/
package mru

View file

@ -123,13 +123,13 @@ func (h *Handler) GetContent(view *View) (storage.Address, []byte, error) {
// just add the desired data and sign it.
// The resulting structure can then be signed and passed to Handler.Update to be verified and sent
func (h *Handler) NewRequest(ctx context.Context, view *View) (request *Request, err error) {
if view == nil {
return nil, NewError(ErrInvalidValue, "view cannot be nil")
}
now := TimestampProvider.Now().Time
request = new(Request)
request.Header.Version = ProtocolVersion
query := NewQueryLatest(view, lookup.NoClue)

View file

@ -38,8 +38,9 @@ type Request struct {
// updateRequestJSON represents a JSON-serialized UpdateRequest
type updateRequestJSON struct {
ID
Data string `json:"data,omitempty"`
Signature string `json:"signature,omitempty"`
ProtocolVersion uint8 `json:"protocolVersion"`
Data string `json:"data,omitempty"`
Signature string `json:"signature,omitempty"`
}
var zeroAddr = common.Address{}
@ -58,6 +59,7 @@ func NewFirstRequest(topic Topic) *Request {
now := TimestampProvider.Now().Time
request.Epoch = lookup.GetFirstEpoch(now)
request.View.Topic = topic
request.Header.Version = ProtocolVersion
return request
}
@ -230,6 +232,7 @@ func (r *Request) AppendValues(values Values) []byte {
func (r *Request) fromJSON(j *updateRequestJSON) error {
r.ID = j.ID
r.Header.Version = j.ProtocolVersion
var err error
if j.Data != "" {
@ -273,9 +276,10 @@ func (r *Request) MarshalJSON() (rawData []byte, err error) {
}
requestJSON := &updateRequestJSON{
ID: r.ID,
Data: dataString,
Signature: signatureString,
ID: r.ID,
ProtocolVersion: r.Header.Version,
Data: dataString,
Signature: signatureString,
}
return json.Marshal(requestJSON)

View file

@ -79,8 +79,8 @@ func TestEncodingDecodingUpdateRequests(t *testing.T) {
// and recover the information above. To sign an update, we need the rootAddr and the metaHash to construct
// proof of ownership
const expectedSignature = "0x1cbdad7702b7d43ca983dc9f2ed87e73984288cdae6a8844e44688ee22c72080516fcd65a894b894b7b41ac780d5ce5d9fb527dc7126ea876501948d2bb6880d00"
const expectedJSON = `{"view":{"topic":"0x6120676f6f64207265736f75726365206e616d65000000000000000000000000","user":"0x876a8936a7cd0b79ef0735ad0896c1afe278781c"},"epoch":{"level":1,"time":1000},"data":"0x5468697320686f75722773207570646174653a20537761726d2039392e3020686173206265656e2072656c656173656421"}`
const expectedSignature = "0x32c2d2c7224e24e4d3ae6a10595fc6e945f1b3ecdf548a04d8247c240a50c9240076aa7730abad6c8a46dfea00cfb8f43b6211f02db5c4cc5ed8584cb0212a4d00"
const expectedJSON = `{"view":{"topic":"0x6120676f6f64207265736f75726365206e616d65000000000000000000000000","user":"0x876a8936a7cd0b79ef0735ad0896c1afe278781c"},"epoch":{"time":1000,"level":1},"protocolVersion":0,"data":"0x5468697320686f75722773207570646174653a20537761726d2039392e3020686173206265656e2072656c656173656421"}`
//Put together an unsigned update request that we will serialize to send it to the signer.
data := []byte("This hour's update: Swarm 99.0 has been released!")
@ -225,7 +225,7 @@ func TestUpdateChunkSerializationErrorChecking(t *testing.T) {
t.Fatalf("error creating update chunk:%s", err)
}
compareByteSliceToExpectedHex(t, "chunk", chunk.Data(), "0x776f726c64206e657773207265706f72742c20657665727920686f7572000000876a8936a7cd0b79ef0735ad0896c1afe278781ce803000000000019416c206269656e206861636572206a616dc3a173206c652066616c7461207072656d696f376972cfb8bba6ad0c0f15e17f28bf03b6829649fddfc6b66d9de79a67f85c990982b513b09e8fd5365bde6920c8c73582ebf6f7fc85938b6d0dd285a3f18e2201")
compareByteSliceToExpectedHex(t, "chunk", chunk.Data(), "0x0000000000000000776f726c64206e657773207265706f72742c20657665727920686f7572000000876a8936a7cd0b79ef0735ad0896c1afe278781ce803000000000019416c206269656e206861636572206a616dc3a173206c652066616c7461207072656d696f5a0ffe0bc27f207cd5b00944c8b9cee93e08b89b5ada777f123ac535189333f174a6a4ca2f43a92c4a477a49d774813c36ce8288552c58e6205b0ac35d0507eb00")
var recovered Request
recovered.fromChunk(chunk.Address(), chunk.Data())

View file

@ -17,22 +17,32 @@
package mru
import (
"fmt"
"strconv"
"github.com/ethereum/go-ethereum/swarm/chunk"
)
// ResourceUpdate encapsulates the information sent as part of a resource update
type ResourceUpdate struct {
ID // metainformation about this resource update
data []byte // actual data payload
// ProtocolVersion defines the current version of the protocol that will be included in each update message
const ProtocolVersion uint8 = 0
const headerLength = 8
// Header defines a update message header including a protocol version byte
type Header struct {
Version uint8 // Protocol version
Padding [headerLength - 1]uint8 // reserved for future use
}
// Header: (see updateHeader)
// Data:
// data (datalength bytes)
//
// Minimum size is Header + 1 (minimum data length, enforced)
const minimumUpdateDataLength = idLength + 1
const maxUpdateDataLength = chunk.DefaultSize - signatureLength - idLength
// ResourceUpdate encapsulates the information sent as part of a resource update
type ResourceUpdate struct {
Header Header //
ID // Resource update identifying information
data []byte // actual data payload
}
const minimumUpdateDataLength = idLength + headerLength + 1
const maxUpdateDataLength = chunk.DefaultSize - signatureLength - idLength - headerLength
// binaryPut serializes the resource update information into the given slice
func (r *ResourceUpdate) binaryPut(serializedData []byte) error {
@ -50,7 +60,12 @@ func (r *ResourceUpdate) binaryPut(serializedData []byte) error {
}
var cursor int
// serialize header (see updateHeader)
// serialize Header
serializedData[cursor] = r.Header.Version
copy(serializedData[cursor+1:headerLength], r.Header.Padding[:headerLength-1])
cursor += headerLength
// serialize ID
if err := r.ID.binaryPut(serializedData[cursor : cursor+idLength]); err != nil {
return err
}
@ -65,7 +80,7 @@ func (r *ResourceUpdate) binaryPut(serializedData []byte) error {
// binaryLength returns the expected number of bytes this structure will take to encode
func (r *ResourceUpdate) binaryLength() int {
return idLength + len(r.data)
return idLength + headerLength + len(r.data)
}
// binaryGet populates this instance from the information contained in the passed byte slice
@ -73,9 +88,16 @@ func (r *ResourceUpdate) binaryGet(serializedData []byte) error {
if len(serializedData) < minimumUpdateDataLength {
return NewErrorf(ErrNothingToReturn, "chunk less than %d bytes cannot be a resource update chunk", minimumUpdateDataLength)
}
dataLength := len(serializedData) - idLength
var cursor int
dataLength := len(serializedData) - idLength - headerLength
// at this point we can be satisfied that we have the correct data length to read
var cursor int
// deserialize Header
r.Header.Version = serializedData[cursor] // extract the protocol version
copy(r.Header.Padding[:headerLength-1], serializedData[cursor+1:headerLength]) // extract the padding
cursor += headerLength
if err := r.ID.binaryGet(serializedData[cursor : cursor+idLength]); err != nil {
return err
}
@ -96,6 +118,8 @@ func (r *ResourceUpdate) binaryGet(serializedData []byte) error {
// useful to parse query strings
func (r *ResourceUpdate) FromValues(values Values, data []byte) error {
r.data = data
version, _ := strconv.ParseUint(values.Get("protocolVersion"), 10, 32)
r.Header.Version = uint8(version)
return r.ID.FromValues(values)
}
@ -103,5 +127,6 @@ func (r *ResourceUpdate) FromValues(values Values, data []byte) error {
// useful to build query strings
func (r *ResourceUpdate) AppendValues(values Values) []byte {
r.ID.AppendValues(values)
values.Set("protocolVersion", fmt.Sprintf("%d", r.Header.Version))
return r.data
}

View file

@ -28,7 +28,7 @@ func getTestResourceUpdate() *ResourceUpdate {
}
func TestResourceUpdateSerializer(t *testing.T) {
testBinarySerializerRecovery(t, getTestResourceUpdate(), "0x776f726c64206e657773207265706f72742c20657665727920686f7572000000876a8936a7cd0b79ef0735ad0896c1afe278781ce803000000000019456c20717565206c6565206d7563686f207920616e6461206d7563686f2c207665206d7563686f20792073616265206d7563686f")
testBinarySerializerRecovery(t, getTestResourceUpdate(), "0x0000000000000000776f726c64206e657773207265706f72742c20657665727920686f7572000000876a8936a7cd0b79ef0735ad0896c1afe278781ce803000000000019456c20717565206c6565206d7563686f207920616e6461206d7563686f2c207665206d7563686f20792073616265206d7563686f")
}
func TestResourceUpdateLengthCheck(t *testing.T) {