ffcapi

package
v1.3.13 Latest Latest
Warning

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

Go to latest
Published: Jun 5, 2024 License: Apache-2.0 Imports: 3 Imported by: 0

Documentation

Index

Constants

View Source
const (
	FromBlockEarliest = "earliest"
	FromBlockLatest   = "latest"
)

Variables

This section is empty.

Functions

func MapSubmissionRejected added in v1.3.5

func MapSubmissionRejected(reason ErrorReason) bool

Types

type API

type API interface {
	// AddressBalance gets the balance of the specified address
	AddressBalance(ctx context.Context, req *AddressBalanceRequest) (*AddressBalanceResponse, ErrorReason, error)

	// BlockInfoByHash gets block information using the hash of the block
	BlockInfoByHash(ctx context.Context, req *BlockInfoByHashRequest) (*BlockInfoByHashResponse, ErrorReason, error)

	// BlockInfoByNumber gets block information from the specified position (block number/index) in the canonical chain currently known to the local node
	BlockInfoByNumber(ctx context.Context, req *BlockInfoByNumberRequest) (*BlockInfoByNumberResponse, ErrorReason, error)

	// NextNonceForSigner is used when there are no outstanding transactions for a given signing identity, to determine the next nonce to use for submission of a transaction
	NextNonceForSigner(ctx context.Context, req *NextNonceForSignerRequest) (*NextNonceForSignerResponse, ErrorReason, error)

	// GasEstimate provides an estimate of the gas required for the given transaction
	GasEstimate(ctx context.Context, req *TransactionInput) (*GasEstimateResponse, ErrorReason, error)

	// GasPriceEstimate provides a blockchain specific gas price estimate
	GasPriceEstimate(ctx context.Context, req *GasPriceEstimateRequest) (*GasPriceEstimateResponse, ErrorReason, error)

	// QueryInvoke executes a method on a blockchain smart contract, which might execute Smart Contract code, but does not affect the blockchain state.
	QueryInvoke(ctx context.Context, req *QueryInvokeRequest) (*QueryInvokeResponse, ErrorReason, error)

	// TransactionReceipt queries to see if a receipt is available for a given transaction hash
	TransactionReceipt(ctx context.Context, req *TransactionReceiptRequest) (*TransactionReceiptResponse, ErrorReason, error)

	// TransactionPrepare validates transaction inputs against the supplied schema/ABI and performs any binary serialization required (prior to signing) to encode a transaction from JSON into the native blockchain format
	TransactionPrepare(ctx context.Context, req *TransactionPrepareRequest) (*TransactionPrepareResponse, ErrorReason, error)

	// TransactionSend combines a previously prepared encoded transaction, with a current gas price, and submits it to the transaction pool of the blockchain for mining
	TransactionSend(ctx context.Context, req *TransactionSendRequest) (*TransactionSendResponse, ErrorReason, error)

	// DeployContractPrepare
	DeployContractPrepare(ctx context.Context, req *ContractDeployPrepareRequest) (*TransactionPrepareResponse, ErrorReason, error)

	// EventStreamStart starts an event stream with an initial set of listeners (which might be empty), a channel to deliver events, and a context that will close to stop the stream
	EventStreamStart(ctx context.Context, req *EventStreamStartRequest) (*EventStreamStartResponse, ErrorReason, error)

	// EventStreamStopped informs a connector that an event stream has been requested to stop, and the context has been cancelled. So the state associated with it can be removed (and a future start of the same ID can be performed)
	EventStreamStopped(ctx context.Context, req *EventStreamStoppedRequest) (*EventStreamStoppedResponse, ErrorReason, error)

	// EventListenerVerifyOptions validates the configuration options for a listener, applying any defaults needed by the connector, and returning the update options for FFTM to persist
	EventListenerVerifyOptions(ctx context.Context, req *EventListenerVerifyOptionsRequest) (*EventListenerVerifyOptionsResponse, ErrorReason, error)

	// EventListenerAdd begins/resumes listening on set of events that must be consistently ordered. Blockchain specific signatures of the events are included, along with initial conditions (initial block number etc.), and the last stored checkpoint (if any)
	EventListenerAdd(ctx context.Context, req *EventListenerAddRequest) (*EventListenerAddResponse, ErrorReason, error)

	// EventListenerRemove ends listening on a set of events previous started
	EventListenerRemove(ctx context.Context, req *EventListenerRemoveRequest) (*EventListenerRemoveResponse, ErrorReason, error)

	// EventListenerHWM queries the current high water mark checkpoint for a listener. Called at regular intervals when there are no events in flight for a listener, to ensure checkpoint are written regularly even when there is no activity
	EventListenerHWM(ctx context.Context, req *EventListenerHWMRequest) (*EventListenerHWMResponse, ErrorReason, error)

	// EventStreamNewCheckpointStruct used during checkpoint restore, to get the specific into which to restore the JSON bytes
	EventStreamNewCheckpointStruct() EventListenerCheckpoint

	// NewBlockListener creates a new block listener, decoupled from an event stream
	NewBlockListener(ctx context.Context, req *NewBlockListenerRequest) (*NewBlockListenerResponse, ErrorReason, error)

	// IsLive confirms if the connector up and running
	IsLive(ctx context.Context) (*LiveResponse, ErrorReason, error)

	// IsReady confirms if the connector is connected to the downstream JSONRPC endpoint and therefore ready to receive traffic
	IsReady(ctx context.Context) (*ReadyResponse, ErrorReason, error)
}

