preconshare

package
v0.0.0-...-d1bef67 Latest Latest
Warning

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

Go to latest
Published: Apr 17, 2024 License: AGPL-3.0 Imports: 26 Imported by: 0

Documentation

Overview

Package preconshare implements preconf-share node Here is a full flow of data through the node:

bundle-relay-api -> API sends:

  • private transaction
  • mev share bundle

API -> SimQueue schedules simulation SimQueue -> SimulationWorker calls with the next simulation to process

SimulationWorker -> SimulationBackend is used to do simulation
SimulationWorker -> SimulationResultBackend is used to consume simulation result

SimulationResultBackend -> RedisHintBackend is used to send hint to hint-relay-api SimulationResultBackend -> BuilderBackend is used to send bundle to the builders

Index

Constants

View Source
const (
	MaxBlockOffset uint64 = 5
	MaxBlockRange  uint64 = 30
	MaxBodySize           = 50

	MaxNestingLevel = 1

	RefundPercent = 90

	HintGasPriceNumberPrecisionDigits = 3
	HintGasNumberPrecisionDigits      = 2
)
View Source
const (
	SendRequestEndpointName    = "preconf_sendRequest"
	ConfirmRequestEndpointName = "preconf_confirmRequest"
	GetRequestEndpointName     = "preconf_getRequest"
)

Variables

View Source
var (
	ErrInvalidInclusion      = errors.New("invalid inclusion")
	ErrInvalidBundleBodySize = errors.New("invalid bundle body size")
	ErrInvalidBundleBody     = errors.New("invalid bundle body")
	ErrBackrunNotFound       = errors.New("backrun not found")
	ErrBackrunInvalidBundle  = errors.New("backrun invalid bundle")
	ErrBackrunInclusion      = errors.New("backrun invalid inclusion")

	ErrInternalServiceError = errors.New("mev-share service error")
)
View Source
var (
	ErrUnsupportedBundleVersion = errors.New("unsupported bundle version")
	ErrBundleTooDeep            = errors.New("bundle too deep")
	ErrInvalidBundleConstraints = errors.New("invalid bundle constraints")
	ErrInvalidBundlePrivacy     = errors.New("invalid bundle privacy")
)
View Source
var (
	ErrInvalidHintIntent = errors.New("invalid hint intent")
	ErrNilBundleMetadata = errors.New("bundle metadata is nil")
)
View Source
var ErrBundleNotCancelled = errors.New("bundle not cancelled")
View Source
var ErrBundleNotFound = errors.New("bundle not found")
View Source
var ErrCannotExtractHints = errors.New("cannot extract hints")

Functions

func Intersect

func Intersect(a, b []string) []string

Intersect returns the intersection of two string arrays, without duplicates

func MergeInclusionIntervals

func MergeInclusionIntervals(topLevel, inner *RequestInclusion) error

MergeInclusionIntervals writes to the topLevel inclusion value of overlap between inner and topLevel or return error if there is no overlap

func RoundUpWithPrecision

func RoundUpWithPrecision(number *big.Int, precisionDigits int) *big.Int

RoundUpWithPrecision rounds number up leaving only precisionDigits non-zero examples: RoundUpWithPrecision(123456, 2) = 130000 RoundUpWithPrecision(111, 2) = 120 RoundUpWithPrecision(199, 2) = 120

func ValidateRequest

func ValidateRequest(bundle *SendRequestArgs, currentBlock uint64, signer types.Signer) (matchingHash common.Hash, unmatched bool, err error)

Types

type API

type API struct {
	// contains filtered or unexported fields
}

func NewAPI

func NewAPI(
	log *zap.Logger,
	scheduler SimScheduler, bundleStorage BundleStorage, eth EthClient, signer types.Signer,
	simBackends []SimulationBackend, cancellationCache *RedisCancellationCache,
	sbundleValidDuration time.Duration,
) *API

func (*API) ConfirmRequest

func (m *API) ConfirmRequest(ctx context.Context, confirmation ConfirmRequestArgs) (_ ConfirmRequestResponse, err error)

func (*API) GetRequest

func (m *API) GetRequest(ctx context.Context, request GetRequestArgs) (_ GetRequestResponse, err error)

func (*API) SendRequest

func (m *API) SendRequest(ctx context.Context, request SendRequestArgs) (_ SendRequestResponse, err error)

type BundleStorage

