mru

package
v0.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 26, 2019 License: GPL-3.0 Imports: 20 Imported by: 0

Documentation

Overview

Package mru defines Mutable resource updates. A Mutable Resource is an entity which allows updates to a resource without resorting to ENS on each update. The update scheme is built on swarm chunks with chunk keys following a predictable, versionable pattern.

Updates are defined to be periodic in nature, where the update frequency is expressed in seconds.

The root entry of a mutable resource is tied to a unique identifier that is deterministically generated out of the metadata content that describes the resource. This metadata includes a user-defined resource name, a resource start time that indicates when the resource becomes valid, the frequency in seconds with which the resource is expected to be updated, both of which are stored as little-endian uint64 values in the database (for a total of 16 bytes). It also contains the owner's address (ownerAddr) This MRU info is stored in a separate content-addressed chunk (call it the metadata chunk), with the following layout:

(00|length|startTime|frequency|name|ownerAddr)

(The two first zero-value bytes are used for disambiguation by the chunk validator, and update chunk will always have a value > 0 there.)

Each metadata chunk is identified by its rootAddr, calculated as follows: metaHash=H(len(metadata), startTime, frequency,name) rootAddr = H(metaHash, ownerAddr). where H is the SHA3 hash function This scheme effectively locks the root chunk so that only the owner of the private key that ownerAddr was derived from can sign updates.

The root entry tells the requester from when the mutable resource was first added (Unix time in seconds) and in which moments to look for the actual updates. Thus, a resource update for identifier "føø.bar" starting at unix time 1528800000 with frequency 300 (every 5 mins) will have updates on 1528800300, 1528800600, 1528800900 and so on.

Actual data updates are also made in the form of swarm chunks. The keys of the updates are the hash of a concatenation of properties as follows:

updateAddr = H(period, version, rootAddr) where H is the SHA3 hash function The period is (currentTime - startTime) / frequency

Using our previous example, this means that a period 3 will happen when the clock hits 1528800900

If more than one update is made in the same period, incremental version numbers are used successively.

A user looking up a resource would only need to know the rootAddr in order to get the versions

the resource update data is: resourcedata = headerlength|period|version|rootAddr|flags|metaHash where flags is a 1-byte flags field. Flag 0 is set to 1 to indicate multihash

the full update data that goes in the chunk payload is: resourcedata|sign(resourcedata)

headerlength is a 16 bit value containing the byte length of period|version|rootAddr|flags|metaHash

Handler is the API for Mutable Resources It enables creating, updating, syncing and retrieving resources and their update data

Index

Constants

View Source
const (
	ErrInit = iota
	ErrNotFound
	ErrIO
	ErrUnauthorized
	ErrInvalidValue
	ErrDataOverflow
	ErrNothingToReturn
	ErrCorruptData
	ErrInvalidSignature
	ErrNotSynced
	ErrPeriodDepth
	ErrCnt
)

Variables

View Source
var TimestampProvider timestampProvider = NewDefaultTimestampProvider()

TimestampProvider sets the time source of the mru package

Functions

func NewError

func NewError(code int, s string) error

NewError creates a new Mutable Resource Error object with the specified code and custom error message

func NewErrorf

func NewErrorf(code int, format string, args ...interface{}) error

NewErrorf is a convenience version of NewError that incorporates printf-style formatting

Types

type DefaultTimestampProvider

type DefaultTimestampProvider struct {
}

func NewDefaultTimestampProvider

func NewDefaultTimestampProvider() *DefaultTimestampProvider

NewDefaultTimestampProvider creates a system clock based timestamp provider

func (*DefaultTimestampProvider) Now

Now returns the current time according to this provider

type Error

type Error struct {
	// contains filtered or unexported fields
}

Error is a the typed error object used for Mutable Resources

func (*Error) Code

func (e *Error) Code() int

Code returns the error code Error codes are enumerated in the error.go file within the mru package

func (*Error) Error

func (e *Error) Error() string

Error implements the error interface

type GenericSigner

type GenericSigner struct {
	PrivKey *ecdsa.PrivateKey
	// contains filtered or unexported fields
}

GenericSigner implements the Signer interface It is the vanilla signer that probably should be used in most cases

func NewGenericSigner

func NewGenericSigner(privKey *ecdsa.PrivateKey) *GenericSigner

NewGenericSigner builds a signer that will sign everything with the provided private key

func (*GenericSigner) Address

func (s *GenericSigner) Address() common.Address

PublicKey returns the public key of the signer's private key

func (*GenericSigner) Sign

func (s *GenericSigner) Sign(data common.Hash) (signature Signature, err error)