API is the interface to the blockchain specific connector, from the FFTM server and policy engine.

The functions follow a consistent pattern of request/response objects, to allow extensibility of the inputs/outputs with minimal code change to existing connector implementations.

type AddressBalanceRequest added in v1.1.6

type AddressBalanceRequest struct {
	Address  string `json:"address"`
	BlockTag string `json:"blockTag"`
}

type AddressBalanceResponse added in v1.1.6

type AddressBalanceResponse struct {
	Balance *fftypes.FFBigInt `json:"balance"`
}

type BlockHashEvent added in v0.9.3

type BlockHashEvent struct {
	BlockHashes  []string        `json:"blockHash"`              // zero or more hashes (can be nil)
	GapPotential bool            `json:"gapPotential,omitempty"` // when true, the caller cannot be sure if blocks have been missed (use on reconnect of a websocket for example)
	Created      *fftypes.FFTime `json:"created,omitempty"`      // timestamp when the blockhash event is created
}

type BlockInfo

type BlockInfo struct {
	BlockNumber       *fftypes.FFBigInt `json:"blockNumber"`
	BlockHash         string            `json:"blockHash"`
	ParentHash        string            `json:"parentHash"`
	TransactionHashes []string          `json:"transactionHashes"`
}

type BlockInfoByHashRequest added in v0.9.3

type BlockInfoByHashRequest struct {
	BlockHash string `json:"blockHash"`
}

type BlockInfoByHashResponse added in v0.9.3

type BlockInfoByHashResponse struct {
	BlockInfo
}

type BlockInfoByNumberRequest added in v0.9.3

type BlockInfoByNumberRequest struct {
	BlockNumber        *fftypes.FFBigInt `json:"blockNumber"`
	ExpectedParentHash string            `json:"expectedParentHash"` // If set then a mismatched parent hash should be considered a cache miss (if the connector does caching)
}

type BlockInfoByNumberResponse added in v0.9.3

type BlockInfoByNumberResponse struct {
	BlockInfo
}

type ContractDeployPrepareRequest added in v0.9.3

type ContractDeployPrepareRequest struct {
	TransactionHeaders
	Definition *fftypes.JSONAny   `json:"definition"` // such as an ABI for EVM
	Contract   *fftypes.JSONAny   `json:"contract"`   // such as the Bytecode for EVM
	Params     []*fftypes.JSONAny `json:"params"`     // such as the inputs to the constructor for EVM
	Errors     []*fftypes.JSONAny `json:"errors"`     // such as the errors spec for EVM
}

