Documentation ¶
Index ¶
Constants ¶
const (
LoggerTag = "WEB_API"
)
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AddressBook ¶
AddressBook provides a list of addresses to which the messages should be sent.
type Config ¶
type Config struct { // ListenAddr is the address of the HTTP server that is used to receive // messages. If used with TOR, server should listen on localhost. // // Ignored if Server is not nil. // // Cannot be empty if Server is nil. ListenAddr string // AddressBook provides the list of message consumers. All produced messages // will be sent only to consumers from the address book. // // Cannot be nil. AddressBook AddressBook // Topics is a list of subscribed topics. A value of the map a type of // message given as a nil pointer, e.g.: (*Message)(nil). Topics map[string]transport.Message // AuthorAllowlist is a list of allowed message authors. Only messages from // these addresses will be accepted. AuthorAllowlist []ethereum.Address // FlushTicker specifies how often the producer will flush messages // to the consumers. If FlushTicker is nil, default ticker with 1 minute // interval is used. // // Flush interval must be less or equal to timeout. FlushTicker *timeutil.Ticker // Signer used to sign and verify messages. Signer ethereum.Signer // Timeout is a timeout for HTTP requests. // // If timeout is zero, default value will be used (60 seconds). Timeout time.Duration // Server is an optional custom HTTP server that will be used to receive // messages. If provided, ListenAddr and Timeout are ignored. Server *httpserver.HTTPServer // Client is an optional custom HTTP client that will be used to send // messages. If provided, Timeout is ignored. Client *http.Client // Rand is an optional random number generator. If not provided, Reader // from crypto/rand package will be used. Rand io.Reader // MaxClockSkew is the maximum allowed clock skew between the consumer // and the producer. If not provided, default value will be used (10 seconds). MaxClockSkew time.Duration // Logger is a custom logger instance. If not provided then null // logger is used. Logger log.Logger }
Config is a configuration of WebAPI.
type EthereumAddressBook ¶
type EthereumAddressBook struct {
// contains filtered or unexported fields
}
EthereumAddressBook is an AddressBook implementation that uses an Ethereum contract to store the list of addresses.
func NewEthereumAddressBook ¶
func NewEthereumAddressBook(c ethereum.Client, addr ethereum.Address, cacheTTL time.Duration) *EthereumAddressBook
NewEthereumAddressBook creates a new instance of EthereumAddressBook. The cacheTTL parameter specifies how long the list of addresses should be cached before it is fetched again from the Ethereum contract.
type MultiAddressBook ¶
type MultiAddressBook struct {
// contains filtered or unexported fields
}
MultiAddressBook is an implementation of AddressBook that merges the addresses from multiple AddressBook instances.
func NewMultiAddressBook ¶
func NewMultiAddressBook(books ...AddressBook) *MultiAddressBook
NewMultiAddressBook creates a new instance of MultiAddressBook.
type StaticAddressBook ¶
type StaticAddressBook struct {
// contains filtered or unexported fields
}
StaticAddressBook is an implementation of AddressBook that returns a static list of addresses.
func NewStaticAddressBook ¶
func NewStaticAddressBook(addresses []string) *StaticAddressBook
NewStaticAddressBook creates a new instance of StaticAddressBook.
type WebAPI ¶
type WebAPI struct {
// contains filtered or unexported fields
}
WebAPI is transport that uses HTTP API to send and receive messages. It is designed to use over secure network, e.g. Tor, I2P or VPN.
Transport involves two main actors: message producers and consumers.
Message producers are responsible for sending messages to the message consumers. List of addresses of message consumers is stored in the address book. Address book must implement the AddressBook interface.
Message producers prepares a batch of messages and send them periodically to the message consumers. The batch is sent as a single HTTP POST request. Each request is signed using the private key of the producer. The signature is sent in the query string of the request. The signature is calculated using the following formula:
signature = sign(timestamp + rand)
Where timestamp is the current UNIX timestamp in seconds encoded as a 10-base string, rand is a random 16-byte string encoded as a hex string. The sign function is provided by the Signer interface.
Signature is stored in three query parameters:
s - hex encoded signature t - timestamp in seconds encoded as a 10-base string r - 16-byte random string encoded as a hex string
Consumer verifies the signature and checks if message producer is on the allowlist. Timestamp must be within following ranges:
now - maxClockSkew <= timestamp <= now + flushInterval + maxClockSkew lastRequest <= now + flushInterval - maxClockSkew
Where now is the current UNIX timestamp in seconds, lastRequest is the timestamp of the last request received from the message producer and timestamp is the timestamp from the t query parameter.
The purpose of the signature is to prevent replay attacks and to allow message consumers to quickly verify if the identity of the message producer.
The request body is a protobuf message (see pb/tor.proto) that contains the following fields:
messages - a list of messages grouped by topic signature - signature of the message pack
The signature of the request body is calculated using Signer interface. The signing data is a concatenation of all messages in the batch prefixed with the topic name. Topics are sorted using sort.Strings function.
The author recovered from the signature must be the same as the author recovered from the signature in the query string. Otherwise, the request is rejected.
Request body is compressed using gzip compression. Requests that are not compressed or are not have a valid gzip header are rejected.
All request must have Content-Type header set to application/x-protobuf.
The HTTP server returns HTTP 200 OK response if the request is valid. Otherwise, it returns 429 Too Many Requests response if producer sends messages too often or 400 Bad Request response for any other error.
func (*WebAPI) Messages ¶
func (w *WebAPI) Messages(topic string) <-chan transport.ReceivedMessage
Messages implements the transport.Transport interface.