Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: contstuction payloads #190

Merged
merged 21 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client_online.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func NewClient(cfg *Config) (*Client, error) {
bank: nil,
tmRPC: nil,
version: fmt.Sprintf("%s/%s", info.AppName, v),
converter: NewConverter(cfg.Codec, cfg.InterfaceRegistry, txConfig),
converter: NewConverter(cfg.Codec, cfg.InterfaceRegistry, txConfig, address.NewBech32Codec(cfg.Bech32Prefix)),
}, nil
}

Expand Down
23 changes: 14 additions & 9 deletions converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
secp "github.com/decred/dcrd/dcrec/secp256k1/v4"

signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1"
"cosmossdk.io/core/address"
sdkmath "cosmossdk.io/math"
banktypes "cosmossdk.io/x/bank/types"

Expand Down Expand Up @@ -107,9 +108,10 @@ type converter struct {
bytesToSign func(tx authsigning.Tx, signerData authsigning.SignerData) (b []byte, err error)
ir codectypes.InterfaceRegistry
cdc *codec.ProtoCodec
ac address.Codec
}

func NewConverter(cdc *codec.ProtoCodec, ir codectypes.InterfaceRegistry, cfg sdkclient.TxConfig) Converter {
func NewConverter(cdc *codec.ProtoCodec, ir codectypes.InterfaceRegistry, cfg sdkclient.TxConfig, ac address.Codec) Converter {
return converter{
newTxBuilder: cfg.NewTxBuilder,
txBuilderFromTx: cfg.WrapTxBuilder,
Expand All @@ -131,6 +133,7 @@ func NewConverter(cdc *codec.ProtoCodec, ir codectypes.InterfaceRegistry, cfg sd
},
ir: ir,
cdc: cdc,
ac: ac,
}
}

Expand Down Expand Up @@ -677,7 +680,7 @@ func (c converter) SigningComponents(tx authsigning.Tx, metadata *ConstructionMe
return nil, nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("getting signers v2 from tx %s", err.Error()))
}

signers, err := tx.GetSignaturesV2()
signers, err := tx.GetSigners()
if err != nil {
return nil, nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("getting signers v2 from tx %s", err.Error()))
}
Expand Down Expand Up @@ -707,18 +710,23 @@ 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, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("while setting signatures %s", err.Error()))
return nil, nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("while checking pubkey %s", err.Error()))
}
if !bytes.Equal(pubKey.Address().Bytes(), signer.PubKey.Address()) {
if !bytes.Equal(pubKey.Address().Bytes(), signer) {
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),
)
}

addr, err := c.ac.BytesToString(signer)
if err != nil {
return nil, nil, crgerrs.WrapError(crgerrs.ErrConverter, fmt.Sprintf("while converting to bech32 address: %s", err.Error()))
}