type ErrorReason

type ErrorReason string

ErrorReason are a set of standard error conditions that a blockchain connector can return from execution, that affect the action of the transaction manager to the response. It is important that error mapping is performed for each of these classification

const (
	// ErrorReasonInvalidInputs transaction inputs could not be parsed by the connector according to the interface (nothing was sent to the blockchain)
	ErrorReasonInvalidInputs ErrorReason = "invalid_inputs"
	// ErrorReasonTransactionReverted on-chain execution (only expected to be returned when the connector is doing gas estimation, or executing a query)
	ErrorReasonTransactionReverted ErrorReason = "transaction_reverted"
	// ErrorReasonNonceTooLow on transaction submission, if the nonce has already been used for a transaction that has made it into a block on the canonical chain known to the local node
	ErrorReasonNonceTooLow ErrorReason = "nonce_too_low"
	// ErrorReasonTransactionUnderpriced if the transaction is rejected due to too low gas price. Either because it was too low according to the minimum configured on the node, or because it's a rescue transaction without a price bump.
	ErrorReasonTransactionUnderpriced ErrorReason = "transaction_underpriced"
	// ErrorReasonInsufficientFunds if the transaction is rejected due to not having enough of the underlying network coin (ether etc.) in your wallet
	ErrorReasonInsufficientFunds ErrorReason = "insufficient_funds"
	// ErrorReasonNotFound if the requested object (block/receipt etc.) was not found
	ErrorReasonNotFound ErrorReason = "not_found"
	// ErrorKnownTransaction if the exact transaction is already known
	ErrorKnownTransaction ErrorReason = "known_transaction"
	// ErrorReasonDownstreamDown if the downstream JSONRPC endpoint is down
	ErrorReasonDownstreamDown = "downstream_down"
)

*** MUST UPDATE MapSubmissionRejected IF ADDING NEW REASONS THAT ARE POSSIBLE DURING TRANSACTION PREPARE PHASE OF SUBMISSION ***

type Event added in v0.9.3

type Event struct {
	ID   EventID          // standard fields provided by the connector
	Info interface{}      // extra custom fields from the connector - can be any JSON serializable struct
	Data *fftypes.JSONAny // data
}

Event is a blockchain event that matches one of the started listeners, and is the structure passed from the connector to FFTM The implementation is responsible for ensuring all events on a listener are ordered on to this channel in the exact sequence from the blockchain.

func (*Event) String added in v0.9.3

func (e *Event) String() string

type EventID added in v0.9.3

type EventID struct {
	ListenerID       *fftypes.UUID    `json:"listenerId"`          // The listener for the event
	Signature        string           `json:"signature"`           // The signature of this specific event (noting a listener might filter on multiple events)
	BlockHash        string           `json:"blockHash"`           // String representation of the block, which will change if any transaction info in the block changes
	BlockNumber      fftypes.FFuint64 `json:"blockNumber"`         // A numeric identifier for the block
	TransactionHash  string           `json:"transactionHash"`     // The transaction
	TransactionIndex fftypes.FFuint64 `json:"transactionIndex"`    // Index within the block of the transaction that emitted the event
	LogIndex         fftypes.FFuint64 `json:"logIndex"`            // Index within the transaction of this emitted event log
	Timestamp        *fftypes.FFTime  `json:"timestamp,omitempty"` // The on-chain timestamp
}

EventID are the set of required fields an FFCAPI compatible connector needs to map to the underlying blockchain constructs, to uniquely identify an event

func (*EventID) ProtocolID added in v0.9.3

func (eid *EventID) ProtocolID() string

ProtocolID represents the unique (once finality is reached) sortable position within the blockchain

func (*EventID) String added in v0.9.3

func (eid *EventID) String() string

String is unique in all cases for an event, by combining the protocol ID with the listener ID and block hash

type EventListenerAddRequest added in v0.9.3

