adapters

package
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Mar 12, 2021 License: ISC Imports: 31 Imported by: 0

Documentation

Overview

Package adapters contain the core adapters used by the Seerlink node.

Bridge

The Bridge adapter is used to send and receive data to and from external adapters. The adapter will POST to the target adapter URL with an "id" field for the TaskRunID and a "data" field. For example:

{"id": "b8004e2989e24e1d8e4449afad2eb480", "data": {}}

Compare

The Compare adapter is used to compare the previous task's result against a specified value. Just like an `if` statement, the compare adapter will save `true` or `false` in the task run's result.

{ "type": "Compare", "params": {"operator": "eq", "value": "Hello" }}

HTTPGet

The HTTPGet adapter is used to grab the JSON data from the given URL.

{ "type": "HTTPGet", "params": {"get": "https://some-api-example.net/api" }}

NOTE: For security, since the URL is untrusted, HTTPGet imposes some restrictions on which IPs may be fetched. Local network and multicast IPs are disallowed by default and attempting to connect will result in an error.

HTTPPost

Sends a POST request to the specified URL and will return the response.

{ "type": "HTTPPost", "params": {"post": "https://weiwatchers.com/api" }}

NOTE: For security, since the URL is untrusted, HTTPPost imposes some restrictions on which IPs may be fetched. Local network and multicast IPs are disallowed by default and attempting to connect will result in an error.

HTTPGetWithUnrestrictedNetworkAccess

Identical to HTTPGet except there are no IP restrictions. Use with caution.

HTTPPostWithUnrestrictedNetworkAccess

Identical to HTTPPost except there are no IP restrictions. Use with caution.

JSONParse

The JSONParse adapter will obtain the value(s) for the given field(s).

{ "type": "JSONParse", "params": {"path": ["someField"] }}

EthBool

The EthBool adapter will take the given values and format them for the Ethereum blockchain in boolean value.

{ "type": "EthBool" }

EthBytes32

The EthBytes32 adapter will take the given values and format them for the Ethereum blockchain.

{ "type": "EthBytes32" }

EthInt256

The EthInt256 adapter will take a given signed 256 bit integer and format it to hex for the Ethereum blockchain.

{ "type": "EthInt256" }

EthUint256

The EthUint256 adapter will take a given 256 bit integer and format it in hex for the Ethereum blockchain.

{ "type": "EthUint256" }

EthTx

The EthTx adapter will write the data to the given address and functionSelector.

{
  "type": "EthTx", "params": {
    "address": "0x0000000000000000000000000000000000000000",
    "functionSelector": "0xffffffff"
  }
}

Multiplier

The Multiplier adapter multiplies the given input value times another specified value.

{ "type": "Multiply", "params": {"times": 100 }}

Quotient

The Quotient adapter gives the result of x / y where x is a specified value (dividend) and y is the input value (result). This can be useful for inverting outputs, e.g. if you have a USD/ETH conversion rate and you want to flip it to ETH/USD you can use this adapter with a dividend of 1 to get 1 / result.

value.

{ "type": "Quotient", "params": {"dividend": 1 }}

Random

Random adapter generates proofs of randomness verifiable against a public key

WARNING: The Random apdater's output is NOT the randomness you are looking
WARNING: for! The node must send the output onchain for verification by the
WARNING: method VRFCoordinator.sol#fulfillRandomnessRequest, which will
WARNING: pass the actual random output back to the consuming contract.
WARNING: Don't use the output of this adapter in any other way, unless you
WARNING: thoroughly understand the cryptography in use here, and the exact
WARNING: security guarantees it provides. See notes in VRFCoordinator.sol
WARNING: for more info.

WARNING: This system guarantees that the oracle cannot independently
WARNING: concoct a random output to suit itself, but it does not protect
WARNING: against collusion between the oracle and the provider of the seed
WARNING: the oracle uses to generate the randomness. It also does not
WARNING: protect against the oracle simply refusing to respond to a
WARNING: randomness request, if it doesn't like the output it would be
WARNING: required to provide. Solutions to these limitations are planned.

Here is an example of a Random task specification. For an example of a full jobspec using this, see ../internal/testdata/randomness_job.json.