type BundleStorage interface {
	GetBundleByMatchingHash(ctx context.Context, hash common.Hash) (*SendRequestArgs, error)
	InsertPreconf(ctx context.Context, preconf *ConfirmRequestArgs) error
	GetPreconfByMatchingHash(ctx context.Context, hash common.Hash) (*int64, *hexutil.Bytes, *int64, error)
	UpdatePreconfTimeBySignature(ctx context.Context, time int64, hash common.Hash) error
}

type CleanLog

type CleanLog struct {
	// address of the contract that generated the event
	Address common.Address `json:"address"`
	// list of topics provided by the contract.
	Topics []common.Hash `json:"topics"`
	// supplied by the contract, usually ABI-encoded
	Data hexutil.Bytes `json:"data"`
}

type ConfirmPreconf

type ConfirmPreconf struct {
	Hash  common.Hash    `json:"hash"`
	Block hexutil.Uint64 `json:"block"`
}

type ConfirmRequestArgs

type ConfirmRequestArgs struct {
	Version   string         `json:"version"`
	Preconf   ConfirmPreconf `json:"preconf"`
	Signature *hexutil.Bytes `json:"signature"`
	Endpoint  string         `json:"endpoint"`
}

type ConfirmRequestResponse

type ConfirmRequestResponse struct {
	Valid bool `json:"valid"`
}

type DBBackend

type DBBackend struct {
	// contains filtered or unexported fields
}

func NewDBBackend

func NewDBBackend(postgresDSN string) (*DBBackend, error)

func (*DBBackend) Close

func (b *DBBackend) Close() error

func (*DBBackend) GetBundleByMatchingHash

func (b *DBBackend) GetBundleByMatchingHash(ctx context.Context, hash common.Hash) (*SendRequestArgs, error)

func (*DBBackend) GetPreconfByMatchingHash

func (b *DBBackend) GetPreconfByMatchingHash(ctx context.Context, hash common.Hash) (*int64, *hexutil.Bytes, *int64, error)

func (*DBBackend) InsertBundleForStats

func (b *DBBackend) InsertBundleForStats(ctx context.Context, bundle *SendRequestArgs) (known bool, err error)

InsertBundleForStats inserts a bundle into the database. When called for the second time for the known bundle, it will return known = true and update bundle simulation results with the last inserted simulation results.

func (*DBBackend) InsertHistoricalHint

func (b *DBBackend) InsertHistoricalHint(ctx context.Context, currentBlock uint64, hint *Hint) error

func (*DBBackend) InsertPreconf

func (b *DBBackend) InsertPreconf(ctx context.Context, preconf *ConfirmRequestArgs) error

func (*DBBackend) UpdatePreconfTimeBySignature

func (b *DBBackend) UpdatePreconfTimeBySignature(ctx context.Context, time int64, hash common.Hash) error

type DBSbundle

type DBSbundle struct {
	Hash               []byte         `db:"hash"`
	MatchingHash       []byte         `db:"matching_hash"`
	Signer             []byte         `db:"signer"`
	Cancelled          bool           `db:"cancelled"`
	AllowMatching      bool           `db:"allow_matching"`
	Prematched         bool           `db:"prematched"`
	ReceivedAt         time.Time      `db:"received_at"`
	SimSuccess         bool           `db:"sim_success"`
	SimError           sql.NullString `db:"sim_error"`
	SimulatedAt        sql.NullTime   `db:"simulated_at"`
	SimEffGasPrice     sql.NullString `db:"sim_eff_gas_price"`
	SimProfit          sql.NullString `db:"sim_profit"`
	SimRefundableValue sql.NullString `db:"sim_refundable_value"`
	SimGasUsed         sql.NullInt64  `db:"sim_gas_used"`
	// sum of all simulations gas used
	SimAllSimsGasUsed sql.NullInt64 `db:"sim_all_sims_gas_used"`
	// number of simulations that were run for this bundle
	SimTotalSimCount sql.NullInt64  `db:"sim_total_sim_count"`
	Body             []byte         `db:"body"`
	BodySize         int            `db:"body_size"`
	OriginID         sql.NullString `db:"origin_id"`
	InsertedAt       time.Time      `db:"inserted_at"`
}

type DBSbundleBody

type DBSbundleBody struct {
	Hash        []byte `db:"hash"`
	ElementHash []byte `db:"element_hash"`
	Idx         int    `db:"idx"`
	Type        int    `db:"type"`
}