type EventListenerAddRequest struct {
	EventListenerOptions
	ListenerID *fftypes.UUID           // Unique UUID for the event listener, that should be included in each event
	StreamID   *fftypes.UUID           // The event stream (previously started) to which events should be delivered
	Name       string                  // Descriptive name of the listener, provided by the user, or defaulted to the signature. Not guaranteed to be unique. Should be included in the event info
	Checkpoint EventListenerCheckpoint // The last persisted checkpoint for this event stream
}

type EventListenerAddResponse added in v0.9.3

type EventListenerAddResponse struct {
}

type EventListenerCheckpoint added in v0.9.3

type EventListenerCheckpoint interface {
	LessThan(b EventListenerCheckpoint) bool
}

EventListenerCheckpoint is the interface that a checkpoint must implement, basically to make it sortable. The checkpoint must also be JSON serializable

type EventListenerHWMRequest added in v0.9.3

type EventListenerHWMRequest struct {
	StreamID   *fftypes.UUID `json:"streamId"`
	ListenerID *fftypes.UUID `json:"listenerId"`
}

type EventListenerHWMResponse added in v0.9.3

type EventListenerHWMResponse struct {
	Checkpoint EventListenerCheckpoint `json:"checkpoint"`
	Catchup    bool                    `json:"catchup,omitempty"` // informational only - informs an operator that the stream is catching up
}

type EventListenerOptions added in v0.9.3

type EventListenerOptions struct {
	FromBlock string            // The instruction for the first block to index from (when there is no previous checkpoint). Special "earliest" and "latest" strings should be supported as well as blockchain specific block ID (like a decimal number etc.)
	Filters   []fftypes.JSONAny // The blockchain specific list of filters. The top-level array is an OR list. The semantics within each entry is defined by the blockchain
	Options   *fftypes.JSONAny  // Blockchain specific set of options, such as the first block to detect events from (can be null)
}

type EventListenerRemoveRequest added in v0.9.3

type EventListenerRemoveRequest struct {
	StreamID   *fftypes.UUID `json:"streamId"`
	ListenerID *fftypes.UUID `json:"listenerId"`
}

type EventListenerRemoveResponse added in v0.9.3

type EventListenerRemoveResponse struct {
}

type EventListenerVerifyOptionsRequest added in v0.9.3

type EventListenerVerifyOptionsRequest struct {
	EventListenerOptions
}

type EventListenerVerifyOptionsResponse added in v0.9.3

type EventListenerVerifyOptionsResponse struct {
	ResolvedSignature string
	ResolvedOptions   fftypes.JSONAny
}

type EventStreamStartRequest added in v0.9.3

type EventStreamStartRequest struct {
	ID               *fftypes.UUID              // UUID of the stream, which we be referenced in any future add/remove listener requests
	StreamContext    context.Context            // Context that will be cancelled when the event stream needs to stop - no further events will be consumed after this, so all pushes to the stream should select on the done channel too
	EventStream      chan<- *ListenerEvent      // The event stream to push events to as they are detected, and checkpoints regularly even if there are no events - remember to select on Done as well when pushing events
	BlockListener    chan<- *BlockHashEvent     // The connector should push new blocks to every stream, marking if it's possible blocks were missed (due to reconnect). The stream guarantees to always consume from this channel, until the stream context closes.
	InitialListeners []*EventListenerAddRequest // Initial list of event listeners to start with the stream - allows these to be started concurrently
}

type EventStreamStartResponse added in v0.9.3

type EventStreamStartResponse struct {
}

type EventStreamStoppedRequest added in v0.9.3

type EventStreamStoppedRequest struct {
	ID *fftypes.UUID // UUID of the stream, which we be referenced in any future add/remove listener requests
}

type EventStreamStoppedResponse added in v0.9.3

type EventStreamStoppedResponse struct {
}

type Events added in v0.9.3

type Events []*Event

Events array has a natural sort order of the block/txIndex/logIndex

func (Events) Len added in v0.9.3

func (es Events) Len() int

func (Events) Less added in v0.9.3

func (es Events) Less(i, j int) bool

func (Events) Swap added in v0.9.3

func (es Events) Swap(i, j int)

