Skip to content

Commit

Permalink
refactor: cosmos-sdk v0.50 upgrade and multi zone enhancements (#27)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
bizk committed Sep 1, 2023
1 parent 1d6db57 commit f4f74b4
Show file tree
Hide file tree
Showing 25 changed files with 2,693 additions and 266 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Rosetta can be executed as a standalone service, it connects to the node endpoin
Install Rosetta standalone server with the following command:

```bash
go install cosmossdk.io/tools/rosetta
go install github.com/cosmos/rosetta
```

Alternatively, for building from source, simply run `make rosetta`. The binary will be located in the root folder.
Expand All @@ -27,7 +27,7 @@ To enable Native Rosetta API support, it's required to add the `RosettaCommand`
Import the `rosettaCmd` package:

```go
import "cosmossdk.io/tools/rosetta/cmd"
import "github.com/cosmos/rosetta/cmd"
```

Find the following line:
Expand All @@ -44,7 +44,7 @@ rootCmd.AddCommand(
)
```

The `RosettaCommand` function builds the `rosetta` root command and is defined in the `rosettaCmd` package (`cosmossdk.io/tools/rosetta/cmd`).
The `RosettaCommand` function builds the `rosetta` root command and is defined in the `rosettaCmd` package (`github.com/cosmos/rosetta/cmd`).

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.

Expand Down Expand Up @@ -109,7 +109,7 @@ import (

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

// CustomClient embeds the standard cosmos client
Expand All @@ -135,7 +135,7 @@ Example:

```go
package custom_errors
import crgerrs "cosmossdk.io/tools/rosetta/lib/errors"
import crgerrs "github.com/cosmos/rosetta/lib/errors"

var customErrRetriable = true
var CustomError = crgerrs.RegisterError(100, "custom message", customErrRetriable, "description")
Expand Down
14 changes: 9 additions & 5 deletions client_offline.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

"github.com/coinbase/rosetta-sdk-go/types"

crgerrs "cosmossdk.io/tools/rosetta/lib/errors"
crgerrs "github.com/cosmos/rosetta/lib/errors"

sdk "github.com/cosmos/cosmos-sdk/types"
)
Expand Down Expand Up @@ -79,15 +79,19 @@ func (c *Client) PreprocessOperationsToOptions(_ context.Context, req *types.Con
}

// get the signers
signers := tx.GetSigners()
signers, err := tx.GetSigners()
if err != nil {
return nil, err
}

signersStr := make([]string, len(signers))
accountIdentifiers := make([]*types.AccountIdentifier, len(signers))