type DBSbundleHistoricalHint

type DBSbundleHistoricalHint struct {
	ID         int64           `db:"id"`
	Block      int64           `db:"block"`
	Hint       json.RawMessage `db:"hint"`
	InsertedAt time.Time       `db:"inserted_at"`
}

type DBSpreconf

type DBSpreconf struct {
	Hash       []byte    `db:"hash"`
	Block      int64     `db:"block"`
	Signature  []byte    `db:"signature"`
	Time       int64     `db:"time"`
	InsertedAt time.Time `db:"inserted_at"`
}

type EthCachingClient

type EthCachingClient struct {
	// contains filtered or unexported fields
}

func NewCachingEthClient

func NewCachingEthClient(ethClient *ethclient.Client) *EthCachingClient

func (*EthCachingClient) BlockNumber

func (c *EthCachingClient) BlockNumber(ctx context.Context) (uint64, error)

BlockNumber returns the most recent block number, cached for 5 seconds

type EthClient

type EthClient interface {
	BlockNumber(ctx context.Context) (uint64, error)
}

type GetRequestArgs

type GetRequestArgs struct {
	Version string      `json:"version"`
	Hash    common.Hash `json:"hash"`
}

type GetRequestResponse

type GetRequestResponse struct {
	Signature *hexutil.Bytes `json:"signature"`
	Block     hexutil.Uint64 `json:"block"`
	Time      hexutil.Uint64 `json:"time"`
}

type Hint

type Hint struct {
	Hash      common.Hash      `json:"hash"`
	Inclusion RequestInclusion `json:"inclusion"`
	Logs      []CleanLog       `json:"logs"`
	Txs       []TxHint         `json:"txs"`
}

func ExtractHints

func ExtractHints(bundle *SendRequestArgs) (Hint, error)

type HintBackend

type HintBackend interface {
	NotifyHint(ctx context.Context, hint *Hint) error
}

type HintIntent

type HintIntent uint8

HintIntent is a set of hint intents its marshalled as an array of strings

const (
	HintContractAddress HintIntent = 1 << iota
	HintFunctionSelector
	HintLogs
	HintCallData
	HintHash
	HintSpecialLogs
	HintTxHash
	HintNone = 0
)

func (*HintIntent) HasHint

func (b *HintIntent) HasHint(flag HintIntent) bool

func (HintIntent) MarshalJSON

func (b HintIntent) MarshalJSON() ([]byte, error)

func (*HintIntent) SetHint

func (b *HintIntent) SetHint(flag HintIntent)

func (*HintIntent) UnmarshalJSON

func (b *HintIntent) UnmarshalJSON(data []byte) error

type JSONRPCBuilder

type JSONRPCBuilder struct {
	// contains filtered or unexported fields
}

func (*JSONRPCBuilder) String

func (b *JSONRPCBuilder) String() string

type JSONRPCSimulationBackend

type JSONRPCSimulationBackend struct {
	// contains filtered or unexported fields
}

func NewJSONRPCSimulationBackend

func NewJSONRPCSimulationBackend(url string) *JSONRPCSimulationBackend

type RedisCancellationCache

type RedisCancellationCache struct {
	// contains filtered or unexported fields
}

func NewRedisCancellationCache

func NewRedisCancellationCache(client *redis.Client, expireDuration time.Duration, keyPrefix string) *RedisCancellationCache

func (*RedisCancellationCache) Add

func (*RedisCancellationCache) DeleteAll

func (c *RedisCancellationCache) DeleteAll(ctx context.Context) error

DeleteAll deletes all the keys in the cache. It can be very slow and should only be used for testing.

func (*RedisCancellationCache) IsCancelled

func (c *RedisCancellationCache) IsCancelled(ctx context.Context, hash []common.Hash) (bool, error)

type RedisHintBackend

type RedisHintBackend struct {
	// contains filtered or unexported fields
}

func NewRedisHintBackend

func NewRedisHintBackend(redisClient *redis.Client, pubChannel string) *RedisHintBackend

func (*RedisHintBackend) NotifyHint

func (b *RedisHintBackend) NotifyHint(ctx context.Context, hint *Hint) error

type RequestBody

type RequestBody struct {
	Tx *hexutil.Bytes `json:"tx,omitempty"`
}

type RequestInclusion

type RequestInclusion struct {
	DesiredBlock hexutil.Uint64 `json:"desiredBlock"`
	MaxBlock     hexutil.Uint64 `json:"maxBlock"`
	Tip          hexutil.Uint64 `json:"tip"`
}