type GasEstimateRequest added in v1.2.13

type GasEstimateRequest struct {
	TransactionInput
}

type GasEstimateResponse added in v1.2.13

type GasEstimateResponse struct {
	GasEstimate *fftypes.FFBigInt `json:"gasEstimate"`
}

type GasPriceEstimateRequest added in v0.9.3

type GasPriceEstimateRequest struct {
}

type GasPriceEstimateResponse added in v0.9.3

type GasPriceEstimateResponse struct {
	GasPrice *fftypes.JSONAny `json:"gasPrice"`
}

type ListenerEvent added in v0.9.3

type ListenerEvent struct {
	Checkpoint EventListenerCheckpoint `json:"checkpoint"`        // the checkpoint information associated with the event, must be non-nil if the event is not removed
	Event      *Event                  `json:"event"`             // the event - for removed events, can only have the EventID fields set (to generate the protocol ID)
	Removed    bool                    `json:"removed,omitempty"` // when true, this is an explicit cancellation of a previous event
}

ListenerEvent is an event+checkpoint for a particular listener, and is the object delivered over the event stream channel when a new event is detected for delivery to the confirmation manager.

type ListenerEvents added in v0.9.3

type ListenerEvents []*ListenerEvent

ListenerEvents array has a natural sort order of the event

func (ListenerEvents) Len added in v0.9.3

func (lu ListenerEvents) Len() int

func (ListenerEvents) Less added in v0.9.3

func (lu ListenerEvents) Less(i, j int) bool

func (ListenerEvents) Swap added in v0.9.3

func (lu ListenerEvents) Swap(i, j int)

type LiveResponse added in v0.9.11

type LiveResponse struct {
	Up bool `json:"up"`
}

type NewBlockListenerRequest added in v0.9.3

type NewBlockListenerRequest struct {
	ID              *fftypes.UUID          // unique identifier for this listener
	ListenerContext context.Context        // Context that will be cancelled when the listener needs to stop - no further events will be consumed after this, so all pushes to the listener should select on the done channel too
	BlockListener   chan<- *BlockHashEvent // The connector should push new blocks to every listener, marking if it's possible blocks were missed (due to reconnect). The listener guarantees to always consume from this channel, until the listener context closes.
}

type NewBlockListenerResponse added in v0.9.3

type NewBlockListenerResponse struct {
}

type NextNonceForSignerRequest added in v0.9.3

type NextNonceForSignerRequest struct {
	Signer string `json:"signer"`
}

NextNonceForSignerRequest used to do a query for the next nonce to use for a given signing identity. This is only used when there are no pending operations outstanding for this signer known to the transaction manager.

type NextNonceForSignerResponse added in v0.9.3

type NextNonceForSignerResponse struct {
	Nonce *fftypes.FFBigInt `json:"nonce"`
}

type QueryInvokeRequest added in v0.9.3

type QueryInvokeRequest struct {
	TransactionInput
	BlockNumber *string `json:"blockNumber,omitempty"`
}

QueryInvokeRequest requests execution of a smart contract method in order to either: 1) Query state 2) Attempt to extract the revert reason from an on-chain failure to execute a transaction

See the list of standard error reasons that should be returned for situations that can be detected by the back-end connector.

type QueryInvokeResponse added in v0.9.3

type QueryInvokeResponse struct {
	Outputs *fftypes.JSONAny `json:"outputs"` // The data output from the method call - can be array or object structure
}

type ReadyResponse added in v0.9.11

type ReadyResponse struct {
	Ready             bool             `json:"ready"`
	DownstreamDetails *fftypes.JSONAny `json:"downstreamDetails"` // The data output from the method call - can be array or object structure
}

type SubmissionError added in v1.3.5

type SubmissionError struct {
	Error string `json:"error"`
	// When submissionRejected: true, the failure is considered final and the operation should transition directly to failed.
	// This should be returned in all cases where the FFCAPI connector or underlying blockchain node has evaluated the transaction
	// during the prepare phase, and determined it will fail if it were submitted.
	// The idempotencyKey is "spent" in these scenarios in the FF Core layer, but the transaction is never recorded into the FFTM
	// database, so the nonce is not spent, and the transaction is never submitted.
	SubmissionRejected bool `json:"submissionRejected,omitempty"`
}