{
  "type": "Random",
  "params": {
  	"publicKey":
      "0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800"
  }
}

The publicKey must be the concatenation of its hex representation of its the secp256k1 point's x-ordinate as a uint256, followed by 00 if the y-ordinate is even, or 01 if it's odd. (Note that this is NOT an RFC 5480 section 2.2 public-key representation. DO NOT prefix with 0x02, 0x03 or 0x04.)

The seerlink node must know the corresponding secret key. Such a key pair can be created with the `seerlink local vrf create` command, and exported to a keystore with `vrf export <keystore-path>`.

E.g. `seerlink local vrf create -p <password-file>` will log the public key under the field "public id".

To see the public keys which have already been imported, use the command `seerlink local vrf list`. See `seerlink local vrf help` for more key-manipulation commands.

The adapter output should be passed via EthTx to VRFCoordinator.sol's method fulfillRandomnessRequest.

A "random" task must be initiated by a "randomnesslog" initiator which explicitly specifies which ethereum address the logs will be emitted from, such as

{"initiators": [{"type": "randomnesslog","address": "0xvrfCoordinatorAddr"}]}

This prevents the node from responding to potentially hostile log requests from other contracts, which could be crafted to prematurely reveal the random output if someone learns a prospective input seed prior to its use in the VRF.

Index

Constants

View Source
const (
	// DataFormatBytes instructs the EthTx Adapter to treat the input value as a
	// bytes string, rather than a hexadecimal encoded bytes32
	DataFormatBytes = "bytes"
)

Variables

View Source
var (
	// TaskTypeCopy is the identifier for the Copy adapter.
	TaskTypeCopy = models.MustNewTaskType("copy")
	// TaskTypeEthBool is the identifier for the EthBool adapter.
	TaskTypeEthBool = models.MustNewTaskType("ethbool")
	// TaskTypeEthBytes32 is the identifier for the EthBytes32 adapter.
	TaskTypeEthBytes32 = models.MustNewTaskType("ethbytes32")
	// TaskTypeEthInt256 is the identifier for the EthInt256 adapter.
	TaskTypeEthInt256 = models.MustNewTaskType("ethint256")
	// TaskTypeEthUint256 is the identifier for the EthUint256 adapter.
	TaskTypeEthUint256 = models.MustNewTaskType("ethuint256")
	// TaskTypeEthTx is the identifier for the EthTx adapter.
	TaskTypeEthTx = models.MustNewTaskType("ethtx")
	// TaskTypeHTTPGetWithUnrestrictedNetworkAccess is the identifier for the HTTPGet adapter, with local/private IP access enabled.
	TaskTypeHTTPGetWithUnrestrictedNetworkAccess = models.MustNewTaskType("httpgetwithunrestrictednetworkaccess")
	// TaskTypeHTTPPostWithUnrestrictedNetworkAccess is the identifier for the HTTPPost adapter, with local/private IP access enabled.
	TaskTypeHTTPPostWithUnrestrictedNetworkAccess = models.MustNewTaskType("httppostwithunrestrictednetworkaccess")
	// TaskTypeHTTPGet is the identifier for the HTTPGet adapter.
	TaskTypeHTTPGet = models.MustNewTaskType("httpget")
	// TaskTypeHTTPPost is the identifier for the HTTPPost adapter.
	TaskTypeHTTPPost = models.MustNewTaskType("httppost")
	// TaskTypeJSONParse is the identifier for the JSONParse adapter.
	TaskTypeJSONParse = models.MustNewTaskType("jsonparse")
	// TaskTypeMultiply is the identifier for the Multiply adapter.
	TaskTypeMultiply = models.MustNewTaskType("multiply")
	// TaskTypeNoOp is the identifier for the NoOp adapter.
	TaskTypeNoOp = models.MustNewTaskType("noop")
	// TaskTypeNoOpPendOutgoing is the identifier for the NoOpPendOutgoing adapter.
	TaskTypeNoOpPendOutgoing = models.MustNewTaskType("nooppendoutgoing")
	// TaskTypeSleep is the identifier for the Sleep adapter.
	TaskTypeSleep = models.MustNewTaskType("sleep")
	// TaskTypeRandom is the identifier for the Random adapter.
	TaskTypeRandom = models.MustNewTaskType("random")
	// TaskTypeCompare is the identifier for the Compare adapter.
	TaskTypeCompare = models.MustNewTaskType("compare")
	// TaskTypeQuotient is the identifier for the Quotient adapter.
	TaskTypeQuotient = models.MustNewTaskType("quotient")
	// TaskTypeResultCollect is the identifier for the ResultCollect adapter.
	TaskTypeResultCollect = models.MustNewTaskType("resultcollect")
)
View Source
var (
	ErrResultNotNumber      = errors.New("the result was not a number")
	ErrValueNotNumber       = errors.New("the value was not a number")
	ErrOperatorNotSpecified = errors.New("operator not specified")
	ErrValueNotSpecified    = errors.New("value not specified")
)
View Source
var (
	ErrInvalidABIEncoding = errors.New("invalid abi encoding")
)