type RequestMetadata

type RequestMetadata struct {
	RequestHash  common.Hash    `json:"requestHash,omitempty"`
	BodyHashes   []common.Hash  `json:"bodyHashes,omitempty"`
	Signer       common.Address `json:"signer,omitempty"`
	OriginID     string         `json:"originId,omitempty"`
	ReceivedAt   hexutil.Uint64 `json:"receivedAt,omitempty"`
	MatchingHash common.Hash    `json:"matchingHash,omitempty"`
	Prematched   bool           `json:"prematched"`
}

type RequestPrivacy

type RequestPrivacy struct {
	Hints     HintIntent `json:"hints,omitempty"`
	Operators []string   `json:"operators,omitempty"`
}

type SendRequestArgs

type SendRequestArgs struct {
	Version   string           `json:"version"`
	Inclusion RequestInclusion `json:"inclusion"`
	Body      []RequestBody    `json:"body"`
	Privacy   *RequestPrivacy  `json:"privacy,omitempty"`
	Metadata  *RequestMetadata `json:"metadata,omitempty"`
}

type SendRequestResponse

type SendRequestResponse struct {
	RequestHash common.Hash    `json:"requestHash"`
	Signature   *hexutil.Bytes `json:"preconfSignature"`
	Block       hexutil.Uint64 `json:"preconfBlock"`
}

type SimQueue

type SimQueue struct {
	// contains filtered or unexported fields
}

func NewQueue

func NewQueue(
	log *zap.Logger, queue simqueue.Queue, eth EthClient, sim []SimulationBackend, simRes SimulationResult,
	workersPerNode int, backgroundWg *sync.WaitGroup, cancelCache *RedisCancellationCache,
) *SimQueue

func (*SimQueue) ScheduleRequest

func (q *SimQueue) ScheduleRequest(ctx context.Context, request *SendRequestArgs, highPriority bool) error

func (*SimQueue) Start

func (q *SimQueue) Start(ctx context.Context) *sync.WaitGroup

type SimScheduler

type SimScheduler interface {
	ScheduleRequest(ctx context.Context, bundle *SendRequestArgs, highPriority bool) error
}

type SimulationBackend

type SimulationBackend interface{}

SimulationBackend is an interface for simulating transactions There should be one simulation backend per worker node

type SimulationResult

type SimulationResult interface {
	SimulatedBundle(ctx context.Context, args *SendRequestArgs, info simqueue.QueueItemInfo) error
}

SimulationResult is responsible for processing simulation results NOTE: That error should be returned only if simulation should be retried, for example if redis is down

type SimulationResultBackend

type SimulationResultBackend struct {
	// contains filtered or unexported fields
}

func NewSimulationResultBackend

func NewSimulationResultBackend(log *zap.Logger, hint HintBackend, eth EthClient, store Storage) *SimulationResultBackend

func (*SimulationResultBackend) ProcessHints

func (s *SimulationResultBackend) ProcessHints(ctx context.Context, bundle *SendRequestArgs) error

func (*SimulationResultBackend) SimulatedBundle

func (s *SimulationResultBackend) SimulatedBundle(ctx context.Context,
	bundle *SendRequestArgs, _ simqueue.QueueItemInfo,
) error

SimulatedBundle is called when simulation is done NOTE: we return error only if we want to retry the simulation

type SimulationWorker

type SimulationWorker struct {
	// contains filtered or unexported fields
}

func (*SimulationWorker) Process

func (w *SimulationWorker) Process(ctx context.Context, data []byte, info simqueue.QueueItemInfo) (err error)

type Storage

type Storage interface {
	InsertBundleForStats(ctx context.Context, bundle *SendRequestArgs) (known bool, err error)
	InsertHistoricalHint(ctx context.Context, currentBlock uint64, hint *Hint) error
	GetPreconfByMatchingHash(ctx context.Context, hash common.Hash) (*int64, *hexutil.Bytes, *int64, error)
}

type TxHint

type TxHint struct {
	Hash             *common.Hash    `json:"hash,omitempty"`
	To               *common.Address `json:"to,omitempty"`
	FunctionSelector *hexutil.Bytes  `json:"functionSelector,omitempty"`
	CallData         *hexutil.Bytes  `json:"callData,omitempty"`
}

Jump to

Keyboard shortcuts

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