s4

package
v2.9.1-automation-2024... Latest Latest
Warning

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

Go to latest
Published: Feb 27, 2024 License: MIT Imports: 18 Imported by: 1

README

S4: Simple Shared Storage Service

See the corresponding CLIP describing the proposal.

Documentation

Index

Constants

View Source
const (
	SharedTableName = "shared"
)

Variables

View Source
var (
	ErrInvalidIntervals = errors.New("invalid intervals value")
	MinAddress          = ubig.New(common.BytesToAddress(bytes.Repeat([]byte{0x00}, common.AddressLength)).Big())
	MaxAddress          = ubig.New(common.BytesToAddress(bytes.Repeat([]byte{0xff}, common.AddressLength)).Big())
)
View Source
var (
	ErrNotFound          = errors.New("not found")
	ErrWrongSignature    = errors.New("wrong signature")
	ErrSlotIdTooBig      = errors.New("slot id is too big")
	ErrPayloadTooBig     = errors.New("payload is too big")
	ErrPastExpiration    = errors.New("past expiration")
	ErrVersionTooLow     = errors.New("version too low")
	ErrExpirationTooLong = errors.New("expiration too long")
)

Functions

This section is empty.

Types

type AddressRange added in v2.3.0

type AddressRange struct {
	// MinAddress (inclusive).
	MinAddress *ubig.Big
	// MaxAddress (inclusive).
	MaxAddress *ubig.Big
}

AddressRange represents a range of Ethereum addresses.

func NewFullAddressRange added in v2.3.0

func NewFullAddressRange() *AddressRange

NewFullAddressRange creates AddressRange for all address space: 0x00..-0xFF..

func NewInitialAddressRangeForIntervals added in v2.3.0

func NewInitialAddressRangeForIntervals(intervals uint) (*AddressRange, error)

NewInitialAddressRangeForIntervals splits the full address space with intervals, and returns a range for the first interval. Number of intervals must be > 0 and a power of 2.

func NewSingleAddressRange added in v2.3.0

func NewSingleAddressRange(address *ubig.Big) (*AddressRange, error)

NewSingleAddressRange creates AddressRange for a single address.

func (*AddressRange) Advance added in v2.3.0

func (r *AddressRange) Advance()

Advances the AddressRange by r.Interval. Has no effect for NewFullAddressRange(). When it reaches the end of the address space, it resets to the initial state, returned by NewAddressRangeForFirstInterval().

func (*AddressRange) Contains added in v2.3.0

func (r *AddressRange) Contains(address *ubig.Big) bool

Contains returns true if the given address belongs to the range.

func (*AddressRange) Interval added in v2.3.0

func (r *AddressRange) Interval() *ubig.Big

Interval returns the interval between max and min address plus one.

type Constraints

type Constraints struct {
	MaxPayloadSizeBytes    uint   `json:"maxPayloadSizeBytes"`
	MaxSlotsPerUser        uint   `json:"maxSlotsPerUser"`
	MaxExpirationLengthSec uint64 `json:"maxExpirationLengthSec"`
}

Constraints specifies the global storage constraints.

type Envelope

type Envelope struct {
	Address    []byte `json:"address"`
	SlotID     uint   `json:"slotid"`
	Payload    []byte `json:"payload"`
	Version    uint64 `json:"version"`
	Expiration int64  `json:"expiration"`
}

Envelope represents a JSON object that is signed for address verification. All []byte values are encoded as base64 (default JSON behavior). Hex is not used to avoid confusion due to case-sensivity and 0x prefix. A signer is responsible for generating a JSON that has no whitespace and the keys appear in this exact order: {"address":base64,"slotid":int,"payload":base64,"version":int,"expiration":int}

func NewEnvelopeFromRecord

func NewEnvelopeFromRecord(key *Key, record *Record) *Envelope

func (Envelope) GetSignerAddress

func (e Envelope) GetSignerAddress(signature []byte) (address common.Address, err error)

