Coder Social home page Coder Social logo

casper-sidecar's Introduction

Casper Event Sidecar README

Summary of Purpose

The Casper Event Sidecar is an application that runs in tandem with the node process. This reduces the load on the node process by allowing subscribers to monitor the event stream through the Sidecar while the node focuses entirely on the blockchain. Users needing access to the JSON-RPC will still need to query the node directly.

While the primary use case for the Sidecar application is running alongside the node on the same machine, it can be run remotely if necessary.

System Components & Architecture

Sidecar Diagram

Casper Nodes offer a Node Event Stream API returning Server-Sent Events (SSEs) that hold JSON-encoded data. The SSE Sidecar uses this API to achieve the following goals:

  • Build a sidecar middleware service that reads the Event Stream of all connected nodes, acting as a passthrough and replicating the SSE interface of the connected nodes and their filters (i.e., /main, /deploys, and /sigs with support for the use of the ?start_from= query to allow clients to get previously sent events from the Sidecar's buffer).

  • Provide a new RESTful endpoint that is discoverable to node operators. See the usage instructions for details.

The SSE Sidecar uses one ring buffer for outbound events, providing some robustness against unintended subscriber disconnects. If a disconnected subscriber re-subscribes before the buffer moves past their last received event, there will be no gap in the event history if they use the start_from URL query.

Prerequisites

  • CMake 3.1.4 or greater
  • Rust
  • pkg-config
  • gcc
  • g++

Configuration

The SSE Sidecar service must be configured using a .toml file specified at runtime.

This repository contains several sample configuration files that can be used as examples and adjusted according to your scenario:

  • EXAMPLE_NCTL_CONFIG.toml - Configuration for connecting to nodes on a local NCTL network. This configuration is used in the unit and integration tests found in this repository
  • EXAMPLE_NCTL_POSTGRES_CONFIG.toml - Configuration for using the PostgreSQL database and nodes on a local NCTL network
  • EXAMPLE_NODE_CONFIG.toml - Configuration for connecting to live nodes on a Casper network and setting up an admin server

Once you create the configuration file and are ready to run the Sidecar service, you must provide the configuration as an argument using the -- --path-to-config option as described here.

Node Connections

The Sidecar can connect to Casper nodes with versions greater or equal to 1.5.2.

The node_connections option configures the node (or multiple nodes) to which the Sidecar will connect and the parameters under which it will operate with that node. Connecting to multiple nodes requires multiple [[connections]] sections.

[[connections]]
ip_address = "127.0.0.1"
sse_port = 18101
rest_port = 14101
max_attempts = 10
delay_between_retries_in_seconds = 5
allow_partial_connection = false
enable_logging = true
connection_timeout_in_seconds = 3
no_message_timeout_in_seconds = 60
sleep_between_keep_alive_checks_in_seconds = 30

[[connections]]
ip_address = "127.0.0.1"
sse_port = 18102
rest_port = 14102
max_attempts = 10
delay_between_retries_in_seconds = 5
allow_partial_connection = false
enable_logging = false
connection_timeout_in_seconds = 3
no_message_timeout_in_seconds = 60
sleep_between_keep_alive_checks_in_seconds = 30

[[connections]]
ip_address = "127.0.0.1"
sse_port = 18103
rest_port = 14103
max_attempts = 10
delay_between_retries_in_seconds = 5
allow_partial_connection = false
enable_logging = false
connection_timeout_in_seconds = 3
no_message_timeout_in_seconds = 60
sleep_between_keep_alive_checks_in_seconds = 30
  • ip_address - The IP address of the node to monitor.
  • sse_port - The node's event stream (SSE) port. This example configuration uses port 9999.
  • rest_port - The node's REST endpoint for status and metrics. This example configuration uses port 8888.
  • max_attempts - The maximum number of attempts the Sidecar will make to connect to the node. If set to 0, the Sidecar will not attempt to connect.
  • delay_between_retries_in_seconds - The delay between attempts to connect to the node.
  • allow_partial_connection - Determining whether the Sidecar will allow a partial connection to this node.
  • enable_logging - This enables the logging of events from the node in question.
  • connection_timeout_in_seconds - Number of seconds before the connection request times out. Parameter is optional, defaults to 5
  • no_message_timeout_in_seconds - Number of seconds after which the connection will be restarted if no bytes were received. Parameter is optional, defaults to 120
  • sleep_between_keep_alive_checks_in_seconds - Optional parameter specifying the time intervals (in seconds) for checking if the connection is still alive. Defaults to 60

Storage

This directory stores the SSE cache and an SQLite database if the Sidecar is configured to use SQLite.

[storage]
storage_path = "./target/storage"

Database Connectivity

The Sidecar can connect to different types of databases. The current options are SQLite or PostgreSQL. The following sections show how to configure the database connection for one of these DBs. Note that the Sidecar can only connect to one DB at a time.

SQLite Database

This section includes configurations for the SQLite database.

[storage.sqlite_config]
file_name = "sqlite_database.db3"
max_connections_in_pool = 100
# https://www.sqlite.org/compile.html#default_wal_autocheckpoint
wal_autocheckpointing_interval = 1000
  • file_name - The database file path.
  • max_connections_in_pool - The maximum number of connections to the database. (Should generally be left as is.)
  • wal_autocheckpointing_interval - This controls how often the system commits pages to the database. The value determines the maximum number of pages before forcing a commit. More information can be found here.

PostgreSQL Database

The properties listed below are elements of the PostgreSQL database connection that can be configured for the Sidecar.

  • database_name - Name of the database.
  • host - URL to PostgreSQL instance.
  • database_username - Username.
  • database_password - Database password.
  • max_connections_in_pool - The maximum number of connections to the database.
  • port - The port for the database connection.

To run the Sidecar with PostgreSQL, you can set the following database environment variables to control how the Sidecar connects to the database. This is the suggested method to set the connection information for the PostgreSQL database.

SIDECAR_POSTGRES_USERNAME="your username"
SIDECAR_POSTGRES_PASSWORD="your password"
SIDECAR_POSTGRES_DATABASE_NAME="your database name"
SIDECAR_POSTGRES_HOST="your host"
SIDECAR_POSTGRES_MAX_CONNECTIONS="max connections"
SIDECAR_POSTGRES_PORT="port"

However, DB connectivity can also be configured using the Sidecar configuration file.

If the DB environment variables and the Sidecar's configuration file have the same variable set, the DB environment variables will take precedence.

It is possible to completely omit the PostgreSQL configuration from the Sidecar's configuration file. In this case, the Sidecar will attempt to connect to the PostgreSQL using the database environment variables or use some default values for non-critical variables.

[storage.postgresql_config]
database_name = "event_sidecar"
host = "localhost"
database_password = "p@$$w0rd"
database_username = "postgres"
max_connections_in_pool = 30

Rest & Event Stream Criteria

This information determines outbound connection criteria for the Sidecar's rest_server.

[rest_server]
port = 18888
max_concurrent_requests = 50
max_requests_per_second = 50
request_timeout_in_seconds = 10
  • port - The port for accessing the sidecar's rest_server. 18888 is the default, but operators are free to choose their own port as needed.
  • max_concurrent_requests - The maximum total number of simultaneous requests that can be made to the REST server.
  • max_requests_per_second - The maximum total number of requests that can be made per second.
  • request_timeout_in_seconds - The total time before a request times out.
[event_stream_server]
port = 19999
max_concurrent_subscribers = 100
event_stream_buffer_length = 5000

The event_stream_server section specifies a port for the Sidecar's event stream.

Additionally, there are the following two options:

  • max_concurrent_subscribers - The maximum number of subscribers that can monitor the Sidecar's event stream.
  • event_stream_buffer_length - The number of events that the stream will hold in its buffer for reference when a subscriber reconnects.

Admin Server

This optional section configures the Sidecar's administrative server. If this section is not specified, the Sidecar will not start an admin server.

[admin_server]
port = 18887
max_concurrent_requests = 1
max_requests_per_second = 1
  • port - The port for accessing the Sidecar's admin server.
  • max_concurrent_requests - The maximum total number of simultaneous requests that can be sent to the admin server.
  • max_requests_per_second - The maximum total number of requests that can be sent per second to the admin server.

Access the admin server at http://localhost:18887/metrics/.

Swagger Documentation

Once the Sidecar is running, access the Swagger documentation at http://localhost:18888/swagger-ui/. You need to replace localhost with the IP address of the machine running the Sidecar application if you are running the Sidecar remotely. The Swagger documentation will allow you to test the REST API.

OpenAPI Specification

An OpenAPI schema is available at http://localhost:18888/api-doc.json/. You need to replace localhost with the IP address of the machine running the Sidecar application if you are running the Sidecar remotely.

Unit Testing the Sidecar

You can run the unit and integration tests included in this repository with the following command:

cargo test

You can also run the performance tests using the following command:

cargo test -- --include-ignored

The EXAMPLE_NCTL_CONFIG.toml file contains the configurations used for these tests.

Running the Sidecar

After creating the configuration file, run the Sidecar using Cargo and point to the configuration file using the --path-to-config option, as shown below. The command needs to run with root privileges.

sudo cargo run -- --path-to-config EXAMPLE_NODE_CONFIG.toml

The Sidecar application leverages tracing, which can be controlled by setting the RUST_LOG environment variable.

The following command will run the sidecar application with the INFO log level.

RUST_LOG=info cargo run -p casper-event-sidecar -- --path-to-config EXAMPLE_NCTL_CONFIG.toml

The log levels, listed in order of increasing verbosity, are:

  • ERROR
  • WARN
  • INFO
  • DEBUG
  • TRACE

Further details about log levels can be found here.

Testing the Sidecar using NCTL

The Sidecar application can be tested against live Casper nodes or a local NCTL network.

The configuration shown within this README will direct the Sidecar application to a locally hosted NCTL network if one is running. The Sidecar should function the same way it would with a live node, displaying events as they occur in the local NCTL network.

Troubleshooting Tips

This section covers helpful tips when troubleshooting the Sidecar service. Replace the URL and ports provided in the examples as appropriate.

Checking liveness

To check whether the Sidecar is running, run the following curl command, which returns the newest stored block.

curl http://SIDECAR_URL:SIDECAR_REST_PORT/block

Each block should have a .block.header.timestamp field. Even if there were no deploys, a block should be produced every 30-60 seconds. If the latest block falls behind, it means there is an issue with the Sidecar reading events from the node. Here is a helpful script provided jq is installed:

curl http://SIDECAR_URL:SIDECAR_REST_PORT/block | jq '.block.header.timestamp'

Checking the node connection

Checking the node connection status requires the admin server to be enabled, as shown here. Use this curl command and observe the output:

curl http://SIDECAR_URL:SIDECAR_ADMIN_PORT/metrics

Sample output:

# HELP node_statuses Current status of node to which sidecar is connected. Numbers mean: 0 - preparing; 1 - connecting; 2 - connected; 3 - reconnecting; -1 - defunct -> used up all connection attempts ; -2 - defunct -> node is in an incompatible version
# TYPE node_statuses gauge
node_statuses{node="35.180.42.211:9999"} 2
node_statuses{node="69.197.42.27:9999"} 2

In the above node_statuses, you can see which nodes are connecting, which are already connected, which are disconnected due to no more retries, etc. The number next to each node represents the connection status:

  • 0 - The Sidecar is preparing to connect
  • 1 - The Sidecar is connecting to the node
  • 2 - The Sidecar is connected to this node
  • 3 - The Sidecar is reconnecting
  • -1 - The Sidecar is not connected and has reached the maximum connection attempts
  • -2 - The Sidecar is not connected due to an incompatible node version

Diagnosing errors

To diagnose errors, look for error logs and check the error_counts on the metrics page, http://SIDECAR_URL:SIDECAR_ADMIN_PORT/metrics, where most of the errors related to data flow will be stored:

# HELP error_counts Error counts
# TYPE error_counts counter
error_counts{category="connection_manager",description="fetching_from_stream_failed"} 6

Monitoring memory consumption

To monitor the Sidecar's memory consumption, observe the metrics page, http://SIDECAR_URL:SIDECAR_ADMIN_PORT/metrics. Search for process_resident_memory_bytes:

# HELP process_resident_memory_bytes Resident memory size in bytes.
# TYPE process_resident_memory_bytes gauge
process_resident_memory_bytes 292110336

If memory consumption is high without an apparent reason, please inform the Sidecar team by creating an issue in GitHub.

Remember to check the event_stream_buffer_length setting in the configuration because it dramatically impacts how much memory the Sidecar consumes. Also, some events, like step events, consume more memory.

Ensuring sufficient storage

Ensuring enough space in the database is essential for the Sidecar to consume events produced from the nodes' SSE streams over a more extended period. Each event is written to the database in a raw format for future processing. Running the Sidecar for an extended period (weeks or months) can result in storing multiple Gigabytes of data. If the database runs out of space, the Sidecar will lose events, as it cannot record them.

Inspecting the REST API

The easiest way to inspect the Sidecar’s REST API is with Swagger.

Limiting concurrent requests

The Sidecar can be configured to limit concurrent requests (max_concurrent_requests) and requests per second (max_requests_per_second) for the REST and admin servers.

However, remember that those are application-level guards, meaning that the operating system already accepted the connection, which used up the operating system's resources. Limiting potential DDoS attacks requires consideration before the requests are directed to the Sidecar application.

casper-sidecar's People

Contributors

acstonecl avatar darthsiroftardis avatar fraser999 avatar george-cl avatar ipopescu avatar sacherjj avatar tomvasile avatar zacshowa avatar zajko avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

casper-sidecar's Issues

Implement Storage DB

In the prototype I implemented a SQLite DB as it was the simplest setup.

I've been advised it would be better to use a PostgreSQL DB instead so we should discuss and then implement it.

Need to decide on how (which crate) to serialise the data - we want to avoid using bytesrepr.

Release checklist for SSE Sidecar v1.0 - Internal Release

  • (DEV) Close or defer all tickets in the epics (code complete/scope closure) - code freeze
  • (DEV) Create release candidate branch (branching, tagging)
  • (Business Owner) Identify destination & distribution targets (communications, announcements)
  • (SRE) Ensure SRE pipelines are in place
  • (DEV) unit & Integration tests have passed
  • (DEV) Create readme in git repo (scope closure)
  • (DEV) ensure changelog is in place
  • (SRE) acceptance tests in a production environment has passed
  • (DEV) Documentation updates are in place (docs team)
  • (DEV) do we need a license added/updated? n/a

Release checklist sidecar v1.1

  • (DEV) Close or defer all tickets in the epics (code complete/scope closure) - code freeze
  • (DEV) Create release candidate branch (branching, tagging)
  • (Business Owner) Identify destination & distribution targets (communications, announcements)
  • (SRE) Ensure SRE pipelines are in place
  • (DEV) unit & Integration tests have passed
  • (DEV) Create readme in git repo (scope closure)
  • (DEV) ensure changelog is in place
  • (SRE) acceptance tests in a production environment has passed
  • (DEV) Documentation updates are in place (docs team)
  • [ ]

too eager panic in the fake_event_stream file

after uncommenting the integration tests there was a test failing. after re-run it passed. Looking into the original failure, a panic in the fake_event_stream file needs investigation.

[SSE Sidecar] GraphQL Analysis

@hectoratcasper commented on Thu Jun 02 2022

Identify required elements to support future implementations for GraphQL

Expected result

GraphQL Analysis determining the following:
Re usage of RESTful models o new design enhancements.
Subscribe to various chunks of server data
Request multiple objects
Maintain constant connection with server using Websockets (bi - direccional)

Resources

Please refer to the SSE Sidecar High Level Design document for high level implementation details.

https://docs.google.com/document/d/1vBRbBmij9HHotY_8HIaUKk5a9Kq9Rqgxlk-UAE_F7xs/edit

Repository for this project:
https://github.com/CasperLabs/event-sidecar

Fix broken integration tests

after removing #[ignore] attr, 2 integration tests fail. One is recreate-able, one is sporadic.
Fix the recreate-able test.

[SSE Sidecar] Configuration

@hectoratcasper commented on Thu Jun 02 2022

Configuration enhancements

Configuration options should provide the ability to connect to more than one node and add the ability to specify the balancing configuration (consistent hashing, round robin)
Configuration options should allow the creation of a “default” database (SQLite)
Configuration options to support other databases, ie: SQLServer, ksqlDB, others.
Configuration should support a default Key storage mechanism
Configuration should support at least a modern Key Storage Management solution like AWS KMS or Azure Vault

#Expected behavior

Pending discussion with developer

Storage

The sidecar needs to have reliable and efficient methods for storing the data consumed from the SSE.

I envisioned there being a relational DB for storing all of the consumed data - with relationships setup to make it convenient to retrieve data relating to entities like Account/Contract rather than Block/Deploy.

I then thought it may be useful to have a fast key-value store(s) to hold frequently queried data like Balance by Public Key/Account Hash which could serve simple but common requests.

[SSE Sidecar] Authentication with Bearer Token

this requirement can be found in the following document:
https://docs.google.com/document/d/1vBRbBmij9HHotY_8HIaUKk5a9Kq9Rqgxlk-UAE_F7xs/edit#heading=h.95i1qjit3j6q

The RESTful endpoint should support basic authentication using an API bearer token.

curl --header "Authorization: Bearer : SIDECAR_API_KEY" http://127.0.0.1:18888/block

The API should return an Unauthorized error code if token is invalid.

HTTP/1.1 401 Unauthorized
Content-Type: application/json

{
  "error": {
    "message": "Unauthorized",
    "code": 401
  }
}

Step event serialization optimization

@RitaMAllenCA commented on Wed Dec 07 2022

I added a few println!s in and the delay is between the FakeEventStream and the EventListener.
It takes about 3.7s to get from the FES to the Listener and then in the listener it takes 1.6s to deserialise the step.
Just FYI, so we could probably improve deserialisation time (1.6s) in the future but it's the 3.7s in flight that I'd like to dissect in the near future.

also see this link: https://casperlabs-team.slack.com/archives/C03HJUB2W9X/p1670596148873599. may not be an issue any longer?


@RitaMAllenCA commented on Wed Dec 21 2022

Issue moved to CasperLabs/event-sidecar #57 via Zenhub

Fix broken duplicate event integration test

During the v1.0 release, 2 integration tests started failing (they had been ignored). We fixed the first in #100. The second was not reprocudeable reliably, This is to continue the work to investigate the case for middleware and perhaps fix the integration test.

Consumption

The sidecar needs to be able to consume the SSE of the node and recover from a dropped connection without losing any of the state.

Retrieval

The sidecar should expose convenient interfaces for clients to retrieve the stored data.

REST

A REST endpoint(s) should allow clients to make one-off requests to the sidecar.
(Existing) Endpoints:

  • /get-block
    • /hash/<hash: string>
    • /height/<height: u16>
  • /get-deploy/hash/<hash: string>
  • /get-step/<era_id: u16>
  • /get-balance
    • /key/<public_key: string>
    • /hash/<account_hash: string>

WS / Pub-Sub (TBC)

Clients would benefit from a convenient subscription-based interface to allow them to be updated with changes to state in real-time.
Endpoints could be for updates to balance (new transfers), contract activity etc.

Decouple from casper-node types

Some types from casper-node are relied upon in this crate and we should look to re-implement them or could they be moved into casper-types?

Event Log logging duplicate events

addresses the issue found here: https://casper-labs-team.slack.com/archives/C03HJUB2W9X/p1676047611062969

You can look at the thread for details, but to recap - there is a possibility that we will write an event log twice with the same data if the message was retried for some reason. This caused one of the tests to be unstable and I "dirty-fixed" it with a retry.

Fraser requested a meeting to discuss what we should do with this.
My initial thoughts and questions for the meeting:

  • Figure out why we need to store the event logs in the first place, and if we do - shouldn't we just treat them as logs not records
  • Maybe we could drop the uniqueness constraints altogether - do we rely on event log uniqueness to imply other record consistency?

from the meeting on 2.24.23

  • unique key over event type and external key
  • add a default of current timestamp to emitted timestamp
  • max_attempts == 0 is an error case that should return early

Implement REST Interface

REST endpoints need to be reviewed/agreed upon. Need to be returning proper HTTP response - status code and payload.

Event Sidecar filter for empty blocks

@caspersteve commented on Wed Nov 30 2022

As the dev team, let's create a sidecar filter to get empty block data so that the Association can consume this for their ESG Dashboard with Proof.io, and so the internal KPI Dashboard can consume this for reporting on empty blocks and demand.

Considerations:

  • Unless there's a better way to do this, I assume the calculations like percentage of empty blocks since date/block height would best be done on the dapp side of the equation.
  • Calculating the usage percentage per block could also be explored.

[SSE Sidecar] Add Basic authentication to RESTful API

@hectoratcasper commented on Thu Jun 02 2022

Add Basic authentication to RESTful API

The sidecar exposes blockchain event endpoints through a RESTful API, but authentication is not implemented for the MVP version. In order to restrict access to these endpoints, we need to implement basic authentication using an API key as the credential.

The RESTful endpoint should support basic authentication using an API key.

curl --header "api_key: SIDECAR_API_KEY" http://127.0.0.1:18888/block

The sidecar should be able to work in both authenticated and non-authenticated modes.

New settings can be added to the existing configuration file in a new [auth] section:

# TOML configuration file for Rust sidecar project 

[auth]
enabled = true

[auth.users] 
username = "user1"
api_key = "SIDECAR_API_KEY" 

api_key: The value of the API key to use for authentication. If this value is not provided or is empty, authentication will be disabled.

enabled: A boolean value indicating whether authentication should be enabled. If set to false, the server will not require authentication and requests will be processed without checking for an API key. If set to true, the server will require an API key in order to process requests.

Resources

Please refer to the SSE Sidecar High Level Design document for high level implementation details.

https://docs.google.com/document/d/1vBRbBmij9HHotY_8HIaUKk5a9Kq9Rqgxlk-UAE_F7xs/edit#heading=h.95i1qjit3j6q

Repository for this project:
https://github.com/CasperLabs/event-sidecar

[SSE Sidecar] The sidecar should support the OpenAPI specification

@hectoratcasper commented on Thu Jun 02 2022

Research for the best implementation to add a swagger.json OpenAPI to endpoint

The OpenAPI Specification, previously known as the Swagger Specification, is a specification for machine-readable interface files for describing, producing, consuming, and visualizing RESTful web services.

Having this added in a programable way will allow to identify the require models for the RESTful API faster.

Expected behavior

generated schema should be validated against https://inspector.swagger.io

Resources

Please refer to the SSE Sidecar High Level Design document for high level implementation details.

https://docs.google.com/document/d/1vBRbBmij9HHotY_8HIaUKk5a9Kq9Rqgxlk-UAE_F7xs/edit

Repository for this project:
https://github.com/CasperLabs/event-sidecar


@George-cl commented on Mon Jun 20 2022

I'm happy to use the Swagger spec - is this something @hectoratcasper would be comfortable/have the cycles to do?
I just mean to use the Swagger Editor to populate what our API should look like and add descriptions which may need the docs team's input.

Then once that spec is fulfilled I can implement the REST API accordingly.

MVP with Actor Pattern

This is to explore a re-architect with the aim of making the application more extensible by laying down a basic Actor system for the components of the sidecar.

[SSE Sidecar] Sidecar service should support configuration file-based Event Filtering

@hectoratcasper commented on Thu Jun 02 2022

The sidecar should allow the ability to implement configuration file-based Event Filtering

The sidecar should allow node operators to set preferences for the types of events they want to receive during their session. This will enable users to filter out events that are not relevant to them and reduce the amount of data they need to process.

[event_filtering_settings]
#Event types to filter
include_event_types = ["shutdown", "deployExpired "]

Resources

Please refer to the SSE Sidecar High Level Design document for high level implementation details.
https://docs.google.com/document/d/1vBRbBmij9HHotY_8HIaUKk5a9Kq9Rqgxlk-UAE_F7xs/edit#heading=h.dqrvn1jm98w6

Repository for this project:
https://github.com/CasperLabs/event-sidecar


@RitaMAllenCA commented on Thu Nov 10 2022

@George-cl need an estimate please

Implement SSE Consumer

The sidecar currently uses sse-client which allows for the construction of an EventSource to iterate over the SSE stream.

There is no handling for a dropped connection as it stands - the SSE events have anid which could be used to retrace missed events and query for the data from the RPC.

Change Max_retries to Max_attempts

have an issue with max_retries=0, but no issues with max_retries=1.
Current config is set to max_retries=10, so this is not a blocker for release but probably a bug to file
With max_retries=0, is get Error: Connected node(s) are unavailable every time.

we should rename the field to max_attempts since that's how it's interpreted in the code so if you don't want it to retry a failed connection then a value of 1 would suffice
max_retries which implied value of 0 would make an attempt to connect but not to retry if it fails.
This isn't the case, the value is the maximum attempts the sidecar will make to connect, so 0 means it won't try at all
2.24.23 additionally, treat a max attempt = 0 as a no-start.

Step event serialization optimization

@RitaMAllenCA commented on Wed Dec 07 2022

I added a few println!s in and the delay is between the FakeEventStream and the EventListener.
It takes about 3.7s to get from the FES to the Listener and then in the listener it takes 1.6s to deserialise the step.
Just FYI, so we could probably improve deserialisation time (1.6s) in the future but it's the 3.7s in flight that I'd like to dissect in the near future.

also see this link: https://casperlabs-team.slack.com/archives/C03HJUB2W9X/p1670596148873599. may not be an issue any longer?

Write inline code comments

This ticket is for me to go through the sidecar code and properly document it with a consistent formatting and style such that if the crate(s) were to be published the documentation would be up to scratch.

[v1.0] SSE Sidecar & Storage

Hector's assets defining the MVP technical requirements for the first implementation of the SSE Sidecar:

Hector has developed the stories based on an existing version of the product, and a recording from Ed found here:

#[derive(Debug)]
pub enum Event {
    BlockAdded(Box<Block>),
    DeployAccepted(Box<Deploy>),
    DeployProcessed {
        deploy_hash: DeployHash,
        deploy_header: Box<DeployHeader>,
        block_hash: BlockHash,
        execution_result: Box<ExecutionResult>,
    },
    DeploysExpired(Vec<DeployHash>),
    Fault {
        era_id: EraId,
        public_key: PublicKey,
        timestamp: Timestamp,
    },
    FinalitySignature(Box<FinalitySignature>),
    Step {
        era_id: EraId,
        execution_effect: ExecutionEffect,
    },
}

Acceptance Criteria:

  • must be robust
  • must be well factored
  • must be low latency
  • must be a drop in replacement for any existing usage of the node's event port
  • must store the data intelligently
  • must be testable and tested
  • must offer a simple REST query for historical events

Additional Considerations:

  • We should investigate how this could interface with indexing/querying systems like TheGraph and with oracles like Chainlink.
  • Something that is end user configurable, user defined, templates we can anticipate built in?
  • Open source first, anyone can build their own data orientation
  • Enterprise version might have a UI on top of it

The below was an earlier attempted description of the MVP for SSE Sidecar, based on an account data filter. This will now become a future FF implementation of a filter and hydration of data.

Account Data Orientation

  • Will collect and store all information from an Account focused perspective:
  • MVP is the API endpoints and how to filter the data
    • Hash
    • A collection of named keys
    • A URef representing the account's "main purse"
    • A collection of "associated keys", weights
    • Thresholds
    • Account Balance in main purse
    • Transaction History
      • DeployInfo
        • Body: containing payment code and session code
        • Header: containing the identity key of the account the deploy will run in
        • the timestamp when the deploy was created
        • a time to live, after which the deploy is expired and cannot be included in a block
        • the blake2b256 hash of the body
        • Deploy hash: the blake2b256 hash of the Header
        • Approvals: the set of signatures which have signed the deploy hash
        • Lifecycle Event:
          • Block Hash
          • Block Number
          • Merkle proof
        • Cost
        • Execution results (Status)
        • Transfers

Account JSON:

"root": {
    "json": {
        "Account": {
            "account_hash": "account-hash-3f539c55a7ef1ce5c81b53ffd6ff2d928fbb943bf63e00b9d28da7b70dc0a9b6"
        "named_keys": []
      "main_purse": "uref-324d657ad0972c6300d677918796cb7bec5f9b880298111313beb2c6b0750b05-007"
        "associated_keys": [
                0: {
                    "account_hash": "account-hash-3f539c55a7ef1ce5c81b53ffd6ff2d928fbb943bf63e00b9d28da7b70dc0a9b6"
           "weight": 1
                }
            ]
        "action_thresholds": {
                "deployment": 1
          "key_management": 1
            }
        }
    }
}

Deploy JSON:

"root": {
    "json": {
        "deploy": {
            "hash": "e5ee7308f9f4d10501f7feb44031971585f658700ebb57ff474f014bcef03c4e"
            "header": {
                "ttl": "1day"
                "account": "01d8f9e8156c1a6a0a655da9c46c86cbd0a8a04b0d2bc962da61e0150763618c3a"
                "body_hash": "03eab24e3fda58c4bca7b9b42879be98c057c044c4cf13a06b0696081bffdee4"
                "gas_price": 1
                "timestamp": "2022-04-28T17:12:32.754Z"
                "chain_name": "casper"
                    "dependencies": []
            }
                "payment": {
                "ModuleBytes": {
                    "args": [
                        0: [
                            0: "amount"
                                1: {
                                "bytes": "0400c2eb0b"
                                "parsed": "200000000"
                                "cl_type": "U512"
                            }
                        ]
                    ]
                "module_bytes": ""
                }
            }
                "session": {
                "Transfer": {
                    "args": [
                        0: [
                            0: "amount"
                                1: {
                                "bytes": "060336ea41a50a"
                                "parsed": "11704891749891"
                                "cl_type": "U512"
                            }
                        ]
                        1: [
                            0: "target"
                            1: {
                                "bytes": "94664ce59fa2e6eb0cc69d270fc91dd9dd2ba02a1f7964c69f036ef4a68bb96f"
                                "parsed": "94664ce59fa2e6eb0cc69d270fc91dd9dd2ba02a1f7964c69f036ef4a68bb96f"
                                "cl_type": {
                                    "ByteArray": 32
                                }
                            }
                        ]
                        2: [
                            0: "id"
                            1: {
                                "bytes": "00"
                                "parsed":NULL
                                "cl_type": {
                                    "Option": "U64"
                                }
                            }
                        ]
                        3: [
                            0: "targetAccountHex"
                            1: {
                                "bytes": "01b92e36567350dd7b339d709bfe341df6fda853e85315418f1bb3ddd414d9f5be"
                                "parsed": "01b92e36567350dd7b339d709bfe341df6fda853e85315418f1bb3ddd414d9f5be"
                                "cl_type": "PublicKey"
                            }
                        ]
                    ]
                }
            }
    "approvals": [
                0: {
                    "signer": "01d8f9e8156c1a6a0a655da9c46c86cbd0a8a04b0d2bc962da61e0150763618c3a"
                    "signature": "015d0a47df8e8bdb6b86469b9dd1d6b9847c745b0c24a83a88d8cf9e7d0cc593f331b187ff856ff378e3b901c8998c1eb30143b871250b02944147b268ac3c1101"
                }
            ]
        }
    "api_version": "1.4.5"
    "execution_results": [
            0: {
                "result": {
                    "Success": {
                        "cost": "100000000"
                        "effect": {
                            "operations": []
                            "transforms": [
                                0 - 10
                            ]
                                [
                                10 - 20
                            ]
                                [
                                20 - 30
                            ]
                                [
                                30 - 38
                            ]
                        }
                        "transfers": [
                            0: "transfer-d492200c53c0508ce82e084cd6078310c51ed2b95d95bc26b2f119e7978573c1"
                        ]
                    }
                }
                "block_hash": "a44fa0eafbcc7385e67861c8811583e342c25db9592e2026ed9f134a9d8c2f04"
            }
        ]
    }
}

From MAKE 2.0 Wishlist regarding how to query the events:

  • SSE streams return predefined types of events, however the stream types and events they stream are predefined. It would be more convenient to have possibility to provide what events the listener wants to listen when connection to the event stream.
  • Additionally, right now the event type is provided as JSON property, which requires JSON parsing to know the event type. With larger numbers of events synchronous JSON parsing may add up to computational overhead. Maybe the following change would stream events with their type separated from the event body.
    • For example, instead of: data:{“BlockAdded: {...}}, the API could be: BlockAdded:{...}

Background/Context:

  • MAKE asked for this previously in their Casper 2.0 Wishlist. They want a ledger like structure to be able to access chronological txs, categorized, and to be presented in the MAKE wallet against users. This effort would effectively provide that structure.

Reference:

Other data orientation possibilities:

  • Asset based orientation - mint, transfer, burn

Listener to use status endpoint to get api version

@RitaMAllenCA commented on Tue Dec 06 2022

This is a ticket to capture work needed as a release blocker for MVP candidate for v1.0. to include:

https://casperlabs-team.slack.com/archives/C03HJUB2W9X/p1670352773897019

refactor listener to query the status endpoint for api version and connect to the relevant available SSE endpoints based on the api version.
should be possible to perform a jquery to fish out the api version field in the response of the status endpoint.

Add tests for multiple connection handling

@George-cl commented on Sat Oct 29 2022

As the title says; need to add functionality around the Fake Event Stream to spin up multiple instances. Each instance should be individually configured.
It should make it convenient for a test to spin up multiple Fake Event Streams and then bind to them on their respective ports.

All tests covering partial connection and re-connection should then be extended to cover the case where there are multiple nodes in play and ensure that the sidecar behaves correctly.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.