feat: enhance rosetta support (#11609)
* fee suggestion for construction/metadata * rename module * change default gas_limit for fee suggestion * add rosetta items in template * type fix for default-suggest-denom * add default values * add suggestion-related config * force set to success for balance operations * enable offline mode * Revert "rename module" This reverts commit ea433e74dacb039e01c4d4fe0dc77bbb29c91952. * increase defaultNodeTimeout for rosetta for huge genesis * use DefaultGasLimit as DefaultSuggestGas * use default gas limit as default gas suggest for rosetta * add enable-default-fee-suggest for rosetta * update config template * prevent bad gateway due to huge genesis * Apply suggestions from code review Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com> Co-authored-by: Anil Kumar Kammari <anil@vitwit.com> * add price flag for rosetta standalone * fix rosetta data/block when block identifier is unset * add checking mismatched index/hash * bump rosetta-sdk-go to v0.7.7 * bump dependency * add changelog * Apply suggestions from code review * Apply suggestions from code review * make gas_prices and gas_limit optional * Apply suggestions from code review * add changelog * revive overwritten by cherrypick * revive overwritten by cherry-pick * rename local variable * rename variables and configs * Apply suggestions from code review Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com> * break validation into two if cases * fix config toml template Co-authored-by: yys <sw.yunsuk@gmail.com> Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com> Co-authored-by: Anil Kumar Kammari <anil@vitwit.com>
This commit is contained in:
parent
53003e15a3
commit
38a1132024
|
@ -85,6 +85,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||||
* [\#10962](https://github.com/cosmos/cosmos-sdk/pull/10962) ADR-040: Add state migration from iavl (v1Store) to smt (v2Store)
|
* [\#10962](https://github.com/cosmos/cosmos-sdk/pull/10962) ADR-040: Add state migration from iavl (v1Store) to smt (v2Store)
|
||||||
* (types) [\#10948](https://github.com/cosmos/cosmos-sdk/issues/10948) Add `app-db-backend` to the `app.toml` config to replace the compile-time `types.DBbackend` variable.
|
* (types) [\#10948](https://github.com/cosmos/cosmos-sdk/issues/10948) Add `app-db-backend` to the `app.toml` config to replace the compile-time `types.DBbackend` variable.
|
||||||
* (authz)[\#11060](https://github.com/cosmos/cosmos-sdk/pull/11060) Support grant with no expire time.
|
* (authz)[\#11060](https://github.com/cosmos/cosmos-sdk/pull/11060) Support grant with no expire time.
|
||||||
|
* (rosetta) [\#11590](https://github.com/cosmos/cosmos-sdk/pull/11590) Add fee suggestion for rosetta and enable offline mode. Also force set events about Fees to Success to pass reconciliation test.
|
||||||
|
|
||||||
### API Breaking Changes
|
### API Breaking Changes
|
||||||
|
|
||||||
|
@ -266,6 +267,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||||
* (cli) [\#11337](https://github.com/cosmos/cosmos-sdk/pull/11337) Fixes `show-adress` cli cmd
|
* (cli) [\#11337](https://github.com/cosmos/cosmos-sdk/pull/11337) Fixes `show-adress` cli cmd
|
||||||
* (crypto) [\#11298](https://github.com/cosmos/cosmos-sdk/pull/11298) Fix cgo secp signature verification and update libscep256k1 library.
|
* (crypto) [\#11298](https://github.com/cosmos/cosmos-sdk/pull/11298) Fix cgo secp signature verification and update libscep256k1 library.
|
||||||
* (x/authz) [\#11512](https://github.com/cosmos/cosmos-sdk/pull/11512) Fix response of a panic to error, when subtracting balances.
|
* (x/authz) [\#11512](https://github.com/cosmos/cosmos-sdk/pull/11512) Fix response of a panic to error, when subtracting balances.
|
||||||
|
* (rosetta) [\#11590](https://github.com/cosmos/cosmos-sdk/pull/11590) `/block` returns an error with nil pointer when a request has both of index and hash and increase timeout for huge genesis.
|
||||||
* (x/feegrant) [\#11813](https://github.com/cosmos/cosmos-sdk/pull/11813) Fix pagination total count in `AllowancesByGranter` query.
|
* (x/feegrant) [\#11813](https://github.com/cosmos/cosmos-sdk/pull/11813) Fix pagination total count in `AllowancesByGranter` query.
|
||||||
|
|
||||||
### State Machine Breaking
|
### State Machine Breaking
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
|
clientflags "github.com/cosmos/cosmos-sdk/client/flags"
|
||||||
pruningtypes "github.com/cosmos/cosmos-sdk/pruning/types"
|
pruningtypes "github.com/cosmos/cosmos-sdk/pruning/types"
|
||||||
"github.com/cosmos/cosmos-sdk/telemetry"
|
"github.com/cosmos/cosmos-sdk/telemetry"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
@ -131,6 +132,15 @@ type RosettaConfig struct {
|
||||||
|
|
||||||
// Offline defines if the server must be run in offline mode
|
// Offline defines if the server must be run in offline mode
|
||||||
Offline bool `mapstructure:"offline"`
|
Offline bool `mapstructure:"offline"`
|
||||||
|
|
||||||
|
// EnableFeeSuggestion defines if the server should suggest fee by default
|
||||||
|
EnableFeeSuggestion bool `mapstructure:"enable-fee-suggestion"`
|
||||||
|
|
||||||
|
// GasToSuggest defines gas limit when calculating the fee
|
||||||
|
GasToSuggest int `mapstructure:"gas-to-suggest"`
|
||||||
|
|
||||||
|
// DenomToSuggest defines the defult denom for fee suggestion
|
||||||
|
DenomToSuggest string `mapstructure:"denom-to-suggest"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GRPCConfig defines configuration for the gRPC server.
|
// GRPCConfig defines configuration for the gRPC server.
|
||||||
|
@ -236,12 +246,15 @@ func DefaultConfig() *Config {
|
||||||
Address: DefaultGRPCAddress,
|
Address: DefaultGRPCAddress,
|
||||||
},
|
},
|
||||||
Rosetta: RosettaConfig{
|
Rosetta: RosettaConfig{
|
||||||
Enable: false,
|
Enable: false,
|
||||||
Address: ":8080",
|
Address: ":8080",
|
||||||
Blockchain: "app",
|
Blockchain: "app",
|
||||||
Network: "network",
|
Network: "network",
|
||||||
Retries: 3,
|
Retries: 3,
|
||||||
Offline: false,
|
Offline: false,
|
||||||
|
EnableFeeSuggestion: false,
|
||||||
|
GasToSuggest: clientflags.DefaultGasLimit,
|
||||||
|
DenomToSuggest: "uatom",
|
||||||
},
|
},
|
||||||
GRPCWeb: GRPCWebConfig{
|
GRPCWeb: GRPCWebConfig{
|
||||||
Enable: true,
|
Enable: true,
|
||||||
|
@ -299,12 +312,15 @@ func GetConfig(v *viper.Viper) Config {
|
||||||
EnableUnsafeCORS: v.GetBool("api.enabled-unsafe-cors"),
|
EnableUnsafeCORS: v.GetBool("api.enabled-unsafe-cors"),
|
||||||
},
|
},
|
||||||
Rosetta: RosettaConfig{
|
Rosetta: RosettaConfig{
|
||||||
Enable: v.GetBool("rosetta.enable"),
|
Enable: v.GetBool("rosetta.enable"),
|
||||||
Address: v.GetString("rosetta.address"),
|
Address: v.GetString("rosetta.address"),
|
||||||
Blockchain: v.GetString("rosetta.blockchain"),
|
Blockchain: v.GetString("rosetta.blockchain"),
|
||||||
Network: v.GetString("rosetta.network"),
|
Network: v.GetString("rosetta.network"),
|
||||||
Retries: v.GetInt("rosetta.retries"),
|
Retries: v.GetInt("rosetta.retries"),
|
||||||
Offline: v.GetBool("rosetta.offline"),
|
Offline: v.GetBool("rosetta.offline"),
|
||||||
|
EnableFeeSuggestion: v.GetBool("rosetta.enable-fee-suggestion"),
|
||||||
|
GasToSuggest: v.GetInt("rosetta.gas-to-suggest"),
|
||||||
|
DenomToSuggest: v.GetString("rosetta.denom-to-suggest"),
|
||||||
},
|
},
|
||||||
GRPC: GRPCConfig{
|
GRPC: GRPCConfig{
|
||||||
Enable: v.GetBool("grpc.enable"),
|
Enable: v.GetBool("grpc.enable"),
|
||||||
|
|
|
@ -170,6 +170,18 @@ retries = {{ .Rosetta.Retries }}
|
||||||
# Offline defines if Rosetta server should run in offline mode.
|
# Offline defines if Rosetta server should run in offline mode.
|
||||||
offline = {{ .Rosetta.Offline }}
|
offline = {{ .Rosetta.Offline }}
|
||||||
|
|
||||||
|
# EnableDefaultSuggestedFee defines if the server should suggest fee by default.
|
||||||
|
# If 'construction/medata' is called without gas limit and gas price,
|
||||||
|
# suggested fee based on gas-to-suggest and denom-to-suggest will be given.
|
||||||
|
enable-fee-suggestion = {{ .Rosetta.EnableFeeSuggestion }}
|
||||||
|
|
||||||
|
# GasToSuggest defines gas limit when calculating the fee
|
||||||
|
gas-to-suggest = {{ .Rosetta.GasToSuggest }}
|
||||||
|
|
||||||
|
# DenomToSuggest defines the defult denom for fee suggestion.
|
||||||
|
# Price must be in minimum-gas-prices.
|
||||||
|
denom-to-suggest = "{{ .Rosetta.DenomToSuggest }}"
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
### gRPC Configuration ###
|
### gRPC Configuration ###
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
|
@ -11,27 +11,32 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
rosettatypes "github.com/coinbase/rosetta-sdk-go/types"
|
"github.com/cosmos/cosmos-sdk/version"
|
||||||
|
|
||||||
abcitypes "github.com/tendermint/tendermint/abci/types"
|
abcitypes "github.com/tendermint/tendermint/abci/types"
|
||||||
tmrpc "github.com/tendermint/tendermint/rpc/client"
|
|
||||||
|
rosettatypes "github.com/coinbase/rosetta-sdk-go/types"
|
||||||
|
"google.golang.org/grpc/metadata"
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/rpc/client/http"
|
"github.com/tendermint/tendermint/rpc/client/http"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
|
|
||||||
crgerrs "github.com/cosmos/cosmos-sdk/server/rosetta/lib/errors"
|
crgerrs "github.com/cosmos/cosmos-sdk/server/rosetta/lib/errors"
|
||||||
crgtypes "github.com/cosmos/cosmos-sdk/server/rosetta/lib/types"
|
crgtypes "github.com/cosmos/cosmos-sdk/server/rosetta/lib/types"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
|
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
|
||||||
"github.com/cosmos/cosmos-sdk/version"
|
|
||||||
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||||
auth "github.com/cosmos/cosmos-sdk/x/auth/types"
|
auth "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
|
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||||
|
|
||||||
|
tmrpc "github.com/tendermint/tendermint/rpc/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
// interface assertion
|
// interface assertion
|
||||||
var _ crgtypes.Client = (*Client)(nil)
|
var _ crgtypes.Client = (*Client)(nil)
|
||||||
|
|
||||||
const defaultNodeTimeout = 15 * time.Second
|
const defaultNodeTimeout = time.Minute
|
||||||
|
|
||||||
// Client implements a single network client to interact with cosmos based chains
|
// Client implements a single network client to interact with cosmos based chains
|
||||||
type Client struct {
|
type Client struct {
|
||||||
|
@ -121,6 +126,14 @@ func (c *Client) Ready() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// to prevent timeout of reading genesis block
|
||||||
|
var height int64 = -1
|
||||||
|
_, err = c.BlockByHeight(ctx, &height)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
_, err = c.bank.TotalSupply(ctx, &bank.QueryTotalSupplyRequest{})
|
_, err = c.bank.TotalSupply(ctx, &bank.QueryTotalSupplyRequest{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -395,6 +408,28 @@ func (c *Client) ConstructionMetadataFromOptions(ctx context.Context, options ma
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if default fees suggestion is enabled and gas limit or price is unset, use default
|
||||||
|
if c.config.EnableFeeSuggestion {
|
||||||
|
if constructionOptions.GasLimit <= 0 {
|
||||||
|
constructionOptions.GasLimit = uint64(c.config.GasToSuggest)
|
||||||
|
}
|
||||||
|
if constructionOptions.GasPrice == "" {
|
||||||
|
denom := c.config.DenomToSuggest
|
||||||
|
constructionOptions.GasPrice = c.config.SuggestPrices.AmountOf(denom).String() + denom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if constructionOptions.GasLimit > 0 && constructionOptions.GasPrice != "" {
|
||||||
|
gasPrice, err := sdk.ParseDecCoin(constructionOptions.GasPrice)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// check gasPrice is in the list
|
||||||
|
if !c.config.SuggestPrices.AmountOf(gasPrice.Denom).IsPositive() {
|
||||||
|
return nil, crgerrs.ErrBadArgument
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
signersData := make([]*SignerData, len(constructionOptions.ExpectedSigners))
|
signersData := make([]*SignerData, len(constructionOptions.ExpectedSigners))
|
||||||
|
|
||||||
for i, signer := range constructionOptions.ExpectedSigners {
|
for i, signer := range constructionOptions.ExpectedSigners {
|
||||||
|
|
|
@ -10,8 +10,10 @@ import (
|
||||||
|
|
||||||
crg "github.com/cosmos/cosmos-sdk/server/rosetta/lib/server"
|
crg "github.com/cosmos/cosmos-sdk/server/rosetta/lib/server"
|
||||||
|
|
||||||
|
clientflags "github.com/cosmos/cosmos-sdk/client/flags"
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// configuration defaults constants
|
// configuration defaults constants
|
||||||
|
@ -30,17 +32,27 @@ const (
|
||||||
DefaultNetwork = "network"
|
DefaultNetwork = "network"
|
||||||
// DefaultOffline defines the default offline value
|
// DefaultOffline defines the default offline value
|
||||||
DefaultOffline = false
|
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 = "0.0uatom"
|
||||||
)
|
)
|
||||||
|
|
||||||
// configuration flags
|
// configuration flags
|
||||||
const (
|
const (
|
||||||
FlagBlockchain = "blockchain"
|
FlagBlockchain = "blockchain"
|
||||||
FlagNetwork = "network"
|
FlagNetwork = "network"
|
||||||
FlagTendermintEndpoint = "tendermint"
|
FlagTendermintEndpoint = "tendermint"
|
||||||
FlagGRPCEndpoint = "grpc"
|
FlagGRPCEndpoint = "grpc"
|
||||||
FlagAddr = "addr"
|
FlagAddr = "addr"
|
||||||
FlagRetries = "retries"
|
FlagRetries = "retries"
|
||||||
FlagOffline = "offline"
|
FlagOffline = "offline"
|
||||||
|
FlagEnableFeeSuggestion = "enable-fee-suggestion"
|
||||||
|
FlagGasToSuggest = "gas-to-suggest"
|
||||||
|
FlagDenomToSuggest = "denom-to-suggest"
|
||||||
|
FlagPricesToSuggest = "prices-to-suggest"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config defines the configuration of the rosetta server
|
// Config defines the configuration of the rosetta server
|
||||||
|
@ -65,6 +77,14 @@ type Config struct {
|
||||||
Retries int
|
Retries int
|
||||||
// Offline defines if the server must be run in offline mode
|
// Offline defines if the server must be run in offline mode
|
||||||
Offline bool
|
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
|
||||||
|
// SuggestPrices defines the gas prices for fee suggestion
|
||||||
|
SuggestPrices sdk.DecCoins
|
||||||
// Codec overrides the default data and construction api client codecs
|
// Codec overrides the default data and construction api client codecs
|
||||||
Codec *codec.ProtoCodec
|
Codec *codec.ProtoCodec
|
||||||
// InterfaceRegistry overrides the default data and construction api interface registry
|
// InterfaceRegistry overrides the default data and construction api interface registry
|
||||||
|
@ -99,8 +119,18 @@ func (c *Config) validate() error {
|
||||||
if c.Network == "" {
|
if c.Network == "" {
|
||||||
return fmt.Errorf("network not provided")
|
return fmt.Errorf("network not provided")
|
||||||
}
|
}
|
||||||
if c.Offline {
|
if c.GasToSuggest <= 0 {
|
||||||
return fmt.Errorf("offline mode is not supported for stargate implementation due to how sigv2 works")
|
c.GasToSuggest = clientflags.DefaultGasLimit
|
||||||
|
}
|
||||||
|
found := false
|
||||||
|
for i := 0; i < c.SuggestPrices.Len(); i++ {
|
||||||
|
if c.SuggestPrices.GetDenomByIndex(i) == c.DenomToSuggest {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
return fmt.Errorf("default suggest denom is not found in minimum-gas-prices")
|
||||||
}
|
}
|
||||||
|
|
||||||
// these are optional but it must be online
|
// these are optional but it must be online
|
||||||
|
@ -153,14 +183,39 @@ func FromFlags(flags *pflag.FlagSet) (*Config, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
enableDefaultFeeSuggestion, err := flags.GetBool(FlagEnableFeeSuggestion)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
suggestGas, err := flags.GetInt(FlagGasToSuggest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
suggestDenom, err := flags.GetString(FlagDenomToSuggest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
suggestPrices, err := flags.GetString(FlagPricesToSuggest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
prices, err := sdk.ParseDecCoins(suggestPrices)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
conf := &Config{
|
conf := &Config{
|
||||||
Blockchain: blockchain,
|
Blockchain: blockchain,
|
||||||
Network: network,
|
Network: network,
|
||||||
TendermintRPC: tendermintRPC,
|
TendermintRPC: tendermintRPC,
|
||||||
GRPCEndpoint: gRPCEndpoint,
|
GRPCEndpoint: gRPCEndpoint,
|
||||||
Addr: addr,
|
Addr: addr,
|
||||||
Retries: retries,
|
Retries: retries,
|
||||||
Offline: offline,
|
Offline: offline,
|
||||||
|
EnableFeeSuggestion: enableDefaultFeeSuggestion,
|
||||||
|
GasToSuggest: suggestGas,
|
||||||
|
DenomToSuggest: suggestDenom,
|
||||||
|
SuggestPrices: prices,
|
||||||
}
|
}
|
||||||
err = conf.validate()
|
err = conf.validate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -201,4 +256,8 @@ func SetFlags(flags *pflag.FlagSet) {
|
||||||
flags.String(FlagAddr, DefaultAddr, "the address rosetta will bind to")
|
flags.String(FlagAddr, DefaultAddr, "the address rosetta will bind to")
|
||||||
flags.Int(FlagRetries, DefaultRetries, "the number of retries that will be done before quitting")
|
flags.Int(FlagRetries, DefaultRetries, "the number of retries that will be done before quitting")
|
||||||
flags.Bool(FlagOffline, DefaultOffline, "run rosetta only with construction API")
|
flags.Bool(FlagOffline, DefaultOffline, "run rosetta only with construction API")
|
||||||
|
flags.Bool(FlagEnableFeeSuggestion, DefaultEnableFeeSuggestion, "enable default fee suggestion")
|
||||||
|
flags.Int(FlagGasToSuggest, clientflags.DefaultGasLimit, "default gas for fee suggestion")
|
||||||
|
flags.String(FlagDenomToSuggest, DenomToSuggest, "default denom for fee suggestion")
|
||||||
|
flags.String(FlagPricesToSuggest, DefaultPrices, "default prices for fee suggestion")
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,7 +297,7 @@ func (c converter) Tx(rawTx tmtypes.Tx, txResult *abci.ResponseDeliverTx) (*rose
|
||||||
var balanceOps []*rosettatypes.Operation
|
var balanceOps []*rosettatypes.Operation
|
||||||
// tx result might be nil, in case we're querying an unconfirmed tx from the mempool
|
// tx result might be nil, in case we're querying an unconfirmed tx from the mempool
|
||||||
if txResult != nil {
|
if txResult != nil {
|
||||||
balanceOps = c.BalanceOps(status, txResult.Events)
|
balanceOps = c.BalanceOps(StatusTxSuccess, txResult.Events) // force set to success because no events for failed tx
|
||||||
}
|
}
|
||||||
|
|
||||||
// now normalize indexes
|
// now normalize indexes
|
||||||
|
|
|
@ -4,8 +4,11 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
|
||||||
"github.com/coinbase/rosetta-sdk-go/types"
|
"github.com/coinbase/rosetta-sdk-go/types"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/server/rosetta/lib/errors"
|
"github.com/cosmos/cosmos-sdk/server/rosetta/lib/errors"
|
||||||
|
@ -69,9 +72,43 @@ func (on OnlineNetwork) ConstructionMetadata(ctx context.Context, request *types
|
||||||
return nil, errors.ToRosetta(err)
|
return nil, errors.ToRosetta(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &types.ConstructionMetadataResponse{
|
response := &types.ConstructionMetadataResponse{
|
||||||
Metadata: metadata,
|
Metadata: metadata,
|
||||||
}, nil
|
}
|
||||||
|
|
||||||
|
if metadata["gas_price"] != nil && metadata["gas_limit"] != nil {
|
||||||
|
gasPrice, ok := metadata["gas_price"].(string)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.ToRosetta(errors.WrapError(errors.ErrBadArgument, "invalid gas_price"))
|
||||||
|
}
|
||||||
|
if gasPrice == "" { // gas_price is unset. skip fee suggestion
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
price, err := sdk.ParseDecCoin(gasPrice)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.ToRosetta(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
gasLimit, ok := metadata["gas_limit"].(float64)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.ToRosetta(errors.WrapError(errors.ErrBadArgument, "invalid gas_limit"))
|
||||||
|
}
|
||||||
|
if gasLimit == 0 { // gas_limit is unset. skip fee suggestion
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
gas := sdk.NewIntFromUint64(uint64(gasLimit))
|
||||||
|
|
||||||
|
suggestedFee := types.Amount{
|
||||||
|
Value: strconv.FormatInt(price.Amount.MulInt64(gas.Int64()).Ceil().TruncateInt64(), 10),
|
||||||
|
Currency: &(types.Currency{
|
||||||
|
Symbol: price.Denom,
|
||||||
|
Decimals: 0,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
response.SuggestedFee = []*types.Amount{&suggestedFee}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConstructionParse Parse is called on both unsigned and signed transactions to understand the
|
// ConstructionParse Parse is called on both unsigned and signed transactions to understand the
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/coinbase/rosetta-sdk-go/types"
|
"github.com/coinbase/rosetta-sdk-go/types"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/server/rosetta/lib/errors"
|
"github.com/cosmos/cosmos-sdk/server/rosetta/lib/errors"
|
||||||
crgtypes "github.com/cosmos/cosmos-sdk/server/rosetta/lib/types"
|
crgtypes "github.com/cosmos/cosmos-sdk/server/rosetta/lib/types"
|
||||||
)
|
)
|
||||||
|
@ -56,9 +55,14 @@ func (on OnlineNetwork) Block(ctx context.Context, request *types.BlockRequest)
|
||||||
blockResponse crgtypes.BlockTransactionsResponse
|
blockResponse crgtypes.BlockTransactionsResponse
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
// block identifier is assumed not to be nil as rosetta will do this check for us
|
|
||||||
// check if we have to query via hash or block number
|
// When fetching data by BlockIdentifier, it may be possible to only specify the index or hash.
|
||||||
|
// If neither property is specified, it is assumed that the client is making a request at the current block.
|
||||||
switch {
|
switch {
|
||||||
|
case request.BlockIdentifier == nil: // unlike AccountBalance(), BlockIdentifer is mandatory by spec 1.4.10.
|
||||||
|
err := errors.WrapError(errors.ErrBadArgument, "block identifier needs to be specified")
|
||||||
|
return nil, errors.ToRosetta(err)
|
||||||
|
|
||||||
case request.BlockIdentifier.Hash != nil:
|
case request.BlockIdentifier.Hash != nil:
|
||||||
blockResponse, err = on.client.BlockTransactionsByHash(ctx, *request.BlockIdentifier.Hash)
|
blockResponse, err = on.client.BlockTransactionsByHash(ctx, *request.BlockIdentifier.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -69,8 +73,23 @@ func (on OnlineNetwork) Block(ctx context.Context, request *types.BlockRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.ToRosetta(err)
|
return nil, errors.ToRosetta(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
err := errors.WrapError(errors.ErrBadArgument, "at least one of hash or index needs to be specified")
|
// both empty
|
||||||
|
blockResponse, err = on.client.BlockTransactionsByHeight(ctx, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.ToRosetta(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Both of index and hash can be specified in reuqest, so make sure they are not mismatching.
|
||||||
|
if request.BlockIdentifier.Index != nil && *request.BlockIdentifier.Index != blockResponse.Block.Index {
|
||||||
|
err := errors.WrapError(errors.ErrBadArgument, "mismatching index")
|
||||||
|
return nil, errors.ToRosetta(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if request.BlockIdentifier.Hash != nil && *request.BlockIdentifier.Hash != blockResponse.Block.Hash {
|
||||||
|
err := errors.WrapError(errors.ErrBadArgument, "mismatching hash")
|
||||||
return nil, errors.ToRosetta(err)
|
return nil, errors.ToRosetta(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/server/rosetta"
|
"github.com/cosmos/cosmos-sdk/server/rosetta"
|
||||||
crgserver "github.com/cosmos/cosmos-sdk/server/rosetta/lib/server"
|
crgserver "github.com/cosmos/cosmos-sdk/server/rosetta/lib/server"
|
||||||
"github.com/cosmos/cosmos-sdk/server/types"
|
"github.com/cosmos/cosmos-sdk/server/types"
|
||||||
|
sdktypes "github.com/cosmos/cosmos-sdk/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -403,16 +404,25 @@ func startInProcess(ctx *Context, clientCtx client.Context, appCreator types.App
|
||||||
offlineMode = true
|
offlineMode = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
minGasPrices, err := sdktypes.ParseDecCoins(config.MinGasPrices)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Logger.Error("failed to parse minimum-gas-prices: ", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
conf := &rosetta.Config{
|
conf := &rosetta.Config{
|
||||||
Blockchain: config.Rosetta.Blockchain,
|
Blockchain: config.Rosetta.Blockchain,
|
||||||
Network: config.Rosetta.Network,
|
Network: config.Rosetta.Network,
|
||||||
TendermintRPC: ctx.Config.RPC.ListenAddress,
|
TendermintRPC: ctx.Config.RPC.ListenAddress,
|
||||||
GRPCEndpoint: config.GRPC.Address,
|
GRPCEndpoint: config.GRPC.Address,
|
||||||
Addr: config.Rosetta.Address,
|
Addr: config.Rosetta.Address,
|
||||||
Retries: config.Rosetta.Retries,
|
Retries: config.Rosetta.Retries,
|
||||||
Offline: offlineMode,
|
Offline: offlineMode,
|
||||||
Codec: clientCtx.Codec.(*codec.ProtoCodec),
|
GasToSuggest: config.Rosetta.GasToSuggest,
|
||||||
InterfaceRegistry: clientCtx.InterfaceRegistry,
|
EnableFeeSuggestion: config.Rosetta.EnableFeeSuggestion,
|
||||||
|
SuggestPrices: minGasPrices.Sort(),
|
||||||
|
Codec: clientCtx.Codec.(*codec.ProtoCodec),
|
||||||
|
InterfaceRegistry: clientCtx.InterfaceRegistry,
|
||||||
}
|
}
|
||||||
|
|
||||||
rosettaSrv, err = rosetta.ServerFromConfig(conf)
|
rosettaSrv, err = rosetta.ServerFromConfig(conf)
|
||||||
|
|
Loading…
Reference in New Issue