Functions

This section is empty.

Types

type BaseAdapter

type BaseAdapter interface {
	TaskType() models.TaskType
	Perform(models.RunInput, *store.Store) models.RunOutput
}

BaseAdapter is the minimum interface required to create an adapter. Only core adapters have this minimum requirement.

func FindNativeAdapterFor

func FindNativeAdapterFor(task models.TaskSpec) BaseAdapter

FindNativeAdapterFor find the native adapter for a given task

type Bridge

type Bridge struct {
	models.BridgeType
	Params models.JSON
}

Bridge adapter is responsible for connecting the task pipeline to external adapters, allowing for custom computations to be executed and included in runs.

func (*Bridge) Perform

func (ba *Bridge) Perform(input models.RunInput, store *store.Store) models.RunOutput

Perform sends a POST request containing the JSON of the input to the external adapter specified in the BridgeType.

It records the RunResult returned to it, and optionally marks the RunResult pending.

If the Perform is resumed with a pending RunResult, the RunResult is marked not pending and the RunResult is returned.

func (*Bridge) TaskType

func (ba *Bridge) TaskType() models.TaskType

TaskType returns the bridges defined type.

type Compare

type Compare struct {
	Operator string `json:"operator"`
	Value    string `json:"value"`
}

Compare adapter type takes an Operator and a Value field to compare to the previous task's Result.

func (*Compare) Perform

func (c *Compare) Perform(input models.RunInput, _ *store.Store) models.RunOutput

Perform uses the Operator to check the run's result against the specified Value.

func (*Compare) TaskType

func (c *Compare) TaskType() models.TaskType

TaskType returns the type of Adapter.

type Copy

type Copy struct {
	CopyPath JSONPath `json:"copyPath"`
}

Copy obj keys refers to which value to copy inside `data`, each obj value refers to where to copy the value to inside `data`

func (*Copy) Perform

func (c *Copy) Perform(input models.RunInput, store *store.Store) models.RunOutput

Perform returns the copied values from the desired mapping within the `data` JSON object

func (*Copy) TaskType

func (c *Copy) TaskType() models.TaskType

TaskType returns the type of Adapter.

type EthBool

type EthBool struct{}

EthBool holds no fields

func (*EthBool) Perform

func (*EthBool) Perform(input models.RunInput, _ *store.Store) models.RunOutput

Perform returns the abi encoding for a boolean

For example, after converting the result false to hex encoded Ethereum ABI, it would be: "0x0000000000000000000000000000000000000000000000000000000000000000"

func (*EthBool) TaskType

func (e *EthBool) TaskType() models.TaskType

TaskType returns the type of Adapter.

type EthBytes32

type EthBytes32 struct{}

EthBytes32 holds no fields.

func (*EthBytes32) Perform

func (*EthBytes32) Perform(input models.RunInput, _ *store.Store) models.RunOutput

Perform returns the hex value of the first 32 bytes of a string so that it is in the proper format to be written to the blockchain.

For example, after converting the string "16800.01" to hex encoded Ethereum ABI, it would be: "0x31363830302e3031000000000000000000000000000000000000000000000000"

func (*EthBytes32) TaskType

func (e *EthBytes32) TaskType() models.TaskType

