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

Add support for broadcasting arbitrary messages as test users #186

Merged
merged 13 commits into from
Jul 6, 2022

Conversation

chatton
Copy link
Contributor

@chatton chatton commented Jun 30, 2022

Description

This PR adds support for the ability to Broadcast transactions on CosmosChains

closes #185

Checklist

  • I have made sure the upstream branch for this PR is correct
  • I have made sure this PR is ready to merge
  • I have made sure that I have assigned reviewers related to this project

Changes

  • Added new interface Broadcaster
  • Add Cosmos chain implementation.
  • Added NewLocalKeyringFromDockerContainer a mechanism to use the keychain of created test users.
  • Added test to ensure a broadcast with a created user succeeds (this also verifies NewLocalKeyringFromDockerContainer works as this would fail if the keyring was not there. )

Notes

  • I tried to design the interfaces in such a way so that the backing congiuration (tx.Factory and client.Context) are fully configurable by the caller so that we can change any arbitrary options we need.

@chatton chatton requested a review from a team as a code owner June 30, 2022 17:15
@chatton chatton requested review from mark-rushakoff and removed request for a team June 30, 2022 17:15
Copy link
Member

@mark-rushakoff mark-rushakoff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple high-level notes:

  • Move Broadcast interface into root ibctest package
  • cosmos_broadcaster.go can be named just broadcaster.go since it is already in the cosmos directory

I think the Broadcast interface is fine to focus on Cosmos, but others on the team have given Cosmos vs non-Cosmos more thought than I have, so it would be good to hear from someone else.

@@ -0,0 +1,59 @@
package broadcast
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the types here make more sense in the root ibctest package.


type FactoryOpt func(factory tx.Factory) tx.Factory

type User interface {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After moving to ibctest, this interface can be named BroadcastUser to distinguish from the User struct.

Copy link
Contributor Author

@chatton chatton Jul 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we are in the ibctest package I believe we may just be able to accept an *ibctest.User directly. However maybe it is no harm to keep the interface.


// Tx uses the provided Broadcaster to broadcast all the provided messages which will be signed
// by the User provided. The sdk.TxResponse and an error are returned.
func Tx(ctx context.Context, broadcaster Broadcaster, broadcastingUser User, msgs ...sdk.Msg) (sdk.TxResponse, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this function can be named BroadcastTx.

// defaultClientContext returns a default client context configured with the user as the sender.
func (b *Broadcaster) defaultClientContext(fromUser broadcast.User, sdkAdd sdk.AccAddress) client.Context {
// initialize a clean buffer each time
b.buf = &bytes.Buffer{}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be b.buf.Reset().

internal/dockerutil/keyring.go Show resolved Hide resolved
Comment on lines 49 to 55
splitName := strings.Split(name, "/")

extractedFileName := splitName[len(splitName)-1]
isDirectory := extractedFileName == ""
if isDirectory {
continue
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could use isDirectory := strings.HasSuffix(name, "/") and extractedFileName := path.Base(name).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

much cleaner, thanks for the suggestion!

@chatton
Copy link
Contributor Author

chatton commented Jul 1, 2022

@mark-rushakoff moving the code into the ibctest package results in a circular import between ibctest and cosmos with a call to cosmos.NewCosmosChain in chainfactory.go. What would be your preferred way of resolving this?

Some options are:

  • Create an additional package just to hold types
  • Remove broadcaster interface and just use the concrete cosmos.Broadcaster and cosmos.BroadCastUser
  • Maintain separate package for broadcast interfaces and types.

@chatton
Copy link
Contributor Author

chatton commented Jul 5, 2022

I ended up keeping the interfaces in a broadcast package, but moved the main function to ibctest as BroadcastTx

Copy link
Member

@mark-rushakoff mark-rushakoff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this came together nicely. Thanks for figuring out a workaround for the import cycle I inadvertently suggested last week. I left a few comments on some minor style points, and then I think this can be merged.

require.Equal(t, uint32(0), resp.Code)
require.NotEmpty(t, resp.Data)
require.NotEmpty(t, resp.TxHash)
require.NotEmpty(t, resp.Events)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this test also have an assertion that the user on gaia1 has received transferAmount?

return nil, err
}

if err := os.Mkdir(fmt.Sprintf("%s/keyring-test", localDirectory), os.ModePerm); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is working on a local filesystem, it should use filepath.Join(localDirectory, "keyring-test") instead of fmt.Sprintf with a literal /.

continue
}

filePath := fmt.Sprintf("%s/keyring-test/%s", localDirectory, extractedFileName)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filepath.Join here too.

internal/dockerutil/keyring.go Show resolved Hide resolved
}

// GetFactory returns an instance of tx.Factory that is configured with this Broadcaster's CosmosChain
// and the provided user.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't hurt to mention ConfigureFactoryOptions in the godoc for this method.

chain/cosmos/broadcaster.go Show resolved Hide resolved
_, ok := b.keyrings[user]
if !ok {
localDir := b.t.TempDir()
containerKeyringDir := fmt.Sprintf("%s/keyring-test", cn.HomeDir())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filepath.Join

// GetTxResponseBytes returns the sdk.TxResponse bytes which returned from broadcast.Tx.
func (b *Broadcaster) GetTxResponseBytes(ctx context.Context, user broadcast.User) ([]byte, error) {
if b.buf == nil || b.buf.Len() == 0 {
return nil, fmt.Errorf("empty buffer, transaction has not be executed yet")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/be/been/

@chatton
Copy link
Contributor Author

chatton commented Jul 5, 2022

I've opened a separate PR to add support for the keyrings that we were discussing:

@chatton chatton mentioned this pull request Jul 6, 2022
33 tasks
Copy link
Member

@mark-rushakoff mark-rushakoff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@mark-rushakoff mark-rushakoff merged commit c709d57 into strangelove-ventures:main Jul 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature Request: Support broadcasting messages as test users from the test host
2 participants