Documentation ¶
Index ¶
- Constants
- Variables
- func BloomFilterMatch(filter, sample []byte) bool
- func BytesToUintBigEndian(b []byte) (res uint64)
- func BytesToUintLittleEndian(b []byte) (res uint64)
- func ContainsOnlyZeros(data []byte) bool
- func GenerateRandomID() (id string, err error)
- func GenerateSecureRandomData(length int) ([]byte, error)
- func IsFullNode(bloom []byte) bool
- func IsMessageSigned(flags byte) bool
- func IsPubKeyEqual(a, b *ecdsa.PublicKey) bool
- func MakeFullNodeBloom() []byte
- func NewSentMessage(params *MessageParams) (*sentMessage, error)
- func ValidateDataIntegrity(k []byte, expectedSize int) bool
- func ValidatePublicKey(k *ecdsa.PublicKey) bool
- type DropPeerRateLimiterHandler
- type Envelope
- func (e *Envelope) Bloom() []byte
- func (e *Envelope) CalculatePoW(diff uint32)
- func (e *Envelope) DecodeRLP(s *rlp.Stream) error
- func (e *Envelope) Hash() common.Hash
- func (e *Envelope) Open(watcher *Filter) (msg *ReceivedMessage)
- func (e *Envelope) OpenAsymmetric(key *ecdsa.PrivateKey) (*ReceivedMessage, error)
- func (e *Envelope) OpenSymmetric(key []byte) (msg *ReceivedMessage, err error)
- func (e *Envelope) PoW() float64
- func (e *Envelope) Seal(options *MessageParams) error
- func (e *Envelope) Size() int
- type EnvelopeError
- type EnvelopeEvent
- type EventType
- type Filter
- type Filters
- func (fs *Filters) AllTopics() []TopicType
- func (fs *Filters) Get(id string) *Filter
- func (fs *Filters) GetWatchersByTopic(topic TopicType) []*Filter
- func (fs *Filters) Install(watcher *Filter) (string, error)
- func (fs *Filters) NotifyWatchers(env *Envelope, p2pMessage bool)
- func (fs *Filters) Uninstall(id string) bool
- type MemoryMessageStore
- type MessageParams
- type MessageStore
- type MessagesRequest
- type MessagesResponse
- type MetricsRateLimiterHandler
- type Peer
- type PeerRateLimiter
- type PeerRateLimiterConfig
- type RateLimiterHandler
- type RateLimiterPeer
- type RateLimits
- type ReceivedMessage
- type TimeSyncError
- type TopicType
- type WakuHost
Constants ¶
const ( SizeMask = byte(3) // mask used to extract the size of payload size field from the flags TopicLength = 4 // in bytes AESKeyLength = 32 // in bytes KeyIDSize = 32 // in bytes BloomFilterSize = 64 // in bytes MaxTopicInterest = 10000 EnvelopeHeaderLength = 20 MaxMessageSize = uint32(10 * 1024 * 1024) // maximum accepted size of a message. DefaultMaxMessageSize = uint32(1024 * 1024) DefaultMinimumPoW = 0.2 ExpirationCycle = time.Second TransmissionCycle = 300 * time.Millisecond DefaultTTL = 50 // seconds DefaultSyncAllowance = 10 // seconds MaxLimitInSyncMailRequest = 1000 EnvelopeTimeNotSynced uint = iota + 1 EnvelopeOtherError MaxLimitInMessagesRequest = 1000 )
Waku protocol parameters
Variables ¶
var ( EnvelopesReceivedCounter = prom.NewCounter(prom.CounterOpts{ Name: "waku_envelopes_received_total", Help: "Number of envelopes received.", }) EnvelopesValidatedCounter = prom.NewCounter(prom.CounterOpts{ Name: "waku_envelopes_validated_total", Help: "Number of envelopes processed successfully.", }) EnvelopesRejectedCounter = prom.NewCounterVec(prom.CounterOpts{ Name: "waku_envelopes_rejected_total", Help: "Number of envelopes rejected.", }, []string{"reason"}) EnvelopesCacheFailedCounter = prom.NewCounterVec(prom.CounterOpts{ Name: "waku_envelopes_cache_failures_total", Help: "Number of envelopes which failed to be cached.", }, []string{"type"}) EnvelopesCachedCounter = prom.NewCounterVec(prom.CounterOpts{ Name: "waku_envelopes_cached_total", Help: "Number of envelopes cached.", }, []string{"cache"}) EnvelopesSizeMeter = prom.NewHistogram(prom.HistogramOpts{ Name: "waku_envelopes_size_bytes", Help: "Size of processed Waku envelopes in bytes.", Buckets: prom.ExponentialBuckets(256, 4, 10), }) RateLimitsProcessed = prom.NewCounter(prom.CounterOpts{ Name: "waku_rate_limits_processed_total", Help: "Number of packets Waku rate limiter processed.", }) RateLimitsExceeded = prom.NewCounterVec(prom.CounterOpts{ Name: "waku_rate_limits_exceeded_total", Help: "Number of times the Waku rate limits were exceeded", }, []string{"type"}) BridgeSent = prom.NewCounter(prom.CounterOpts{ Name: "waku_bridge_sent_total", Help: "Number of envelopes bridged from Waku", }) BridgeReceivedSucceed = prom.NewCounter(prom.CounterOpts{ Name: "waku_bridge_received_success_total", Help: "Number of envelopes bridged to Waku and successfully added", }) BridgeReceivedFailed = prom.NewCounter(prom.CounterOpts{ Name: "waku_bridge_received_failure_total", Help: "Number of envelopes bridged to Waku and failed to be added", }) )
Functions ¶
func BloomFilterMatch ¶
func BytesToUintBigEndian ¶
BytesToUintBigEndian converts the slice to 64-bit unsigned integer.
func BytesToUintLittleEndian ¶
BytesToUintLittleEndian converts the slice to 64-bit unsigned integer.
func ContainsOnlyZeros ¶
ContainsOnlyZeros checks if the data contain only zeros.
func GenerateRandomID ¶
GenerateRandomID generates a random string, which is then returned to be used as a key id
func GenerateSecureRandomData ¶
GenerateSecureRandomData generates random data where extra security is required. The purpose of this function is to prevent some bugs in software or in hardware from delivering not-very-random data. This is especially useful for AES nonce, where true randomness does not really matter, but it is very important to have a unique nonce for every message.
func IsFullNode ¶
func IsMessageSigned ¶
func IsPubKeyEqual ¶
IsPubKeyEqual checks that two public keys are equal
func MakeFullNodeBloom ¶
func MakeFullNodeBloom() []byte
func NewSentMessage ¶
func NewSentMessage(params *MessageParams) (*sentMessage, error)
NewSentMessage creates and initializes a non-signed, non-encrypted Waku message.
func ValidateDataIntegrity ¶
ValidateDataIntegrity returns false if the data have the wrong or contains all zeros, which is the simplest and the most common bug.
func ValidatePublicKey ¶
ValidatePublicKey checks the format of the given public key.
Types ¶
type DropPeerRateLimiterHandler ¶
type DropPeerRateLimiterHandler struct { // Tolerance is a number by which a limit must be exceeded before a peer is dropped. Tolerance int64 // contains filtered or unexported fields }
DropPeerRateLimiterHandler implements RateLimiterHandler, represents a handler that introduces Tolerance to the number of Peer connections before Limit Exceeded errors are returned.
func (*DropPeerRateLimiterHandler) ExceedIPLimit ¶
func (h *DropPeerRateLimiterHandler) ExceedIPLimit() error
func (*DropPeerRateLimiterHandler) ExceedPeerLimit ¶
func (h *DropPeerRateLimiterHandler) ExceedPeerLimit() error
type Envelope ¶
type Envelope struct { Expiry uint32 TTL uint32 Topic TopicType Data []byte Nonce uint64 // contains filtered or unexported fields }
Envelope represents a clear-text data packet to transmit through the Waku network. Its contents may or may not be encrypted and signed.
func NewEnvelope ¶
NewEnvelope wraps a Waku message with expiration and destination data included into an envelope for network forwarding.
func (*Envelope) Bloom ¶
Bloom maps 4-bytes Topic into 64-byte bloom filter with 3 bits set (at most).
func (*Envelope) CalculatePoW ¶
func (*Envelope) Open ¶
func (e *Envelope) Open(watcher *Filter) (msg *ReceivedMessage)
Open tries to decrypt an envelope, and populates the message fields in case of success.
func (*Envelope) OpenAsymmetric ¶
func (e *Envelope) OpenAsymmetric(key *ecdsa.PrivateKey) (*ReceivedMessage, error)
OpenAsymmetric tries to decrypt an envelope, potentially encrypted with a particular key.
func (*Envelope) OpenSymmetric ¶
func (e *Envelope) OpenSymmetric(key []byte) (msg *ReceivedMessage, err error)
OpenSymmetric tries to decrypt an envelope, potentially encrypted with a particular key.
func (*Envelope) PoW ¶
PoW computes (if necessary) and returns the proof of work target of the envelope.
func (*Envelope) Seal ¶
func (e *Envelope) Seal(options *MessageParams) error
Seal closes the envelope by spending the requested amount of time as a proof of work on hashing the data.
type EnvelopeError ¶
EnvelopeError code and optional description of the error.
func ErrorToEnvelopeError ¶
func ErrorToEnvelopeError(hash common.Hash, err error) EnvelopeError
ErrorToEnvelopeError converts common golang error into EnvelopeError with a code.
type EnvelopeEvent ¶
type EnvelopeEvent struct { Event EventType Topic TopicType Hash common.Hash Batch common.Hash Peer enode.ID Data interface{} }
EnvelopeEvent represents an envelope event.
type EventType ¶
type EventType string
EventType used to define known waku events.
const ( // EventEnvelopeSent fires when envelope was sent to a peer. EventEnvelopeSent EventType = "envelope.sent" // EventEnvelopeExpired fires when envelop expired EventEnvelopeExpired EventType = "envelope.expired" // EventEnvelopeReceived is sent once envelope was received from a peer. // EventEnvelopeReceived must be sent to the feed even if envelope was previously in the cache. // And event, ideally, should contain information about peer that sent envelope to us. EventEnvelopeReceived EventType = "envelope.received" // EventBatchAcknowledged is sent when batch of envelopes was acknowledged by a peer. EventBatchAcknowledged EventType = "batch.acknowledged" // EventEnvelopeAvailable fires when envelop is available for filters EventEnvelopeAvailable EventType = "envelope.available" // EventMailServerRequestSent fires when such request is sent. EventMailServerRequestSent EventType = "mailserver.request.sent" // EventMailServerRequestCompleted fires after mailserver sends all the requested messages EventMailServerRequestCompleted EventType = "mailserver.request.completed" // EventMailServerRequestExpired fires after mailserver the request TTL ends. // This event is independent and concurrent to EventMailServerRequestCompleted. // Request should be considered as expired only if expiry event was received first. EventMailServerRequestExpired EventType = "mailserver.request.expired" // EventMailServerEnvelopeArchived fires after an envelope has been archived EventMailServerEnvelopeArchived EventType = "mailserver.envelope.archived" // EventMailServerSyncFinished fires when the sync of messages is finished. EventMailServerSyncFinished EventType = "mailserver.sync.finished" )
type Filter ¶
type Filter struct { Src *ecdsa.PublicKey // Sender of the message KeyAsym *ecdsa.PrivateKey // Private Key of recipient KeySym []byte // Key associated with the Topic Topics [][]byte // Topics to filter messages with PoW float64 // Proof of work as described in the Waku spec AllowP2P bool // Indicates whether this filter is interested in direct peer-to-peer messages SymKeyHash common.Hash // The Keccak256Hash of the symmetric key, needed for optimization Messages MessageStore // contains filtered or unexported fields }
Filter represents a Waku message filter
func (*Filter) MatchEnvelope ¶
MatchEnvelope checks if it's worth decrypting the message. If it returns `true`, client code is expected to attempt decrypting the message and subsequently call MatchMessage. Topics are not checked here, since this is done by topic matchers.
func (*Filter) MatchMessage ¶
func (f *Filter) MatchMessage(msg *ReceivedMessage) bool
MatchMessage checks if the filter matches an already decrypted message (i.e. a Message that has already been handled by MatchEnvelope when checked by a previous filter). Topics are not checked here, since this is done by topic matchers.
func (*Filter) Retrieve ¶
func (f *Filter) Retrieve() []*ReceivedMessage
Retrieve will return the list of all received messages associated to a filter.
func (*Filter) Trigger ¶
func (f *Filter) Trigger(msg *ReceivedMessage)
Trigger adds a yet-unknown message to the filter's list of received messages.
type Filters ¶
type Filters struct {
// contains filtered or unexported fields
}
Filters represents a collection of filters
func (*Filters) GetWatchersByTopic ¶
GetWatchersByTopic returns a slice containing the filters that match a specific topic
func (*Filters) NotifyWatchers ¶
NotifyWatchers notifies any filter that has declared interest for the envelope's topic.
type MemoryMessageStore ¶
type MemoryMessageStore struct {
// contains filtered or unexported fields
}
MemoryMessageStore represents messages stored in a memory hash table.
func NewMemoryMessageStore ¶
func NewMemoryMessageStore() *MemoryMessageStore
NewMemoryMessageStore returns pointer to an instance of the MemoryMessageStore.
func (*MemoryMessageStore) Add ¶
func (store *MemoryMessageStore) Add(msg *ReceivedMessage) error
Add adds message to store.
func (*MemoryMessageStore) Pop ¶
func (store *MemoryMessageStore) Pop() ([]*ReceivedMessage, error)
Pop returns all available messages and cleans the store.
type MessageParams ¶
type MessageParams struct { TTL uint32 Src *ecdsa.PrivateKey Dst *ecdsa.PublicKey KeySym []byte Topic TopicType WorkTime uint32 PoW float64 Payload []byte Padding []byte }
MessageParams specifies the exact way a message should be wrapped into an Envelope.
type MessageStore ¶
type MessageStore interface { Add(*ReceivedMessage) error Pop() ([]*ReceivedMessage, error) }
MessageStore defines interface for temporary message store.
type MessagesRequest ¶
type MessagesRequest struct { // ID of the request. The current implementation requires ID to be 32-byte array, // however, it's not enforced for future implementation. ID []byte `json:"id"` // From is a lower bound of time range. From uint32 `json:"from"` // To is a upper bound of time range. To uint32 `json:"to"` // Limit determines the number of messages sent by the mail server // for the current paginated request. Limit uint32 `json:"limit"` // Cursor is used as starting point for paginated requests. Cursor []byte `json:"cursor"` // Bloom is a filter to match requested messages. Bloom []byte `json:"bloom"` // Topics is a list of topics. A returned message should // belong to one of the topics from the list. Topics [][]byte `json:"topics"` }
MessagesRequest contains details of a request for historic messages.
func (MessagesRequest) Validate ¶
func (r MessagesRequest) Validate() error
type MessagesResponse ¶
type MessagesResponse struct { // Hash is a hash of all envelopes sent in the single batch. Hash common.Hash // Per envelope error. Errors []EnvelopeError }
MessagesResponse sent as a response after processing batch of envelopes.
type MetricsRateLimiterHandler ¶
type MetricsRateLimiterHandler struct{}
MetricsRateLimiterHandler implements RateLimiterHandler, represents a handler for reporting rate limit Exceed data to the metrics collection service (currently prometheus)
func (MetricsRateLimiterHandler) ExceedIPLimit ¶
func (MetricsRateLimiterHandler) ExceedIPLimit() error
func (MetricsRateLimiterHandler) ExceedPeerLimit ¶
func (MetricsRateLimiterHandler) ExceedPeerLimit() error
type Peer ¶
type Peer interface { // Start performs the handshake and initialize the broadcasting of messages Start() error Stop() // Run start the polling loop Run() error // NotifyAboutPowRequirementChange notifies the peer that POW for the host has changed NotifyAboutPowRequirementChange(float64) error // NotifyAboutBloomFilterChange notifies the peer that bloom filter for the host has changed NotifyAboutBloomFilterChange([]byte) error // NotifyAboutTopicInterestChange notifies the peer that topics for the host have changed NotifyAboutTopicInterestChange([]TopicType) error // SetPeerTrusted sets the value of trusted, meaning we will // allow p2p messages from them, which is necessary to interact // with mailservers. SetPeerTrusted(bool) // SetRWWriter sets the socket to read/write SetRWWriter(p2p.MsgReadWriter) RequestHistoricMessages(*Envelope) error SendMessagesRequest(MessagesRequest) error SendHistoricMessageResponse([]byte) error SendP2PMessages([]*Envelope) error SendRawP2PDirect([]rlp.RawValue) error // Mark marks an envelope known to the peer so that it won't be sent back. Mark(*Envelope) // Marked checks if an envelope is already known to the remote peer. Marked(*Envelope) bool ID() []byte IP() net.IP EnodeID() enode.ID PoWRequirement() float64 BloomFilter() []byte ConfirmationsEnabled() bool }
Peer represents a remote Waku client with which the local host waku instance exchanges data / messages.
type PeerRateLimiter ¶
type PeerRateLimiter struct { PacketLimitPerSecIP int64 PacketLimitPerSecPeerID int64 BytesLimitPerSecIP int64 BytesLimitPerSecPeerID int64 // contains filtered or unexported fields }
PeerRateLimiter represents a rate limiter that limits communication between Peers
func NewPeerRateLimiter ¶
func NewPeerRateLimiter(cfg *PeerRateLimiterConfig, handlers ...RateLimiterHandler) *PeerRateLimiter
func (*PeerRateLimiter) Decorate ¶
func (r *PeerRateLimiter) Decorate(p RateLimiterPeer, rw p2p.MsgReadWriter, runLoop runLoop) error
type PeerRateLimiterConfig ¶
type PeerRateLimiterConfig struct { PacketLimitPerSecIP int64 PacketLimitPerSecPeerID int64 BytesLimitPerSecIP int64 BytesLimitPerSecPeerID int64 WhitelistedIPs []string WhitelistedPeerIDs []enode.ID }
PeerRateLimiterConfig represents configurations for initialising a PeerRateLimiter
type RateLimiterHandler ¶
RateLimiterHandler interface represents handler functionality for a Rate Limiter in the cases of exceeding a peer limit and exceeding an IP limit
type RateLimiterPeer ¶
RateLimiterPeer interface represents a Peer that is capable of being rate limited
type RateLimits ¶
type RateLimits struct { IPLimits uint64 // amount per second from a single IP (default 0, no limits) PeerIDLimits uint64 // amount per second from a single peer ID (default 0, no limits) TopicLimits uint64 // amount per second from a single topic (default 0, no limits) }
RateLimits contains information about rate limit settings. It's agnostic on what it's being rate limited on (bytes or number of packets currently) It's exchanged with the status-update packet code
func (RateLimits) IsZero ¶
func (r RateLimits) IsZero() bool
type ReceivedMessage ¶
type ReceivedMessage struct { Raw []byte Payload []byte Padding []byte Signature []byte Salt []byte PoW float64 // Proof of work as described in the Waku spec Sent uint32 // Time when the message was posted into the network TTL uint32 // Maximum time to live allowed for the message Src *ecdsa.PublicKey // Message recipient (identity used to decode the message) Dst *ecdsa.PublicKey // Message recipient (identity used to decode the message) Topic TopicType SymKeyHash common.Hash // The Keccak256Hash of the key EnvelopeHash common.Hash // Message envelope hash to act as a unique id P2P bool // is set to true if this message was received from mail server. }
ReceivedMessage represents a data packet to be received through the Waku protocol and successfully decrypted.
func (*ReceivedMessage) SigToPubKey ¶
func (msg *ReceivedMessage) SigToPubKey() *ecdsa.PublicKey
SigToPubKey returns the public key associated to the message's signature.
func (*ReceivedMessage) ValidateAndParse ¶
func (msg *ReceivedMessage) ValidateAndParse() bool
ValidateAndParse checks the message validity and extracts the fields in case of success.
type TopicType ¶
type TopicType [TopicLength]byte
TopicType represents a cryptographically secure, probabilistic partial classifications of a message, determined as the first (leftmost) 4 bytes of the SHA3 hash of some arbitrary data given by the original author of the message.
func BytesToTopic ¶
BytesToTopic converts from the byte array representation of a topic into the TopicType type.
func (TopicType) MarshalText ¶
MarshalText returns the hex representation of t.
func (*TopicType) UnmarshalText ¶
UnmarshalText parses a hex representation to a topic.
type WakuHost ¶
type WakuHost interface { // HandlePeer handles the connection of a new peer HandlePeer(Peer, p2p.MsgReadWriter) error // MaxMessageSize returns the maximum accepted message size. MaxMessageSize() uint32 // LightClientMode returns whether the host is running in light client mode LightClientMode() bool // Mailserver returns whether the host is running a mailserver Mailserver() bool // LightClientModeConnectionRestricted indicates that connection to light client in light client mode not allowed LightClientModeConnectionRestricted() bool // ConfirmationsEnabled returns true if message confirmations are enabled. ConfirmationsEnabled() bool // PacketRateLimits returns the current rate limits for the host PacketRateLimits() RateLimits // BytesRateLimits returns the current rate limits for the host BytesRateLimits() RateLimits // MinPow returns the MinPow for the host MinPow() float64 // BloomFilterMode returns whether the host is using bloom filter BloomFilterMode() bool // BloomFilter returns the bloom filter for the host BloomFilter() []byte //TopicInterest returns the topics for the host TopicInterest() []TopicType // IsEnvelopeCached checks if envelope with specific hash has already been received and cached. IsEnvelopeCached(common.Hash) bool // Envelopes returns all the envelopes queued Envelopes() []*Envelope SendEnvelopeEvent(EnvelopeEvent) int // OnNewEnvelopes handles newly received envelopes from a peer OnNewEnvelopes([]*Envelope, Peer) ([]EnvelopeError, error) // OnNewP2PEnvelopes handles envelopes received though the P2P // protocol (i.e from a mailserver in most cases) OnNewP2PEnvelopes([]*Envelope) error // OnMessagesResponse handles when the peer receive a message response // from a mailserver OnMessagesResponse(MessagesResponse, Peer) error // OnMessagesRequest handles when the peer receive a message request // this only works if the peer is a mailserver OnMessagesRequest(MessagesRequest, Peer) error // OnDeprecatedMessagesRequest handles when the peer receive a message request // using the *Envelope format. Currently the only production client (status-react) // is exclusively using this one. OnDeprecatedMessagesRequest(*Envelope, Peer) error OnBatchAcknowledged(common.Hash, Peer) error OnP2PRequestCompleted([]byte, Peer) error }
WakuHost is the local instance of waku, which both interacts with remote clients (peers) and local clients (through RPC API)