TaskType returns the type of Adapter.

type EthInt256

type EthInt256 struct{}

EthInt256 holds no fields

func (*EthInt256) Perform

func (*EthInt256) Perform(input models.RunInput, _ *store.Store) models.RunOutput

Perform returns the hex value of a given string so that it is in the proper format to be written to the blockchain.

For example, after converting the string "-123.99" to hex encoded Ethereum ABI, it would be: "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85"

func (*EthInt256) TaskType

func (e *EthInt256) TaskType() models.TaskType

TaskType returns the type of Adapter.

type EthTx

type EthTx struct {
	ToAddress common.Address `json:"address"`
	// NOTE: FromAddress is deprecated and kept for backwards compatibility, new job specs should use fromAddresses
	FromAddress      common.Address          `json:"fromAddress,omitempty"`
	FromAddresses    []common.Address        `json:"fromAddresses,omitempty"`
	FunctionSelector models.FunctionSelector `json:"functionSelector"`
	// DataPrefix is typically a standard first argument
	// to seerlink callback calls - usually the requestID
	DataPrefix hexutil.Bytes `json:"dataPrefix"`
	DataFormat string        `json:"format"`
	GasLimit   uint64        `json:"gasLimit,omitempty"`

	// Optional list of desired encodings for ResultCollectKey arguments.
	// i.e. ["uint256", "bytes32"]
	ABIEncoding []string `json:"abiEncoding"`

	// MinRequiredOutgoingConfirmations only works with bulletprooftxmanager
	MinRequiredOutgoingConfirmations uint64 `json:"minRequiredOutgoingConfirmations,omitempty"`
}

EthTx holds the Address to send the result to and the FunctionSelector to execute.

func (*EthTx) Perform

func (e *EthTx) Perform(input models.RunInput, store *strpkg.Store) models.RunOutput

Perform creates the run result for the transaction if the existing run result is not currently pending. Then it confirms the transaction was confirmed on the blockchain.

func (*EthTx) TaskType

func (e *EthTx) TaskType() models.TaskType

TaskType returns the type of Adapter.

type EthUint256

type EthUint256 struct{}

EthUint256 holds no fields.

func (*EthUint256) Perform

func (*EthUint256) Perform(input models.RunInput, _ *store.Store) models.RunOutput

Perform returns the hex value of a given string so that it is in the proper format to be written to the blockchain.

For example, after converting the string "123.99" to hex encoded Ethereum ABI, it would be: "0x000000000000000000000000000000000000000000000000000000000000007b"

func (*EthUint256) TaskType

func (e *EthUint256) TaskType() models.TaskType

TaskType returns the type of Adapter.

type ExtendedPath

type ExtendedPath []string

ExtendedPath is the path to append to a base URL

func (*ExtendedPath) UnmarshalJSON

func (ep *ExtendedPath) UnmarshalJSON(input []byte) error

UnmarshalJSON implements the Unmarshaler interface

type HTTPGet

type HTTPGet struct {
	URL                            models.WebURL   `json:"url"`
	GET                            models.WebURL   `json:"get"`
	Headers                        http.Header     `json:"headers"`
	QueryParams                    QueryParameters `json:"queryParams"`
	ExtendedPath                   ExtendedPath    `json:"extPath"`
	AllowUnrestrictedNetworkAccess bool            `json:"-"`
}

HTTPGet requires a URL which is used for a GET request when the adapter is called.

func (*HTTPGet) GetRequest

func (hga *HTTPGet) GetRequest() (*http.Request, error)

GetRequest returns the HTTP request including query parameters and headers

func (*HTTPGet) GetURL

func (hga *HTTPGet) GetURL() string

GetURL retrieves the GET field if set otherwise returns the URL field

func (*HTTPGet) Perform

func (hga *HTTPGet) Perform(input models.RunInput, store *store.Store) models.RunOutput

Perform ensures that the adapter's URL responds to a GET request without errors and returns the response body as the "value" field of the result.

func (*HTTPGet) TaskType

func (hga *HTTPGet) TaskType() models.TaskType

TaskType returns the type of Adapter.

type HTTPPost

type HTTPPost struct {
	URL                            models.WebURL   `json:"url"`
	POST                           models.WebURL   `json:"post"`
	Headers                        http.Header     `json:"headers"`
	QueryParams                    QueryParameters `json:"queryParams"`
	Body                           *string         `json:"body,omitempty"`
	ExtendedPath                   ExtendedPath    `json:"extPath"`
	AllowUnrestrictedNetworkAccess bool            `json:"-"`
}

HTTPPost requires a URL which is used for a POST request when the adapter is called.

func (*HTTPPost) GetRequest

func (hpa *HTTPPost) GetRequest(body string) (*http.Request, error)

GetRequest takes the request body and returns the HTTP request including query parameters and headers.

HTTPPost's Body parameter overrides the given argument if present.

func (*HTTPPost) GetURL

func (hpa *HTTPPost) GetURL() string

GetURL retrieves the POST field if set otherwise returns the URL field

func (*HTTPPost) Perform

func (hpa *HTTPPost) Perform(input models.RunInput, store *store.Store) models.RunOutput

Perform ensures that the adapter's URL responds to a POST request without errors and returns the response body as the "value" field of the result.

func (*HTTPPost) TaskType

func (hpa *HTTPPost) TaskType() models.TaskType

TaskType returns the type of Adapter.

type JSONParse

type JSONParse struct {
	Path JSONPath `json:"path"`
}

JSONParse holds a path to the desired field in a JSON object, made up of an array of strings.

func (*JSONParse) Perform

func (jpa *JSONParse) Perform(input models.RunInput, _ *store.Store) models.RunOutput

Perform returns the value associated to the desired field for a given JSON object.

For example, if the JSON data looks like this:

{
  "data": [
    {"last": "1111"},
    {"last": "2222"}
  ]
}

Then ["0","last"] would be the path, and "1111" would be the returned value

func (*JSONParse) TaskType

func (jpa *JSONParse) TaskType() models.TaskType

TaskType returns the type of Adapter.

type JSONPath

type JSONPath []string

JSONPath is a path to a value in a JSON object

func (*JSONPath) UnmarshalJSON

func (jp *JSONPath) UnmarshalJSON(b []byte) error

UnmarshalJSON implements the Unmarshaler interface

type Multiply

type Multiply struct {
	Times *decimal.Decimal `json:"times,omitempty"`
}

Multiply holds the a number to multiply the given value by.

func (*Multiply) Perform

func (m *Multiply) Perform(input models.RunInput, _ *store.Store) models.RunOutput

Perform returns the input's "result" field, multiplied times the adapter's "times" field.

For example, if input value is "99.994" and the adapter's "times" is set to "100", the result's value will be "9999.4".

func (*Multiply) TaskType

func (m *Multiply) TaskType() models.TaskType

TaskType returns the type of Adapter.

type NoOp

type NoOp struct{}

NoOp adapter type holds no fields

func (*NoOp) Perform

func (noa *NoOp) Perform(input models.RunInput, _ *store.Store) models.RunOutput

Perform returns the input

func (*NoOp) TaskType

func (noa *NoOp) TaskType() models.TaskType

TaskType returns the type of Adapter.

type NoOpPendOutgoing

type NoOpPendOutgoing struct{}

NoOpPendOutgoing adapter type holds no fields

func (*NoOpPendOutgoing) Perform

Perform on this adapter type returns an empty RunResult with an added field for the status to indicate the task is Pending.

func (*NoOpPendOutgoing) TaskType

func (noa *NoOpPendOutgoing) TaskType() models.TaskType

TaskType returns the type of Adapter.

type PipelineAdapter

type PipelineAdapter struct {
	BaseAdapter
	// contains filtered or unexported fields
}

PipelineAdapter wraps a BaseAdapter with requirements for execution in the pipeline.

func For

func For(task models.TaskSpec, config orm.ConfigReader, orm *orm.ORM) (*PipelineAdapter, error)

For determines the adapter type to use for a given task.

func (PipelineAdapter) MinConfs

func (p PipelineAdapter) MinConfs() uint32

MinConfs returns the private attribute

func (PipelineAdapter) MinPayment

func (p PipelineAdapter) MinPayment() *assets.Link

MinPayment returns the payment for this adapter (defaults to none)

type QueryParameters

type QueryParameters url.Values

QueryParameters are the keys and values to append to the URL

func (*QueryParameters) UnmarshalJSON

func (qp *QueryParameters) UnmarshalJSON(input []byte) error

UnmarshalJSON implements the Unmarshaler interface

type Quotient

type Quotient struct {
	Dividend *big.Float `json:"-"`
}

Quotient holds the Dividend.

func (Quotient) MarshalJSON

func (q Quotient) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshal interface.

func (*Quotient) Perform

func (q *Quotient) Perform(input models.RunInput, _ *store.Store) models.RunOutput

Perform returns result of dividend / divisor were divisor is the input's "result" field.

For example, if input value is "2.5", and the adapter's "dividend" value is "1", the result's value will be "0.4".

func (*Quotient) TaskType

func (q *Quotient) TaskType() models.TaskType

TaskType returns the type of Adapter.

func (*Quotient) UnmarshalJSON

func (q *Quotient) UnmarshalJSON(buf []byte) error

UnmarshalJSON implements the json.Unqrshal interface.

type Random

type Random struct {
	// Compressed hex representation public key used in Random's VRF proofs
	//
	// This is just a hex string because Random is instantiated by json.Unmarshal.
	// (See adapters.For function.)
	PublicKey string `json:"publicKey"`
}

Random adapter type implements VRF calculation in its Perform method.

The VRFCoordinator.sol contract and its integration with the seerlink node will handle interaction with the Random adapter, but if you need to interact with it directly, its input to should be a JSON object with "preSeed", "blockHash", "blockNum", and "keyHash" fields containing, respectively,

  • The input seed as a hex-represented uint256 (this is the preSeed generated by VRFCoordinator#requestRandomness)
  • The hex-represented hash of the block in which request appeared
  • The number of the block in which the request appeared, as a JSON number
  • The keccak256 hash of the UNCOMPRESSED REPRESENTATION(*) of the public key

E.g., given the input

{
  "preSeed":
    "0x0000000000000000000000000000000000000000000000000000000000000001",
  "blockHash":
    "0x31dcb7c2e3f80ce552bf730d5c1a7ed7f9b42c17aff254729b5be081394617e6",
  "blockNum": 10000000,
  "keyHash":
    "0xc0a6c424ac7157ae408398df7e5f4552091a69125d5dfcb7b8c2659029395bdf",
}

The adapter will return a proof for the VRF output given these values, as long as the keccak256 hash of its public key matches the hash in the input. Otherwise, it will error.

The seed which is actually passed to the VRF cryptographic module is controlled by vrf.FinalSeed, and is computed from the above inputs.

The adapter returns the hex representation of a solidity bytes array suitable for passing to VRFCoordinator#fulfillRandomnessRequest, a vrf.MarshaledOnChainResponse.

(*) I.e., the 64-byte concatenation of the point's x- and y- ordinates as uint256's

func (*Random) Perform

func (ra *Random) Perform(input models.RunInput, store *store.Store) models.RunOutput

Perform returns the the proof for the VRF output given seed, or an error.

func (*Random) TaskType

func (ra *Random) TaskType() models.TaskType

TaskType returns the type of Adapter.

type ResultCollect

type ResultCollect struct{}

func (ResultCollect) Perform

func (r ResultCollect) Perform(input models.RunInput, store *store.Store) models.RunOutput

func (ResultCollect) TaskType

func (r ResultCollect) TaskType() models.TaskType

type Sleep

type Sleep struct {
	Until models.AnyTime `json:"until"`
}

Sleep adapter allows a job to do nothing for some amount of wall time.

func (*Sleep) Duration

func (adapter *Sleep) Duration() time.Duration

Duration returns the amount of sleeping this task should be paused for.

func (*Sleep) Perform

func (adapter *Sleep) Perform(input models.RunInput, str *store.Store) models.RunOutput

Perform returns the input RunResult after waiting for the specified Until parameter.

func (*Sleep) TaskType

func (adapter *Sleep) TaskType() models.TaskType

TaskType returns the type of Adapter.

Jump to

Keyboard shortcuts

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