type TransactionHeaders

type TransactionHeaders struct {
	From  string            `json:"from,omitempty"`
	To    string            `json:"to,omitempty"`
	Nonce *fftypes.FFBigInt `json:"nonce,omitempty"`
	Gas   *fftypes.FFBigInt `json:"gas,omitempty"`
	Value *fftypes.FFBigInt `json:"value,omitempty"`
}

type TransactionInput

type TransactionInput struct {
	TransactionHeaders
	Method *fftypes.JSONAny   `json:"method"`
	Params []*fftypes.JSONAny `json:"params"`
	Errors []*fftypes.JSONAny `json:"errors"`
}

TransactionInput is a standardized set of parameters that describe a transaction submission to a blockchain. For convenience, ths structure is compatible with the EthConnect `TransactionSend` structure, for the subset of usage made by FireFly core / Tokens connectors. - Numeric values such as nonce/gas/gasPrice, are all passed as string encoded Base 10 integers - From/To are passed as strings, and are pass-through for FFTM from the values it receives from FireFly core after signing key resolution - The interface is a structure describing the method to invoke. The `variant` in the header tells you how to decode it. For variant=evm it will be an ABI method definition - The supplied value is passed through for each input parameter. It could be any JSON type (simple number/boolean/string, or complex object/array). The blockchain connection is responsible for serializing these according to the rules in the interface.

type TransactionPrepareRequest added in v0.9.3

type TransactionPrepareRequest struct {
	TransactionInput
}

TransactionPrepareRequest is used to prepare a set of JSON formatted developer friendly inputs, into a raw transaction ready for submission to the blockchain.

The connector is responsible for encoding the transaction ready for submission, and returning the hash for the transaction as well as a string serialization of the pre-signed raw transaction in a format of its own choosing (hex etc.). The hash is expected to be a function of: - the method signature - the signing identity - the nonce - the particular blockchain the transaction is submitted to - the input parameters

If "gas" is not supplied, the connector is expected to perform gas estimation prior to generating the payload.

See the list of standard error reasons that should be returned for situations that can be detected by the back-end connector.

type TransactionPrepareResponse added in v0.9.3

type TransactionPrepareResponse struct {
	Gas             *fftypes.FFBigInt `json:"gas"`
	TransactionData string            `json:"transactionData"`
}

type TransactionReceiptRequest added in v0.9.3

type TransactionReceiptRequest struct {
	TransactionHash string `json:"transactionHash"`
}

type TransactionReceiptResponse added in v0.9.3

type TransactionReceiptResponse struct {
	BlockNumber      *fftypes.FFBigInt `json:"blockNumber"`
	TransactionIndex *fftypes.FFBigInt `json:"transactionIndex"`
	BlockHash        string            `json:"blockHash"`
	Success          bool              `json:"success"`
	ProtocolID       string            `json:"protocolId"`
	ExtraInfo        *fftypes.JSONAny  `json:"extraInfo"`
	ContractLocation *fftypes.JSONAny  `json:"contractLocation"`
}

type TransactionSendRequest added in v0.9.3

type TransactionSendRequest struct {
	GasPrice *fftypes.JSONAny `json:"gasPrice,omitempty"` // can be a simple string/number, or a complex object - contract is between policy engine and blockchain connector
	TransactionHeaders
	TransactionData string `json:"transactionData"`
	PreSigned       bool   `json:"preSigned,omitempty"`
}

TransactionSendRequest is used to send a transaction to the blockchain. The connector is responsible for adding it to the transaction pool of the blockchain, noting the transaction hash has already been calculated in the prepare step previously.

type TransactionSendResponse added in v0.9.3

type TransactionSendResponse struct {
	TransactionHash string `json:"transactionHash"`
}

Jump to

Keyboard shortcuts

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