Sign signs the supplied data It wraps the ethereum crypto.Sign() method

type Handler

type Handler struct {
	HashSize int
	// contains filtered or unexported fields
}

func NewHandler

func NewHandler(params *HandlerParams) *Handler

NewHandler creates a new Mutable Resource API

func (*Handler) GetContent

func (h *Handler) GetContent(rootAddr storage.Address) (storage.Address, []byte, error)

GetContent retrieves the data payload of the last synced update of the Mutable Resource

func (*Handler) GetLastPeriod

func (h *Handler) GetLastPeriod(rootAddr storage.Address) (uint32, error)

GetLastPeriod retrieves the period of the last synced update of the Mutable Resource

func (*Handler) GetVersion

func (h *Handler) GetVersion(rootAddr storage.Address) (uint32, error)

GetVersion retrieves the period of the last synced update of the Mutable Resource

func (*Handler) Load

func (h *Handler) Load(ctx context.Context, rootAddr storage.Address) (*resource, error)

Load retrieves the Mutable Resource metadata chunk stored at rootAddr Upon retrieval it creates/updates the index entry for it with metadata corresponding to the chunk contents

func (*Handler) Lookup

func (h *Handler) Lookup(ctx context.Context, params *LookupParams) (*resource, error)

Lookup retrieves a specific or latest version of the resource update with metadata chunk at params.Root Lookup works differently depending on the configuration of `LookupParams` See the `LookupParams` documentation and helper functions: `LookupLatest`, `LookupLatestVersionInPeriod` and `LookupVersion` When looking for the latest update, it starts at the next period after the current time. upon failure tries the corresponding keys of each previous period until one is found (or startTime is reached, in which case there are no updates).

func (*Handler) LookupPrevious

func (h *Handler) LookupPrevious(ctx context.Context, params *LookupParams) (*resource, error)

LookupPrevious returns the resource before the one currently loaded in the resource cache This is useful where resource updates are used incrementally in contrast to merely replacing content. Requires a cached resource object to determine the current state of the resource.

func (*Handler) New

func (h *Handler) New(ctx context.Context, request *Request) error

New creates a new metadata chunk out of the request passed in.

func (*Handler) NewUpdateRequest

func (h *Handler) NewUpdateRequest(ctx context.Context, rootAddr storage.Address) (updateRequest *Request, err error)

NewUpdateRequest prepares an UpdateRequest structure with all the necessary information to 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 (*Handler) SetStore

func (h *Handler) SetStore(store *storage.NetStore)

SetStore sets the store backend for the Mutable Resource API

func (*Handler) Update

Update adds an actual data update Uses the Mutable Resource metadata currently loaded in the resources map entry. It is the caller's responsibility to make sure that this data is not stale. Note that a Mutable Resource update cannot span chunks, and thus has a MAX NET LENGTH 4096, INCLUDING update header data and signature. An error will be returned if the total length of the chunk payload will exceed this limit. Update can only check if the caller is trying to overwrite the very last known version, otherwise it just puts the update on the network.

func (*Handler) Validate

func (h *Handler) Validate(chunkAddr storage.Address, data []byte) bool

Validate is a chunk validation method If it looks like a resource update, the chunk address is checked against the ownerAddr of the update's signature It implements the storage.ChunkValidator interface

type HandlerParams

type HandlerParams struct {
	QueryMaxPeriods uint32
}

HandlerParams pass parameters to the Handler constructor NewHandler Signer and TimestampProvider are mandatory parameters

type LookupParams

type LookupParams struct {
	UpdateLookup
	Limit uint32
}

LookupParams is used to specify constraints when performing an update lookup Limit defines whether or not the lookup should be limited If Limit is set to true then Max defines the amount of hops that can be performed

func LookupLatest

func LookupLatest(rootAddr storage.Address) *LookupParams

LookupLatest generates lookup parameters that look for the latest version of a resource

func LookupLatestVersionInPeriod

func LookupLatestVersionInPeriod(rootAddr storage.Address, period uint32) *LookupParams

LookupLatestVersionInPeriod generates lookup parameters that look for the latest version of a resource in a given period

func LookupVersion

func LookupVersion(rootAddr storage.Address, period, version uint32) *LookupParams

LookupVersion generates lookup parameters that look for a specific version of a resource

func NewLookupParams

func NewLookupParams(rootAddr storage.Address, period, version uint32, limit uint32) *LookupParams

func (*LookupParams) RootAddr

func (r *LookupParams) RootAddr() storage.Address

RootAddr returns the metadata chunk address

type Request

type Request struct {
	SignedResourceUpdate
	// contains filtered or unexported fields
}