// set the signer data
signerData := authsigning.SignerData{
Address: string(signer.PubKey.Address()),
Address: addr,
ChainID: metadata.ChainID,
AccountNumber: metadata.SignersData[i].AccountNumber,
Sequence: metadata.SignersData[i].Sequence,
Expand All @@ -731,11 +739,8 @@ func (c converter) SigningComponents(tx authsigning.Tx, metadata *ConstructionMe
return nil, nil, crgerrs.WrapError(crgerrs.ErrUnknown, fmt.Sprintf("unable to sign tx: %s", err.Error()))
}

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

payloadsToSign[i] = &rosettatypes.SigningPayload{
AccountIdentifier: &rosettatypes.AccountIdentifier{Address: signerAddress},
AccountIdentifier: &rosettatypes.AccountIdentifier{Address: addr},
Bytes: signBytes,
SignatureType: rosettatypes.Ecdsa,
}
Expand Down
2 changes: 1 addition & 1 deletion converter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (s *ConverterTestSuite) SetupTest() {
// instantiate converter
cdc, ir := rosetta.MakeCodec()
txConfig := authtx.NewTxConfig(cdc, address.NewBech32Codec("cosmos"), address.NewBech32Codec("cosmosvaloper"), authtx.DefaultSignModes)
s.c = rosetta.NewConverter(cdc, ir, txConfig)
s.c = rosetta.NewConverter(cdc, ir, txConfig, address.NewBech32Codec("cosmos"))
// add utils
s.ir = ir
s.cdc = cdc
Expand Down
2 changes: 1 addition & 1 deletion tests/systemtests/accounts_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//go:build system_test

package systemtests
package rossetaSystemTests

import (
"testing"
Expand Down
2 changes: 1 addition & 1 deletion tests/systemtests/block_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//go:build system_test

package systemtests
package rossetaSystemTests

import (
"testing"
Expand Down
36 changes: 32 additions & 4 deletions tests/systemtests/construction_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
//go:build system_test

package systemtests
package rossetaSystemTests
JulianToledano marked this conversation as resolved.
Show resolved Hide resolved

import (
"encoding/base64"
"encoding/hex"
"fmt"
"strings"
"testing"

Expand All @@ -25,12 +26,13 @@ func TestDerive(t *testing.T) {
rosettaRest := newRestClient(rosetta)

pubKey := secp256k1.GenPrivKey().PubKey()
addr, err := address.NewBech32Codec("cosmos").BytesToString(pubKey.Address().Bytes())
assert.NoError(t, err)

hexPk := strings.Split(pubKey.String(), "{")[1]

res, err := rosettaRest.constructionDerive(hexPk[:len(hexPk)-1])
assert.NoError(t, err)

addr, err := address.NewBech32Codec("cosmos").BytesToString(pubKey.Address().Bytes())
assert.NoError(t, err)
assert.Equal(t, addr, gjson.GetBytes(res, "address").String())
}

Expand Down Expand Up @@ -82,3 +84,29 @@ func TestMetadata(t *testing.T) {
assert.Equal(t, gjson.GetBytes(res, "metadata.gas_price").String(), "123uatom")
assert.Greater(t, gjson.GetBytes(res, "suggested_fee.0.value").Int(), int64(0))
}

func TestPayloads(t *testing.T) {
sut.ResetChain(t)
sut.StartChain(t)

rosetta.restart(t)
rosettaRest := newRestClient(rosetta)

cli := systemtests.NewCLIWrapper(t, sut, verbose)
addr := cli.GetKeyAddr("node0")
bz, err := base64.StdEncoding.DecodeString(cli.GetPubKeyByCustomField(addr, "address"))
assert.NoError(t, err)
JulianToledano marked this conversation as resolved.
Show resolved Hide resolved

pk := secp256k1.PubKey{Key: bz}
hexPk := strings.Split(pk.String(), "{")[1]
hexPk = hexPk[:len(hexPk)-1]

op := operation{
msgType: "/cosmos.bank.v1beta1.MsgSend",
metadata: fmt.Sprintf(`{"from_address": "%s", "to_address": "%s", "amount":[{"amount":"123", "denom":"stake"}]}`, addr, "cosmos1qcym25uch54xmja4eys35zcyr8npwlm80glwuk"),
JulianToledano marked this conversation as resolved.
Show resolved Hide resolved
}
res, err := rosettaRest.constructionPayloads(`"signer_data":[{"account_number":1, "sequence": 0}]`, hexPk, op)
assert.NoError(t, err)
assert.NotEmpty(t, gjson.GetBytes(res, "unsigned_transaction"))
assert.Equal(t, gjson.GetBytes(res, "payloads.0.address").String(), addr)
}
2 changes: 1 addition & 1 deletion tests/systemtests/main_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//go:build system_test

package systemtests
package rossetaSystemTests

import (
"testing"
Expand Down
2 changes: 1 addition & 1 deletion tests/systemtests/mempool_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//go:build system_test

package systemtests
package rossetaSystemTests

import (
"testing"
Expand Down
2 changes: 1 addition & 1 deletion tests/systemtests/network_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//go:build system_test

package systemtests
package rossetaSystemTests

import (
"testing"
Expand Down
34 changes: 33 additions & 1 deletion tests/systemtests/rest_client.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package systemtests
package rossetaSystemTests

import (
"fmt"
Expand Down Expand Up @@ -156,3 +156,35 @@ func (c *restClient) constructionMetadata(hexPk string, options map[string]inter

return res.Body(), nil
}

func (c *restClient) constructionPayloads(metadata, hexPk string, opts ...operation) ([]byte, error) {
body := fmt.Sprintf(
`{%s, "operations":%s, "metadata":{%s}, "public_keys":[{"hex_bytes":"%s", "curve_type":"secp256k1"}]}`,
c.networkIdentifier, payloadsOperations(opts...), metadata, hexPk)
res, err := c.client.R().SetBody(
body,
).Post("/construction/payloads")
if err != nil {
return nil, err
}

return res.Body(), nil
}

type operation struct {
msgType string
metadata string
}

func (o *operation) String() string {
return fmt.Sprintf(`"type":"%s", "metadata": %s`, o.msgType, o.metadata)
}

func payloadsOperations(ops ...operation) []string {
r := make([]string, len(ops))
for i, op := range ops {
r = append(r, fmt.Sprintf(`{"operation_identifier":{"index": %d}, %s}`, i, op.String()))
}

return r
}
7 changes: 2 additions & 5 deletions tests/systemtests/rosetta.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package systemtests
package rossetaSystemTests

import (
"bufio"
Expand Down Expand Up @@ -35,7 +35,6 @@ type rosettaRunner struct {
Network string // the network name (default "network")
Plugin string // plugin folder name
Tendermint string // CometBFT rpc endpoint
Offline bool // run rosetta only with construction API
verbose bool
out io.Writer
outBuff *ring.Ring
Expand All @@ -46,7 +45,7 @@ type rosettaRunner struct {
outputDir string
}

func newRosettaRunner(binary, denom, grpcTypesServer, plugin string, offline, verbose bool) rosettaRunner {
func newRosettaRunner(binary, denom, grpcTypesServer, plugin string, verbose bool) rosettaRunner {
execBinary := filepath.Join(systemtests.WorkDir, "binaries", binary)
return rosettaRunner{
execBinary: execBinary,
Expand All @@ -58,7 +57,6 @@ func newRosettaRunner(binary, denom, grpcTypesServer, plugin string, offline, ve
Network: "cosmos",
Plugin: plugin,
Tendermint: "tcp://localhost:26657",
Offline: offline,
out: os.Stdout,
outBuff: ring.New(100),
errBuff: ring.New(100),
Expand All @@ -77,7 +75,6 @@ func (r *rosettaRunner) start(t *testing.T) {
"--addr", r.Addr,
"--grpc", r.GRPC,
"--grpc-types-server", r.GRPCTypesServer,
"--plugin", r.Plugin,
}

r.log("Start Rosetta\n")
Expand Down
5 changes: 2 additions & 3 deletions tests/systemtests/test_runner.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package systemtests
package rossetaSystemTests

import (
"flag"
Expand Down Expand Up @@ -33,7 +33,6 @@ func RunTests(m *testing.M) {
rosettaDenom := flag.String("rosetta-denom", "ustake", "rosetta denom to suggest")
rosettaGRPCTypesServer := flag.String("rosetta-grpc-types-server", "localhost:9090", "rosetta gRPC Server endpoint for proto messages types and reflection")
rosettaPlugin := flag.String("rosetta-plugin", "", "rosetta plugin folder name")
rosettaOffline := flag.Bool("rosetta-offline", false, "rosetta run only with construction API")
flag.Parse()

requireEnoughFileHandlers(*nodesCount + 1) // +1 as tests may start another node
Expand All @@ -56,7 +55,7 @@ func RunTests(m *testing.M) {
sut = systemtests.NewSystemUnderTest(*execBinary, verbose, *nodesCount, *blockTime)
sut.SetupChain() // setup chain and keyring

rosetta = newRosettaRunner(*rosettaBinary, *rosettaDenom, *rosettaGRPCTypesServer, *rosettaPlugin, *rosettaOffline, verbose)
rosetta = newRosettaRunner(*rosettaBinary, *rosettaDenom, *rosettaGRPCTypesServer, *rosettaPlugin, verbose)

JulianToledano marked this conversation as resolved.
Show resolved Hide resolved
// run tests
exitCode := m.Run()
Expand Down
2 changes: 1 addition & 1 deletion utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func parseTxData(tx authsigning.Tx, signerData signing2.SignerData) (*signing2.T
return nil, crgerrs.WrapError(crgerrs.ErrCodec, fmt.Sprintf("parsing tx data %s", err.Error()))
}

// todo: timeouthecigh
// todo: timeoutHeigh
txData := signing2.TxData{
Body: &txv1beta1.TxBody{
Messages: parsedTxMsgs,
Expand Down
Loading