for i, sig := range signers {
addr := sig.String()
signersStr[i] = addr
addr := sdk.AccAddress(sig)
signersStr[i] = addr.String()
accountIdentifiers[i] = &types.AccountIdentifier{
Address: addr,
Address: addr.String(),
}
}
// get the metadata request information
Expand Down
14 changes: 6 additions & 8 deletions client_online.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import (
"github.com/cometbft/cometbft/rpc/client/http"
"google.golang.org/grpc"

crgerrs "cosmossdk.io/tools/rosetta/lib/errors"
crgtypes "cosmossdk.io/tools/rosetta/lib/types"
crgerrs "github.com/cosmos/rosetta/lib/errors"
crgtypes "github.com/cosmos/rosetta/lib/types"

sdk "github.com/cosmos/cosmos-sdk/types"
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
Expand Down Expand Up @@ -71,14 +71,12 @@ func NewClient(cfg *Config) (*Client, error) {

var supportedOperations []string
for _, ii := range cfg.InterfaceRegistry.ListImplementations(sdk.MsgInterfaceProtoName) {
resolvedMsg, err := cfg.InterfaceRegistry.Resolve(ii)
_, err := cfg.InterfaceRegistry.Resolve(ii)
if err != nil {
continue
}

if _, ok := resolvedMsg.(sdk.Msg); ok {
supportedOperations = append(supportedOperations, ii)
}
supportedOperations = append(supportedOperations, ii)
}

supportedOperations = append(
Expand Down Expand Up @@ -518,15 +516,15 @@ func (c *Client) blockTxs(ctx context.Context, height *int64) (crgtypes.BlockTra
TransactionIdentifier: &rosettatypes.TransactionIdentifier{Hash: c.converter.ToRosetta().BeginBlockTxHash(blockInfo.BlockID.Hash)},
Operations: AddOperationIndexes(
nil,
c.converter.ToRosetta().BalanceOps(StatusTxSuccess, blockResults.BeginBlockEvents),
c.converter.ToRosetta().BalanceOps(StatusTxSuccess, blockResults.FinalizeBlockEvents),
),
}

endBlockTx := &rosettatypes.Transaction{
TransactionIdentifier: &rosettatypes.TransactionIdentifier{Hash: c.converter.ToRosetta().EndBlockTxHash(blockInfo.BlockID.Hash)},
Operations: AddOperationIndexes(
nil,
c.converter.ToRosetta().BalanceOps(StatusTxSuccess, blockResults.EndBlockEvents),
c.converter.ToRosetta().BalanceOps(StatusTxSuccess, blockResults.FinalizeBlockEvents),
),
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/rosetta.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import (

"github.com/spf13/cobra"

"cosmossdk.io/tools/rosetta"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/rosetta"
)

// RosettaCommand builds the rosetta root command given
Expand Down
11 changes: 5 additions & 6 deletions cmd/rosetta/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,16 @@ package main
import (
"os"

"github.com/cosmos/rosetta"

"cosmossdk.io/log"
rosettaCmd "cosmossdk.io/tools/rosetta/cmd"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
rosettaCmd "github.com/cosmos/rosetta/cmd"
)

func main() {
var (
logger = log.NewLogger(os.Stdout).With(log.ModuleKey, "rosetta")
interfaceRegistry = codectypes.NewInterfaceRegistry()
cdc = codec.NewProtoCodec(interfaceRegistry)
cdc, interfaceRegistry = rosetta.MakeCodec()
logger = log.NewLogger(os.Stdout).With(log.ModuleKey, "rosetta")
)

if err := rosettaCmd.RosettaCommand(interfaceRegistry, cdc).Execute(); err != nil {
Expand Down
18 changes: 17 additions & 1 deletion codec.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,38 @@
package rosetta

import (
"cosmossdk.io/x/tx/signing"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/address"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
authcodec "github.com/cosmos/cosmos-sdk/x/auth/types"
bankcodec "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/gogoproto/proto"
)

// MakeCodec generates the codec required to interact
// with the cosmos APIs used by the rosetta gateway
func MakeCodec() (*codec.ProtoCodec, codectypes.InterfaceRegistry) {
ir := codectypes.NewInterfaceRegistry()
ir, _ := codectypes.NewInterfaceRegistryWithOptions(codectypes.InterfaceRegistryOptions{
ProtoFiles: proto.HybridResolver,
SigningOptions: signing.Options{
AddressCodec: address.Bech32Codec{
Bech32Prefix: sdk.GetConfig().GetBech32AccountAddrPrefix(),
},
ValidatorAddressCodec: address.Bech32Codec{
Bech32Prefix: sdk.GetConfig().GetBech32ValidatorAddrPrefix(),
},
},
})
cdc := codec.NewProtoCodec(ir)

authcodec.RegisterInterfaces(ir)
bankcodec.RegisterInterfaces(ir)
cryptocodec.RegisterInterfaces(ir)
txtypes.RegisterInterfaces(ir)

return cdc, ir
}
2 changes: 1 addition & 1 deletion config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/coinbase/rosetta-sdk-go/types"
"github.com/spf13/pflag"

crg "cosmossdk.io/tools/rosetta/lib/server"
crg "github.com/cosmos/rosetta/lib/server"

clientflags "github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/codec"
Expand Down
75 changes: 45 additions & 30 deletions converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package rosetta

import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"fmt"
"reflect"

signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1"

rosettatypes "github.com/coinbase/rosetta-sdk-go/types"
abci "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/crypto"
Expand All @@ -15,8 +18,8 @@ import (
secp "github.com/decred/dcrd/dcrec/secp256k1/v4"

sdkmath "cosmossdk.io/math"
crgerrs "cosmossdk.io/tools/rosetta/lib/errors"
crgtypes "cosmossdk.io/tools/rosetta/lib/types"
crgerrs "github.com/cosmos/rosetta/lib/errors"
crgtypes "github.com/cosmos/rosetta/lib/types"

sdkclient "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
Expand All @@ -27,8 +30,6 @@ import (
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"

auth "github.com/cosmos/cosmos-sdk/x/auth/types"
)

// Converter is a utility that can be used to convert
Expand Down Expand Up @@ -71,7 +72,7 @@ type ToRosettaConverter interface {
// 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 CometBFT transaction and tx result if provided to a rosetta tx
Tx(rawTx cmttypes.Tx, txResult *abci.ResponseDeliverTx) (*rosettatypes.Transaction, error)
Tx(rawTx cmttypes.Tx, txResult *abci.ExecTxResult) (*rosettatypes.Transaction, error)
// TxIdentifiers converts a CometBFT tx to transaction identifiers
TxIdentifiers(txs []cmttypes.Tx) []*rosettatypes.TransactionIdentifier
// BalanceOps converts events to balance operations
Expand Down Expand Up @@ -117,7 +118,13 @@ func NewConverter(cdc *codec.ProtoCodec, ir codectypes.InterfaceRegistry, cfg sd
txDecode: cfg.TxDecoder(),
txEncode: cfg.TxEncoder(),
bytesToSign: func(tx authsigning.Tx, signerData authsigning.SignerData) (b []byte, err error) {
bytesToSign, err := cfg.SignModeHandler().GetSignBytes(signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signerData, tx)
parsedSignerData := parseSignerData(signerData)
txData, err := parseTxData(tx, parsedSignerData)
if err != nil {
return nil, err
}

bytesToSign, err := cfg.SignModeHandler().GetSignBytes(context.TODO(), signingv1beta1.SignMode(signing.SignMode_SIGN_MODE_DIRECT), parsedSignerData, *txData)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -146,30 +153,22 @@ func (c converter) UnsignedTx(ops []*rosettatypes.Operation) (tx authsigning.Tx,
for i := 0; i < len(ops); i++ {
op := ops[i]

protoMessage, err := c.ir.Resolve(op.Type)
msg, err := c.ir.Resolve(op.Type)
if err != nil {
return nil, crgerrs.WrapError(crgerrs.ErrBadArgument, "operation not found: "+op.Type)
}

msg, ok := protoMessage.(sdk.Msg)
if !ok {
return nil, crgerrs.WrapError(crgerrs.ErrBadArgument, "operation is not a valid supported sdk.Msg: "+op.Type)
}

err = c.Msg(op.Metadata, msg)
if err != nil {
return nil, crgerrs.WrapError(crgerrs.ErrCodec, err.Error())
}

// verify message correctness
if err = msg.ValidateBasic(); err != nil {
return nil, crgerrs.WrapError(
crgerrs.ErrBadArgument,
fmt.Sprintf("validation of operation at index %d failed: %s", op.OperationIdentifier.Index, err),
)
legacyMsg, ok := msg.(sdk.LegacyMsg)
if !ok {
return nil, crgerrs.WrapError(crgerrs.ErrCodec, "Failed asserting LegacyMsg type")
}

signers := msg.GetSigners()
signers := legacyMsg.GetSigners()
// check if there are enough signers
if len(signers) == 0 {
return nil, crgerrs.WrapError(crgerrs.ErrBadArgument, fmt.Sprintf("operation at index %d got no signers", op.OperationIdentifier.Index))
Expand Down Expand Up @@ -247,8 +246,13 @@ func (c converter) Ops(status string, msg sdk.Msg) ([]*rosettatypes.Operation, e
return nil, err
}

ops := make([]*rosettatypes.Operation, len(msg.GetSigners()))
for i, signer := range msg.GetSigners() {
legacyMsg, ok := msg.(sdk.LegacyMsg)
if !ok {
return nil, crgerrs.WrapError(crgerrs.ErrCodec, "Failed asserting LegacyMsg type")
}

ops := make([]*rosettatypes.Operation, len(legacyMsg.GetSigners()))
for i, signer := range legacyMsg.GetSigners() {
op := &rosettatypes.Operation{
Type: opName,
Status: &status,
Expand All @@ -263,7 +267,7 @@ func (c converter) Ops(status string, msg sdk.Msg) ([]*rosettatypes.Operation, e
}

// Tx converts a CometBFT raw transaction and its result (if provided) to a rosetta transaction
func (c converter) Tx(rawTx cmttypes.Tx, txResult *abci.ResponseDeliverTx) (*rosettatypes.Transaction, error) {
func (c converter) Tx(rawTx cmttypes.Tx, txResult *abci.ExecTxResult) (*rosettatypes.Transaction, error) {
// decode tx
tx, err := c.txDecode(rawTx)
if err != nil {
Expand Down Expand Up @@ -596,9 +600,14 @@ func (c converter) OpsAndSigners(txBytes []byte) (ops []*rosettatypes.Operation,
return nil, nil, crgerrs.WrapError(crgerrs.ErrCodec, err.Error())
}

for _, signer := range txBuilder.GetTx().GetSigners() {
txSigners, err := txBuilder.GetTx().GetSigners()
if err != nil {
return nil, nil, crgerrs.WrapError(crgerrs.ErrCodec, err.Error())
}

for _, signer := range txSigners {
signers = append(signers, &rosettatypes.AccountIdentifier{
Address: signer.String(),
Address: string(signer),
})
}

Expand Down Expand Up @@ -678,7 +687,11 @@ func (c converter) SigningComponents(tx authsigning.Tx, metadata *ConstructionMe
return nil, nil, crgerrs.WrapError(crgerrs.ErrBadArgument, err.Error())
}

signers := tx.GetSigners()
signers, err := tx.GetSignaturesV2()
if err != nil {
return nil, nil, crgerrs.WrapError(crgerrs.ErrBadArgument, err.Error())
}

// assert the signers data provided in options are the same as the expected signing accounts
// and that the number of rosetta provided public keys equals the one of the signers
if len(metadata.SignersData) != len(signers) || len(signers) != len(rosPubKeys) {
Expand Down Expand Up @@ -706,16 +719,16 @@ func (c converter) SigningComponents(tx authsigning.Tx, metadata *ConstructionMe
if err != nil {
return nil, nil, err
}
if !bytes.Equal(pubKey.Address().Bytes(), signer.Bytes()) {
if !bytes.Equal(pubKey.Address().Bytes(), signer.PubKey.Address()) {
return nil, nil, crgerrs.WrapError(
crgerrs.ErrBadArgument,
fmt.Sprintf("public key at index %d does not match the expected transaction signer: %X <-> %X", i, rosPubKeys[i].Bytes, signer.Bytes()),
fmt.Sprintf("public key at index %d does not match the expected transaction signer: %X <-> %X", i, rosPubKeys[i].Bytes, signer),
)
}

// set the signer data
signerData := authsigning.SignerData{
Address: signer.String(),
Address: string(signer.PubKey.Address()),
ChainID: metadata.ChainID,
AccountNumber: metadata.SignersData[i].AccountNumber,
Sequence: metadata.SignersData[i].Sequence,
Expand All @@ -729,8 +742,10 @@ func (c converter) SigningComponents(tx authsigning.Tx, metadata *ConstructionMe
}

// set payload
signerAddress := sdk.AccAddress(signer.PubKey.Address()).String()

payloadsToSign[i] = &rosettatypes.SigningPayload{
AccountIdentifier: &rosettatypes.AccountIdentifier{Address: signer.String()},
AccountIdentifier: &rosettatypes.AccountIdentifier{Address: signerAddress},
Bytes: signBytes,
SignatureType: rosettatypes.Ecdsa,
}
Expand Down Expand Up @@ -763,7 +778,7 @@ func (c converter) SigningComponents(tx authsigning.Tx, metadata *ConstructionMe

// SignerData converts the given any account to signer data
func (c converter) SignerData(anyAccount *codectypes.Any) (*SignerData, error) {
var acc auth.AccountI
var acc sdkclient.Account
err := c.ir.UnpackAny(anyAccount, &acc)
if err != nil {
return nil, crgerrs.WrapError(crgerrs.ErrCodec, err.Error())
Expand Down
Loading

0 comments on commit f4f74b4

Please sign in to comment.