executor

package
v0.18.0 Latest Latest
Warning

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

Go to latest
Published: Jun 27, 2024 License: MIT Imports: 36 Imported by: 0

README

Executor

The Executor is an agent responsible for executing messages on the Destination.sol contracts. It verifies that the message has been accepted by verifying a merkle proof, as well as the message's optimistic period.

Components

The Executor operates with four main components:

Run

streamLogs is the data-getter for the Executor. It works by instantiating a gRPC connection to Scribe, and puts logs in a channel for the origin and destination contracts on each chain in the config. From here, it verifies the logs' order since the order of logs are very important for merkle tree construction.
Additionally, if the Executor unexpectedly stops in the middle of streaming logs, it will use the current database state to reconstruct the tree up to where the last log was, then continue to use gRPC.

receiveLogs is the data-processor for the Executor. It works by taking the logs streamed from streamLogs and parsing the logs into either a Message on the Origin.sol contract, or a Attestation on the Destination.sol contract. It then stores the data into the Executor's database and builds the tree accordingly.

setMinimumTime sets the minimum unix time for a message before it has passed the optimistic period and can be executed. It works by going through all messages in the database that haven't been set, and checks for attestations to set each message's time.

executeExecutable is the function that executes messages. It looks through all messages that have a time set from setMinimumTime and executes them if the minimum time is past the current time.

Message Lifecycle

As a message gets sent by a user on an Origin chain, there are a few important variables with the message that guide its execution.

  • Origin: The chain ID of the chain the message is originating from
  • Nonce: The nonce of the message for all messages sent on this origin (if 5 other messages by other users were sent before on this origin, the nonce would be 6)
  • Destination: The chain ID of the chain the message is targeting
  • OptimisticSeconds: How many seconds should be allocated for fraud catching before the message is able to be executed on the Destination

Once a message is constructed with all of these fields and is dispatched via the SendBaseMessage function on the Origin's Origin.sol contract, the message starts its lifecycle in the SIN. Let's say this message has nonce N.

  1. A Guard captures a State of the Origin with a nonce of N. So messages from 1 to N are all included in this State.
  2. The Guard collects different States across various chains and submits them all in a Snapshot to the SynChain.
  3. A Notary looks at all States that Guards have submitted to the SynChain, and creates a Snapshot with the new states. So a Notary sees the state that was caputred in step 1 and submits it in a Snapshot on SynChain.
  4. After the Notary is submitted, a Snapshot Root, representing a Merkle Tree of all the data in the Snapshot has been saved. Now, the message is included in a Notary's Snapshot on SynChain and is ready to be delivered to the Destination.
  5. A Notary (same or different than the one that performed step 3) now submits an Attestation to the Destination. Once this Attestation is accepted on the Destination, the message's OptimisticSeconds timer starts.

Now, it is the executors job to ensure that a message that it has seen on Origin has gone through the whole lifecycle, while proving inclusion at various steps, before it is able to wait for the message's optimistic period and execute the message.

Execute

Execute works in 3 parts.

  1. Verify that the optimistic period for the message has passed. This is done by checking the timestamp that the attestation was accepted on the Destination, then checking the timestamp of the last block.
  2. Verify that the message is in the merkle tree.
  3. Call the Execute function on the Destination.sol contract.

Usage

Navigate to sanguine/agents/agents/executor/main and run the following command to start the Executor:

$ go run main.go

Then the Executor command line will be exposed. The Executor requires a gRPC connection to a Scribe instance to stream logs. This can be done with either a remote Scribe or an embedded Scribe.

From the CLI, you specify whether you want to use a remote or embedded scribe via the --scribe-type flag. If using remote, you need to use the --scribe-port, --scribe-grpc-port and --scribe-url flags. If using embedded, you need to use the --scribe-db and --scribe-path flags.

Remote Scribe

Run the following command to start the Executor with a remote Scribe:

# Start the Executor
$ run --config </Users/synapsecns/config.yaml> --db <sqlite> or <mysql>\
 --path <path/to/database> or <database url> --scribe-type remote\
 --scribe-port <port> --scribe-grpc-port <port> --scribe-url <url>
Embedded Scribe

When using an embedded Scribe, a Scribe config must be included in the Executor config.

Run the following command to start the Executor with an embedded Scribe:

# Start the Executor and an embedded Scribe
$ run --config </Users/synapsecns/config.yaml> --db <sqlite> or <mysql>\
 --path <path/to/database> or <database url> --scribe-type embedded\
 --scribe-db <sqlite> or <mysql> --scribe-path <path/to/database> or <database url>

Directory Structure

Executor
├── cmd: CLI commands
├── config: Configuration files
├── db: Database interface
│   └── sql: Database writer, reader, and migrations
├── main: CLI entrypoint
└── types: Executor types

