diff --git a/lib/README.md b/lib/README.md index 029ea78..63780d0 100644 --- a/lib/README.md +++ b/lib/README.md @@ -45,7 +45,7 @@ func main() { } fmt.Println(txJSON) - _, err = lib.BroadcastTx(addr0, msg1, msg2, msg3) + _, err = lib.BroadcastTxWithFileLock(addr0, msg1, msg2, msg3) if err != nil { log.Fatal(err) } diff --git a/lib/tx.go b/lib/tx.go index b0471d3..a0101f3 100644 --- a/lib/tx.go +++ b/lib/tx.go @@ -140,16 +140,6 @@ func BuildUnsignedTx(address sdk.AccAddress, msgs ...sdk.Msg) (txJSON string, er return } -// BroadcastTx broadcasts a transaction via RPC. -func BroadcastTx(address sdk.AccAddress, msgs ...sdk.Msg) (out *bytes.Buffer, err error) { - clientCtx, txf, err := getClientContextAndTxFactory(address) - if err != nil { - return - } - out, err = broadcastTx(clientCtx, txf, msgs...) - return -} - func broadcastTx(clientCtx client.Context, txf tx.Factory, msgs ...sdk.Msg) (out *bytes.Buffer, err error) { err = tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msgs...) if err != nil { diff --git a/lib/utils.go b/lib/utils.go new file mode 100644 index 0000000..adf11b2 --- /dev/null +++ b/lib/utils.go @@ -0,0 +1,26 @@ +package lib + +import ( + "bytes" + "encoding/json" + "regexp" + + sdk "github.com/cosmos/cosmos-sdk/types" + "sigs.k8s.io/yaml" +) + +// GetTxResponseFromOut converts strings to numbers and unmarshalles out into TxResponse struct +func GetTxResponseFromOut(out *bytes.Buffer) (txResponse sdk.TxResponse, err error) { + m := regexp.MustCompile(`"([0-9]+?)"`) + str := m.ReplaceAllString(out.String(), "${1}") + + // We might have YAML here, so we need to convert to JSON first, because TxResponse struct lacks `yaml:"height,omitempty"`, etc. + // Since JSON is a subset of YAML, passing JSON through YAMLToJSON is a no-op and the result is the byte array of the JSON again. + j, err := yaml.YAMLToJSON([]byte(str)) + if err != nil { + return + } + + err = json.Unmarshal(j, &txResponse) + return +} diff --git a/tests/e2e/asset/suite.go b/tests/e2e/asset/suite.go index 8a32495..d6d1a6a 100644 --- a/tests/e2e/asset/suite.go +++ b/tests/e2e/asset/suite.go @@ -129,7 +129,7 @@ func (s *E2ETestSuite) TestNotarizeAsset() { out, err := lib.BroadcastTxWithFileLock(addr, tc.msg) s.Require().NoError(err) - txResponse, err := clitestutil.GetTxResponseFromOut(out) + txResponse, err := lib.GetTxResponseFromOut(out) s.Require().NoError(err) s.Require().NoError(s.network.WaitForNextBlock()) diff --git a/tests/e2e/dao/suite.go b/tests/e2e/dao/suite.go index d9ec4e2..5d99215 100644 --- a/tests/e2e/dao/suite.go +++ b/tests/e2e/dao/suite.go @@ -160,7 +160,7 @@ func (s *E2ETestSuite) TestMintToken() { out, err := lib.BroadcastTxWithFileLock(val.Address, msg1) s.Require().NoError(err) - txResponse, err := clitestutil.GetTxResponseFromOut(out) + txResponse, err := lib.GetTxResponseFromOut(out) s.Require().NoError(err) s.Require().Equal(int(0), int(txResponse.Code)) @@ -202,7 +202,7 @@ func (s *E2ETestSuite) TestMintToken() { out, err = lib.BroadcastTxWithFileLock(addr, msg1) s.Require().NoError(err) - txResponse, err = clitestutil.GetTxResponseFromOut(out) + txResponse, err = lib.GetTxResponseFromOut(out) s.Require().NoError(err) s.Require().Equal(int(2), int(txResponse.Code)) } diff --git a/tests/e2e/machine/suite.go b/tests/e2e/machine/suite.go index 348a910..f23cd7a 100644 --- a/tests/e2e/machine/suite.go +++ b/tests/e2e/machine/suite.go @@ -135,7 +135,7 @@ func (s *E2ETestSuite) TestInvalidAttestMachine() { msg := machinetypes.NewMsgAttestMachine(addr.String(), &machine) out, _ := lib.BroadcastTxWithFileLock(addr, msg) - txResponse, err := clitestutil.GetTxResponseFromOut(out) + txResponse, err := lib.GetTxResponseFromOut(out) s.Require().NoError(err) s.Require().Equal(int(txResponse.Code), int(4)) @@ -145,7 +145,7 @@ func (s *E2ETestSuite) TestInvalidAttestMachine() { msg = machinetypes.NewMsgAttestMachine(addr.String(), &machine) out, _ = lib.BroadcastTxWithFileLock(addr, msg) - txResponse, err = clitestutil.GetTxResponseFromOut(out) + txResponse, err = lib.GetTxResponseFromOut(out) s.Require().NoError(err) s.Require().Equal(int(txResponse.Code), int(3)) } diff --git a/testutil/cli/cmd.go b/testutil/cli/cmd.go index d990703..a8a1b6a 100644 --- a/testutil/cli/cmd.go +++ b/testutil/cli/cmd.go @@ -1,94 +1,81 @@ package cli import ( + "bytes" "context" - "encoding/json" "errors" - "regexp" + "github.com/planetmint/planetmint-go/lib" "github.com/planetmint/planetmint-go/testutil" "github.com/cosmos/cosmos-sdk/testutil/network" - sdk "github.com/cosmos/cosmos-sdk/types" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/cobra" - "sigs.k8s.io/yaml" ) // ExecTestCLICmd builds the client context, mocks the output and executes the command. -func ExecTestCLICmd(clientCtx client.Context, cmd *cobra.Command, extraArgs []string) (testutil.BufferWriter, error) { +func ExecTestCLICmd(clientCtx client.Context, cmd *cobra.Command, extraArgs []string) (out testutil.BufferWriter, err error) { cmd.SetArgs(extraArgs) - _, out := testutil.ApplyMockIO(cmd) + _, out = testutil.ApplyMockIO(cmd) clientCtx = clientCtx.WithOutput(out) ctx := context.Background() ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) - if err := cmd.ExecuteContext(ctx); err != nil { - return out, err + if err = cmd.ExecuteContext(ctx); err != nil { + return } - txResponse, err := GetTxResponseFromOut(out) + output, ok := out.(*bytes.Buffer) + if !ok { + err = lib.ErrTypeAssertionFailed + return + } + + txResponse, err := lib.GetTxResponseFromOut(output) if err != nil { - return out, err + return } if txResponse.Code != 0 { err = errors.New(txResponse.RawLog) - return out, err + return } - - return out, nil -} - -// GetTxResponseFromOut converts strings to numbers and unmarshalles out into TxResponse struct -func GetTxResponseFromOut(out testutil.BufferWriter) (sdk.TxResponse, error) { - var txResponse sdk.TxResponse - - m := regexp.MustCompile(`"([0-9]+?)"`) - str := m.ReplaceAllString(out.String(), "${1}") - - // We might have YAML here, so we need to convert to JSON first, because TxResponse struct lacks `yaml:"height,omitempty"`, etc. - // Since JSON is a subset of YAML, passing JSON through YAMLToJSON is a no-op and the result is the byte array of the JSON again. - j, err := yaml.YAMLToJSON([]byte(str)) - if err != nil { - return txResponse, err - } - - err = json.Unmarshal(j, &txResponse) - if err != nil { - return txResponse, err - } - - return txResponse, nil + return } // GetRawLogFromTxOut queries the TxHash of out from the chain and returns the RawLog from the answer. -func GetRawLogFromTxOut(val *network.Validator, out testutil.BufferWriter) (string, error) { - txResponse, err := GetTxResponseFromOut(out) +func GetRawLogFromTxOut(val *network.Validator, out *bytes.Buffer) (rawLog string, err error) { + txResponse, err := lib.GetTxResponseFromOut(out) if err != nil { - return "", err + return } if txResponse.Code != 0 { err = errors.New(txResponse.RawLog) - return "", err + return } args := []string{ txResponse.TxHash, } - out, err = ExecTestCLICmd(val.ClientCtx, authcmd.QueryTxCmd(), args) + output, err := ExecTestCLICmd(val.ClientCtx, authcmd.QueryTxCmd(), args) if err != nil { - return "", err + return } - txRes, err := GetTxResponseFromOut(out) - if err != nil { - return "", err + out, ok := output.(*bytes.Buffer) + if !ok { + err = lib.ErrTypeAssertionFailed + return } - return txRes.RawLog, nil + txRes, err := lib.GetTxResponseFromOut(out) + if err != nil { + return + } + rawLog = txRes.RawLog + return } diff --git a/util/issue_commands.go b/util/issue_commands.go index df80433..7117053 100644 --- a/util/issue_commands.go +++ b/util/issue_commands.go @@ -8,6 +8,7 @@ import ( "github.com/planetmint/planetmint-go/lib" daotypes "github.com/planetmint/planetmint-go/x/dao/types" machinetypes "github.com/planetmint/planetmint-go/x/machine/types" + "sigs.k8s.io/yaml" ) func buildSignBroadcastTx(goCtx context.Context, loggingContext string, sendingValidatorAddress string, msg sdk.Msg) { @@ -20,12 +21,22 @@ func buildSignBroadcastTx(goCtx context.Context, loggingContext string, sendingV return } GetAppLogger().Debug(ctx, loggingContext+" unsigned tx: "+txJSON) - _, err = lib.BroadcastTxWithFileLock(addr, msg) + out, err := lib.BroadcastTxWithFileLock(addr, msg) if err != nil { GetAppLogger().Error(ctx, loggingContext+" broadcast tx failed: "+err.Error()) return } - GetAppLogger().Info(ctx, loggingContext+" broadcast tx succeeded") + txResponse, err := lib.GetTxResponseFromOut(out) + if err != nil { + GetAppLogger().Error(ctx, loggingContext+" getting tx response from out failed: "+err.Error()) + return + } + txResponseJSON, err := yaml.YAMLToJSON([]byte(txResponse.String())) + if err != nil { + GetAppLogger().Error(ctx, loggingContext+" converting tx response from yaml to json failed: "+err.Error()) + return + } + GetAppLogger().Info(ctx, loggingContext+" broadcast tx succeeded: "+string(txResponseJSON)) }() }