From 3c104b204707d731fcf7a02de6bfcb5b702e50ee Mon Sep 17 00:00:00 2001 From: Carlos Santiago Yanzon <27785807+bizk@users.noreply.github.com> Date: Mon, 4 Sep 2023 15:18:46 -0300 Subject: [PATCH] refactor: Improvements on error handling (#29) * feat: multi zone - plugin & reflection (#5) * added plugins feature and reflection features * fixed minor sdkTx variables issue * Roll back some changes on config.go * fixed makefile build command * improvements over lint * Added nolint ant changed variable name * fix .gitworkflow build * fix .gitworkflow build * Added makefile build plugin steps * added nolint on staticcheck on load.go * added nolint on staticcheck on load.go * added nolint on staticcheck on load.go * added nolint on staticcheck on load.go * gofumpt on project * skiped a test due to reliance on an experimental feature of cosmos v0.46.0-beta * build plugin before test * build plugin before test * fixed failing test * fix make test * added docs * small refactor on variable names * Zondax/feature/multi zone fix * added plugins feature and reflection features * fixed minor sdkTx variables issue * Roll back some changes on config.go * fixed makefile build command * improvements over lint * Added nolint ant changed variable name * fix .gitworkflow build * fix .gitworkflow build * Added makefile build plugin steps * added nolint on staticcheck on load.go * added nolint on staticcheck on load.go * added nolint on staticcheck on load.go * added nolint on staticcheck on load.go * gofumpt on project * skiped a test due to reliance on an experimental feature of cosmos v0.46.0-beta * build plugin before test * build plugin before test * fixed failing test * fix make test * added docs * small refactor on variable names * Updated documentation and added --plugin flag * updated install step on README * lint fix * updated docs * updated go.sum (#8) * refactor: Upgrade rosetta to cosmos-sdk v0.50.0 (#7) * changed go.mod name, renamed dependencies on rosetta, adapted methods and uses of cosmos-sdk, upgraded dependencies * fixed all code errors * improvements over parsing * fees and gas parsing * remmoved validation on message due to deprecation (it should be validated on the server side) * solved issue on missing tx tipper * added codec types * fixed interface registre addr issue * improvements * fixed converter tests * commented plugin_test.go due to some modules not being available at v0.50 yet * improved code, moved parsing functions to utils.go * solved comments, fixed lint and added utils.go for parsing * fixed comment on cast variables * lint comments * Commented ibc-go dependdency until upgrade * added type assertion error handlinhg * updated go.sum * rename module for vanity url * update go.mod and go.sum * refactor: error handling improvements (#9) * issue on load.go * fixed tests * added client offline * client_online.go * added error handling on utils.go and unified both files * added plugins.go * added config, converter and libraries * linted and fixed issues * fixed some issues --- client_offline.go | 21 ++++----- client_online.go | 90 +++++++++++++++++++-------------------- config.go | 44 ++++++++++--------- converter.go | 40 ++++++++--------- converter_test.go | 2 +- lib/errors/errors.go | 10 +++++ lib/errors/errors_test.go | 14 +++--- load.go | 34 ++++++++------- plugins.go | 16 +++---- util.go | 43 ------------------- utils.go | 44 +++++++++++++++++-- 11 files changed, 182 insertions(+), 176 deletions(-) delete mode 100644 util.go diff --git a/client_offline.go b/client_offline.go index 75f1241..323d1da 100644 --- a/client_offline.go +++ b/client_offline.go @@ -3,6 +3,7 @@ package rosetta import ( "context" "encoding/hex" + "fmt" "github.com/coinbase/rosetta-sdk-go/types" @@ -48,17 +49,17 @@ func (c *Client) ConstructionPayload(_ context.Context, request *types.Construct tx, err := c.converter.ToSDK().UnsignedTx(request.Operations) if err != nil { - return nil, crgerrs.WrapError(crgerrs.ErrInvalidOperation, err.Error()) + return nil, crgerrs.WrapError(crgerrs.ErrOffline, fmt.Sprintf("getting unsigned tx %s", err.Error())) } metadata := new(ConstructionMetadata) if err = metadata.FromMetadata(request.Metadata); err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrOffline, fmt.Sprintf("getting metadata from request %s", err.Error())) } txBytes, payloads, err := c.converter.ToRosetta().SigningComponents(tx, metadata, request.PublicKeys) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrOffline, fmt.Sprintf("getting signed components %s", err.Error())) } return &types.ConstructionPayloadsResponse{ @@ -75,13 +76,13 @@ func (c *Client) PreprocessOperationsToOptions(_ context.Context, req *types.Con // now we need to parse the operations to cosmos sdk messages tx, err := c.converter.ToSDK().UnsignedTx(req.Operations) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrOffline, fmt.Sprintf("converting unsigned tx %s", err.Error())) } // get the signers signers, err := tx.GetSigners() if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrOffline, fmt.Sprintf("getting signers from unsigned tx %s", err.Error())) } signersStr := make([]string, len(signers)) @@ -98,15 +99,15 @@ func (c *Client) PreprocessOperationsToOptions(_ context.Context, req *types.Con meta := new(ConstructionPreprocessMetadata) err = meta.FromMetadata(req.Metadata) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrOffline, fmt.Sprintf("parsing metadata %s", err.Error())) } if meta.GasPrice == "" { - return nil, crgerrs.WrapError(crgerrs.ErrBadArgument, "no gas prices") + return nil, crgerrs.WrapError(crgerrs.ErrOffline, "no gas price") } if meta.GasLimit == 0 { - return nil, crgerrs.WrapError(crgerrs.ErrBadArgument, "no gas limit") + return nil, crgerrs.WrapError(crgerrs.ErrOffline, "no gas limit") } // prepare the options to return @@ -119,7 +120,7 @@ func (c *Client) PreprocessOperationsToOptions(_ context.Context, req *types.Con metaOptions, err := options.ToMetadata() if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrOffline, fmt.Sprintf("parsing metadata %s", err.Error())) } return &types.ConstructionPreprocessResponse{ Options: metaOptions, @@ -130,7 +131,7 @@ func (c *Client) PreprocessOperationsToOptions(_ context.Context, req *types.Con func (c *Client) AccountIdentifierFromPublicKey(pubKey *types.PublicKey) (*types.AccountIdentifier, error) { pk, err := c.converter.ToSDK().PubKey(pubKey) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("converting pub key to sdk %s", err.Error())) } return &types.AccountIdentifier{ diff --git a/client_online.go b/client_online.go index 3e2ee4f..4028b0f 100644 --- a/client_online.go +++ b/client_online.go @@ -5,7 +5,6 @@ import ( "context" "encoding/base64" "encoding/hex" - "errors" "fmt" "regexp" "strconv" @@ -103,12 +102,12 @@ func NewClient(cfg *Config) (*Client, error) { func (c *Client) Bootstrap() error { grpcConn, err := grpc.Dial(c.config.GRPCEndpoint, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { - return err + return crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("dialing grpc endpoint %s", err.Error())) } tmRPC, err := http.New(c.config.TendermintRPC, tmWebsocketPath) if err != nil { - return err + return crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting rpc path %s", err.Error())) } authClient := auth.NewQueryClient(grpcConn) @@ -127,17 +126,17 @@ func (c *Client) Ready() error { defer cancel() _, err := c.tmRPC.Health(ctx) if err != nil { - return err + return crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting grpc health %s", err.Error())) } _, err = c.tmRPC.Status(ctx) if err != nil { - return err + return crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting grpc status %s", err.Error())) } _, err = c.bank.TotalSupply(ctx, &bank.QueryTotalSupplyRequest{}) if err != nil { - return err + return crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting bank total supply %s", err.Error())) } return nil } @@ -150,11 +149,11 @@ func (c *Client) GenesisBlock(ctx context.Context) (crgtypes.BlockResponse, erro func (c *Client) InitialHeightBlock(ctx context.Context) (crgtypes.BlockResponse, error) { genesisChunk, err := c.tmRPC.GenesisChunked(ctx, 0) if err != nil { - return crgtypes.BlockResponse{}, err + return crgtypes.BlockResponse{}, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting bank total supply %s", err.Error())) } heightNum, err := extractInitialHeightFromGenesisChunk(genesisChunk.Data) if err != nil { - return crgtypes.BlockResponse{}, err + return crgtypes.BlockResponse{}, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting height from genesis chunk %s", err.Error())) } return c.BlockByHeight(ctx, &heightNum) } @@ -162,7 +161,7 @@ func (c *Client) InitialHeightBlock(ctx context.Context) (crgtypes.BlockResponse func (c *Client) OldestBlock(ctx context.Context) (crgtypes.BlockResponse, error) { status, err := c.tmRPC.Status(ctx) if err != nil { - return crgtypes.BlockResponse{}, err + return crgtypes.BlockResponse{}, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting oldest block %s", err.Error())) } return c.BlockByHeight(ctx, &status.SyncInfo.EarliestBlockHeight) } @@ -182,7 +181,7 @@ func (c *Client) accountInfo(ctx context.Context, addr string, height *int64) (* signerData, err := c.converter.ToRosetta().SignerData(accountInfo.Account) if err != nil { - return nil, err + return nil, crgerrs.FromGRPCToRosettaError(err) } return signerData, nil } @@ -202,7 +201,7 @@ func (c *Client) Balances(ctx context.Context, addr string, height *int64) ([]*r availableCoins, err := c.coins(ctx) if err != nil { - return nil, err + return nil, crgerrs.FromGRPCToRosettaError(err) } return c.converter.ToRosetta().Amounts(balance.Balances, availableCoins), nil @@ -211,12 +210,12 @@ func (c *Client) Balances(ctx context.Context, addr string, height *int64) ([]*r func (c *Client) BlockByHash(ctx context.Context, hash string) (crgtypes.BlockResponse, error) { bHash, err := hex.DecodeString(hash) if err != nil { - return crgtypes.BlockResponse{}, fmt.Errorf("invalid block hash: %s", err) + return crgtypes.BlockResponse{}, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("invalid block hash %s", err.Error())) } block, err := c.tmRPC.BlockByHash(ctx, bHash) if err != nil { - return crgtypes.BlockResponse{}, crgerrs.WrapError(crgerrs.ErrBadGateway, err.Error()) + return crgtypes.BlockResponse{}, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting block by hash %s", err.Error())) } return c.converter.ToRosetta().BlockResponse(block), nil @@ -225,7 +224,7 @@ func (c *Client) BlockByHash(ctx context.Context, hash string) (crgtypes.BlockRe func (c *Client) BlockByHeight(ctx context.Context, height *int64) (crgtypes.BlockResponse, error) { block, err := c.tmRPC.Block(ctx, height) if err != nil { - return crgtypes.BlockResponse{}, crgerrs.WrapError(crgerrs.ErrInternal, err.Error()) + return crgtypes.BlockResponse{}, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting block by height %s", err.Error())) } return c.converter.ToRosetta().BlockResponse(block), nil @@ -235,7 +234,7 @@ func (c *Client) BlockTransactionsByHash(ctx context.Context, hash string) (crgt // TODO(fdymylja): use a faster path, by searching the block by hash, instead of doing a double query operation blockResp, err := c.BlockByHash(ctx, hash) if err != nil { - return crgtypes.BlockTransactionsResponse{}, err + return crgtypes.BlockTransactionsResponse{}, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting block transactions by hash %s", err.Error())) } return c.blockTxs(ctx, &blockResp.Block.Index) @@ -244,18 +243,18 @@ func (c *Client) BlockTransactionsByHash(ctx context.Context, hash string) (crgt func (c *Client) BlockTransactionsByHeight(ctx context.Context, height *int64) (crgtypes.BlockTransactionsResponse, error) { blockTxResp, err := c.blockTxs(ctx, height) if err != nil { - return crgtypes.BlockTransactionsResponse{}, err + return crgtypes.BlockTransactionsResponse{}, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting block transactions by height %s", err.Error())) } return blockTxResp, nil } -// Coins fetches the existing coins in the application +// Coins f etches the existing coins in the application func (c *Client) coins(ctx context.Context) (sdk.Coins, error) { var result sdk.Coins supply, err := c.bank.TotalSupply(ctx, &bank.QueryTotalSupplyRequest{}) if err != nil { - return nil, crgerrs.FromGRPCToRosettaError(err) + return nil, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting coins supply %s", err.Error())) } pages := supply.GetPagination().GetTotal() @@ -263,13 +262,13 @@ func (c *Client) coins(ctx context.Context) (sdk.Coins, error) { // get next key page := supply.GetPagination() if page == nil { - return nil, crgerrs.WrapError(crgerrs.ErrCodec, "error pagination") + return nil, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting supply pagination %s", err.Error())) } nextKey := page.GetNextKey() supply, err = c.bank.TotalSupply(ctx, &bank.QueryTotalSupplyRequest{Pagination: &query.PageRequest{Key: nextKey}}) if err != nil { - return nil, crgerrs.FromGRPCToRosettaError(err) + return nil, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting supply from bank %s", err.Error())) } result = append(result[:0], supply.Supply[:]...) @@ -283,9 +282,9 @@ func (c *Client) TxOperationsAndSignersAccountIdentifiers(signed bool, txBytes [ case false: rosTx, err := c.converter.ToRosetta().Tx(txBytes, nil) if err != nil { - return nil, nil, err + return nil, nil, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting rosseta Tx format %s", err.Error())) } - return rosTx.Operations, nil, err + return rosTx.Operations, nil, nil default: ops, signers, err = c.converter.ToRosetta().OpsAndSigners(txBytes) return @@ -298,7 +297,7 @@ func (c *Client) TxOperationsAndSignersAccountIdentifiers(signed bool, txBytes [ func (c *Client) GetTx(ctx context.Context, hash string) (*rosettatypes.Transaction, error) { hashBytes, err := hex.DecodeString(hash) if err != nil { - return nil, crgerrs.WrapError(crgerrs.ErrCodec, fmt.Sprintf("bad tx hash: %s", err)) + return nil, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("bad tx hash %s", err.Error())) } // get tx type and hash @@ -311,13 +310,13 @@ func (c *Client) GetTx(ctx context.Context, hash string) (*rosettatypes.Transact // get block height by hash block, err := c.tmRPC.BlockByHash(ctx, hashBytes) if err != nil { - return nil, crgerrs.WrapError(crgerrs.ErrUnknown, err.Error()) + return nil, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting block by hash %s", err.Error())) } // get block txs fullBlock, err := c.blockTxs(ctx, &block.Block.Height) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting block tx %s", err.Error())) } return fullBlock.Transactions[0], nil @@ -325,7 +324,7 @@ func (c *Client) GetTx(ctx context.Context, hash string) (*rosettatypes.Transact case DeliverTxTx: rawTx, err := c.tmRPC.Tx(ctx, hashBytes, true) if err != nil { - return nil, crgerrs.WrapError(crgerrs.ErrUnknown, err.Error()) + return nil, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting tx %s", err.Error())) } return c.converter.ToRosetta().Tx(rawTx.Tx, &rawTx.TxResult) // handle end block hash @@ -333,13 +332,13 @@ func (c *Client) GetTx(ctx context.Context, hash string) (*rosettatypes.Transact // get block height by hash block, err := c.tmRPC.BlockByHash(ctx, hashBytes) if err != nil { - return nil, crgerrs.WrapError(crgerrs.ErrUnknown, err.Error()) + return nil, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting block by hash %s", err.Error())) } // get block txs fullBlock, err := c.blockTxs(ctx, &block.Block.Height) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting block by hash %s", err.Error())) } // get last tx @@ -354,12 +353,12 @@ func (c *Client) GetTx(ctx context.Context, hash string) (*rosettatypes.Transact func (c *Client) GetUnconfirmedTx(ctx context.Context, hash string) (*rosettatypes.Transaction, error) { res, err := c.tmRPC.UnconfirmedTxs(ctx, nil) if err != nil { - return nil, crgerrs.WrapError(crgerrs.ErrNotFound, "unconfirmed tx not found") + return nil, crgerrs.WrapError(crgerrs.ErrNotFound, fmt.Sprintf("unconfirmed tx not found %s", err.Error())) } hashAsBytes, err := hex.DecodeString(hash) if err != nil { - return nil, crgerrs.WrapError(crgerrs.ErrInterpreting, "invalid hash") + return nil, crgerrs.WrapError(crgerrs.ErrCodec, fmt.Sprintf("invalid hash %s", err.Error())) } // assert that correct tx length is provided @@ -387,7 +386,7 @@ func (c *Client) GetUnconfirmedTx(ctx context.Context, hash string) (*rosettatyp func (c *Client) Mempool(ctx context.Context) ([]*rosettatypes.TransactionIdentifier, error) { txs, err := c.tmRPC.UnconfirmedTxs(ctx, nil) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting unconfirmed tx %s", err.Error())) } return c.converter.ToRosetta().TxIdentifiers(txs.Txs), nil @@ -397,7 +396,7 @@ func (c *Client) Mempool(ctx context.Context) ([]*rosettatypes.TransactionIdenti func (c *Client) Peers(ctx context.Context) ([]*rosettatypes.Peer, error) { netInfo, err := c.tmRPC.NetInfo(ctx) if err != nil { - return nil, crgerrs.WrapError(crgerrs.ErrUnknown, err.Error()) + return nil, crgerrs.WrapError(crgerrs.ErrOnlineClient, "getting network information "+err.Error()) } return c.converter.ToRosetta().Peers(netInfo.Peers), nil } @@ -405,7 +404,7 @@ func (c *Client) Peers(ctx context.Context) ([]*rosettatypes.Peer, error) { func (c *Client) Status(ctx context.Context) (*rosettatypes.SyncStatus, error) { status, err := c.tmRPC.Status(ctx) if err != nil { - return nil, crgerrs.WrapError(crgerrs.ErrUnknown, err.Error()) + return nil, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting network information %s", err.Error())) } return c.converter.ToRosetta().SyncStatus(status), err } @@ -414,7 +413,7 @@ func (c *Client) PostTx(txBytes []byte) (*rosettatypes.TransactionIdentifier, ma // sync ensures it will go through checkTx res, err := c.tmRPC.BroadcastTxSync(context.Background(), txBytes) if err != nil { - return nil, nil, crgerrs.WrapError(crgerrs.ErrUnknown, err.Error()) + return nil, nil, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting BroadcastTxSync %s", err.Error())) } // check if tx was broadcast successfully if res.Code != abcitypes.CodeTypeOK { @@ -437,14 +436,14 @@ func (c *Client) PostTx(txBytes []byte) (*rosettatypes.TransactionIdentifier, ma // ConstructionMetadataFromOptions builds the metadata given the options func (c *Client) ConstructionMetadataFromOptions(ctx context.Context, options map[string]interface{}) (meta map[string]interface{}, err error) { if len(options) == 0 { - return nil, crgerrs.ErrBadArgument + return nil, crgerrs.WrapError(crgerrs.ErrBadArgument, "options length is 0") } constructionOptions := new(PreprocessOperationsOptionsResponse) err = constructionOptions.FromMetadata(options) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrBadArgument, fmt.Sprintf("getting metadata %s", err.Error())) } // if default fees suggestion is enabled and gas limit or price is unset, use default @@ -461,7 +460,7 @@ func (c *Client) ConstructionMetadataFromOptions(ctx context.Context, options ma if constructionOptions.GasLimit > 0 && constructionOptions.GasPrice != "" { gasPrice, err := sdk.ParseDecCoin(constructionOptions.GasPrice) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("parsing gas price %s", err.Error())) } if !gasPrice.IsPositive() { return nil, crgerrs.WrapError(crgerrs.ErrBadArgument, "gas price must be positive") @@ -473,7 +472,7 @@ func (c *Client) ConstructionMetadataFromOptions(ctx context.Context, options ma for i, signer := range constructionOptions.ExpectedSigners { accountInfo, err := c.accountInfo(ctx, signer, nil) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting account info %s", err.Error())) } signersData[i] = accountInfo @@ -481,7 +480,7 @@ func (c *Client) ConstructionMetadataFromOptions(ctx context.Context, options ma status, err := c.tmRPC.Status(ctx) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting rpc status %s", err.Error())) } metadataResp := ConstructionMetadata{ @@ -499,17 +498,16 @@ func (c *Client) blockTxs(ctx context.Context, height *int64) (crgtypes.BlockTra // get block info blockInfo, err := c.tmRPC.Block(ctx, height) if err != nil { - return crgtypes.BlockTransactionsResponse{}, err + return crgtypes.BlockTransactionsResponse{}, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting rpc block %s", err.Error())) } // get block events blockResults, err := c.tmRPC.BlockResults(ctx, height) if err != nil { - return crgtypes.BlockTransactionsResponse{}, err + return crgtypes.BlockTransactionsResponse{}, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting rpc block results %s", err.Error())) } if len(blockResults.TxsResults) != len(blockInfo.Block.Txs) { - // wtf? - panic("block results transactions do now match block transactions") + return crgtypes.BlockTransactionsResponse{}, crgerrs.WrapError(crgerrs.ErrOnlineClient, "block results transactions do now match block transactions") } // process begin and end block txs beginBlockTx := &rosettatypes.Transaction{ @@ -533,7 +531,7 @@ func (c *Client) blockTxs(ctx context.Context, height *int64) (crgtypes.BlockTra for i, tx := range blockInfo.Block.Txs { rosTx, err := c.converter.ToRosetta().Tx(tx, blockResults.TxsResults[i]) if err != nil { - return crgtypes.BlockTransactionsResponse{}, err + return crgtypes.BlockTransactionsResponse{}, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting rosetta tx %s", err.Error())) } deliverTx[i] = rosTx } @@ -554,12 +552,12 @@ var initialHeightRE = regexp.MustCompile(`"initial_height":"(\d+)"`) func extractInitialHeightFromGenesisChunk(genesisChunk string) (int64, error) { firstChunk, err := base64.StdEncoding.DecodeString(genesisChunk) if err != nil { - return 0, err + return 0, crgerrs.WrapError(crgerrs.ErrOnlineClient, fmt.Sprintf("getting first chunk %s", err.Error())) } matches := initialHeightRE.FindStringSubmatch(string(firstChunk)) if len(matches) != 2 { - return 0, errors.New("failed to fetch initial_height") + return 0, crgerrs.WrapError(crgerrs.ErrOnlineClient, "failed to fetch initial_height") } heightStr := matches[1] diff --git a/config.go b/config.go index b5f9d18..395f99f 100644 --- a/config.go +++ b/config.go @@ -5,6 +5,8 @@ import ( "strings" "time" + crgerrs "github.com/cosmos/rosetta/lib/errors" + "github.com/coinbase/rosetta-sdk-go/types" "github.com/spf13/pflag" @@ -109,7 +111,7 @@ func (c *Config) NetworkIdentifier() *types.NetworkIdentifier { // its defaults in case they were not provided func (c *Config) validate() error { if (c.Codec == nil) != (c.InterfaceRegistry == nil) { - return fmt.Errorf("codec and interface registry must be both different from nil or nil") + return crgerrs.WrapError(crgerrs.ErrConfig, "codec and interface registry must be both different from nil or nil") } if c.Addr == "" { @@ -123,10 +125,10 @@ func (c *Config) validate() error { } // these are must if c.Network == "" { - return fmt.Errorf("network not provided") + return crgerrs.WrapError(crgerrs.ErrConfig, "network not provided") } if c.GasToSuggest <= 0 { - return fmt.Errorf("gas to suggest must be positive") + return crgerrs.WrapError(crgerrs.ErrConfig, "gas to suggest must be positive") } if c.EnableFeeSuggestion { found := false @@ -137,16 +139,16 @@ func (c *Config) validate() error { } } if !found { - return fmt.Errorf("default suggest denom is not found in prices to suggest") + return crgerrs.WrapError(crgerrs.ErrConfig, "default suggest denom is not found in prices to suggest") } } // these are optional but it must be online if c.GRPCEndpoint == "" { - return fmt.Errorf("grpc endpoint not provided") + return crgerrs.WrapError(crgerrs.ErrConfig, "grpc endpoint not provided") } if c.TendermintRPC == "" { - return fmt.Errorf("cometbft rpc not provided") + return crgerrs.WrapError(crgerrs.ErrConfig, "cometbft rpc not provided") } if !strings.HasPrefix(c.TendermintRPC, "tcp://") { c.TendermintRPC = fmt.Sprintf("tcp://%s", c.TendermintRPC) @@ -165,54 +167,54 @@ func (c *Config) WithCodec(ir codectypes.InterfaceRegistry, cdc *codec.ProtoCode func FromFlags(flags *pflag.FlagSet) (*Config, error) { blockchain, err := flags.GetString(FlagBlockchain) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConfig, fmt.Sprintf("while getting blockchain flag %s", err.Error())) } network, err := flags.GetString(FlagNetwork) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConfig, fmt.Sprintf("while getting network flag %s", err.Error())) } tendermintRPC, err := flags.GetString(FlagTendermintEndpoint) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConfig, fmt.Sprintf("while getting tendermintRPC flag %s", err.Error())) } gRPCEndpoint, err := flags.GetString(FlagGRPCEndpoint) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConfig, fmt.Sprintf("while getting gRPCEndpoint flag %s", err.Error())) } addr, err := flags.GetString(FlagAddr) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConfig, fmt.Sprintf("while getting addr flag %s", err.Error())) } retries, err := flags.GetInt(FlagRetries) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConfig, fmt.Sprintf("while getting retries flag %s", err.Error())) } offline, err := flags.GetBool(FlagOffline) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConfig, fmt.Sprintf("while getting offline flag %s", err.Error())) } enableDefaultFeeSuggestion, err := flags.GetBool(FlagEnableFeeSuggestion) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConfig, fmt.Sprintf("while getting enableDefaultFeeSuggestion flag %s", err.Error())) } gasToSuggest, err := flags.GetInt(FlagGasToSuggest) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConfig, fmt.Sprintf("while getting gasToSuggest flag %s", err.Error())) } denomToSuggest, err := flags.GetString(FlagDenomToSuggest) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConfig, fmt.Sprintf("while getting denomToSuggest flag %s", err.Error())) } var prices sdk.DecCoins if enableDefaultFeeSuggestion { pricesToSuggest, err := flags.GetString(FlagPricesToSuggest) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConfig, fmt.Sprintf("while getting pricesToSuggest flag %s", err.Error())) } prices, err = sdk.ParseDecCoins(pricesToSuggest) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConfig, fmt.Sprintf("while parcing prices from the sdk %s", err.Error())) } } @@ -231,7 +233,7 @@ func FromFlags(flags *pflag.FlagSet) (*Config, error) { } err = conf.validate() if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConfig, fmt.Sprintf("while validating configs %s", err.Error())) } return conf, nil } @@ -239,11 +241,11 @@ func FromFlags(flags *pflag.FlagSet) (*Config, error) { func ServerFromConfig(conf *Config) (crg.Server, error) { err := conf.validate() if err != nil { - return crg.Server{}, err + return crg.Server{}, crgerrs.WrapError(crgerrs.ErrConfig, fmt.Sprintf("while validating configs %s", err.Error())) } client, err := NewClient(conf) if err != nil { - return crg.Server{}, err + return crg.Server{}, crgerrs.WrapError(crgerrs.ErrConfig, fmt.Sprintf("while creating a new client from configs %s", err.Error())) } return crg.NewServer( crg.Settings{ diff --git a/converter.go b/converter.go index f483161..dc2eae9 100644 --- a/converter.go +++ b/converter.go @@ -121,12 +121,12 @@ func NewConverter(cdc *codec.ProtoCodec, ir codectypes.InterfaceRegistry, cfg sd parsedSignerData := parseSignerData(signerData) txData, err := parseTxData(tx, parsedSignerData) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("while getting tx data %s", err.Error())) } bytesToSign, err := cfg.SignModeHandler().GetSignBytes(context.TODO(), signingv1beta1.SignMode(signing.SignMode_SIGN_MODE_DIRECT), parsedSignerData, *txData) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("while getting bytes to sign %s", err.Error())) } return crypto.Sha256(bytesToSign), nil @@ -216,7 +216,7 @@ func (c converter) UnsignedTx(ops []*rosettatypes.Operation) (tx authsigning.Tx, func (c converter) Msg(meta map[string]interface{}, msg sdk.Msg) error { metaBytes, err := json.Marshal(meta) if err != nil { - return err + return crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("while marshaling meta to json %s", err.Error())) } return c.cdc.UnmarshalJSON(metaBytes, msg) } @@ -243,7 +243,7 @@ func (c converter) Ops(status string, msg sdk.Msg) ([]*rosettatypes.Operation, e meta, err := c.Meta(msg) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("while getting meta from message %s", err.Error())) } legacyMsg, ok := msg.(sdk.LegacyMsg) @@ -296,7 +296,7 @@ func (c converter) Tx(rawTx cmttypes.Tx, txResult *abci.ExecTxResult) (*rosettat for _, msg := range msgs { ops, err := c.Ops(status, msg) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("while getting operations from status and msg %s", err.Error())) } rawTxOps = append(rawTxOps, ops...) } @@ -592,17 +592,17 @@ func (c converter) OpsAndSigners(txBytes []byte) (ops []*rosettatypes.Operation, // get the signers sdkTx, err := c.txDecode(txBytes) if err != nil { - return nil, nil, crgerrs.WrapError(crgerrs.ErrCodec, err.Error()) + return nil, nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("getting tx encoder %s", err.Error())) } txBuilder, err := c.txBuilderFromTx(sdkTx) if err != nil { - return nil, nil, crgerrs.WrapError(crgerrs.ErrCodec, err.Error()) + return nil, nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("getting tx builder %s", err.Error())) } txSigners, err := txBuilder.GetTx().GetSigners() if err != nil { - return nil, nil, crgerrs.WrapError(crgerrs.ErrCodec, err.Error()) + return nil, nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("getting tx signers %s", err.Error())) } for _, signer := range txSigners { @@ -617,17 +617,17 @@ func (c converter) OpsAndSigners(txBytes []byte) (ops []*rosettatypes.Operation, func (c converter) SignedTx(txBytes []byte, signatures []*rosettatypes.Signature) (signedTxBytes []byte, err error) { rawTx, err := c.txDecode(txBytes) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("while decoding tx from bytes %s", err.Error())) } txBuilder, err := c.txBuilderFromTx(rawTx) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("getting tx bytes from tx %s", err.Error())) } notSignedSigs, err := txBuilder.GetTx().GetSignaturesV2() // if err != nil { - return nil, crgerrs.WrapError(crgerrs.ErrCodec, err.Error()) + return nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("getting signatures from tx %s", err.Error())) } if len(notSignedSigs) != len(signatures) { @@ -650,12 +650,12 @@ func (c converter) SignedTx(txBytes []byte, signatures []*rosettatypes.Signature } if err = txBuilder.SetSignatures(signedSigs...); err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("while setting signatures %s", err.Error())) } txBytes, err = c.txEncode(txBuilder.GetTx()) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("getting bytes from tx %s", err.Error())) } return txBytes, nil @@ -684,12 +684,12 @@ func (c converter) SigningComponents(tx authsigning.Tx, metadata *ConstructionMe // verify metadata correctness feeAmount, err := sdk.ParseCoinsNormalized(metadata.GasPrice) if err != nil { - return nil, nil, crgerrs.WrapError(crgerrs.ErrBadArgument, err.Error()) + return nil, nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("getting signers v2 from tx %s", err.Error())) } signers, err := tx.GetSignaturesV2() if err != nil { - return nil, nil, crgerrs.WrapError(crgerrs.ErrBadArgument, err.Error()) + return nil, nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("getting signers v2 from tx %s", err.Error())) } // assert the signers data provided in options are the same as the expected signing accounts @@ -701,7 +701,7 @@ func (c converter) SigningComponents(tx authsigning.Tx, metadata *ConstructionMe // add transaction metadata builder, err := c.txBuilderFromTx(tx) if err != nil { - return nil, nil, crgerrs.WrapError(crgerrs.ErrCodec, err.Error()) + return nil, nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("getting tx builder %s", err.Error())) } builder.SetFeeAmount(feeAmount) builder.SetGasLimit(metadata.GasLimit) @@ -717,7 +717,7 @@ func (c converter) SigningComponents(tx authsigning.Tx, metadata *ConstructionMe // by checking if the signer at index i matches the pubkey at index pubKey, err := c.ToSDK().PubKey(rosPubKeys[0]) if err != nil { - return nil, nil, err + return nil, nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("while setting signatures %s", err.Error())) } if !bytes.Equal(pubKey.Address().Bytes(), signer.PubKey.Address()) { return nil, nil, crgerrs.WrapError( @@ -764,13 +764,13 @@ func (c converter) SigningComponents(tx authsigning.Tx, metadata *ConstructionMe // information of each account in a stateless way err = builder.SetSignatures(partialSignatures...) if err != nil { - return nil, nil, crgerrs.WrapError(crgerrs.ErrCodec, err.Error()) + return nil, nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("while setting signatures %s", err.Error())) } // finally encode the tx txBytes, err = c.txEncode(builder.GetTx()) if err != nil { - return nil, nil, crgerrs.WrapError(crgerrs.ErrCodec, err.Error()) + return nil, nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("while encoding tx %s", err.Error())) } return txBytes, payloadsToSign, nil @@ -781,7 +781,7 @@ func (c converter) SignerData(anyAccount *codectypes.Any) (*SignerData, error) { var acc sdkclient.Account err := c.ir.UnpackAny(anyAccount, &acc) if err != nil { - return nil, crgerrs.WrapError(crgerrs.ErrCodec, err.Error()) + return nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("while unpacking an account %s", err.Error())) } return &SignerData{ diff --git a/converter_test.go b/converter_test.go index 07528db..0e1dbb6 100644 --- a/converter_test.go +++ b/converter_test.go @@ -223,7 +223,7 @@ func (s *ConverterTestSuite) TestBeginEndBlockAndHashToTxType() { func (s *ConverterTestSuite) TestSigningComponents() { s.Run("invalid metadata coins", func() { _, _, err := s.c.ToRosetta().SigningComponents(nil, &rosetta.ConstructionMetadata{GasPrice: "invalid"}, nil) - s.Require().ErrorIs(err, crgerrs.ErrBadArgument) + s.Require().ErrorIs(err, crgerrs.ErrConverter) }) s.Run("length signers data does not match signers", func() { diff --git a/lib/errors/errors.go b/lib/errors/errors.go index 4ad034f..c406618 100644 --- a/lib/errors/errors.go +++ b/lib/errors/errors.go @@ -160,4 +160,14 @@ var ( ErrNotImplemented = RegisterError(14, "not implemented", false, "returned when querying an endpoint which is not implemented") // ErrUnsupportedCurve is returned when the curve specified is not supported ErrUnsupportedCurve = RegisterError(15, "unsupported curve, expected secp256k1", false, "returned when using an unsupported crypto curve") + // ErrPlugin is returned when using a plugin + ErrPlugin = RegisterError(16, "error on plugin", false, "returned when using a plugin") + // ErrClient is returned when there is an error with the client + ErrClient = RegisterError(17, "error on client operation", false, "returned when there is an error with the client") + // ErrConverter is returned when there is an error with the converter + ErrConverter = RegisterError(18, "error on converter operation", false, "returned when there is an error with the client") + // ErrOnlineClient is returned when there is an error with the online client + ErrOnlineClient = RegisterError(171, "error on online client operation", false, "returned when there is an error with the client") + // ErrConfig is returned when there is an error on the config + ErrConfig = RegisterError(19, "error on config operation", false, "returned when there is an error on the config") ) diff --git a/lib/errors/errors_test.go b/lib/errors/errors_test.go index 6b9ed60..a7dbfde 100644 --- a/lib/errors/errors_test.go +++ b/lib/errors/errors_test.go @@ -8,14 +8,14 @@ import ( ) func TestRegisterError(t *testing.T) { - var error *Error + var err *Error // this is the number of errors registered by cosmos-hub in errors.go - registeredErrorsCount := 16 - assert.Equal(t, len(registry.list()), registeredErrorsCount) + registeredErrorsCount := 21 + assert.Equal(t, registeredErrorsCount, len(registry.list())) assert.ElementsMatch(t, registry.list(), ListErrors()) // add a new Error - error = RegisterError(69, "nice!", false, "nice!") - assert.NotNil(t, error) + err = RegisterError(69, "nice!", false, "nice!") + assert.NotNil(t, err) // now we have a new error registeredErrorsCount++ assert.Equal(t, len(ListErrors()), registeredErrorsCount) @@ -29,8 +29,8 @@ func TestRegisterError(t *testing.T) { assert.Equal(t, registry.sealed, true) assert.Equal(t, len(errors), registeredErrorsCount) // add a new error on a sealed registry - error = RegisterError(1024, "bytes", false, "bytes") - assert.NotNil(t, error) + err = RegisterError(1024, "bytes", false, "bytes") + assert.NotNil(t, err) } func TestError_Error(t *testing.T) { diff --git a/load.go b/load.go index 3463729..61b3f41 100644 --- a/load.go +++ b/load.go @@ -8,6 +8,8 @@ import ( "io" "strings" + crgerrs "github.com/cosmos/rosetta/lib/errors" + reflectionv1beta1 "cosmossdk.io/api/cosmos/base/reflection/v1beta1" codectypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -22,12 +24,12 @@ func ReflectInterfaces(ir codectypes.InterfaceRegistry, endpoint string) (err er ctx := context.Background() client, err := openClient(endpoint) if err != nil { - return err + return crgerrs.WrapError(crgerrs.ErrClient, fmt.Sprintf("While opening client %s", err.Error())) } fdSet, err := getFileDescriptorSet(ctx, client) if err != nil { - return err + return crgerrs.WrapError(crgerrs.ErrClient, fmt.Sprintf("While getting file descriptor set %s", err.Error())) } for _, descriptorProto := range fdSet.File { @@ -35,7 +37,7 @@ func ReflectInterfaces(ir codectypes.InterfaceRegistry, endpoint string) (err er registerProtoInterface(ir, descriptorProto) } } - return err + return nil } func openClient(endpoint string) (client *grpc.ClientConn, err error) { @@ -45,10 +47,9 @@ func openClient(endpoint string) (client *grpc.ClientConn, err error) { client, err = grpc.Dial(endpoint, grpc.WithTransportCredentials(tlsCredentials)) if err != nil { - fmt.Println("[ERROR] getting grpc client connection") - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrClient, fmt.Sprintf("getting grpc client connection %s", err.Error())) } - return client, err + return client, nil } func getFileDescriptorSet(c context.Context, client *grpc.ClientConn) (fdSet *descriptorpb.FileDescriptorSet, err error) { @@ -56,12 +57,12 @@ func getFileDescriptorSet(c context.Context, client *grpc.ClientConn) (fdSet *de interfaceImplNames, err := getInterfaceImplNames(c, client) if err != nil { - return fdSet, err + return fdSet, crgerrs.WrapError(crgerrs.ErrClient, fmt.Sprintf("unable to initialize files descriptor set %s", err.Error())) } reflectClient, err := grpc_reflection_v1alpha.NewServerReflectionClient(client).ServerReflectionInfo(c) if err != nil { - return fdSet, err + return fdSet, crgerrs.WrapError(crgerrs.ErrClient, fmt.Sprintf("while generating reflection client %s", err.Error())) } fdMap := map[string]*descriptorpb.FileDescriptorProto{} @@ -143,15 +144,16 @@ func getFileDescriptorSet(c context.Context, client *grpc.ClientConn) (fdSet *de func getInterfaceImplNames(c context.Context, client *grpc.ClientConn) (interfaceImplNames []string, err error) { cosmosReflectBetaClient := reflectionv1beta1.NewReflectionServiceClient(client) interfacesRes, err := cosmosReflectBetaClient.ListAllInterfaces(c, &reflectionv1beta1.ListAllInterfacesRequest{}) + if err != nil { + return nil, crgerrs.WrapError(crgerrs.ErrClient, fmt.Sprintf("listing client registered interfaces %s", err.Error())) + } - if err == nil { - for _, iface := range interfacesRes.InterfaceNames { - implRes, err := cosmosReflectBetaClient.ListImplementations(c, &reflectionv1beta1.ListImplementationsRequest{ - InterfaceName: iface, - }) - if err == nil { - interfaceImplNames = append(interfaceImplNames, cleanImplMsgNames(implRes.GetImplementationMessageNames())...) - } + for _, iface := range interfacesRes.InterfaceNames { + implRes, err := cosmosReflectBetaClient.ListImplementations(c, &reflectionv1beta1.ListImplementationsRequest{ + InterfaceName: iface, + }) + if err == nil { + interfaceImplNames = append(interfaceImplNames, cleanImplMsgNames(implRes.GetImplementationMessageNames())...) } } return interfaceImplNames, err diff --git a/plugins.go b/plugins.go index cc2ce00..858dd99 100644 --- a/plugins.go +++ b/plugins.go @@ -5,6 +5,8 @@ import ( "os" "plugin" + crgerrs "github.com/cosmos/rosetta/lib/errors" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" ) @@ -12,30 +14,26 @@ func LoadPlugin(ir codectypes.InterfaceRegistry, pluginLocation string) (err err pluginPathMain := fmt.Sprintf("./plugins/%s/main.so", pluginLocation) if _, err := os.Stat(pluginPathMain); os.IsExist(err) { - fmt.Printf("Plugin file '%s' does not exist...\n", pluginPathMain) - return err + return crgerrs.WrapError(crgerrs.ErrPlugin, fmt.Sprintf("Plugin file '%s' does not exist %s", pluginPathMain, err.Error())) } // load module plug, err := plugin.Open(pluginPathMain) if err != nil { - fmt.Println("There was an error while opening the plugin...", err) - return err + return crgerrs.WrapError(crgerrs.ErrPlugin, fmt.Sprintf("There was an error while opening plugin on %s - %s", pluginPathMain, err.Error())) } initZone, err := plug.Lookup("InitZone") if err != nil { - fmt.Println("There was an error while initializing the zone.", err) - return err + return crgerrs.WrapError(crgerrs.ErrPlugin, fmt.Sprintf("There was an error while initializing the zone %s", err.Error())) } initZone.(func())() registerInterfaces, err := plug.Lookup("RegisterInterfaces") if err != nil { - fmt.Println("There was an error while registering interfaces...", err) - return err + return crgerrs.WrapError(crgerrs.ErrPlugin, fmt.Sprintf("There was an error while registering interfaces %s", err.Error())) } registerInterfaces.(func(codectypes.InterfaceRegistry))(ir) - return err + return nil } diff --git a/util.go b/util.go deleted file mode 100644 index ec95311..0000000 --- a/util.go +++ /dev/null @@ -1,43 +0,0 @@ -package rosetta - -import ( - "encoding/json" - "time" - - crgerrs "github.com/cosmos/rosetta/lib/errors" -) - -// timeToMilliseconds converts time to milliseconds timestamp -func timeToMilliseconds(t time.Time) int64 { - return t.UnixNano() / (int64(time.Millisecond) / int64(time.Nanosecond)) -} - -// unmarshalMetadata unmarshals the given meta to the target -func unmarshalMetadata(meta map[string]interface{}, target interface{}) error { - b, err := json.Marshal(meta) - if err != nil { - return crgerrs.WrapError(crgerrs.ErrCodec, err.Error()) - } - - err = json.Unmarshal(b, target) - if err != nil { - return crgerrs.WrapError(crgerrs.ErrCodec, err.Error()) - } - - return nil -} - -// marshalMetadata marshals the given interface to map[string]interface{} -func marshalMetadata(o interface{}) (meta map[string]interface{}, err error) { - b, err := json.Marshal(o) - if err != nil { - return nil, crgerrs.WrapError(crgerrs.ErrCodec, err.Error()) - } - meta = make(map[string]interface{}) - err = json.Unmarshal(b, &meta) - if err != nil { - return nil, err - } - - return -} diff --git a/utils.go b/utils.go index f32a353..86f0c5e 100644 --- a/utils.go +++ b/utils.go @@ -1,7 +1,10 @@ package rosetta import ( + "encoding/json" + "fmt" "strconv" + "time" v1beta1 "cosmossdk.io/api/cosmos/base/v1beta1" txv1beta1 "cosmossdk.io/api/cosmos/tx/v1beta1" @@ -13,6 +16,41 @@ import ( crgerrs "github.com/cosmos/rosetta/lib/errors" ) +// timeToMilliseconds converts time to milliseconds timestamp +func timeToMilliseconds(t time.Time) int64 { + return t.UnixNano() / (int64(time.Millisecond) / int64(time.Nanosecond)) +} + +// unmarshalMetadata unmarshals the given meta to the target +func unmarshalMetadata(meta map[string]interface{}, target interface{}) error { + b, err := json.Marshal(meta) + if err != nil { + return crgerrs.WrapError(crgerrs.ErrCodec, fmt.Sprintf("marshaling meta on json %s", err.Error())) + } + + err = json.Unmarshal(b, target) + if err != nil { + return crgerrs.WrapError(crgerrs.ErrCodec, fmt.Sprintf("unmarshaling json target %s", err.Error())) + } + + return nil +} + +// marshalMetadata marshals the given interface to map[string]interface{} +func marshalMetadata(o interface{}) (meta map[string]interface{}, err error) { + b, err := json.Marshal(o) + if err != nil { + return nil, crgerrs.WrapError(crgerrs.ErrCodec, fmt.Sprintf("marshaling object into json %s", err.Error())) + } + meta = make(map[string]interface{}) + err = json.Unmarshal(b, &meta) + if err != nil { + return nil, crgerrs.WrapError(crgerrs.ErrCodec, fmt.Sprintf("unmarshaling json into meta %s", err.Error())) + } + + return +} + func parseSignerData(signerData authsigning.SignerData) signing2.SignerData { parsedSignerDataPublicKey := anypb.Any{ TypeUrl: sdk.MsgTypeURL(signerData.PubKey), @@ -57,7 +95,7 @@ func parseTxMessages(tx authsigning.Tx) ([]*anypb.Any, error) { txPubKeys, err := tx.GetPubKeys() if err != nil { - return nil, crgerrs.WrapError(crgerrs.ErrBadArgument, "Error on parsing TxData: ") + return nil, crgerrs.WrapError(crgerrs.ErrBadArgument, fmt.Sprintf("Getting pub keys from tx %s", err.Error())) } for _, txPubKey := range txPubKeys { parsedPubKey := anypb.Any{ @@ -101,7 +139,7 @@ func parseAuthInfo(tx authsigning.Tx, signerData signing2.SignerData) *txv1beta1 func parseTxData(tx authsigning.Tx, signerData signing2.SignerData) (*signing2.TxData, error) { parsedTxMsgs, err := parseTxMessages(tx) if err != nil { - return nil, err + return nil, crgerrs.WrapError(crgerrs.ErrCodec, fmt.Sprintf("parsing tx data %s", err.Error())) } txData := signing2.TxData{ @@ -118,5 +156,5 @@ func parseTxData(tx authsigning.Tx, signerData signing2.SignerData) (*signing2.T BodyHasUnknownNonCriticals: false, } - return &txData, err + return &txData, nil }