Documentation

Overview

Package executor is the executor agent responsible for proving and executing cross-chain messages.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewTreeFromDB added in v0.0.81

func NewTreeFromDB(ctx context.Context, chainID uint32, executorDB db.ExecutorDB) (*merkle.HistoricalTree, error)

NewTreeFromDB builds a merkle tree from the db.

Types

type Backend added in v0.0.63

type Backend interface {
	// HeaderByNumber returns the block header with the given block number.
	HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error)
}

Backend is the backend for the executor.

type Executor

type Executor struct {

	// NowFunc returns the current time.
	NowFunc func() time.Time
	// GetChainTimeFunc gets the chain time.
	GetChainTimeFunc func(ctx context.Context, backend Backend) (uint64, error)
	// contains filtered or unexported fields
}

Executor is the executor agent.

func NewExecutor

func NewExecutor(ctx context.Context, config executor.Config, executorDB db.ExecutorDB, scribeClient client.ScribeClient, omniRPCClient omnirpcClient.RPCClient, handler metrics.Handler) (*Executor, error)

NewExecutor creates a new executor agent.

func (Executor) CheckIfExecuted added in v0.0.184

func (e Executor) CheckIfExecuted(ctx context.Context, message types.Message) (bool, error)

CheckIfExecuted checks if a message has been executed.

func (Executor) Execute added in v0.0.69

func (e Executor) Execute(parentCtx context.Context, message types.Message) (_ bool, err error)

Execute calls execute on `Destination.sol` on the destination chain, after verifying the message. TODO: Use multi-call to batch execute.

func (Executor) ExecuteExecutable added in v0.0.86

func (e Executor) ExecuteExecutable(ctx context.Context) error

ExecuteExecutable executes executable messages in the database.

func (Executor) GetLogChan added in v0.0.81

func (e Executor) GetLogChan(chainID uint32) chan *ethTypes.Log

GetLogChan gets a log channel.

func (Executor) GetMerkleTree added in v0.0.81

func (e Executor) GetMerkleTree(chainID uint32) *merkle.HistoricalTree

GetMerkleTree gets a merkle tree.

func (Executor) OverrideMerkleTree added in v0.0.81

func (e Executor) OverrideMerkleTree(chainID uint32, tree *merkle.HistoricalTree)

OverrideMerkleTree overrides the merkle tree for the chainID and domain.

func (Executor) Run added in v0.0.78

func (e Executor) Run(parentCtx context.Context) error

Run starts the executor agent. It calls `Start` and `Listen`.

func (Executor) SetMinimumTime added in v0.0.86

func (e Executor) SetMinimumTime(ctx context.Context) error

SetMinimumTime sets the minimum times.

func (Executor) StartAndListenOrigin added in v0.0.130

func (e Executor) StartAndListenOrigin(ctx context.Context, chainID uint32, address string) error

StartAndListenOrigin starts and listens to a chain.

func (Executor) Stop

func (e Executor) Stop(chainID uint32)

Stop stops the executor agent.

func (Executor) VerifyMessageMerkleProof added in v0.0.69

func (e Executor) VerifyMessageMerkleProof(message types.Message) (bool, error)

VerifyMessageMerkleProof verifies message merkle proof.

func (Executor) VerifyMessageOptimisticPeriod added in v0.0.69

func (e Executor) VerifyMessageOptimisticPeriod(ctx context.Context, message types.Message) (*uint32, error)

VerifyMessageOptimisticPeriod verifies message optimistic period.

func (Executor) VerifyStateMerkleProof added in v0.0.130

func (e Executor) VerifyStateMerkleProof(ctx context.Context, state types.State) (bool, error)

VerifyStateMerkleProof verifies state merkle proof.

Directories

Path Synopsis
Package api contains the API for the executor.
Package api contains the API for the executor.
Package cmd provides the command line interface for the Executor.
Package cmd provides the command line interface for the Executor.
db
Package db provides a database interface for the executor.
Package db provides a database interface for the executor.
sql
Package sql provides a datastore implementation for the executor.
Package sql provides a datastore implementation for the executor.
sql/base
Package base contains the base sql implementation
Package base contains the base sql implementation
sql/mysql
Package mysql implements the mysql package
Package mysql implements the mysql package
sql/sqlite
Package sqlite implements the sqlite package
Package sqlite implements the sqlite package
Package main provides the main entry point for the executor.
Package main provides the main entry point for the executor.
Package metadata provides metadata for Executor.
Package metadata provides metadata for Executor.
Package types contains the database types for the Executor.
Package types contains the database types for the Executor.

Jump to

Keyboard shortcuts

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