Request represents an update and/or resource create message

func NewCreateRequest

func NewCreateRequest(metadata *ResourceMetadata) (request *Request, err error)

NewCreateRequest returns a request to create a new resource

func NewCreateUpdateRequest

func NewCreateUpdateRequest(metadata *ResourceMetadata) (*Request, error)

NewCreateUpdateRequest returns a ready to sign request to create and initialize a resource with data

func (*Request) Frequency

func (r *Request) Frequency() uint64

Frequency returns the resource's expected update frequency

func (*Request) IsNew

func (r *Request) IsNew() bool

func (*Request) IsUpdate

func (r *Request) IsUpdate() bool

func (*Request) MarshalJSON

func (r *Request) MarshalJSON() (rawData []byte, err error)

MarshalJSON takes an update request and encodes it as a JSON structure into a byte array Implements json.Marshaler interface

func (*Request) Multihash

func (r *Request) Multihash() bool

Multihash returns true if the resource data should be interpreted as a multihash

func (*Request) Name

func (r *Request) Name() string

Name returns the resource human-readable name

func (*Request) Owner

func (r *Request) Owner() common.Address

Owner returns the resource owner's address

func (*Request) Period

func (r *Request) Period() uint32

Period returns in which period the resource will be published

func (*Request) RootAddr

func (r *Request) RootAddr() storage.Address

RootAddr returns the metadata chunk address

func (*Request) SetData

func (r *Request) SetData(data []byte, multihash bool)

SetData stores the payload data the resource will be updated with

func (*Request) Sign

func (r *Request) Sign(signer Signer) error

Sign executes the signature to validate the resource and sets the owner address field

func (*Request) StartTime

func (r *Request) StartTime() Timestamp

StartTime returns the time that the resource was/will be created at

func (*Request) UnmarshalJSON

func (r *Request) UnmarshalJSON(rawData []byte) error

UnmarshalJSON takes a JSON structure stored in a byte array and populates the Request object Implements json.Unmarshaler interface

func (*Request) Version

func (r *Request) Version() uint32

Version returns the resource version to publish

type ResourceMetadata

type ResourceMetadata struct {
	StartTime Timestamp      // time at which the resource starts to be valid
	Frequency uint64         // expected update frequency for the resource
	Name      string         // name of the resource, for the reference of the user or to disambiguate resources with same starttime, frequency, owneraddr
	Owner     common.Address // public address of the resource owner
}

ResourceMetadata encapsulates the immutable information about a mutable resource :) once serialized into a chunk, the resource can be retrieved by knowing its content-addressed rootAddr

type Signature

type Signature [signatureLength]byte

Signature is an alias for a static byte array with the size of a signature

type SignedResourceUpdate

type SignedResourceUpdate struct {
	// contains filtered or unexported fields
}

SignedResourceUpdate represents a resource update with all the necessary information to prove ownership of the resource

func (*SignedResourceUpdate) GetDigest

func (r *SignedResourceUpdate) GetDigest() (result common.Hash, err error)

GetDigest creates the resource update digest used in signatures (formerly known as keyDataHash) the serialized payload is cached in .binaryData

func (*SignedResourceUpdate) Multihash

func (r *SignedResourceUpdate) Multihash() bool

Multihash specifies whether the resource data should be interpreted as multihash

func (*SignedResourceUpdate) Sign

func (r *SignedResourceUpdate) Sign(signer Signer) error

Sign executes the signature to validate the resource

func (*SignedResourceUpdate) Verify

func (r *SignedResourceUpdate) Verify() (err error)

Verify checks that signatures are valid and that the signer owns the resource to be updated

type Signer

type Signer interface {
	Sign(common.Hash) (Signature, error)
	Address() common.Address
}

Signer signs Mutable Resource update payloads

type TestHandler

type TestHandler struct {
	*Handler
}

func NewTestHandler

func NewTestHandler(datadir string, params *HandlerParams) (*TestHandler, error)

NewTestHandler creates Handler object to be used for testing purposes.

func (*TestHandler) Close

func (t *TestHandler) Close()

type Timestamp

type Timestamp struct {
	Time uint64 // Unix epoch timestamp, in seconds
}

Encodes a point in time as a Unix epoch

type UpdateLookup

type UpdateLookup struct {
	// contains filtered or unexported fields
}

UpdateLookup represents the components of a resource update search key

func (*UpdateLookup) UpdateAddr

func (u *UpdateLookup) UpdateAddr() (updateAddr storage.Address)

UpdateAddr calculates the resource update chunk address corresponding to this lookup key

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL