rosetta

package module
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Feb 20, 2023 License: Apache-2.0 Imports: 45 Imported by: 15

README


sidebar_position: 1

Rosetta

The rosetta package implements Coinbase's Rosetta API. This document provides instructions on how to use the Rosetta API integration. For information about the motivation and design choices, refer to ADR 035.

Add Rosetta Command

The Rosetta API server is a stand-alone server that connects to a node of a chain developed with Cosmos SDK.

To enable Rosetta API support, it's required to add the RosettaCommand to your application's root command file (e.g. simd/cmd/root.go).

Import the server package:

import "github.com/cosmos/cosmos-sdk/server"

Find the following line:

initRootCmd(rootCmd, encodingConfig)

After that line, add the following:

rootCmd.AddCommand(
  server.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Codec)
)

The RosettaCommand function builds the rosetta root command and is defined in the server package within Cosmos SDK.

Since we’ve updated the Cosmos SDK to work with the Rosetta API, updating the application's root command file is all you need to do.

An implementation example can be found in simapp package.

Use Rosetta Command

To run Rosetta in your application CLI, use the following command:

simd rosetta --help

To test and run Rosetta API endpoints for applications that are running and exposed, use the following command:

simd rosetta
     --blockchain "your application name (ex: gaia)"
     --network "your chain identifier (ex: testnet-1)"
     --tendermint "tendermint endpoint (ex: localhost:26657)"
     --grpc "gRPC endpoint (ex: localhost:9090)"
     --addr "rosetta binding address (ex: :8080)"

Extensions

There are two ways in which you can customize and extend the implementation with your custom settings.

Message extension

In order to make an sdk.Msg understandable by rosetta the only thing which is required is adding the methods to your messages that satisfy the rosetta.Msg interface. Examples on how to do so can be found in the staking types such as MsgDelegate, or in bank types such as MsgSend.

Client interface override

In case more customization is required, it's possible to embed the Client type and override the methods which require customizations.

Example:

package custom_client
import (

"context"
"github.com/coinbase/rosetta-sdk-go/types"
"cosmossdk.io/tools/rosetta/lib"
)

// CustomClient embeds the standard cosmos client
// which means that it implements the cosmos-rosetta-gateway Client
// interface while at the same time allowing to customize certain methods
type CustomClient struct {
    *rosetta.Client
}

func (c *CustomClient) ConstructionPayload(_ context.Context, request *types.ConstructionPayloadsRequest) (resp *types.ConstructionPayloadsResponse, err error) {
    // provide custom signature bytes
    panic("implement me")
}

NOTE: when using a customized client, the command cannot be used as the constructors required may differ, so it's required to create a new one. We intend to provide a way to init a customized client without writing extra code in the future.

Error extension

Since rosetta requires to provide 'returned' errors to network options. In order to declare a new rosetta error, we use the errors package in cosmos-rosetta-gateway.

Example:

package custom_errors
import crgerrs "cosmossdk.io/tools/rosetta/lib/errors"

var customErrRetriable = true
var CustomError = crgerrs.RegisterError(100, "custom message", customErrRetriable, "description")

Note: errors must be registered before cosmos-rosetta-gateway's Server.Start method is called. Otherwise the registration will be ignored. Errors with same code will be ignored too.

Documentation

Index

Constants

View Source
const (
	// DefaultBlockchain defines the default blockchain identifier name
	DefaultBlockchain = "app"
	// DefaultAddr defines the default rosetta binding address
	DefaultAddr = ":8080"
	// DefaultRetries is the default number of retries
	DefaultRetries = 5
	// DefaultTendermintEndpoint is the default value for the tendermint endpoint
	DefaultTendermintEndpoint = "localhost:26657"
	// DefaultGRPCEndpoint is the default value for the gRPC endpoint
	DefaultGRPCEndpoint = "localhost:9090"
	// DefaultNetwork defines the default network name
	DefaultNetwork = "network"
	// DefaultOffline defines the default offline value
	DefaultOffline = false
	// DefaultEnableFeeSuggestion indicates to use fee suggestion if `construction/metadata` is called without gas limit and price
	DefaultEnableFeeSuggestion = false
	// DenomToSuggest defines the default denom for fee suggestion
	DenomToSuggest = "uatom"
	// DefaultPrices defines the default list of prices to suggest
	DefaultPrices = "1uatom,1stake"
)

configuration defaults constants

View Source
const (
	FlagBlockchain          = "blockchain"
	FlagNetwork             = "network"
	FlagTendermintEndpoint  = "tendermint"
	FlagGRPCEndpoint        = "grpc"
	FlagAddr                = "addr"
	FlagRetries             = "retries"
	FlagOffline             = "offline"
	FlagEnableFeeSuggestion = "enable-fee-suggestion"
	FlagGasToSuggest        = "gas-to-suggest"
	FlagDenomToSuggest      = "denom-to-suggest"
	FlagPricesToSuggest     = "prices-to-suggest"
)

configuration flags

View Source
const (
	StatusTxSuccess   = "Success"
	StatusTxReverted  = "Reverted"
	StatusPeerSynced  = "synced"
	StatusPeerSyncing = "syncing"
)

statuses

View Source
const (
	DeliverTxSize       = sha256.Size
	BeginEndBlockTxSize = DeliverTxSize + 1
	EndBlockHashStart   = 0x0
	BeginBlockHashStart = 0x1
)

In rosetta all state transitions must be represented as transactions since in tendermint begin block and end block are state transitions which are not represented as transactions we mock only the balance changes happening at those levels as transactions. (check BeginBlockTxHash for more info)

View Source
const (
	// BurnerAddressIdentifier mocks the account identifier of a burner address
	// all coins burned in the sdk will be sent to this identifier, which per sdk.AccAddress
	// design we will never be able to query (as of now).
	// Rosetta does not understand supply contraction.
	BurnerAddressIdentifier = "burner"
)
View Source
const (
	Log = "log"
)

misc

Variables

This section is empty.

Functions

func AddOperationIndexes

func AddOperationIndexes(msgOps []*rosettatypes.Operation, balanceOps []*rosettatypes.Operation) (finalOps []*rosettatypes.Operation)

AddOperationIndexes adds the indexes to operations adhering to specific rules: operations related to messages will be always before than the balance ones

func MakeCodec

MakeCodec generates the codec required to interact with the cosmos APIs used by the rosetta gateway

func ServerFromConfig

func ServerFromConfig(conf *Config) (crg.Server, error)

func SetFlags

func SetFlags(flags *pflag.FlagSet)

SetFlags sets the configuration flags to the given flagset

Types

type Client

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

Client implements a single network client to interact with cosmos based chains

func NewClient

func NewClient(cfg *Config) (*Client, error)

NewClient instantiates a new online servicer

func (*Client) AccountIdentifierFromPublicKey

func (c *Client) AccountIdentifierFromPublicKey(pubKey *types.PublicKey) (*types.AccountIdentifier, error)

func (*Client) Balances

func (c *Client) Balances(ctx context.Context, addr string, height *int64) ([]*rosettatypes.Amount, error)

func (*Client) BlockByHash

func (c *Client) BlockByHash(ctx context.Context, hash string) (crgtypes.BlockResponse, error)

func (*Client) BlockByHeight

func (c *Client) BlockByHeight(ctx context.Context, height *int64) (crgtypes.BlockResponse, error)

func (*Client) BlockTransactionsByHash

func (c *Client) BlockTransactionsByHash(ctx context.Context, hash string) (crgtypes.BlockTransactionsResponse, error)

func (*Client) BlockTransactionsByHeight

func (c *Client) BlockTransactionsByHeight(ctx context.Context, height *int64) (crgtypes.BlockTransactionsResponse, error)

func (*Client) Bootstrap

func (c *Client) Bootstrap() error

Bootstrap is gonna connect the client to the endpoints

func (*Client) ConstructionMetadataFromOptions

func (c *Client) ConstructionMetadataFromOptions(ctx context.Context, options map[string]interface{}) (meta map[string]interface{}, err error)

ConstructionMetadataFromOptions builds the metadata given the options

func (*Client) ConstructionPayload

func (c *Client) ConstructionPayload(_ context.Context, request *types.ConstructionPayloadsRequest) (resp *types.ConstructionPayloadsResponse, err error)

func (*Client) GetTx

func (c *Client) GetTx(ctx context.Context, hash string) (*rosettatypes.Transaction, error)

GetTx returns a transaction given its hash. For Rosetta we make a synthetic transaction for BeginBlock

and EndBlock to adhere to balance tracking rules.

func (*Client) GetUnconfirmedTx

func (c *Client) GetUnconfirmedTx(ctx context.Context, hash string) (*rosettatypes.Transaction, error)

GetUnconfirmedTx gets an unconfirmed transaction given its hash

func (*Client) Mempool

Mempool returns the unconfirmed transactions in the mempool

func (*Client) OperationStatuses

func (c *Client) OperationStatuses() []*types.OperationStatus

func (*Client) Peers

func (c *Client) Peers(ctx context.Context) ([]*rosettatypes.Peer, error)

Peers gets the number of peers

func (*Client) PostTx

func (c *Client) PostTx(txBytes []byte) (*rosettatypes.TransactionIdentifier, map[string]interface{}, error)

func (*Client) PreprocessOperationsToOptions

func (c *Client) PreprocessOperationsToOptions(_ context.Context, req *types.ConstructionPreprocessRequest) (response *types.ConstructionPreprocessResponse, err error)

func (*Client) Ready

func (c *Client) Ready() error

Ready performs a health check and returns an error if the client is not ready.

func (*Client) SignedTx

func (c *Client) SignedTx(_ context.Context, txBytes []byte, signatures []*types.Signature) (signedTxBytes []byte, err error)

func (*Client) Status

func (c *Client) Status(ctx context.Context) (*rosettatypes.SyncStatus, error)

func (*Client) SupportedOperations

func (c *Client) SupportedOperations() []string

func (*Client) TxOperationsAndSignersAccountIdentifiers

func (c *Client) TxOperationsAndSignersAccountIdentifiers(signed bool, txBytes []byte) (ops []*rosettatypes.Operation, signers []*rosettatypes.AccountIdentifier, err error)

func (*Client) Version

func (c *Client) Version() string

type Config

type Config struct {
	// Blockchain defines the blockchain name
	// defaults to DefaultBlockchain
	Blockchain string
	// Network defines the network name
	Network string
	// TendermintRPC defines the endpoint to connect to
	// tendermint RPC, specifying 'tcp://' before is not
	// required, usually it's at port 26657 of the
	TendermintRPC string
	// GRPCEndpoint defines the cosmos application gRPC endpoint
	// usually it is located at 9090 port
	GRPCEndpoint string
	// Addr defines the default address to bind the rosetta server to
	// defaults to DefaultAddr
	Addr string
	// Retries defines the maximum number of retries
	// rosetta will do before quitting
	Retries int
	// Offline defines if the server must be run in offline mode
	Offline bool
	// EnableFeeSuggestion indicates to use fee suggestion when `construction/metadata` is called without gas limit and price
	EnableFeeSuggestion bool
	// GasToSuggest defines the gas limit for fee suggestion
	GasToSuggest int
	// DenomToSuggest defines the default denom for fee suggestion
	DenomToSuggest string
	// GasPrices defines the gas prices for fee suggestion
	GasPrices sdk.DecCoins
	// Codec overrides the default data and construction api client codecs
	Codec *codec.ProtoCodec
	// InterfaceRegistry overrides the default data and construction api interface registry
	InterfaceRegistry codectypes.InterfaceRegistry
}

Config defines the configuration of the rosetta server

func FromFlags

func FromFlags(flags *pflag.FlagSet) (*Config, error)

FromFlags gets the configuration from flags

func (*Config) NetworkIdentifier

func (c *Config) NetworkIdentifier() *types.NetworkIdentifier

NetworkIdentifier returns the network identifier given the configuration

func (*Config) WithCodec

func (c *Config) WithCodec(ir codectypes.InterfaceRegistry, cdc *codec.ProtoCodec)

WithCodec extends the configuration with a predefined Codec

type ConstructionMetadata

type ConstructionMetadata struct {
	ChainID     string        `json:"chain_id"`
	SignersData []*SignerData `json:"signer_data"`
	GasLimit    uint64        `json:"gas_limit"`
	GasPrice    string        `json:"gas_price"`
	Memo        string        `json:"memo"`
}

ConstructionMetadata are the metadata options used to construct a transaction. It is returned by ConstructionMetadataFromOptions and fed to ConstructionPayload to process the bytes to sign.

func (*ConstructionMetadata) FromMetadata

func (c *ConstructionMetadata) FromMetadata(meta map[string]interface{}) error

func (ConstructionMetadata) ToMetadata

func (c ConstructionMetadata) ToMetadata() (map[string]interface{}, error)

type ConstructionPreprocessMetadata

type ConstructionPreprocessMetadata struct {
	Memo     string `json:"memo"`
	GasLimit uint64 `json:"gas_limit"`
	GasPrice string `json:"gas_price"`
}

ConstructionPreprocessMetadata is used to represent the metadata rosetta can provide during preprocess options

func (*ConstructionPreprocessMetadata) FromMetadata

func (c *ConstructionPreprocessMetadata) FromMetadata(meta map[string]interface{}) error

type Converter

type Converter interface {
	// ToSDK exposes the methods that convert
	// rosetta types to cosmos sdk and tendermint types
	ToSDK() ToSDKConverter
	// ToRosetta exposes the methods that convert
	// sdk and tendermint types to rosetta types
	ToRosetta() ToRosettaConverter
}

Converter is a utility that can be used to convert back and forth from rosetta to sdk and tendermint types IMPORTANT NOTES:

  • IT SHOULD BE USED ONLY TO DEAL WITH THINGS IN A STATELESS WAY! IT SHOULD NEVER INTERACT DIRECTLY WITH TENDERMINT RPC AND COSMOS GRPC

- IT SHOULD RETURN cosmos rosetta gateway error types!

func NewConverter

type PreprocessOperationsOptionsResponse

type PreprocessOperationsOptionsResponse struct {
	ExpectedSigners []string `json:"expected_signers"`
	Memo            string   `json:"memo"`
	GasLimit        uint64   `json:"gas_limit"`
	GasPrice        string   `json:"gas_price"`
}

PreprocessOperationsOptionsResponse is the structured metadata options returned by the preprocess operations endpoint

func (*PreprocessOperationsOptionsResponse) FromMetadata

func (c *PreprocessOperationsOptionsResponse) FromMetadata(meta map[string]interface{}) error

func (PreprocessOperationsOptionsResponse) ToMetadata

func (c PreprocessOperationsOptionsResponse) ToMetadata() (map[string]interface{}, error)

type SignerData

type SignerData struct {
	AccountNumber uint64 `json:"account_number"`
	Sequence      uint64 `json:"sequence"`
}

SignerData contains information on the signers when the request is being created, used to populate the account information

type ToRosettaConverter

type ToRosettaConverter interface {
	// BlockResponse returns a block response given a result block
	BlockResponse(block *tmcoretypes.ResultBlock) crgtypes.BlockResponse
	// BeginBlockToTx converts the given begin block hash to rosetta transaction hash
	BeginBlockTxHash(blockHash []byte) string
	// EndBlockTxHash converts the given endblock hash to rosetta transaction hash
	EndBlockTxHash(blockHash []byte) string
	// Amounts converts sdk.Coins to rosetta.Amounts
	Amounts(ownedCoins []sdk.Coin, availableCoins sdk.Coins) []*rosettatypes.Amount
	// Ops converts an sdk.Msg to rosetta operations
	Ops(status string, msg sdk.Msg) ([]*rosettatypes.Operation, error)
	// OpsAndSigners takes raw transaction bytes and returns rosetta operations and the expected signers
	OpsAndSigners(txBytes []byte) (ops []*rosettatypes.Operation, signers []*rosettatypes.AccountIdentifier, err error)
	// Meta converts an sdk.Msg to rosetta metadata
	Meta(msg sdk.Msg) (meta map[string]interface{}, err error)
	// SignerData returns account signing data from a queried any account
	SignerData(anyAccount *codectypes.Any) (*SignerData, error)
	// SigningComponents returns rosetta's components required to build a signable transaction
	SigningComponents(tx authsigning.Tx, metadata *ConstructionMetadata, rosPubKeys []*rosettatypes.PublicKey) (txBytes []byte, payloadsToSign []*rosettatypes.SigningPayload, err error)
	// Tx converts a tendermint transaction and tx result if provided to a rosetta tx
	Tx(rawTx tmtypes.Tx, txResult *abci.ResponseDeliverTx) (*rosettatypes.Transaction, error)
	// TxIdentifiers converts a tendermint tx to transaction identifiers
	TxIdentifiers(txs []tmtypes.Tx) []*rosettatypes.TransactionIdentifier
	// BalanceOps converts events to balance operations
	BalanceOps(status string, events []abci.Event) []*rosettatypes.Operation
	// SyncStatus converts a tendermint status to sync status
	SyncStatus(status *tmcoretypes.ResultStatus) *rosettatypes.SyncStatus
	// Peers converts tendermint peers to rosetta
	Peers(peers []tmcoretypes.Peer) []*rosettatypes.Peer
}

ToRosettaConverter is an interface that exposes all the functions used to convert sdk and tendermint types to rosetta known types

type ToSDKConverter

type ToSDKConverter interface {
	// UnsignedTx converts rosetta operations to an unsigned cosmos sdk transactions
	UnsignedTx(ops []*rosettatypes.Operation) (tx authsigning.Tx, err error)
	// SignedTx adds the provided signatures after decoding the unsigned transaction raw bytes
	// and returns the signed tx bytes
	SignedTx(txBytes []byte, signatures []*rosettatypes.Signature) (signedTxBytes []byte, err error)
	// Msg converts metadata to an sdk message
	Msg(meta map[string]interface{}, msg sdk.Msg) (err error)
	// HashToTxType returns the transaction type (end block, begin block or deliver tx)
	// and the real hash to query in order to get information
	HashToTxType(hashBytes []byte) (txType TransactionType, realHash []byte)
	// PubKey attempts to convert a rosetta public key to cosmos sdk one
	PubKey(pk *rosettatypes.PublicKey) (cryptotypes.PubKey, error)
}

ToSDKConverter is an interface that exposes all the functions used to convert rosetta types to tendermint and sdk types

type TransactionType

type TransactionType int

TransactionType is used to distinguish if a rosetta provided hash represents endblock, beginblock or deliver tx

const (
	UnrecognizedTx TransactionType = iota
	BeginBlockTx
	EndBlockTx
	DeliverTxTx
)

Directories

Path Synopsis
lib

Jump to

Keyboard shortcuts

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