GetSignerAddress verifies the signature and returns the signing address.

func (Envelope) Sign

func (e Envelope) Sign(privateKey *ecdsa.PrivateKey) (signature []byte, err error)

Sign calculates signature for the serialized envelope data.

func (Envelope) ToJson

func (e Envelope) ToJson() ([]byte, error)

type Key

type Key struct {
	// Address is a user address
	Address common.Address
	// SlotId is a slot number
	SlotId uint
	// Version is a data version
	Version uint64
}

Key identifies a versioned user record.

type Metadata

type Metadata struct {
	// Confirmed turns true once consensus is reached.
	Confirmed bool
	// Signature contains the original user signature.
	Signature []byte
}

Metadata is the internal S4 data associated with a Record

type ORM

type ORM interface {
	// Get reads a row for the given address and slotId combination.
	// If such row does not exist, ErrNotFound is returned.
	// There is no filter on Expiration.
	Get(address *big.Big, slotId uint, qopts ...pg.QOpt) (*Row, error)

	// Update inserts or updates the row identified by (Address, SlotId) pair.
	// When updating, the new row must have greater or equal version,
	// otherwise ErrVersionTooLow is returned.
	// UpdatedAt field value is ignored.
	Update(row *Row, qopts ...pg.QOpt) error

	// DeleteExpired deletes any entries having Expiration < utcNow,
	// up to the given limit.
	// Returns the number of deleted rows.
	DeleteExpired(limit uint, utcNow time.Time, qopts ...pg.QOpt) (int64, error)

	// GetSnapshot selects all non-expired row versions for the given addresses range.
	// For the full address range, use NewFullAddressRange().
	GetSnapshot(addressRange *AddressRange, qopts ...pg.QOpt) ([]*SnapshotRow, error)

	// GetUnconfirmedRows selects all non-expired, non-confirmed rows ordered by UpdatedAt.
	// The number of returned rows is limited to the given limit.
	GetUnconfirmedRows(limit uint, qopts ...pg.QOpt) ([]*Row, error)
}

ORM represents S4 persistence layer. All functions are thread-safe.

func NewInMemoryORM

func NewInMemoryORM() ORM

func NewPostgresORM added in v2.3.0

func NewPostgresORM(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig, tableName, namespace string) ORM

type Record

type Record struct {
	// Arbitrary user data
	Payload []byte
	// Expiration timestamp assigned by user (unix time in milliseconds)
	Expiration int64
}

Record represents a user record persisted by S4.

type Row

type Row struct {
	Address    *big.Big
	SlotId     uint
	Payload    []byte
	Version    uint64
	Expiration int64
	Confirmed  bool
	Signature  []byte
}

Row represents a data row persisted by ORM.

func (Row) Clone

func (r Row) Clone() *Row

type SnapshotRow added in v2.3.0

type SnapshotRow struct {
	Address     *big.Big
	SlotId      uint
	Version     uint64
	Expiration  int64
	Confirmed   bool
	PayloadSize uint64
}

SnapshotRow(s) are returned by GetSnapshot function.

type Storage

type Storage interface {
	// Constraints returns a copy of Constraints struct specified during service creation.
	// The implementation is thread-safe.
	Constraints() Constraints

	// Get returns a copy of record (with metadata) associated with the specified key.
	// The returned Record & Metadata are always a copy.
	Get(ctx context.Context, key *Key) (*Record, *Metadata, error)

	// Put creates (or updates) a record identified by the specified key.
	// For signature calculation see envelope.go
	Put(ctx context.Context, key *Key, record *Record, signature []byte) error

	// List returns a snapshot for the specified address.
	// Slots having no data are not returned.
	List(ctx context.Context, address common.Address) ([]*SnapshotRow, error)
}

Storage represents S4 storage access interface. All functions are thread-safe.

func NewStorage

func NewStorage(lggr logger.Logger, contraints Constraints, orm ORM, clock utils.Clock) Storage

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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