From 131c4417248bd7bae9cc33e5dfccb7db292ea20c Mon Sep 17 00:00:00 2001 From: Pantani Date: Wed, 6 Dec 2023 12:57:35 +0100 Subject: [PATCH 01/42] create a method to fill other methods --- ignite/pkg/goanalysis/goanalysis.go | 58 ++++++++++++++++++ ignite/pkg/goanalysis/goanalysis_test.go | 74 +++++++++++++++++++++++ ignite/pkg/goanalysis/testdata/replace.go | 15 +++++ 3 files changed, 147 insertions(+) create mode 100644 ignite/pkg/goanalysis/testdata/replace.go diff --git a/ignite/pkg/goanalysis/goanalysis.go b/ignite/pkg/goanalysis/goanalysis.go index 96115824ce..e88b030ede 100644 --- a/ignite/pkg/goanalysis/goanalysis.go +++ b/ignite/pkg/goanalysis/goanalysis.go @@ -279,3 +279,61 @@ func createUnderscoreImport(imp string) *ast.ImportSpec { }, } } + +// ReplaceCode replace a function implementation into a package path. The method will find +// the method signature and re-write the method implementation based in the new function. +func ReplaceCode(path, oldFunctionName, newFunction string) (err error) { + absPath, err := filepath.Abs(path) + if err != nil { + return err + } + + // Parse the input Go source file into an AST. + fset := token.NewFileSet() + node, err := parser.ParseFile(fset, absPath, nil, parser.ParseComments) + if err != nil { + return err + } + + // Traverse the AST to find and replace the function. + ast.Inspect(node, func(n ast.Node) bool { + // Check if the node is a function declaration. + if funcDecl, ok := n.(*ast.FuncDecl); ok { + // Check if the function has the name you want to replace. + if funcDecl.Name.Name == oldFunctionName { + // Replace the function body with the replacement code. + funcDecl.Body, err = parseReplacementCode(newFunction) + return false + } + } + return true + }) + if err != nil { + return err + } + + outFile, err := os.Create(absPath) + if err != nil { + return err + } + defer outFile.Close() + + // Format and write the modified AST to the output file. + return format.Node(outFile, fset, node) +} + +// parseReplacementCode parse the replacement code and create a *ast.BlockStmt. +func parseReplacementCode(code string) (*ast.BlockStmt, error) { + fset := token.NewFileSet() + node, err := parser.ParseFile(fset, "", code, parser.ParseComments) + if err != nil { + return nil, err + } + // Assuming there's only one function in the replacement code. + if len(node.Decls) > 0 { + if funcDecl, ok := node.Decls[0].(*ast.FuncDecl); ok { + return funcDecl.Body, nil + } + } + return nil, fmt.Errorf("replacement code does not contain a valid function declaration") +} diff --git a/ignite/pkg/goanalysis/goanalysis_test.go b/ignite/pkg/goanalysis/goanalysis_test.go index c562080eb5..acb8337837 100644 --- a/ignite/pkg/goanalysis/goanalysis_test.go +++ b/ignite/pkg/goanalysis/goanalysis_test.go @@ -502,3 +502,77 @@ func TestUpdateInitImports(t *testing.T) { }) } } + +func TestReplaceCode(t *testing.T) { + var ( + newFunction = `package test +func NewMethod1() { + n := "test new method" + bla := fmt.Sprintf("test new - %s", n) + fmt.Println(bla) +}` + rollback = `package test +func NewMethod1() { + foo := 100 + bar := fmt.Sprintf("test - %d", foo) + fmt.Println(bar) +}` + ) + + type args struct { + path string + oldFunctionName string + newFunction string + } + tests := []struct { + name string + args args + err error + }{ + { + name: "function fooTest", + args: args{ + path: "testdata/replace.go", + oldFunctionName: "fooTest", + newFunction: newFunction, + }, + }, + { + name: "function BazTest", + args: args{ + path: "testdata/replace.go", + oldFunctionName: "BazTest", + newFunction: newFunction, + }, + }, + { + name: "function invalidFunction", + args: args{ + path: "testdata/replace.go", + oldFunctionName: "invalidFunction", + newFunction: newFunction, + }, + }, + { + name: "invalid path", + args: args{ + path: "invalid_path/invalid.go", + oldFunctionName: "invalidPath", + newFunction: newFunction, + }, + err: os.ErrNotExist, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := goanalysis.ReplaceCode(tt.args.path, tt.args.oldFunctionName, tt.args.newFunction) + if tt.err != nil { + require.Error(t, err) + require.ErrorIs(t, err, tt.err) + return + } + require.NoError(t, err) + require.NoError(t, goanalysis.ReplaceCode(tt.args.path, tt.args.oldFunctionName, rollback)) + }) + } +} diff --git a/ignite/pkg/goanalysis/testdata/replace.go b/ignite/pkg/goanalysis/testdata/replace.go new file mode 100644 index 0000000000..30c88d1fdc --- /dev/null +++ b/ignite/pkg/goanalysis/testdata/replace.go @@ -0,0 +1,15 @@ +package testdata + +import "fmt" + +func fooTest() { + foo := 100 + bar := fmt.Sprintf("test - %d", foo) + fmt.Println(bar) +} + +func BazTest() { + foo := 100 + bar := fmt.Sprintf("test - %d", foo) + fmt.Println(bar) +} From af20cbae6deb209d3385ebc67a65c44abe66c56b Mon Sep 17 00:00:00 2001 From: Pantani Date: Wed, 6 Dec 2023 18:31:57 +0100 Subject: [PATCH 02/42] add chain methods --- ignite/pkg/goanalysis/goanalysis.go | 66 +++--- ignite/pkg/goanalysis/goanalysis_test.go | 8 +- ignite/pkg/goanalysis/testdata/replace.go | 7 +- integration/ibc/cmd_relayer_test.go | 268 ++++++++++++++++++++++ 4 files changed, 315 insertions(+), 34 deletions(-) create mode 100644 integration/ibc/cmd_relayer_test.go diff --git a/ignite/pkg/goanalysis/goanalysis.go b/ignite/pkg/goanalysis/goanalysis.go index e88b030ede..57f55ff693 100644 --- a/ignite/pkg/goanalysis/goanalysis.go +++ b/ignite/pkg/goanalysis/goanalysis.go @@ -282,44 +282,56 @@ func createUnderscoreImport(imp string) *ast.ImportSpec { // ReplaceCode replace a function implementation into a package path. The method will find // the method signature and re-write the method implementation based in the new function. -func ReplaceCode(path, oldFunctionName, newFunction string) (err error) { - absPath, err := filepath.Abs(path) +func ReplaceCode(pkgPath, oldFunctionName, newFunction string) (err error) { + absPath, err := filepath.Abs(pkgPath) if err != nil { return err } - // Parse the input Go source file into an AST. - fset := token.NewFileSet() - node, err := parser.ParseFile(fset, absPath, nil, parser.ParseComments) + fileSet := token.NewFileSet() + all, err := parser.ParseDir(fileSet, absPath, func(os.FileInfo) bool { return true }, parser.ParseComments) if err != nil { return err } - // Traverse the AST to find and replace the function. - ast.Inspect(node, func(n ast.Node) bool { - // Check if the node is a function declaration. - if funcDecl, ok := n.(*ast.FuncDecl); ok { - // Check if the function has the name you want to replace. - if funcDecl.Name.Name == oldFunctionName { - // Replace the function body with the replacement code. - funcDecl.Body, err = parseReplacementCode(newFunction) - return false + for _, pkg := range all { + for _, f := range pkg.Files { + found := false + ast.Inspect(f, func(n ast.Node) bool { + // Check if the node is a function declaration. + if funcDecl, ok := n.(*ast.FuncDecl); ok { + // Check if the function has the name you want to replace. + if funcDecl.Name.Name == oldFunctionName { + // Replace the function body with the replacement code. + funcDecl.Body, err = parseReplacementCode(newFunction) + found = true + return false + } + } + return true + }) + if err != nil { + return err + } + if !found { + continue + } + filePath := fileSet.Position(f.Package).Filename + outFile, err := os.Create(filePath) + if err != nil { + return err } - } - return true - }) - if err != nil { - return err - } - outFile, err := os.Create(absPath) - if err != nil { - return err + // Format and write the modified AST to the output file. + if err := format.Node(outFile, fileSet, f); err != nil { + return err + } + if err := outFile.Close(); err != nil { + return err + } + } } - defer outFile.Close() - - // Format and write the modified AST to the output file. - return format.Node(outFile, fset, node) + return nil } // parseReplacementCode parse the replacement code and create a *ast.BlockStmt. diff --git a/ignite/pkg/goanalysis/goanalysis_test.go b/ignite/pkg/goanalysis/goanalysis_test.go index acb8337837..12e0eecade 100644 --- a/ignite/pkg/goanalysis/goanalysis_test.go +++ b/ignite/pkg/goanalysis/goanalysis_test.go @@ -532,7 +532,7 @@ func NewMethod1() { { name: "function fooTest", args: args{ - path: "testdata/replace.go", + path: "testdata", oldFunctionName: "fooTest", newFunction: newFunction, }, @@ -540,7 +540,7 @@ func NewMethod1() { { name: "function BazTest", args: args{ - path: "testdata/replace.go", + path: "testdata", oldFunctionName: "BazTest", newFunction: newFunction, }, @@ -548,7 +548,7 @@ func NewMethod1() { { name: "function invalidFunction", args: args{ - path: "testdata/replace.go", + path: "testdata", oldFunctionName: "invalidFunction", newFunction: newFunction, }, @@ -556,7 +556,7 @@ func NewMethod1() { { name: "invalid path", args: args{ - path: "invalid_path/invalid.go", + path: "invalid_path", oldFunctionName: "invalidPath", newFunction: newFunction, }, diff --git a/ignite/pkg/goanalysis/testdata/replace.go b/ignite/pkg/goanalysis/testdata/replace.go index 30c88d1fdc..20c1a12c70 100644 --- a/ignite/pkg/goanalysis/testdata/replace.go +++ b/ignite/pkg/goanalysis/testdata/replace.go @@ -3,9 +3,10 @@ package testdata import "fmt" func fooTest() { - foo := 100 - bar := fmt.Sprintf("test - %d", foo) - fmt.Println(bar) + n := "test new method" + bla := fmt.Sprintf("test new - %s", n) + fmt. + Println(bla) } func BazTest() { diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go new file mode 100644 index 0000000000..090aac76bb --- /dev/null +++ b/integration/ibc/cmd_relayer_test.go @@ -0,0 +1,268 @@ +//go:build !relayer + +package ibc_test + +import ( + "fmt" + "github.com/ignite/cli/v28/ignite/pkg/protoanalysis/protoutil" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ignite/cli/v28/ignite/pkg/cmdrunner/step" + "github.com/ignite/cli/v28/ignite/pkg/goanalysis" + envtest "github.com/ignite/cli/v28/integration" +) + +var ( + nameSendIbcPost = "SendIbcPost" + funcSendIbcPost = `package keeper +func (k msgServer) SendIbcPost(goCtx context.Context, msg *types.MsgSendIbcPost) (*types.MsgSendIbcPostResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + // TODO: logic before transmitting the packet + + // Construct the packet + var packet types.IbcPostPacketData + + packet.Title = msg.Title + packet.Content = msg.Content + + // Transmit the packet + _, err := k.TransmitIbcPostPacket( + ctx, + packet, + msg.Port, + msg.ChannelID, + clienttypes.ZeroHeight(), + msg.TimeoutTimestamp, + ) + if err != nil { + return nil, err + } + + return &types.MsgSendIbcPostResponse{}, nil +}` + + nameOnRecvIbcPostPacket = "OnRecvIbcPostPacket" + funcOnRecvIbcPostPacket = `package keeper +func (k Keeper) OnRecvIbcPostPacket(ctx sdk.Context, packet channeltypes.Packet, data types.IbcPostPacketData) (packetAck types.IbcPostPacketAck, err error) { + // validate packet data upon receiving + if err := data.ValidateBasic(); err != nil { + return packetAck, err + } + + id := k.AppendPost( + ctx, + types.Post{ + Title: data.Title, + Content: data.Content, + }, + ) + + packetAck.PostId = strconv.FormatUint(id, 10) + + return packetAck, nil +}` + + nameOnAcknowledgementIbcPostPacket = "OnAcknowledgementIbcPostPacket" + funcOnAcknowledgementIbcPostPacket = `package keeper +func (k Keeper) OnAcknowledgementIbcPostPacket(ctx sdk.Context, packet channeltypes.Packet, data types.IbcPostPacketData, ack channeltypes.Acknowledgement) error { + switch dispatchedAck := ack.Response.(type) { + case *channeltypes.Acknowledgement_Error: + // We will not treat acknowledgment error in this tutorial + return nil + case *channeltypes.Acknowledgement_Result: + // Decode the packet acknowledgment + var packetAck types.IbcPostPacketAck + + if err := types.ModuleCdc.UnmarshalJSON(dispatchedAck.Result, &packetAck); err != nil { + // The counter-party module doesn't implement the correct acknowledgment format + return errors.New("cannot unmarshal acknowledgment") + } + + k.AppendSentPost( + ctx, + types.SentPost{ + PostId: packetAck.PostId, + Title: data.Title, + Chain: packet.DestinationPort + "-" + packet.DestinationChannel, + }, + ) + + return nil + default: + return errors.New("the counter-party module does not implement the correct acknowledgment format") + } +}` + + nameOnTimeoutIbcPostPacket = "OnTimeoutIbcPostPacket" + funcOnTimeoutIbcPostPacket = `package keeper +func (k Keeper) OnTimeoutIbcPostPacket(ctx sdk.Context, packet channeltypes.Packet, data types.IbcPostPacketData) error { + k.AppendTimedoutPost( + ctx, + types.TimedoutPost{ + Title: data.Title, + Chain: packet.DestinationPort + "-" + packet.DestinationChannel, + }, + ) + + return nil +}` +) + +func TestBlogIBC(t *testing.T) { + var ( + env = envtest.New(t) + app = env.Scaffold("github.com/test/planet") + ) + + env.Must(env.Exec("create an IBC module", + step.NewSteps(step.New( + step.Exec(envtest.IgniteApp, + "s", + "module", + "blog", + "--ibc", + "--require-registration", + "--yes", + ), + step.Workdir(app.SourcePath()), + )), + )) + + env.Must(env.Exec("create a post type list in an IBC module", + step.NewSteps(step.New( + step.Exec(envtest.IgniteApp, + "s", + "list", + "post", + "title", + "content", + "creator", + "--no-message", + "--module", + "blog", + "--yes", + ), + step.Workdir(app.SourcePath()), + )), + )) + + env.Must(env.Exec("create a sentPost type list in an IBC module", + step.NewSteps(step.New( + step.Exec(envtest.IgniteApp, + "s", + "list", + "sentPost", + "postID", + "title", + "chain", + "creator", + "--no-message", + "--module", + "blog", + "--yes", + ), + step.Workdir(app.SourcePath()), + )), + )) + + env.Must(env.Exec("create a timedoutPost type list in an IBC module", + step.NewSteps(step.New( + step.Exec(envtest.IgniteApp, + "s", + "list", + "timedoutPost", + "title", + "chain", + "creator", + "--no-message", + "--module", + "blog", + "--yes", + ), + step.Workdir(app.SourcePath()), + )), + )) + + env.Must(env.Exec("create a ibcPost package in an IBC module", + step.NewSteps(step.New( + step.Exec(envtest.IgniteApp, + "s", + "packet", + "ibcPost", + "title", + "content", + "--ack", + "postID", + "--module", + "blog", + "--yes", + ), + step.Workdir(app.SourcePath()), + )), + )) + + //protoPacketPath := filepath.Join(app.SourcePath(), "proto/planet/blog/packet.proto") + //require.NoError(t, addCreatorToPacket(protoPacketPath)) + + blogKeeperPath := filepath.Join(app.SourcePath(), "x/blog/keeper") + require.NoError(t, goanalysis.ReplaceCode( + blogKeeperPath, + nameSendIbcPost, + funcSendIbcPost, + )) + require.NoError(t, goanalysis.ReplaceCode( + blogKeeperPath, + nameOnRecvIbcPostPacket, + funcOnRecvIbcPostPacket, + )) + require.NoError(t, goanalysis.ReplaceCode( + blogKeeperPath, + nameOnAcknowledgementIbcPostPacket, + funcOnAcknowledgementIbcPostPacket, + )) + require.NoError(t, goanalysis.ReplaceCode( + blogKeeperPath, + nameOnTimeoutIbcPostPacket, + funcOnTimeoutIbcPostPacket, + )) + + app.EnsureSteady() +} + +func addCreatorToPacket(path string) error { + f, err := os.OpenFile(path, os.O_RDWR|os.O_TRUNC|os.O_APPEND, 0660) + if err != nil { + return err + } + protoFile, err := protoutil.ParseProtoFile(f) + if err != nil { + return err + } + + IbcPostPacketData, err := protoutil.GetMessageByName(protoFile, "IbcPostPacketData") + if err != nil { + return fmt.Errorf("couldn't find message 'IbcPostPacketData' in %s: %w", path, err) + } + field := protoutil.NewField("creator", "string", protoutil.NextUniqueID(IbcPostPacketData)) + protoutil.Append(IbcPostPacketData, field) + + p := protoutil.Print(protoFile) + err = f.Truncate(0) + if err != nil { + return err + } + _, err = f.Seek(0, 0) + if err != nil { + return err + } + _, err = fmt.Fprintf(f, "%d", len(p)) + if err != nil { + return err + } + return nil +} From 72f9af815e1d3cbbbefa94f3c49ca4f760f2d8f3 Mon Sep 17 00:00:00 2001 From: Pantani Date: Wed, 6 Dec 2023 18:43:21 +0100 Subject: [PATCH 03/42] simplify te logic --- integration/ibc/cmd_relayer_test.go | 78 +++-------------------------- 1 file changed, 6 insertions(+), 72 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index 090aac76bb..aa1adb84e4 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -3,9 +3,6 @@ package ibc_test import ( - "fmt" - "github.com/ignite/cli/v28/ignite/pkg/protoanalysis/protoutil" - "os" "path/filepath" "testing" @@ -21,15 +18,10 @@ var ( funcSendIbcPost = `package keeper func (k msgServer) SendIbcPost(goCtx context.Context, msg *types.MsgSendIbcPost) (*types.MsgSendIbcPostResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - - // TODO: logic before transmitting the packet - // Construct the packet var packet types.IbcPostPacketData - packet.Title = msg.Title packet.Content = msg.Content - // Transmit the packet _, err := k.TransmitIbcPostPacket( ctx, @@ -39,11 +31,7 @@ func (k msgServer) SendIbcPost(goCtx context.Context, msg *types.MsgSendIbcPost) clienttypes.ZeroHeight(), msg.TimeoutTimestamp, ) - if err != nil { - return nil, err - } - - return &types.MsgSendIbcPostResponse{}, nil + return &types.MsgSendIbcPostResponse{}, err }` nameOnRecvIbcPostPacket = "OnRecvIbcPostPacket" @@ -53,17 +41,7 @@ func (k Keeper) OnRecvIbcPostPacket(ctx sdk.Context, packet channeltypes.Packet, if err := data.ValidateBasic(); err != nil { return packetAck, err } - - id := k.AppendPost( - ctx, - types.Post{ - Title: data.Title, - Content: data.Content, - }, - ) - - packetAck.PostId = strconv.FormatUint(id, 10) - + packetAck.PostId = k.AppendPost(ctx, types.Post{Title: data.Title, Content: data.Content}) return packetAck, nil }` @@ -77,21 +55,18 @@ func (k Keeper) OnAcknowledgementIbcPostPacket(ctx sdk.Context, packet channelty case *channeltypes.Acknowledgement_Result: // Decode the packet acknowledgment var packetAck types.IbcPostPacketAck - if err := types.ModuleCdc.UnmarshalJSON(dispatchedAck.Result, &packetAck); err != nil { // The counter-party module doesn't implement the correct acknowledgment format return errors.New("cannot unmarshal acknowledgment") } - k.AppendSentPost( - ctx, + k.AppendSentPost(ctx, types.SentPost{ PostId: packetAck.PostId, Title: data.Title, Chain: packet.DestinationPort + "-" + packet.DestinationChannel, }, ) - return nil default: return errors.New("the counter-party module does not implement the correct acknowledgment format") @@ -101,14 +76,12 @@ func (k Keeper) OnAcknowledgementIbcPostPacket(ctx sdk.Context, packet channelty nameOnTimeoutIbcPostPacket = "OnTimeoutIbcPostPacket" funcOnTimeoutIbcPostPacket = `package keeper func (k Keeper) OnTimeoutIbcPostPacket(ctx sdk.Context, packet channeltypes.Packet, data types.IbcPostPacketData) error { - k.AppendTimedoutPost( - ctx, + k.AppendTimedoutPost(ctx, types.TimedoutPost{ Title: data.Title, Chain: packet.DestinationPort + "-" + packet.DestinationChannel, }, ) - return nil }` ) @@ -141,7 +114,6 @@ func TestBlogIBC(t *testing.T) { "post", "title", "content", - "creator", "--no-message", "--module", "blog", @@ -157,10 +129,9 @@ func TestBlogIBC(t *testing.T) { "s", "list", "sentPost", - "postID", + "postID:uint", "title", "chain", - "creator", "--no-message", "--module", "blog", @@ -178,7 +149,6 @@ func TestBlogIBC(t *testing.T) { "timedoutPost", "title", "chain", - "creator", "--no-message", "--module", "blog", @@ -197,7 +167,7 @@ func TestBlogIBC(t *testing.T) { "title", "content", "--ack", - "postID", + "postID:uint", "--module", "blog", "--yes", @@ -206,9 +176,6 @@ func TestBlogIBC(t *testing.T) { )), )) - //protoPacketPath := filepath.Join(app.SourcePath(), "proto/planet/blog/packet.proto") - //require.NoError(t, addCreatorToPacket(protoPacketPath)) - blogKeeperPath := filepath.Join(app.SourcePath(), "x/blog/keeper") require.NoError(t, goanalysis.ReplaceCode( blogKeeperPath, @@ -233,36 +200,3 @@ func TestBlogIBC(t *testing.T) { app.EnsureSteady() } - -func addCreatorToPacket(path string) error { - f, err := os.OpenFile(path, os.O_RDWR|os.O_TRUNC|os.O_APPEND, 0660) - if err != nil { - return err - } - protoFile, err := protoutil.ParseProtoFile(f) - if err != nil { - return err - } - - IbcPostPacketData, err := protoutil.GetMessageByName(protoFile, "IbcPostPacketData") - if err != nil { - return fmt.Errorf("couldn't find message 'IbcPostPacketData' in %s: %w", path, err) - } - field := protoutil.NewField("creator", "string", protoutil.NextUniqueID(IbcPostPacketData)) - protoutil.Append(IbcPostPacketData, field) - - p := protoutil.Print(protoFile) - err = f.Truncate(0) - if err != nil { - return err - } - _, err = f.Seek(0, 0) - if err != nil { - return err - } - _, err = fmt.Fprintf(f, "%d", len(p)) - if err != nil { - return err - } - return nil -} From 77b727c8b71c9c359e8b946d602b02380d861163 Mon Sep 17 00:00:00 2001 From: Pantani Date: Wed, 6 Dec 2023 19:12:27 +0100 Subject: [PATCH 04/42] spin up both chains --- integration/ibc/cmd_relayer_test.go | 95 ++++++++++++++++++++++++++++- integration/ibc/testdata/earth.yml | 28 +++++++++ integration/ibc/testdata/mars.yml | 41 +++++++++++++ 3 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 integration/ibc/testdata/earth.yml create mode 100644 integration/ibc/testdata/mars.yml diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index aa1adb84e4..5cfd2c8801 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -3,6 +3,10 @@ package ibc_test import ( + "bytes" + "context" + "encoding/json" + "fmt" "path/filepath" "testing" @@ -10,6 +14,7 @@ import ( "github.com/ignite/cli/v28/ignite/pkg/cmdrunner/step" "github.com/ignite/cli/v28/ignite/pkg/goanalysis" + "github.com/ignite/cli/v28/ignite/pkg/xurl" envtest "github.com/ignite/cli/v28/integration" ) @@ -88,10 +93,17 @@ func (k Keeper) OnTimeoutIbcPostPacket(ctx sdk.Context, packet channeltypes.Pack func TestBlogIBC(t *testing.T) { var ( - env = envtest.New(t) - app = env.Scaffold("github.com/test/planet") + env = envtest.New(t) + app = env.Scaffold("github.com/test/planet") + servers = app.RandomizeServerPorts() + ctx = env.Ctx() ) + nodeAddr, err := xurl.TCP(servers.RPC) + if err != nil { + t.Fatalf("cant read nodeAddr from host.RPC %v: %v", servers.RPC, err) + } + env.Must(env.Exec("create an IBC module", step.NewSteps(step.New( step.Exec(envtest.IgniteApp, @@ -198,5 +210,82 @@ func TestBlogIBC(t *testing.T) { funcOnTimeoutIbcPostPacket, )) - app.EnsureSteady() + // serve both chains + ctxEarth, cancelEarth := context.WithCancel(ctx) + go func() { + defer cancelEarth() + env.Must(app.Serve("should serve earth", envtest.ExecCtx(ctxEarth))) + }() + ctxMars, cancelMars := context.WithCancel(ctx) + go func() { + defer cancelMars() + env.Must(app.Serve("should serve mars", envtest.ExecCtx(ctxMars))) + }() + + // check the chains is up + stepsCheck := step.NewSteps( + step.New( + step.Exec( + app.Binary(), + "config", + "output", "json", + ), + step.PreExec(func() error { + // todo set chain configs + if err := env.IsAppServed(ctx, servers.API); err != nil { + return err + } + return env.IsAppServed(ctx, servers.API) + }), + ), + ) + env.Exec("waiting the chain is up", stepsCheck, envtest.ExecRetry()) + + var ( + output = &bytes.Buffer{} + txResponse struct { + Code int + RawLog string `json:"raw_log"` + } + ) + // sign tx to add an item to the list. + stepsTx := step.NewSteps( + step.New( + step.Stdout(output), + step.PreExec(func() error { + err := env.IsAppServed(ctx, servers.API) + return err + }), + step.Exec( + app.Binary(), + "tx", + "blog", + "send-ibc-post", + "channel-0", + "Hello", + "Hello Mars, I'm Alice from Earth", + "--chain-id", "blog", + "--from", "alice", + "--node", nodeAddr, + "--output", "json", + "--log_format", "json", + "--yes", + ), + step.PostExec(func(execErr error) error { + if execErr != nil { + return execErr + } + err := json.Unmarshal(output.Bytes(), &txResponse) + if err != nil { + return fmt.Errorf("unmarshling tx response: %w", err) + } + return nil + }), + ), + ) + if !env.Exec("sign a tx", stepsTx, envtest.ExecRetry()) { + t.FailNow() + } + require.Equal(t, 0, txResponse.Code, + "tx failed code=%d log=%s", txResponse.Code, txResponse.RawLog) } diff --git a/integration/ibc/testdata/earth.yml b/integration/ibc/testdata/earth.yml new file mode 100644 index 0000000000..a432139314 --- /dev/null +++ b/integration/ibc/testdata/earth.yml @@ -0,0 +1,28 @@ +version: 1 +build: + proto: + path: proto + third_party_paths: + - third_party/proto + - proto_vendor +accounts: + - name: alice + coins: + - 1000token + - 100000000stake + - name: bob + coins: + - 500token + - 100000000stake +faucet: + name: bob + coins: + - 5token + - 100000stake + host: 0.0.0.0:4500 +genesis: + chain_id: earth +validators: + - name: alice + bonded: 100000000stake + home: $HOME/.earth \ No newline at end of file diff --git a/integration/ibc/testdata/mars.yml b/integration/ibc/testdata/mars.yml new file mode 100644 index 0000000000..b6042529fd --- /dev/null +++ b/integration/ibc/testdata/mars.yml @@ -0,0 +1,41 @@ +version: 1 +build: + proto: + path: proto + third_party_paths: + - third_party/proto + - proto_vendor +accounts: + - name: alice + coins: + - 1000token + - 1000000000stake + - name: bob + coins: + - 500token + - 100000000stake +faucet: + name: bob + coins: + - 5token + - 100000stake + host: :4501 +genesis: + chain_id: mars +validators: + - name: alice + bonded: 100000000stake + app: + api: + address: :1318 + grpc: + address: :9092 + grpc-web: + address: :9093 + config: + p2p: + laddr: :26658 + rpc: + laddr: :26659 + pprof_laddr: :6061 + home: $HOME/.mars \ No newline at end of file From d3ffcc436bf021ff373e6bdd022b04e4077cd1fe Mon Sep 17 00:00:00 2001 From: Pantani Date: Wed, 6 Dec 2023 19:13:01 +0100 Subject: [PATCH 05/42] add reminder --- integration/ibc/cmd_relayer_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index 5cfd2c8801..8f90f6f853 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -241,6 +241,8 @@ func TestBlogIBC(t *testing.T) { ) env.Exec("waiting the chain is up", stepsCheck, envtest.ExecRetry()) + // TODO setup a relayer + var ( output = &bytes.Buffer{} txResponse struct { From 434adb1889ec9dad1c80e7c270536c3af635ad34 Mon Sep 17 00:00:00 2001 From: Pantani Date: Fri, 8 Dec 2023 17:17:47 -0300 Subject: [PATCH 06/42] add relayers --- integration/ibc/cmd_relayer_test.go | 43 +++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index 8f90f6f853..d924323819 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -81,8 +81,8 @@ func (k Keeper) OnAcknowledgementIbcPostPacket(ctx sdk.Context, packet channelty nameOnTimeoutIbcPostPacket = "OnTimeoutIbcPostPacket" funcOnTimeoutIbcPostPacket = `package keeper func (k Keeper) OnTimeoutIbcPostPacket(ctx sdk.Context, packet channeltypes.Packet, data types.IbcPostPacketData) error { - k.AppendTimedoutPost(ctx, - types.TimedoutPost{ + k.AppendTimeoutPost(ctx, + types.TimeoutPost{ Title: data.Title, Chain: packet.DestinationPort + "-" + packet.DestinationChannel, }, @@ -153,12 +153,12 @@ func TestBlogIBC(t *testing.T) { )), )) - env.Must(env.Exec("create a timedoutPost type list in an IBC module", + env.Must(env.Exec("create a timeoutPost type list in an IBC module", step.NewSteps(step.New( step.Exec(envtest.IgniteApp, "s", "list", - "timedoutPost", + "timeoutPost", "title", "chain", "--no-message", @@ -222,6 +222,39 @@ func TestBlogIBC(t *testing.T) { env.Must(app.Serve("should serve mars", envtest.ExecCtx(ctxMars))) }() + // configure and run the ts relayer. + env.Must(env.Exec("configure the ts relayer", + step.NewSteps(step.New( + step.Exec(envtest.IgniteApp, + "relayer", + "configure", "-a", + "--source-rpc", "http://0.0.0.0:26657", + "--source-faucet", "http://0.0.0.0:4500", + "--source-port", "planet", + "--source-version", "earth-1", + "--source-gasprice", "0.0000025stake", + "--source-prefix", "cosmos", + "--source-gaslimit", "300000", + "--target-rpc", "http://0.0.0.0:26659", + "--target-faucet", "http://0.0.0.0:4501", + "--target-port", "planet", + "--target-version", "mars-1", + "--target-gasprice", "0.0000025stake", + "--target-prefix", "cosmos", + "--target-gaslimit", "300000", + ), + step.Workdir(app.SourcePath()), + )), + )) + go func() { + env.Must(env.Exec("run the ts relayer", + step.NewSteps(step.New( + step.Exec(envtest.IgniteApp, "relayer", "connect"), + step.Workdir(app.SourcePath()), + )), + )) + }() + // check the chains is up stepsCheck := step.NewSteps( step.New( @@ -241,8 +274,6 @@ func TestBlogIBC(t *testing.T) { ) env.Exec("waiting the chain is up", stepsCheck, envtest.ExecRetry()) - // TODO setup a relayer - var ( output = &bytes.Buffer{} txResponse struct { From 138615d6df8b31d89443f2d2d2eab8220198687e Mon Sep 17 00:00:00 2001 From: Pantani Date: Sat, 9 Dec 2023 20:13:41 -0300 Subject: [PATCH 07/42] create configs into the code and add a helper to setup and run chains --- integration/ibc/cmd_relayer_test.go | 191 +++++++++++++++++++++------- integration/ibc/testdata/earth.yml | 28 ---- integration/ibc/testdata/mars.yml | 41 ------ 3 files changed, 148 insertions(+), 112 deletions(-) delete mode 100644 integration/ibc/testdata/earth.yml delete mode 100644 integration/ibc/testdata/mars.yml diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index d924323819..c2119c1c3d 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -7,18 +7,127 @@ import ( "context" "encoding/json" "fmt" + "os" "path/filepath" "testing" "github.com/stretchr/testify/require" + "github.com/ignite/cli/v28/ignite/config/chain" + "github.com/ignite/cli/v28/ignite/config/chain/base" + v1 "github.com/ignite/cli/v28/ignite/config/chain/v1" + "github.com/ignite/cli/v28/ignite/pkg/availableport" "github.com/ignite/cli/v28/ignite/pkg/cmdrunner/step" "github.com/ignite/cli/v28/ignite/pkg/goanalysis" + "github.com/ignite/cli/v28/ignite/pkg/randstr" "github.com/ignite/cli/v28/ignite/pkg/xurl" + "github.com/ignite/cli/v28/ignite/pkg/yaml" envtest "github.com/ignite/cli/v28/integration" ) +func runChain(t *testing.T, env envtest.Env, app envtest.App, cfg v1.Config) string { + t.Helper() + var ( + ctx = env.Ctx() + tmpDir = t.TempDir() + homePath = filepath.Join(tmpDir, randstr.Runes(10)) + cfgPath = filepath.Join(tmpDir, chain.ConfigFilenames[0]) + ) + t.Cleanup(func() { + require.NoError(t, os.RemoveAll(homePath)) + }) + + genAddr := func(port uint) string { + return fmt.Sprintf("127.0.0.1:%d", port) + } + + cfg.Validators[0].Home = homePath + ports, err := availableport.Find(7) + require.NoError(t, err) + + cfg.Faucet.Host = genAddr(ports[0]) + cfg.Validators[0].App["api"] = yaml.Map{"address": genAddr(ports[1])} + cfg.Validators[0].App["grpc"] = yaml.Map{"address": genAddr(ports[2])} + cfg.Validators[0].App["grpc-web"] = yaml.Map{"address": genAddr(ports[3])} + cfg.Validators[0].Config["p2p"] = yaml.Map{"laddr": genAddr(ports[4])} + cfg.Validators[0].Config["rpc"] = yaml.Map{ + "laddr": genAddr(ports[5]), + "pprof_laddr": genAddr(ports[6]), + } + + err = chain.Save(cfg, cfgPath) + require.NoError(t, err) + + app.SetConfigPath(cfgPath) + + ctx, cancel := context.WithCancel(ctx) + go func() { + defer cancel() + env.Must(app.Serve("should serve chain", envtest.ExecCtx(ctx))) + }() + return genAddr(ports[5]) +} + var ( + bobName = "bob" + marsConfig = v1.Config{ + Config: base.Config{ + Build: base.Build{ + Proto: base.Proto{ + Path: "proto", + ThirdPartyPaths: []string{"third_party/proto", "proto_vendor"}, + }, + }, + Accounts: []base.Account{ + {Name: "alice", Coins: []string{"1000token", "1000000000stake"}}, + {Name: "bob", Coins: []string{"500token", "100000000stake"}}, + }, + Faucet: base.Faucet{ + Name: &bobName, + Coins: []string{"5token", "100000stake"}, + Host: ":4501", + }, + Genesis: yaml.Map{"chain_id": "mars"}, + }, + Validators: []v1.Validator{ + { + Name: "alice", + Bonded: "100000000stake", + App: yaml.Map{ + "api": yaml.Map{"address": ":1318"}, + "grpc": yaml.Map{"address": ":9092"}, + "grpc-web": yaml.Map{"address": ":9093"}, + }, + Config: yaml.Map{ + "p2p": yaml.Map{"laddr": ":26658"}, + "rpc": yaml.Map{"laddr": ":26658", "pprof_laddr": ":6061"}, + }, + Home: "$HOME/.mars", + }, + }, + } + earthConfig = v1.Config{ + Config: base.Config{ + Build: base.Build{ + Proto: base.Proto{ + Path: "proto", + ThirdPartyPaths: []string{"third_party/proto", "proto_vendor"}, + }, + }, + Accounts: []base.Account{ + {Name: "alice", Coins: []string{"1000token", "1000000000stake"}}, + {Name: "bob", Coins: []string{"500token", "100000000stake"}}, + }, + Faucet: base.Faucet{ + Name: &bobName, + Coins: []string{"5token", "100000stake"}, + Host: ":4500", + }, + Genesis: yaml.Map{"chain_id": "earth"}, + }, + Validators: []v1.Validator{{Name: "alice", Bonded: "100000000stake", Home: "$HOME/.earth"}}, + } + nameSendIbcPost = "SendIbcPost" funcSendIbcPost = `package keeper func (k msgServer) SendIbcPost(goCtx context.Context, msg *types.MsgSendIbcPost) (*types.MsgSendIbcPostResponse, error) { @@ -93,16 +202,15 @@ func (k Keeper) OnTimeoutIbcPostPacket(ctx sdk.Context, packet channeltypes.Pack func TestBlogIBC(t *testing.T) { var ( - env = envtest.New(t) - app = env.Scaffold("github.com/test/planet") - servers = app.RandomizeServerPorts() - ctx = env.Ctx() + env = envtest.New(t) + app = env.Scaffold("github.com/test/planet") + ctx = env.Ctx() ) - nodeAddr, err := xurl.TCP(servers.RPC) - if err != nil { - t.Fatalf("cant read nodeAddr from host.RPC %v: %v", servers.RPC, err) - } + //nodeAddr, err := xurl.TCP(servers.RPC) + //if err != nil { + // t.Fatalf("cant read nodeAddr from host.RPC %v: %v", servers.RPC, err) + //} env.Must(env.Exec("create an IBC module", step.NewSteps(step.New( @@ -210,17 +318,27 @@ func TestBlogIBC(t *testing.T) { funcOnTimeoutIbcPostPacket, )) - // serve both chains - ctxEarth, cancelEarth := context.WithCancel(ctx) - go func() { - defer cancelEarth() - env.Must(app.Serve("should serve earth", envtest.ExecCtx(ctxEarth))) - }() - ctxMars, cancelMars := context.WithCancel(ctx) - go func() { - defer cancelMars() - env.Must(app.Serve("should serve mars", envtest.ExecCtx(ctxMars))) - }() + // serve both chains. + earthRPC := runChain(t, env, app, earthConfig) + marsRPC := runChain(t, env, app, marsConfig) + + // check the chains is up + stepsCheck := step.NewSteps( + step.New( + step.Exec( + app.Binary(), + "base", + "output", "json", + ), + step.PreExec(func() error { + if err := env.IsAppServed(ctx, earthRPC); err != nil { + return err + } + return env.IsAppServed(ctx, marsRPC) + }), + ), + ) + env.Exec("waiting the chain is up", stepsCheck, envtest.ExecRetry()) // configure and run the ts relayer. env.Must(env.Exec("configure the ts relayer", @@ -230,15 +348,15 @@ func TestBlogIBC(t *testing.T) { "configure", "-a", "--source-rpc", "http://0.0.0.0:26657", "--source-faucet", "http://0.0.0.0:4500", - "--source-port", "planet", - "--source-version", "earth-1", + "--source-port", "blog", + "--source-version", "blog-1", "--source-gasprice", "0.0000025stake", "--source-prefix", "cosmos", "--source-gaslimit", "300000", "--target-rpc", "http://0.0.0.0:26659", "--target-faucet", "http://0.0.0.0:4501", - "--target-port", "planet", - "--target-version", "mars-1", + "--target-port", "blog", + "--target-version", "blog-1", "--target-gasprice", "0.0000025stake", "--target-prefix", "cosmos", "--target-gaslimit", "300000", @@ -255,25 +373,6 @@ func TestBlogIBC(t *testing.T) { )) }() - // check the chains is up - stepsCheck := step.NewSteps( - step.New( - step.Exec( - app.Binary(), - "config", - "output", "json", - ), - step.PreExec(func() error { - // todo set chain configs - if err := env.IsAppServed(ctx, servers.API); err != nil { - return err - } - return env.IsAppServed(ctx, servers.API) - }), - ), - ) - env.Exec("waiting the chain is up", stepsCheck, envtest.ExecRetry()) - var ( output = &bytes.Buffer{} txResponse struct { @@ -281,12 +380,18 @@ func TestBlogIBC(t *testing.T) { RawLog string `json:"raw_log"` } ) + + nodeAddr, err := xurl.TCP(earthRPC) + if err != nil { + t.Fatalf("cant read nodeAddr from host.RPC %v: %v", earthRPC, err) + } + // sign tx to add an item to the list. stepsTx := step.NewSteps( step.New( step.Stdout(output), step.PreExec(func() error { - err := env.IsAppServed(ctx, servers.API) + err := env.IsAppServed(ctx, earthRPC) return err }), step.Exec( diff --git a/integration/ibc/testdata/earth.yml b/integration/ibc/testdata/earth.yml deleted file mode 100644 index a432139314..0000000000 --- a/integration/ibc/testdata/earth.yml +++ /dev/null @@ -1,28 +0,0 @@ -version: 1 -build: - proto: - path: proto - third_party_paths: - - third_party/proto - - proto_vendor -accounts: - - name: alice - coins: - - 1000token - - 100000000stake - - name: bob - coins: - - 500token - - 100000000stake -faucet: - name: bob - coins: - - 5token - - 100000stake - host: 0.0.0.0:4500 -genesis: - chain_id: earth -validators: - - name: alice - bonded: 100000000stake - home: $HOME/.earth \ No newline at end of file diff --git a/integration/ibc/testdata/mars.yml b/integration/ibc/testdata/mars.yml deleted file mode 100644 index b6042529fd..0000000000 --- a/integration/ibc/testdata/mars.yml +++ /dev/null @@ -1,41 +0,0 @@ -version: 1 -build: - proto: - path: proto - third_party_paths: - - third_party/proto - - proto_vendor -accounts: - - name: alice - coins: - - 1000token - - 1000000000stake - - name: bob - coins: - - 500token - - 100000000stake -faucet: - name: bob - coins: - - 5token - - 100000stake - host: :4501 -genesis: - chain_id: mars -validators: - - name: alice - bonded: 100000000stake - app: - api: - address: :1318 - grpc: - address: :9092 - grpc-web: - address: :9093 - config: - p2p: - laddr: :26658 - rpc: - laddr: :26659 - pprof_laddr: :6061 - home: $HOME/.mars \ No newline at end of file From a1d0e9e4f57f66cbb87f41a013360fe09439e14c Mon Sep 17 00:00:00 2001 From: Pantani Date: Sat, 9 Dec 2023 20:38:19 -0300 Subject: [PATCH 08/42] fix chain config --- integration/ibc/cmd_relayer_test.go | 131 +++++++++++++++------------- 1 file changed, 72 insertions(+), 59 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index c2119c1c3d..e5cf5d59eb 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -12,6 +12,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "gopkg.in/yaml.v2" "github.com/ignite/cli/v28/ignite/config/chain" "github.com/ignite/cli/v28/ignite/config/chain/base" @@ -21,53 +22,10 @@ import ( "github.com/ignite/cli/v28/ignite/pkg/goanalysis" "github.com/ignite/cli/v28/ignite/pkg/randstr" "github.com/ignite/cli/v28/ignite/pkg/xurl" - "github.com/ignite/cli/v28/ignite/pkg/yaml" + yamlmap "github.com/ignite/cli/v28/ignite/pkg/yaml" envtest "github.com/ignite/cli/v28/integration" ) -func runChain(t *testing.T, env envtest.Env, app envtest.App, cfg v1.Config) string { - t.Helper() - var ( - ctx = env.Ctx() - tmpDir = t.TempDir() - homePath = filepath.Join(tmpDir, randstr.Runes(10)) - cfgPath = filepath.Join(tmpDir, chain.ConfigFilenames[0]) - ) - t.Cleanup(func() { - require.NoError(t, os.RemoveAll(homePath)) - }) - - genAddr := func(port uint) string { - return fmt.Sprintf("127.0.0.1:%d", port) - } - - cfg.Validators[0].Home = homePath - ports, err := availableport.Find(7) - require.NoError(t, err) - - cfg.Faucet.Host = genAddr(ports[0]) - cfg.Validators[0].App["api"] = yaml.Map{"address": genAddr(ports[1])} - cfg.Validators[0].App["grpc"] = yaml.Map{"address": genAddr(ports[2])} - cfg.Validators[0].App["grpc-web"] = yaml.Map{"address": genAddr(ports[3])} - cfg.Validators[0].Config["p2p"] = yaml.Map{"laddr": genAddr(ports[4])} - cfg.Validators[0].Config["rpc"] = yaml.Map{ - "laddr": genAddr(ports[5]), - "pprof_laddr": genAddr(ports[6]), - } - - err = chain.Save(cfg, cfgPath) - require.NoError(t, err) - - app.SetConfigPath(cfgPath) - - ctx, cancel := context.WithCancel(ctx) - go func() { - defer cancel() - env.Must(app.Serve("should serve chain", envtest.ExecCtx(ctx))) - }() - return genAddr(ports[5]) -} - var ( bobName = "bob" marsConfig = v1.Config{ @@ -87,20 +45,20 @@ var ( Coins: []string{"5token", "100000stake"}, Host: ":4501", }, - Genesis: yaml.Map{"chain_id": "mars"}, + Genesis: yamlmap.Map{"chain_id": "mars"}, }, Validators: []v1.Validator{ { Name: "alice", Bonded: "100000000stake", - App: yaml.Map{ - "api": yaml.Map{"address": ":1318"}, - "grpc": yaml.Map{"address": ":9092"}, - "grpc-web": yaml.Map{"address": ":9093"}, + App: yamlmap.Map{ + "api": yamlmap.Map{"address": ":1318"}, + "grpc": yamlmap.Map{"address": ":9092"}, + "grpc-web": yamlmap.Map{"address": ":9093"}, }, - Config: yaml.Map{ - "p2p": yaml.Map{"laddr": ":26658"}, - "rpc": yaml.Map{"laddr": ":26658", "pprof_laddr": ":6061"}, + Config: yamlmap.Map{ + "p2p": yamlmap.Map{"laddr": ":26658"}, + "rpc": yamlmap.Map{"laddr": ":26658", "pprof_laddr": ":6061"}, }, Home: "$HOME/.mars", }, @@ -123,9 +81,24 @@ var ( Coins: []string{"5token", "100000stake"}, Host: ":4500", }, - Genesis: yaml.Map{"chain_id": "earth"}, + Genesis: yamlmap.Map{"chain_id": "earth"}, + }, + Validators: []v1.Validator{ + { + Name: "alice", + Bonded: "100000000stake", + App: yamlmap.Map{ + "api": yamlmap.Map{"address": ":1317"}, + "grpc": yamlmap.Map{"address": ":9090"}, + "grpc-web": yamlmap.Map{"address": ":9091"}, + }, + Config: yamlmap.Map{ + "p2p": yamlmap.Map{"laddr": ":26656"}, + "rpc": yamlmap.Map{"laddr": ":26656", "pprof_laddr": ":6060"}, + }, + Home: "$HOME/.earth", + }, }, - Validators: []v1.Validator{{Name: "alice", Bonded: "100000000stake", Home: "$HOME/.earth"}}, } nameSendIbcPost = "SendIbcPost" @@ -200,6 +173,51 @@ func (k Keeper) OnTimeoutIbcPostPacket(ctx sdk.Context, packet channeltypes.Pack }` ) +func runChain(t *testing.T, env envtest.Env, app envtest.App, cfg v1.Config) string { + t.Helper() + var ( + tmpDir = t.TempDir() + homePath = filepath.Join(tmpDir, randstr.Runes(10)) + cfgPath = filepath.Join(tmpDir, chain.ConfigFilenames[0]) + ctx = env.Ctx() + ) + genAddr := func(port uint) string { + return fmt.Sprintf("0.0.0.0:%d", port) + } + + cfg.Validators[0].Home = homePath + ports, err := availableport.Find(7) + require.NoError(t, err) + + cfg.Faucet.Host = genAddr(ports[0]) + cfg.Validators[0].App["api"] = yamlmap.Map{"address": genAddr(ports[1])} + cfg.Validators[0].App["grpc"] = yamlmap.Map{"address": genAddr(ports[2])} + cfg.Validators[0].App["grpc-web"] = yamlmap.Map{"address": genAddr(ports[3])} + cfg.Validators[0].Config["p2p"] = yamlmap.Map{"laddr": genAddr(ports[4])} + cfg.Validators[0].Config["rpc"] = yamlmap.Map{ + "laddr": genAddr(ports[5]), + "pprof_laddr": genAddr(ports[6]), + } + + file, err := os.Create(cfgPath) + require.NoError(t, err) + require.NoError(t, yaml.NewEncoder(file).Encode(cfg)) + require.NoError(t, file.Close()) + + app.SetConfigPath(cfgPath) + + ctx, cancel := context.WithCancel(ctx) + t.Cleanup(func() { + cancel() + require.NoError(t, os.RemoveAll(homePath)) + }) + + go func() { + env.Must(app.Serve("should serve chain", envtest.ExecCtx(ctx))) + }() + return genAddr(ports[5]) +} + func TestBlogIBC(t *testing.T) { var ( env = envtest.New(t) @@ -207,11 +225,6 @@ func TestBlogIBC(t *testing.T) { ctx = env.Ctx() ) - //nodeAddr, err := xurl.TCP(servers.RPC) - //if err != nil { - // t.Fatalf("cant read nodeAddr from host.RPC %v: %v", servers.RPC, err) - //} - env.Must(env.Exec("create an IBC module", step.NewSteps(step.New( step.Exec(envtest.IgniteApp, From e8399652011dd38440b9757e12ab4d6c4add5a65 Mon Sep 17 00:00:00 2001 From: Pantani Date: Sat, 9 Dec 2023 21:12:38 -0300 Subject: [PATCH 09/42] fix rpc ports --- integration/app.go | 4 +++ integration/ibc/cmd_relayer_test.go | 39 +++++++++++++++++------------ 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/integration/app.go b/integration/app.go index 29aceb8dbd..2af4f6a816 100644 --- a/integration/app.go +++ b/integration/app.go @@ -118,6 +118,10 @@ func (a App) SourcePath() string { return a.path } +func (a *App) SetHomePath(homePath string) { + a.homePath = homePath +} + func (a *App) SetConfigPath(path string) { a.configPath = path } diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index e5cf5d59eb..341a39e6d6 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -30,6 +30,7 @@ var ( bobName = "bob" marsConfig = v1.Config{ Config: base.Config{ + Version: 1, Build: base.Build{ Proto: base.Proto{ Path: "proto", @@ -66,6 +67,7 @@ var ( } earthConfig = v1.Config{ Config: base.Config{ + Version: 1, Build: base.Build{ Proto: base.Proto{ Path: "proto", @@ -173,16 +175,21 @@ func (k Keeper) OnTimeoutIbcPostPacket(ctx sdk.Context, packet channeltypes.Pack }` ) -func runChain(t *testing.T, env envtest.Env, app envtest.App, cfg v1.Config) string { +func runChain( + t *testing.T, + env envtest.Env, + app envtest.App, + cfg v1.Config, +) (api string, rpc string, faucet string) { t.Helper() var ( + ctx = env.Ctx() tmpDir = t.TempDir() homePath = filepath.Join(tmpDir, randstr.Runes(10)) cfgPath = filepath.Join(tmpDir, chain.ConfigFilenames[0]) - ctx = env.Ctx() ) genAddr := func(port uint) string { - return fmt.Sprintf("0.0.0.0:%d", port) + return fmt.Sprintf("127.0.0.1:%d", port) } cfg.Validators[0].Home = homePath @@ -204,18 +211,18 @@ func runChain(t *testing.T, env envtest.Env, app envtest.App, cfg v1.Config) str require.NoError(t, yaml.NewEncoder(file).Encode(cfg)) require.NoError(t, file.Close()) - app.SetConfigPath(cfgPath) - ctx, cancel := context.WithCancel(ctx) t.Cleanup(func() { cancel() - require.NoError(t, os.RemoveAll(homePath)) + require.NoError(t, os.RemoveAll(tmpDir)) }) + app.SetConfigPath(cfgPath) + app.SetHomePath(homePath) go func() { env.Must(app.Serve("should serve chain", envtest.ExecCtx(ctx))) }() - return genAddr(ports[5]) + return genAddr(ports[1]), genAddr(ports[5]), genAddr(ports[0]) } func TestBlogIBC(t *testing.T) { @@ -332,22 +339,22 @@ func TestBlogIBC(t *testing.T) { )) // serve both chains. - earthRPC := runChain(t, env, app, earthConfig) - marsRPC := runChain(t, env, app, marsConfig) + earthAPI, earthRPC, earthFaucet := runChain(t, env, app, earthConfig) + marsAPI, marsRPC, marsFaucet := runChain(t, env, app, marsConfig) // check the chains is up stepsCheck := step.NewSteps( step.New( step.Exec( app.Binary(), - "base", + "config", "output", "json", ), step.PreExec(func() error { - if err := env.IsAppServed(ctx, earthRPC); err != nil { + if err := env.IsAppServed(ctx, earthAPI); err != nil { return err } - return env.IsAppServed(ctx, marsRPC) + return env.IsAppServed(ctx, marsAPI) }), ), ) @@ -359,15 +366,15 @@ func TestBlogIBC(t *testing.T) { step.Exec(envtest.IgniteApp, "relayer", "configure", "-a", - "--source-rpc", "http://0.0.0.0:26657", - "--source-faucet", "http://0.0.0.0:4500", + "--source-rpc", earthRPC, + "--source-faucet", earthFaucet, "--source-port", "blog", "--source-version", "blog-1", "--source-gasprice", "0.0000025stake", "--source-prefix", "cosmos", "--source-gaslimit", "300000", - "--target-rpc", "http://0.0.0.0:26659", - "--target-faucet", "http://0.0.0.0:4501", + "--target-rpc", marsRPC, + "--target-faucet", marsFaucet, "--target-port", "blog", "--target-version", "blog-1", "--target-gasprice", "0.0000025stake", From 25c53bdfdde9c91519dd79a350cc139990ccd1b6 Mon Sep 17 00:00:00 2001 From: Pantani Date: Sat, 9 Dec 2023 21:53:53 -0300 Subject: [PATCH 10/42] fix wrong urls and missing relayer accounts --- integration/ibc/cmd_relayer_test.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index 341a39e6d6..0df6d223cd 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -21,7 +21,6 @@ import ( "github.com/ignite/cli/v28/ignite/pkg/cmdrunner/step" "github.com/ignite/cli/v28/ignite/pkg/goanalysis" "github.com/ignite/cli/v28/ignite/pkg/randstr" - "github.com/ignite/cli/v28/ignite/pkg/xurl" yamlmap "github.com/ignite/cli/v28/ignite/pkg/yaml" envtest "github.com/ignite/cli/v28/integration" ) @@ -222,7 +221,11 @@ func runChain( go func() { env.Must(app.Serve("should serve chain", envtest.ExecCtx(ctx))) }() - return genAddr(ports[1]), genAddr(ports[5]), genAddr(ports[0]) + + genHTTPAddr := func(port uint) string { + return fmt.Sprintf("http://127.0.0.1:%d", port) + } + return genHTTPAddr(ports[1]), genHTTPAddr(ports[5]), genHTTPAddr(ports[0]) } func TestBlogIBC(t *testing.T) { @@ -373,6 +376,7 @@ func TestBlogIBC(t *testing.T) { "--source-gasprice", "0.0000025stake", "--source-prefix", "cosmos", "--source-gaslimit", "300000", + "--source-account", "default", "--target-rpc", marsRPC, "--target-faucet", marsFaucet, "--target-port", "blog", @@ -380,8 +384,11 @@ func TestBlogIBC(t *testing.T) { "--target-gasprice", "0.0000025stake", "--target-prefix", "cosmos", "--target-gaslimit", "300000", + "--target-account", "default", ), step.Workdir(app.SourcePath()), + step.Stdout(os.Stdout), + step.Stderr(os.Stderr), )), )) go func() { @@ -401,11 +408,6 @@ func TestBlogIBC(t *testing.T) { } ) - nodeAddr, err := xurl.TCP(earthRPC) - if err != nil { - t.Fatalf("cant read nodeAddr from host.RPC %v: %v", earthRPC, err) - } - // sign tx to add an item to the list. stepsTx := step.NewSteps( step.New( @@ -424,7 +426,7 @@ func TestBlogIBC(t *testing.T) { "Hello Mars, I'm Alice from Earth", "--chain-id", "blog", "--from", "alice", - "--node", nodeAddr, + "--node", earthRPC, "--output", "json", "--log_format", "json", "--yes", From 0cbcb5d9a1efc85f141e0b7a16fad54ea6c8bf5f Mon Sep 17 00:00:00 2001 From: Pantani Date: Sat, 9 Dec 2023 22:08:28 -0300 Subject: [PATCH 11/42] reset relayer config and avoid port conflicts --- integration/ibc/cmd_relayer_test.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index 0df6d223cd..6ef7363c7f 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -179,8 +179,12 @@ func runChain( env envtest.Env, app envtest.App, cfg v1.Config, + ports []uint, ) (api string, rpc string, faucet string) { t.Helper() + if len(ports) < 7 { + t.Fatalf("invalid number of ports %d", len(ports)) + } var ( ctx = env.Ctx() tmpDir = t.TempDir() @@ -192,8 +196,6 @@ func runChain( } cfg.Validators[0].Home = homePath - ports, err := availableport.Find(7) - require.NoError(t, err) cfg.Faucet.Host = genAddr(ports[0]) cfg.Validators[0].App["api"] = yamlmap.Map{"address": genAddr(ports[1])} @@ -342,8 +344,10 @@ func TestBlogIBC(t *testing.T) { )) // serve both chains. - earthAPI, earthRPC, earthFaucet := runChain(t, env, app, earthConfig) - marsAPI, marsRPC, marsFaucet := runChain(t, env, app, marsConfig) + ports, err := availableport.Find(14) + require.NoError(t, err) + earthAPI, earthRPC, earthFaucet := runChain(t, env, app, earthConfig, ports[:7]) + marsAPI, marsRPC, marsFaucet := runChain(t, env, app, marsConfig, ports[7:]) // check the chains is up stepsCheck := step.NewSteps( @@ -368,7 +372,7 @@ func TestBlogIBC(t *testing.T) { step.NewSteps(step.New( step.Exec(envtest.IgniteApp, "relayer", - "configure", "-a", + "configure", "-a", "-r", "--source-rpc", earthRPC, "--source-faucet", earthFaucet, "--source-port", "blog", From 8ccd0f80956b948b9a0ede4baccf5a1343bd4707 Mon Sep 17 00:00:00 2001 From: Pantani Date: Sat, 9 Dec 2023 22:22:48 -0300 Subject: [PATCH 12/42] test relayer --- integration/ibc/cmd_relayer_test.go | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index 6ef7363c7f..39bd940fe6 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -391,18 +391,17 @@ func TestBlogIBC(t *testing.T) { "--target-account", "default", ), step.Workdir(app.SourcePath()), + )), + )) + + env.Must(env.Exec("run the ts relayer", + step.NewSteps(step.New( + step.Exec(envtest.IgniteApp, "relayer", "connect", "earth-mars"), + step.Workdir(app.SourcePath()), step.Stdout(os.Stdout), step.Stderr(os.Stderr), )), )) - go func() { - env.Must(env.Exec("run the ts relayer", - step.NewSteps(step.New( - step.Exec(envtest.IgniteApp, "relayer", "connect"), - step.Workdir(app.SourcePath()), - )), - )) - }() var ( output = &bytes.Buffer{} From 3fa1f543ce6e9e9ae37fcb70115cbf5921d2fbfc Mon Sep 17 00:00:00 2001 From: Pantani Date: Sat, 9 Dec 2023 22:27:12 -0300 Subject: [PATCH 13/42] fix config port address --- integration/ibc/cmd_relayer_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index 39bd940fe6..ef4e2ff82b 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -37,7 +37,7 @@ var ( }, }, Accounts: []base.Account{ - {Name: "alice", Coins: []string{"1000token", "1000000000stake"}}, + {Name: "alice", Coins: []string{"1000token", "100000000stake"}}, {Name: "bob", Coins: []string{"500token", "100000000stake"}}, }, Faucet: base.Faucet{ @@ -74,7 +74,7 @@ var ( }, }, Accounts: []base.Account{ - {Name: "alice", Coins: []string{"1000token", "1000000000stake"}}, + {Name: "alice", Coins: []string{"1000token", "100000000stake"}}, {Name: "bob", Coins: []string{"500token", "100000000stake"}}, }, Faucet: base.Faucet{ @@ -192,7 +192,7 @@ func runChain( cfgPath = filepath.Join(tmpDir, chain.ConfigFilenames[0]) ) genAddr := func(port uint) string { - return fmt.Sprintf("127.0.0.1:%d", port) + return fmt.Sprintf("0.0.0.0:%d", port) } cfg.Validators[0].Home = homePath From 85e0036c63632c62f1cbf31e1da48c5a4c22e8a0 Mon Sep 17 00:00:00 2001 From: Pantani Date: Sat, 9 Dec 2023 22:34:50 -0300 Subject: [PATCH 14/42] draft check realyer --- integration/ibc/cmd_relayer_test.go | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index ef4e2ff82b..963591b6be 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -350,7 +350,7 @@ func TestBlogIBC(t *testing.T) { marsAPI, marsRPC, marsFaucet := runChain(t, env, app, marsConfig, ports[7:]) // check the chains is up - stepsCheck := step.NewSteps( + stepsCheckChains := step.NewSteps( step.New( step.Exec( app.Binary(), @@ -365,7 +365,7 @@ func TestBlogIBC(t *testing.T) { }), ), ) - env.Exec("waiting the chain is up", stepsCheck, envtest.ExecRetry()) + env.Exec("waiting the chain is up", stepsCheckChains, envtest.ExecRetry()) // configure and run the ts relayer. env.Must(env.Exec("configure the ts relayer", @@ -394,6 +394,7 @@ func TestBlogIBC(t *testing.T) { )), )) + //go func() { env.Must(env.Exec("run the ts relayer", step.NewSteps(step.New( step.Exec(envtest.IgniteApp, "relayer", "connect", "earth-mars"), @@ -402,6 +403,25 @@ func TestBlogIBC(t *testing.T) { step.Stderr(os.Stderr), )), )) + //}() + + stepsCheckRelayer := step.NewSteps( + step.New( + step.Exec( + // TODO query chain connection-id + app.Binary(), + "config", + "output", "json", + ), + step.PreExec(func() error { + if err := env.IsAppServed(ctx, earthAPI); err != nil { + return err + } + return env.IsAppServed(ctx, marsAPI) + }), + ), + )) + env.Exec("run the ts relayer", stepsCheckRelayer, envtest.ExecRetry()) var ( output = &bytes.Buffer{} From f5da266565a82e426687718554c94104de420037 Mon Sep 17 00:00:00 2001 From: Pantani Date: Tue, 12 Dec 2023 23:20:10 -0300 Subject: [PATCH 15/42] use hermes realyer instead ts relayer --- changelog.md | 1 + ignite/pkg/cosmosver/detect_test.go | 3 +- ignite/pkg/goenv/goenv.go | 5 ++ integration/ibc/cmd_relayer_test.go | 114 +++++++++++++++++++--------- 4 files changed, 86 insertions(+), 37 deletions(-) diff --git a/changelog.md b/changelog.md index 421b9ae1f0..89a08f4c3f 100644 --- a/changelog.md +++ b/changelog.md @@ -5,6 +5,7 @@ ### Features - [#3830](https://github.com/ignite/cli/pull/3830) Remove gRPC info from Ignite Apps errors +- [#3820](https://github.com/ignite/cli/pull/3820) Add integration tests for IBC chains ### Changes diff --git a/ignite/pkg/cosmosver/detect_test.go b/ignite/pkg/cosmosver/detect_test.go index a77a4b0c0d..57f5295802 100644 --- a/ignite/pkg/cosmosver/detect_test.go +++ b/ignite/pkg/cosmosver/detect_test.go @@ -3,8 +3,9 @@ package cosmosver_test import ( "testing" - "github.com/ignite/cli/v28/ignite/pkg/cosmosver" "github.com/stretchr/testify/require" + + "github.com/ignite/cli/v28/ignite/pkg/cosmosver" ) func TestDetect(t *testing.T) { diff --git a/ignite/pkg/goenv/goenv.go b/ignite/pkg/goenv/goenv.go index 17bc304280..954974574b 100644 --- a/ignite/pkg/goenv/goenv.go +++ b/ignite/pkg/goenv/goenv.go @@ -55,3 +55,8 @@ func GoModCache() string { } return filepath.Join(build.Default.GOPATH, modDir) } + +// GoPath returns the go path. +func GoPath() string { + return os.Getenv(GOPATH) +} diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index 963591b6be..507bf14448 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -20,11 +20,16 @@ import ( "github.com/ignite/cli/v28/ignite/pkg/availableport" "github.com/ignite/cli/v28/ignite/pkg/cmdrunner/step" "github.com/ignite/cli/v28/ignite/pkg/goanalysis" + "github.com/ignite/cli/v28/ignite/pkg/goenv" "github.com/ignite/cli/v28/ignite/pkg/randstr" yamlmap "github.com/ignite/cli/v28/ignite/pkg/yaml" envtest "github.com/ignite/cli/v28/integration" ) +const ( + relayerMnemonic = "great immense still pill defense fetch pencil slow purchase symptom speed arm shoot fence have divorce cigar rapid hen vehicle pear evolve correct nerve" +) + var ( bobName = "bob" marsConfig = v1.Config{ @@ -37,15 +42,28 @@ var ( }, }, Accounts: []base.Account{ - {Name: "alice", Coins: []string{"1000token", "100000000stake"}}, - {Name: "bob", Coins: []string{"500token", "100000000stake"}}, + { + Name: "alice", + Coins: []string{"1000token", "100000000stake"}, + Mnemonic: "slide moment original seven milk crawl help text kick fluid boring awkward doll wonder sure fragile plate grid hard next casual expire okay body", + }, + { + Name: "bob", + Coins: []string{"500token", "100000000stake"}, + Mnemonic: "trap possible liquid elite embody host segment fantasy swim cable digital eager tiny broom burden diary earn hen grow engine pigeon fringe claim program", + }, + { + Name: "relayer", + Coins: []string{"500000token", "100000000000000stake"}, + Mnemonic: relayerMnemonic, + }, }, Faucet: base.Faucet{ Name: &bobName, - Coins: []string{"5token", "100000stake"}, + Coins: []string{"500token", "10000000stake"}, Host: ":4501", }, - Genesis: yamlmap.Map{"chain_id": "mars"}, + Genesis: yamlmap.Map{"chain_id": "mars-1"}, }, Validators: []v1.Validator{ { @@ -74,15 +92,28 @@ var ( }, }, Accounts: []base.Account{ - {Name: "alice", Coins: []string{"1000token", "100000000stake"}}, - {Name: "bob", Coins: []string{"500token", "100000000stake"}}, + { + Name: "alice", + Coins: []string{"1000token", "100000000stake"}, + Mnemonic: "slide moment original seven milk crawl help text kick fluid boring awkward doll wonder sure fragile plate grid hard next casual expire okay body", + }, + { + Name: "bob", + Coins: []string{"500token", "100000000stake"}, + Mnemonic: "trap possible liquid elite embody host segment fantasy swim cable digital eager tiny broom burden diary earn hen grow engine pigeon fringe claim program", + }, + { + Name: "relayer", + Coins: []string{"500000token", "100000000000000stake"}, + Mnemonic: relayerMnemonic, + }, }, Faucet: base.Faucet{ Name: &bobName, - Coins: []string{"5token", "100000stake"}, + Coins: []string{"500token", "10000000stake"}, Host: ":4500", }, - Genesis: yamlmap.Map{"chain_id": "earth"}, + Genesis: yamlmap.Map{"chain_id": "earth-1"}, }, Validators: []v1.Validator{ { @@ -180,7 +211,7 @@ func runChain( app envtest.App, cfg v1.Config, ports []uint, -) (api string, rpc string, faucet string) { +) (api, rpc, grpc, faucet string) { t.Helper() if len(ports) < 7 { t.Fatalf("invalid number of ports %d", len(ports)) @@ -227,7 +258,7 @@ func runChain( genHTTPAddr := func(port uint) string { return fmt.Sprintf("http://127.0.0.1:%d", port) } - return genHTTPAddr(ports[1]), genHTTPAddr(ports[5]), genHTTPAddr(ports[0]) + return genHTTPAddr(ports[1]), genHTTPAddr(ports[5]), genHTTPAddr(ports[2]), genHTTPAddr(ports[0]) } func TestBlogIBC(t *testing.T) { @@ -346,8 +377,10 @@ func TestBlogIBC(t *testing.T) { // serve both chains. ports, err := availableport.Find(14) require.NoError(t, err) - earthAPI, earthRPC, earthFaucet := runChain(t, env, app, earthConfig, ports[:7]) - marsAPI, marsRPC, marsFaucet := runChain(t, env, app, marsConfig, ports[7:]) + earthAPI, earthRPC, earthGRPC, earthFaucet := runChain(t, env, app, earthConfig, ports[:7]) + marsAPI, marsRPC, marsGRPC, marsFaucet := runChain(t, env, app, marsConfig, ports[7:]) + earthChainID := earthConfig.Genesis["chain_id"].(string) + marsChainID := marsConfig.Genesis["chain_id"].(string) // check the chains is up stepsCheckChains := step.NewSteps( @@ -367,37 +400,46 @@ func TestBlogIBC(t *testing.T) { ) env.Exec("waiting the chain is up", stepsCheckChains, envtest.ExecRetry()) - // configure and run the ts relayer. - env.Must(env.Exec("configure the ts relayer", + // ibc relayer. + env.Must(env.Exec("install the hermes relayer app", + step.NewSteps(step.New( + step.Exec(envtest.IgniteApp, + "app", + "install", + "-g", + filepath.Join(goenv.GoPath(), "src/github.com/ignite/apps/hermes"), + ), + step.Workdir(app.SourcePath()), + )), + )) + + env.Must(env.Exec("configure the hermes relayer app", step.NewSteps(step.New( step.Exec(envtest.IgniteApp, "relayer", - "configure", "-a", "-r", - "--source-rpc", earthRPC, - "--source-faucet", earthFaucet, - "--source-port", "blog", - "--source-version", "blog-1", - "--source-gasprice", "0.0000025stake", - "--source-prefix", "cosmos", - "--source-gaslimit", "300000", - "--source-account", "default", - "--target-rpc", marsRPC, - "--target-faucet", marsFaucet, - "--target-port", "blog", - "--target-version", "blog-1", - "--target-gasprice", "0.0000025stake", - "--target-prefix", "cosmos", - "--target-gaslimit", "300000", - "--target-account", "default", + "hermes", + "configure", + earthChainID, + earthRPC, + earthGRPC, + marsChainID, + marsRPC, + marsGRPC, + "--chain-a-faucet", earthFaucet, + "--chain-b-faucet", marsFaucet, + "--generate-wallets", + "--generate-config", ), step.Workdir(app.SourcePath()), + step.Stdout(os.Stdout), + step.Stderr(os.Stderr), )), )) - //go func() { + // go func() { env.Must(env.Exec("run the ts relayer", step.NewSteps(step.New( - step.Exec(envtest.IgniteApp, "relayer", "connect", "earth-mars"), + step.Exec(envtest.IgniteApp, "relayer", "hermes", "start", earthChainID, marsChainID), step.Workdir(app.SourcePath()), step.Stdout(os.Stdout), step.Stderr(os.Stderr), @@ -420,7 +462,7 @@ func TestBlogIBC(t *testing.T) { return env.IsAppServed(ctx, marsAPI) }), ), - )) + ) env.Exec("run the ts relayer", stepsCheckRelayer, envtest.ExecRetry()) var ( @@ -436,7 +478,7 @@ func TestBlogIBC(t *testing.T) { step.New( step.Stdout(output), step.PreExec(func() error { - err := env.IsAppServed(ctx, earthRPC) + err := env.IsAppServed(ctx, earthGRPC) return err }), step.Exec( @@ -449,7 +491,7 @@ func TestBlogIBC(t *testing.T) { "Hello Mars, I'm Alice from Earth", "--chain-id", "blog", "--from", "alice", - "--node", earthRPC, + "--node", earthGRPC, "--output", "json", "--log_format", "json", "--yes", From a49364ef94c2cad1cd04514b18f0984567d571cf Mon Sep 17 00:00:00 2001 From: Pantani Date: Wed, 13 Dec 2023 02:59:30 -0300 Subject: [PATCH 16/42] fix the default config values --- integration/ibc/cmd_relayer_test.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index 507bf14448..2a4a2515be 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -44,23 +44,23 @@ var ( Accounts: []base.Account{ { Name: "alice", - Coins: []string{"1000token", "100000000stake"}, + Coins: []string{"100000000000token", "10000000000000000000stake"}, Mnemonic: "slide moment original seven milk crawl help text kick fluid boring awkward doll wonder sure fragile plate grid hard next casual expire okay body", }, { Name: "bob", - Coins: []string{"500token", "100000000stake"}, + Coins: []string{"100000000000token", "10000000000000000000stake"}, Mnemonic: "trap possible liquid elite embody host segment fantasy swim cable digital eager tiny broom burden diary earn hen grow engine pigeon fringe claim program", }, { Name: "relayer", - Coins: []string{"500000token", "100000000000000stake"}, + Coins: []string{"100000000000token", "1000000000000000000000stake"}, Mnemonic: relayerMnemonic, }, }, Faucet: base.Faucet{ Name: &bobName, - Coins: []string{"500token", "10000000stake"}, + Coins: []string{"500token", "100000000stake"}, Host: ":4501", }, Genesis: yamlmap.Map{"chain_id": "mars-1"}, @@ -94,23 +94,23 @@ var ( Accounts: []base.Account{ { Name: "alice", - Coins: []string{"1000token", "100000000stake"}, + Coins: []string{"100000000000token", "10000000000000000000stake"}, Mnemonic: "slide moment original seven milk crawl help text kick fluid boring awkward doll wonder sure fragile plate grid hard next casual expire okay body", }, { Name: "bob", - Coins: []string{"500token", "100000000stake"}, + Coins: []string{"100000000000token", "10000000000000000000stake"}, Mnemonic: "trap possible liquid elite embody host segment fantasy swim cable digital eager tiny broom burden diary earn hen grow engine pigeon fringe claim program", }, { Name: "relayer", - Coins: []string{"500000token", "100000000000000stake"}, + Coins: []string{"100000000000token", "1000000000000000000000stake"}, Mnemonic: relayerMnemonic, }, }, Faucet: base.Faucet{ Name: &bobName, - Coins: []string{"500token", "10000000stake"}, + Coins: []string{"500token", "100000000stake"}, Host: ":4500", }, Genesis: yamlmap.Map{"chain_id": "earth-1"}, From abea944662bb06be926bf0debbfb2718e6d8776b Mon Sep 17 00:00:00 2001 From: Pantani Date: Wed, 13 Dec 2023 07:46:03 -0300 Subject: [PATCH 17/42] fix the config flag --- integration/ibc/cmd_relayer_test.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index 2a4a2515be..0ba48e0b6e 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -428,20 +428,19 @@ func TestBlogIBC(t *testing.T) { "--chain-a-faucet", earthFaucet, "--chain-b-faucet", marsFaucet, "--generate-wallets", - "--generate-config", + "--overwrite-config", ), step.Workdir(app.SourcePath()), - step.Stdout(os.Stdout), - step.Stderr(os.Stderr), )), )) // go func() { - env.Must(env.Exec("run the ts relayer", + env.Must(env.Exec("run the hermes relayer", step.NewSteps(step.New( step.Exec(envtest.IgniteApp, "relayer", "hermes", "start", earthChainID, marsChainID), step.Workdir(app.SourcePath()), step.Stdout(os.Stdout), + step.Stdin(os.Stdin), step.Stderr(os.Stderr), )), )) From 0af2b33600f84026fbef8fa1580b8cf18a3db817 Mon Sep 17 00:00:00 2001 From: Pantani Date: Tue, 19 Dec 2023 02:16:44 -0300 Subject: [PATCH 18/42] add missing tx.go file by default and enable cli if autocli not exist --- ignite/templates/ibc/packet.go | 15 --------------- .../base/x/{{moduleName}}/client/cli/tx.go.plush} | 13 +++++++------ .../base/x/{{moduleName}}/module/module.go.plush | 6 +++--- 3 files changed, 10 insertions(+), 24 deletions(-) rename ignite/templates/{ibc/templates/packet/tx.tpl => module/create/files/base/x/{{moduleName}}/client/cli/tx.go.plush} (66%) diff --git a/ignite/templates/ibc/packet.go b/ignite/templates/ibc/packet.go index b7520cdcc7..ddadcf728d 100644 --- a/ignite/templates/ibc/packet.go +++ b/ignite/templates/ibc/packet.go @@ -3,7 +3,6 @@ package ibc import ( "embed" "fmt" - "os" "path/filepath" "github.com/emicklei/proto" @@ -352,24 +351,10 @@ func protoTxModify(opts *PacketOptions) genny.RunFn { } } -//go:embed templates/packet/tx.tpl -var txTemplate string - // clientCliTxModify does not use AutoCLI here, because it as a better UX as it is. func clientCliTxModify(replacer placeholder.Replacer, opts *PacketOptions) genny.RunFn { return func(r *genny.Runner) error { filePath := filepath.Join(opts.AppPath, "x", opts.ModuleName, "client/cli/tx.go") - if _, err := os.Stat(filePath); errors.Is(err, os.ErrNotExist) { - content := fmt.Sprintf(txTemplate, opts.ModulePath, opts.ModuleName) - if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil { - return err - } - - if err := os.WriteFile(filePath, []byte(content), 0o644); err != nil { - return err - } - } - f, err := r.Disk.Find(filePath) if err != nil { return err diff --git a/ignite/templates/ibc/templates/packet/tx.tpl b/ignite/templates/module/create/files/base/x/{{moduleName}}/client/cli/tx.go.plush similarity index 66% rename from ignite/templates/ibc/templates/packet/tx.tpl rename to ignite/templates/module/create/files/base/x/{{moduleName}}/client/cli/tx.go.plush index 1d09bbccfa..58b885e9db 100644 --- a/ignite/templates/ibc/templates/packet/tx.tpl +++ b/ignite/templates/module/create/files/base/x/{{moduleName}}/client/cli/tx.go.plush @@ -7,18 +7,19 @@ import ( "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client" - "%s/x/%s/types" + // "github.com/cosmos/cosmos-sdk/client/flags" + "<%= modulePath %>/x/<%= moduleName %>/types" ) var DefaultRelativePacketTimeoutTimestamp = uint64((time.Duration(10) * time.Minute).Nanoseconds()) - + const listSeparator = "," -// GetTxCmd returns the transaction commands for this module +// GetTxCmd returns the transaction commands for this module. func GetTxCmd() *cobra.Command { cmd := &cobra.Command{ Use: types.ModuleName, - Short: fmt.Sprintf("%%s transactions subcommands", types.ModuleName), + Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName), DisableFlagParsing: true, SuggestionsMinimumDistance: 2, RunE: client.ValidateCmd, @@ -26,5 +27,5 @@ func GetTxCmd() *cobra.Command { // this line is used by starport scaffolding # 1 - return cmd -} \ No newline at end of file + return cmd +} diff --git a/ignite/templates/module/create/files/base/x/{{moduleName}}/module/module.go.plush b/ignite/templates/module/create/files/base/x/{{moduleName}}/module/module.go.plush index 558c9e745d..cfc5a4f001 100644 --- a/ignite/templates/module/create/files/base/x/{{moduleName}}/module/module.go.plush +++ b/ignite/templates/module/create/files/base/x/{{moduleName}}/module/module.go.plush @@ -94,9 +94,9 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *r // GetTxCmd returns the root Tx command for the module. // These commands enrich the AutoCLI tx commands. // When creating non AutoCLI commands, add the following: -// func (a AppModuleBasic) GetTxCmd() *cobra.Command { -// return cli.GetTxCmd() -// } +func (a AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.GetTxCmd() +} // ---------------------------------------------------------------------------- // AppModule From 543b08d0b21f7c1102fd7022cf4b8c12d1f87df8 Mon Sep 17 00:00:00 2001 From: Pantani Date: Tue, 19 Dec 2023 02:20:34 -0300 Subject: [PATCH 19/42] add changelog --- changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.md b/changelog.md index 7b715484dc..24511a843e 100644 --- a/changelog.md +++ b/changelog.md @@ -20,6 +20,7 @@ - [#3825](https://github.com/ignite/cli/pull/3825) Fix a minor Keplr type-checking bug in TS client - [#3836](https://github.com/ignite/cli/pull/3836) Add missing IBC commands for scaffolded chain - [#3833](https://github.com/ignite/cli/pull/3833) Improve Cosmos SDK detection to support SDK forks +- [#3849](https://github.com/ignite/cli/pull/3849) Add missing `tx.go` file by default and enable cli if autocli does not exist ## [`v28.0.0`](https://github.com/ignite/cli/releases/tag/v28.0.0) From d5d7722f4e1372d3bb024f6dc1447dcc38312186 Mon Sep 17 00:00:00 2001 From: Pantani Date: Tue, 19 Dec 2023 02:22:32 -0300 Subject: [PATCH 20/42] fix wrong error pkg --- ignite/pkg/goanalysis/goanalysis.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ignite/pkg/goanalysis/goanalysis.go b/ignite/pkg/goanalysis/goanalysis.go index 65fe93552a..7f770af4e7 100644 --- a/ignite/pkg/goanalysis/goanalysis.go +++ b/ignite/pkg/goanalysis/goanalysis.go @@ -347,5 +347,5 @@ func parseReplacementCode(code string) (*ast.BlockStmt, error) { return funcDecl.Body, nil } } - return nil, fmt.Errorf("replacement code does not contain a valid function declaration") + return nil, errors.Errorf("replacement code does not contain a valid function declaration") } From f5a059c85f86e2389062177224bd1b7665855532 Mon Sep 17 00:00:00 2001 From: Pantani Date: Tue, 19 Dec 2023 02:32:41 -0300 Subject: [PATCH 21/42] add missing imports --- .../create/files/base/x/{{moduleName}}/module/module.go.plush | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ignite/templates/module/create/files/base/x/{{moduleName}}/module/module.go.plush b/ignite/templates/module/create/files/base/x/{{moduleName}}/module/module.go.plush index cfc5a4f001..87b69b05f7 100644 --- a/ignite/templates/module/create/files/base/x/{{moduleName}}/module/module.go.plush +++ b/ignite/templates/module/create/files/base/x/{{moduleName}}/module/module.go.plush @@ -17,6 +17,7 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" <%= if (isIBC) { %>porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper" ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper"<% } %> @@ -24,6 +25,7 @@ import ( // this line is used by starport scaffolding # 1 modulev1 "<%= modulePath %>/api/<%= appName %>/<%= moduleName %>/module" + "<%= modulePath %>/x/<%= moduleName %>/client/cli" "<%= modulePath %>/x/<%= moduleName %>/keeper" "<%= modulePath %>/x/<%= moduleName %>/types" ) From d976cbdb962849b113b82541c918ba34b875e29c Mon Sep 17 00:00:00 2001 From: Pantani Date: Tue, 19 Dec 2023 14:24:52 -0300 Subject: [PATCH 22/42] only scaffold `cli/tx.go` if is a ibc module --- .../create/files/base/x/{{moduleName}}/module/module.go.plush | 4 ++-- .../{base/x/{{moduleName}} => ibc}/client/cli/tx.go.plush | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename ignite/templates/module/create/files/{base/x/{{moduleName}} => ibc}/client/cli/tx.go.plush (100%) diff --git a/ignite/templates/module/create/files/base/x/{{moduleName}}/module/module.go.plush b/ignite/templates/module/create/files/base/x/{{moduleName}}/module/module.go.plush index 87b69b05f7..a86369e5d8 100644 --- a/ignite/templates/module/create/files/base/x/{{moduleName}}/module/module.go.plush +++ b/ignite/templates/module/create/files/base/x/{{moduleName}}/module/module.go.plush @@ -25,9 +25,9 @@ import ( // this line is used by starport scaffolding # 1 modulev1 "<%= modulePath %>/api/<%= appName %>/<%= moduleName %>/module" - "<%= modulePath %>/x/<%= moduleName %>/client/cli" "<%= modulePath %>/x/<%= moduleName %>/keeper" "<%= modulePath %>/x/<%= moduleName %>/types" + <%= if (isIBC) { %>"<%= modulePath %>/x/<%= moduleName %>/client/cli"<% } %> ) var ( @@ -97,7 +97,7 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *r // These commands enrich the AutoCLI tx commands. // When creating non AutoCLI commands, add the following: func (a AppModuleBasic) GetTxCmd() *cobra.Command { - return cli.GetTxCmd() + <%= if (isIBC) { %> return cli.GetTxCmd() <% } else { %>return nil<% } %> } // ---------------------------------------------------------------------------- diff --git a/ignite/templates/module/create/files/base/x/{{moduleName}}/client/cli/tx.go.plush b/ignite/templates/module/create/files/ibc/client/cli/tx.go.plush similarity index 100% rename from ignite/templates/module/create/files/base/x/{{moduleName}}/client/cli/tx.go.plush rename to ignite/templates/module/create/files/ibc/client/cli/tx.go.plush From a43c2741fa9b8bd4bfc0e9002d0655ebfe0137b6 Mon Sep 17 00:00:00 2001 From: Pantani Date: Tue, 19 Dec 2023 14:32:29 -0300 Subject: [PATCH 23/42] move tx.go.plush to right place --- .../files/ibc/{ => x/{{moduleName}}}/client/cli/tx.go.plush | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ignite/templates/module/create/files/ibc/{ => x/{{moduleName}}}/client/cli/tx.go.plush (100%) diff --git a/ignite/templates/module/create/files/ibc/client/cli/tx.go.plush b/ignite/templates/module/create/files/ibc/x/{{moduleName}}/client/cli/tx.go.plush similarity index 100% rename from ignite/templates/module/create/files/ibc/client/cli/tx.go.plush rename to ignite/templates/module/create/files/ibc/x/{{moduleName}}/client/cli/tx.go.plush From d968d93003e312f4ee5f3e9f66ca1eb6b13a2905 Mon Sep 17 00:00:00 2001 From: Pantani Date: Tue, 19 Dec 2023 16:14:54 -0300 Subject: [PATCH 24/42] add comment to cobra send packet command --- .../x/{{moduleName}}/client/cli/tx_{{packetName}}.go.plush | 1 + 1 file changed, 1 insertion(+) diff --git a/ignite/templates/ibc/files/packet/messages/x/{{moduleName}}/client/cli/tx_{{packetName}}.go.plush b/ignite/templates/ibc/files/packet/messages/x/{{moduleName}}/client/cli/tx_{{packetName}}.go.plush index 647cfda4c8..762e279b0d 100644 --- a/ignite/templates/ibc/files/packet/messages/x/{{moduleName}}/client/cli/tx_{{packetName}}.go.plush +++ b/ignite/templates/ibc/files/packet/messages/x/{{moduleName}}/client/cli/tx_{{packetName}}.go.plush @@ -14,6 +14,7 @@ import ( var _ = strconv.Itoa(0) +// CmdSend<%= packetName.UpperCamel %>() returns the <%= packetName.UpperCamel %> send packet command. // This command does not use AutoCLI because it gives a better UX to do not. func CmdSend<%= packetName.UpperCamel %>() *cobra.Command { flagPacketTimeoutTimestamp := "packet-timeout-timestamp" From 3eddf13f6b4fdbebcdec682b331fcc8f0d4e2a8a Mon Sep 17 00:00:00 2001 From: Pantani Date: Tue, 19 Dec 2023 16:24:55 -0300 Subject: [PATCH 25/42] add missing ibc interfaces to chain client --- ignite/pkg/cosmosanalysis/app/app.go | 2 +- ignite/templates/app/files/app/ibc.go.plush | 8 ++++++-- .../app/files/cmd/{{binaryNamePrefix}}d/cmd/root.go.plush | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ignite/pkg/cosmosanalysis/app/app.go b/ignite/pkg/cosmosanalysis/app/app.go index 059d8aa3aa..3501b4f327 100644 --- a/ignite/pkg/cosmosanalysis/app/app.go +++ b/ignite/pkg/cosmosanalysis/app/app.go @@ -260,7 +260,7 @@ func discoverIBCModules(ibcPath string) ([]string, error) { return nil } - if fn.Name.Name != "AddIBCModuleManager" { + if fn.Name.Name != "RegisterIBC" && fn.Name.Name != "AddIBCModuleManager" { return nil } diff --git a/ignite/templates/app/files/app/ibc.go.plush b/ignite/templates/app/files/app/ibc.go.plush index 2fa1ea3766..d0bf4dd3b9 100644 --- a/ignite/templates/app/files/app/ibc.go.plush +++ b/ignite/templates/app/files/app/ibc.go.plush @@ -2,6 +2,7 @@ package app import ( storetypes "cosmossdk.io/store/types" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/types/module" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" @@ -179,11 +180,14 @@ func (app *App) registerIBCModules() { } } -// AddIBCModuleManager adds the missing IBC modules into the module manager. -func AddIBCModuleManager(moduleManager module.BasicManager) { +// RegisterIBC adds the missing IBC modules and interfaces into the module manager. +func RegisterIBC(moduleManager module.BasicManager, registry cdctypes.InterfaceRegistry) { moduleManager[ibcexported.ModuleName] = ibc.AppModule{} moduleManager[ibctransfertypes.ModuleName] = ibctransfer.AppModule{} moduleManager[ibcfeetypes.ModuleName] = ibcfee.AppModule{} moduleManager[icatypes.ModuleName] = icamodule.AppModule{} moduleManager[capabilitytypes.ModuleName] = capability.AppModule{} + + ibctm.AppModuleBasic{}.RegisterInterfaces(registry) + solomachine.AppModuleBasic{}.RegisterInterfaces(registry) } diff --git a/ignite/templates/app/files/cmd/{{binaryNamePrefix}}d/cmd/root.go.plush b/ignite/templates/app/files/cmd/{{binaryNamePrefix}}d/cmd/root.go.plush index 9015b89c31..c9951d5850 100644 --- a/ignite/templates/app/files/cmd/{{binaryNamePrefix}}d/cmd/root.go.plush +++ b/ignite/templates/app/files/cmd/{{binaryNamePrefix}}d/cmd/root.go.plush @@ -58,7 +58,7 @@ func NewRootCmd() *cobra.Command { // Since the IBC modules don't support dependency injection, we need to // manually add the modules to the basic manager on the client side. // This needs to be removed after IBC supports App Wiring. - app.AddIBCModuleManager(moduleBasicManager) + app.RegisterIBC(moduleBasicManager, clientCtx.InterfaceRegistry) rootCmd := &cobra.Command{ Use: app.Name + "d", From fd346294d95858b2c5490778efa55da1fc25f562 Mon Sep 17 00:00:00 2001 From: Pantani Date: Mon, 25 Dec 2023 13:13:14 -0300 Subject: [PATCH 26/42] set port range --- integration/ibc/cmd_relayer_test.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index 0ba48e0b6e..69e54b7eb8 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -223,7 +223,7 @@ func runChain( cfgPath = filepath.Join(tmpDir, chain.ConfigFilenames[0]) ) genAddr := func(port uint) string { - return fmt.Sprintf("0.0.0.0:%d", port) + return fmt.Sprintf(":%d", port) } cfg.Validators[0].Home = homePath @@ -375,7 +375,11 @@ func TestBlogIBC(t *testing.T) { )) // serve both chains. - ports, err := availableport.Find(14) + ports, err := availableport.Find( + 14, + availableport.WithMinPort(4000), + availableport.WithMaxPort(5000), + ) require.NoError(t, err) earthAPI, earthRPC, earthGRPC, earthFaucet := runChain(t, env, app, earthConfig, ports[:7]) marsAPI, marsRPC, marsGRPC, marsFaucet := runChain(t, env, app, marsConfig, ports[7:]) From 68c8e2969b758c061e162dd9a4f6492f6cdad76e Mon Sep 17 00:00:00 2001 From: Danilo Pantani Date: Mon, 25 Dec 2023 13:31:53 -0300 Subject: [PATCH 27/42] Revert "refactor(templates): add all ibc commands (#3858)" This reverts commit 3dda9b0b5a30e167e52018b3cbdd20773092b283. --- changelog.md | 2 +- ignite/templates/app/files/app/ibc.go.plush | 35 ++++++------------- .../cmd/commands.go.plush | 3 ++ .../{{binaryNamePrefix}}d/cmd/root.go.plush | 11 +++--- 4 files changed, 19 insertions(+), 32 deletions(-) diff --git a/changelog.md b/changelog.md index d101690c5e..06e6f612c7 100644 --- a/changelog.md +++ b/changelog.md @@ -22,7 +22,7 @@ - [#3827](https://github.com/ignite/cli/pull/3827) Change ignite apps to be able to run in any directory - [#3831](https://github.com/ignite/cli/pull/3831) Correct ignite app gRPC server stop memory issue - [#3825](https://github.com/ignite/cli/pull/3825) Fix a minor Keplr type-checking bug in TS client -- [#3836](https://github.com/ignite/cli/pull/3836), [#3858](https://github.com/ignite/cli/pull/3858) Add missing IBC commands for scaffolded chain +- [#3836](https://github.com/ignite/cli/pull/3836) Add missing IBC commands for scaffolded chain - [#3833](https://github.com/ignite/cli/pull/3833) Improve Cosmos SDK detection to support SDK forks - [#3849](https://github.com/ignite/cli/pull/3849) Add missing `tx.go` file by default and enable cli if autocli does not exist - [#3851](https://github.com/ignite/cli/pull/3851) Add missing ibc interfaces to chain client diff --git a/ignite/templates/app/files/app/ibc.go.plush b/ignite/templates/app/files/app/ibc.go.plush index 7c76bc9506..d0bf4dd3b9 100644 --- a/ignite/templates/app/files/app/ibc.go.plush +++ b/ignite/templates/app/files/app/ibc.go.plush @@ -1,9 +1,9 @@ package app import ( - "cosmossdk.io/core/appmodule" storetypes "cosmossdk.io/store/types" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/types/module" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" @@ -180,27 +180,14 @@ func (app *App) registerIBCModules() { } } -// Since the IBC modules don't support dependency injection, we need to -// manually register the modules on the client side. -// This needs to be removed after IBC supports App Wiring. -func RegisterIBC(registry cdctypes.InterfaceRegistry) map[string]appmodule.AppModule { - modules := map[string]appmodule.AppModule{ - ibcexported.ModuleName: ibc.AppModule{}, - ibctransfertypes.ModuleName: ibctransfer.AppModule{}, - ibcfeetypes.ModuleName: ibcfee.AppModule{}, - icatypes.ModuleName: icamodule.AppModule{}, - capabilitytypes.ModuleName: capability.AppModule{}, - ibctm.ModuleName: ibctm.AppModule{}, - solomachine.ModuleName: solomachine.AppModule{}, - } - - for _, module := range modules { - if mod, ok := module.(interface { - RegisterInterfaces(registry cdctypes.InterfaceRegistry) - }); ok { - mod.RegisterInterfaces(registry) - } - } +// RegisterIBC adds the missing IBC modules and interfaces into the module manager. +func RegisterIBC(moduleManager module.BasicManager, registry cdctypes.InterfaceRegistry) { + moduleManager[ibcexported.ModuleName] = ibc.AppModule{} + moduleManager[ibctransfertypes.ModuleName] = ibctransfer.AppModule{} + moduleManager[ibcfeetypes.ModuleName] = ibcfee.AppModule{} + moduleManager[icatypes.ModuleName] = icamodule.AppModule{} + moduleManager[capabilitytypes.ModuleName] = capability.AppModule{} - return modules -} \ No newline at end of file + ibctm.AppModuleBasic{}.RegisterInterfaces(registry) + solomachine.AppModuleBasic{}.RegisterInterfaces(registry) +} diff --git a/ignite/templates/app/files/cmd/{{binaryNamePrefix}}d/cmd/commands.go.plush b/ignite/templates/app/files/cmd/{{binaryNamePrefix}}d/cmd/commands.go.plush index 8bb54e2f73..8058636f52 100644 --- a/ignite/templates/app/files/cmd/{{binaryNamePrefix}}d/cmd/commands.go.plush +++ b/ignite/templates/app/files/cmd/{{binaryNamePrefix}}d/cmd/commands.go.plush @@ -22,6 +22,7 @@ import ( authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" "github.com/cosmos/cosmos-sdk/x/crisis" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" + ibccmd "github.com/cosmos/ibc-go/v8/modules/core/client/cli" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -87,6 +88,7 @@ func queryCommand() *cobra.Command { server.QueryBlocksCmd(), authcmd.QueryTxCmd(), server.QueryBlockResultsCmd(), + ibccmd.GetQueryCmd(), ) cmd.PersistentFlags().String(flags.FlagChainID, "", "The network chain ID") @@ -113,6 +115,7 @@ func txCommand() *cobra.Command { authcmd.GetEncodeCommand(), authcmd.GetDecodeCommand(), authcmd.GetSimulateCmd(), + ibccmd.GetTxCmd(), ) cmd.PersistentFlags().String(flags.FlagChainID, "", "The network chain ID") diff --git a/ignite/templates/app/files/cmd/{{binaryNamePrefix}}d/cmd/root.go.plush b/ignite/templates/app/files/cmd/{{binaryNamePrefix}}d/cmd/root.go.plush index 065c775b72..200251ec01 100644 --- a/ignite/templates/app/files/cmd/{{binaryNamePrefix}}d/cmd/root.go.plush +++ b/ignite/templates/app/files/cmd/{{binaryNamePrefix}}d/cmd/root.go.plush @@ -55,6 +55,10 @@ func NewRootCmd() *cobra.Command { ); err != nil { panic(err) } + // Since the IBC modules don't support dependency injection, we need to + // manually add the modules to the basic manager on the client side. + // This needs to be removed after IBC supports App Wiring. + app.RegisterIBC(moduleBasicManager, clientCtx.InterfaceRegistry) rootCmd := &cobra.Command{ Use: app.Name + "d", @@ -104,13 +108,6 @@ func NewRootCmd() *cobra.Command { }, } - // Since the IBC modules don't support dependency injection, we need to - // manually register the modules on the client side. - // This needs to be removed after IBC supports App Wiring. - ibcModules := app.RegisterIBC(clientCtx.InterfaceRegistry) - for name, module := range ibcModules { - autoCliOpts.Modules[name] = module - } initRootCmd(rootCmd, clientCtx.TxConfig, clientCtx.InterfaceRegistry, clientCtx.Codec, moduleBasicManager) overwriteFlagDefaults(rootCmd, map[string]string{ From fcc21868daa13f9c39924d7c7f63c362651d05ca Mon Sep 17 00:00:00 2001 From: Pantani Date: Tue, 16 Jan 2024 16:28:12 -0300 Subject: [PATCH 28/42] fix changelog --- changelog.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index 4a27116aa9..bde2e2c1b3 100644 --- a/changelog.md +++ b/changelog.md @@ -5,6 +5,7 @@ ### Features - [#3835](https://github.com/ignite/cli/pull/3835) Add `--minimal` flag to `scaffold chain` to scaffold a chain with the least amount of sdk modules +- [#3820](https://github.com/ignite/cli/pull/3820) Add integration tests for IBC chains ## [`v28.1.1`](https://github.com/ignite/cli/releases/tag/v28.1.1) @@ -26,7 +27,6 @@ - [#3786](https://github.com/ignite/cli/pull/3786) Add artifacts for publishing Ignite to FlatHub and Snapcraft - [#3830](https://github.com/ignite/cli/pull/3830) Remove gRPC info from Ignite Apps errors -- [#3820](https://github.com/ignite/cli/pull/3820) Add integration tests for IBC chains - [#3861](https://github.com/ignite/cli/pull/3861) Send to the analytics if the user is using a GitPod ### Changes @@ -41,7 +41,7 @@ - [#3827](https://github.com/ignite/cli/pull/3827) Change ignite apps to be able to run in any directory - [#3831](https://github.com/ignite/cli/pull/3831) Correct ignite app gRPC server stop memory issue - [#3825](https://github.com/ignite/cli/pull/3825) Fix a minor Keplr type-checking bug in TS client -- [#3836](https://github.com/ignite/cli/pull/3836) Add missing IBC commands for scaffolded chain +- [#3836](https://github.com/ignite/cli/pull/3836), [#3858](https://github.com/ignite/cli/pull/3858) Add missing IBC commands for scaffolded chain - [#3833](https://github.com/ignite/cli/pull/3833) Improve Cosmos SDK detection to support SDK forks - [#3849](https://github.com/ignite/cli/pull/3849) Add missing `tx.go` file by default and enable cli if autocli does not exist - [#3851](https://github.com/ignite/cli/pull/3851) Add missing ibc interfaces to chain client From aa8af901d914a612c4534b781d452926bfe7fbe4 Mon Sep 17 00:00:00 2001 From: Pantani Date: Tue, 16 Jan 2024 16:39:01 -0300 Subject: [PATCH 29/42] fix ibc.go app --- ignite/templates/app/files/app/ibc.go.plush | 35 ++++++++++++++------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/ignite/templates/app/files/app/ibc.go.plush b/ignite/templates/app/files/app/ibc.go.plush index d0bf4dd3b9..7c76bc9506 100644 --- a/ignite/templates/app/files/app/ibc.go.plush +++ b/ignite/templates/app/files/app/ibc.go.plush @@ -1,9 +1,9 @@ package app import ( + "cosmossdk.io/core/appmodule" storetypes "cosmossdk.io/store/types" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/cosmos-sdk/types/module" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" @@ -180,14 +180,27 @@ func (app *App) registerIBCModules() { } } -// RegisterIBC adds the missing IBC modules and interfaces into the module manager. -func RegisterIBC(moduleManager module.BasicManager, registry cdctypes.InterfaceRegistry) { - moduleManager[ibcexported.ModuleName] = ibc.AppModule{} - moduleManager[ibctransfertypes.ModuleName] = ibctransfer.AppModule{} - moduleManager[ibcfeetypes.ModuleName] = ibcfee.AppModule{} - moduleManager[icatypes.ModuleName] = icamodule.AppModule{} - moduleManager[capabilitytypes.ModuleName] = capability.AppModule{} +// Since the IBC modules don't support dependency injection, we need to +// manually register the modules on the client side. +// This needs to be removed after IBC supports App Wiring. +func RegisterIBC(registry cdctypes.InterfaceRegistry) map[string]appmodule.AppModule { + modules := map[string]appmodule.AppModule{ + ibcexported.ModuleName: ibc.AppModule{}, + ibctransfertypes.ModuleName: ibctransfer.AppModule{}, + ibcfeetypes.ModuleName: ibcfee.AppModule{}, + icatypes.ModuleName: icamodule.AppModule{}, + capabilitytypes.ModuleName: capability.AppModule{}, + ibctm.ModuleName: ibctm.AppModule{}, + solomachine.ModuleName: solomachine.AppModule{}, + } - ibctm.AppModuleBasic{}.RegisterInterfaces(registry) - solomachine.AppModuleBasic{}.RegisterInterfaces(registry) -} + for _, module := range modules { + if mod, ok := module.(interface { + RegisterInterfaces(registry cdctypes.InterfaceRegistry) + }); ok { + mod.RegisterInterfaces(registry) + } + } + + return modules +} \ No newline at end of file From f67900bfa1e5e6e60ba5d58c0c6560c3a77cee66 Mon Sep 17 00:00:00 2001 From: Pantani Date: Wed, 17 Jan 2024 17:01:05 -0300 Subject: [PATCH 30/42] query channels --- integration/ibc/cmd_relayer_test.go | 99 ++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 31 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index 69e54b7eb8..d5628fdeea 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -10,6 +10,7 @@ import ( "os" "path/filepath" "testing" + "time" "github.com/stretchr/testify/require" "gopkg.in/yaml.v2" @@ -205,6 +206,29 @@ func (k Keeper) OnTimeoutIbcPostPacket(ctx sdk.Context, packet channeltypes.Pack }` ) +type QueryChannels struct { + Channels []struct { + ChannelId string `json:"channel_id"` + ConnectionHops []string `json:"connection_hops"` + Counterparty struct { + ChannelId string `json:"channel_id"` + PortId string `json:"port_id"` + } `json:"counterparty"` + Ordering string `json:"ordering"` + PortId string `json:"port_id"` + State string `json:"state"` + Version string `json:"version"` + } `json:"channels"` + Height struct { + RevisionHeight string `json:"revision_height"` + RevisionNumber string `json:"revision_number"` + } `json:"height"` + Pagination struct { + NextKey interface{} `json:"next_key"` + Total string `json:"total"` + } `json:"pagination"` +} + func runChain( t *testing.T, env envtest.Env, @@ -413,7 +437,6 @@ func TestBlogIBC(t *testing.T) { "-g", filepath.Join(goenv.GoPath(), "src/github.com/ignite/apps/hermes"), ), - step.Workdir(app.SourcePath()), )), )) @@ -434,42 +457,59 @@ func TestBlogIBC(t *testing.T) { "--generate-wallets", "--overwrite-config", ), - step.Workdir(app.SourcePath()), )), )) - // go func() { - env.Must(env.Exec("run the hermes relayer", - step.NewSteps(step.New( - step.Exec(envtest.IgniteApp, "relayer", "hermes", "start", earthChainID, marsChainID), - step.Workdir(app.SourcePath()), - step.Stdout(os.Stdout), - step.Stdin(os.Stdin), - step.Stderr(os.Stderr), - )), - )) - //}() + go func() { + env.Must(env.Exec("run the hermes relayer", + step.NewSteps(step.New( + step.Exec(envtest.IgniteApp, "relayer", "hermes", "start", earthChainID, marsChainID), + )), + )) + }() + time.Sleep(3 * time.Second) + + var ( + queryOutput = &bytes.Buffer{} + queryResponse QueryChannels + ) - stepsCheckRelayer := step.NewSteps( + // sign tx to add an item to the list. + env.Must(env.Exec("run the hermes relayer", step.NewSteps( step.New( + step.Stdout(queryOutput), step.Exec( - // TODO query chain connection-id app.Binary(), - "config", - "output", "json", + "q", + "ibc", + "channel", + "channels", + "--node", earthRPC, + "--log_format", "json", + "--output", "json", ), - step.PreExec(func() error { - if err := env.IsAppServed(ctx, earthAPI); err != nil { - return err + step.PostExec(func(execErr error) error { + if execErr != nil { + return execErr } - return env.IsAppServed(ctx, marsAPI) + err := json.Unmarshal(queryOutput.Bytes(), &queryResponse) + if err != nil { + return fmt.Errorf("unmarshling tx response: %w", err) + } + if len(queryResponse.Channels) == 0 || + len(queryResponse.Channels[0].ConnectionHops) == 0 { + return fmt.Errorf("channel not found") + } + if queryResponse.Channels[0].State != "STATE_OPEN" { + return fmt.Errorf("channel is not open") + } + return nil }), ), - ) - env.Exec("run the ts relayer", stepsCheckRelayer, envtest.ExecRetry()) + ))) var ( - output = &bytes.Buffer{} + txOutput = &bytes.Buffer{} txResponse struct { Code int RawLog string `json:"raw_log"` @@ -479,20 +519,17 @@ func TestBlogIBC(t *testing.T) { // sign tx to add an item to the list. stepsTx := step.NewSteps( step.New( - step.Stdout(output), - step.PreExec(func() error { - err := env.IsAppServed(ctx, earthGRPC) - return err - }), + step.Stdout(txOutput), step.Exec( app.Binary(), "tx", "blog", "send-ibc-post", + "transfer", "channel-0", "Hello", "Hello Mars, I'm Alice from Earth", - "--chain-id", "blog", + "--chain-id", earthChainID, "--from", "alice", "--node", earthGRPC, "--output", "json", @@ -503,7 +540,7 @@ func TestBlogIBC(t *testing.T) { if execErr != nil { return execErr } - err := json.Unmarshal(output.Bytes(), &txResponse) + err := json.Unmarshal(txOutput.Bytes(), &txResponse) if err != nil { return fmt.Errorf("unmarshling tx response: %w", err) } From e174df1cb7b24c823425aa05bcc34ec6044782a3 Mon Sep 17 00:00:00 2001 From: Pantani Date: Thu, 18 Jan 2024 15:40:38 -0300 Subject: [PATCH 31/42] check balances --- integration/ibc/cmd_relayer_test.go | 102 ++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 15 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index d5628fdeea..0f931dd410 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -12,6 +12,7 @@ import ( "testing" "time" + "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/stretchr/testify/require" "gopkg.in/yaml.v2" @@ -19,6 +20,7 @@ import ( "github.com/ignite/cli/v28/ignite/config/chain/base" v1 "github.com/ignite/cli/v28/ignite/config/chain/v1" "github.com/ignite/cli/v28/ignite/pkg/availableport" + "github.com/ignite/cli/v28/ignite/pkg/cmdrunner" "github.com/ignite/cli/v28/ignite/pkg/cmdrunner/step" "github.com/ignite/cli/v28/ignite/pkg/goanalysis" "github.com/ignite/cli/v28/ignite/pkg/goenv" @@ -28,7 +30,8 @@ import ( ) const ( - relayerMnemonic = "great immense still pill defense fetch pencil slow purchase symptom speed arm shoot fence have divorce cigar rapid hen vehicle pear evolve correct nerve" + keyringTestDirName = "keyring-test" + relayerMnemonic = "great immense still pill defense fetch pencil slow purchase symptom speed arm shoot fence have divorce cigar rapid hen vehicle pear evolve correct nerve" ) var ( @@ -70,6 +73,7 @@ var ( { Name: "alice", Bonded: "100000000stake", + Client: yamlmap.Map{"keyring-backend": keyring.BackendTest}, App: yamlmap.Map{ "api": yamlmap.Map{"address": ":1318"}, "grpc": yamlmap.Map{"address": ":9092"}, @@ -120,6 +124,7 @@ var ( { Name: "alice", Bonded: "100000000stake", + Client: yamlmap.Map{"keyring-backend": keyring.BackendTest}, App: yamlmap.Map{ "api": yamlmap.Map{"address": ":1317"}, "grpc": yamlmap.Map{"address": ":9090"}, @@ -270,7 +275,6 @@ func runChain( ctx, cancel := context.WithCancel(ctx) t.Cleanup(func() { cancel() - require.NoError(t, os.RemoveAll(tmpDir)) }) app.SetConfigPath(cfgPath) @@ -408,7 +412,9 @@ func TestBlogIBC(t *testing.T) { earthAPI, earthRPC, earthGRPC, earthFaucet := runChain(t, env, app, earthConfig, ports[:7]) marsAPI, marsRPC, marsGRPC, marsFaucet := runChain(t, env, app, marsConfig, ports[7:]) earthChainID := earthConfig.Genesis["chain_id"].(string) + earthHome := earthConfig.Validators[0].Home marsChainID := marsConfig.Genesis["chain_id"].(string) + marsHome := marsConfig.Validators[0].Home // check the chains is up stepsCheckChains := step.NewSteps( @@ -473,9 +479,7 @@ func TestBlogIBC(t *testing.T) { queryOutput = &bytes.Buffer{} queryResponse QueryChannels ) - - // sign tx to add an item to the list. - env.Must(env.Exec("run the hermes relayer", step.NewSteps( + env.Must(env.Exec("verify if the channel was created", step.NewSteps( step.New( step.Stdout(queryOutput), step.Exec( @@ -508,32 +512,37 @@ func TestBlogIBC(t *testing.T) { ), ))) + // sign tx to add an item to the list. var ( - txOutput = &bytes.Buffer{} - txResponse struct { + sender = "alice" + receiverAddr = "cosmos1nrksk5swk6lnmlq670a8kwxmsjnu0ezqts39sa" + txOutput = &bytes.Buffer{} + txResponse struct { Code int RawLog string `json:"raw_log"` + TxHash string `json:"txhash"` } ) - // sign tx to add an item to the list. stepsTx := step.NewSteps( step.New( step.Stdout(txOutput), step.Exec( app.Binary(), "tx", - "blog", - "send-ibc-post", + "ibc-transfer", + "transfer", "transfer", "channel-0", - "Hello", - "Hello Mars, I'm Alice from Earth", + receiverAddr, + "100000stake", + "--from", sender, + "--node", earthRPC, + "--home", earthHome, "--chain-id", earthChainID, - "--from", "alice", - "--node", earthGRPC, "--output", "json", "--log_format", "json", + "--keyring-backend", "test", "--yes", ), step.PostExec(func(execErr error) error { @@ -544,7 +553,34 @@ func TestBlogIBC(t *testing.T) { if err != nil { return fmt.Errorf("unmarshling tx response: %w", err) } - return nil + return cmdrunner.New().Run(ctx, step.New( + step.Exec( + app.Binary(), + "q", + "tx", + txResponse.TxHash, + "--node", earthRPC, + "--home", earthHome, + "--chain-id", earthChainID, + "--output", "json", + "--log_format", "json", + ), + step.PreExec(func() error { + txOutput.Reset() + return nil + }), + step.PostExec(func(execErr error) error { + if execErr != nil { + return execErr + } + + if err := json.NewDecoder(txOutput).Decode(&txResponse); err != nil { + return err + } + return nil + }), + step.Stdout(txOutput), + )) }), ), ) @@ -553,4 +589,40 @@ func TestBlogIBC(t *testing.T) { } require.Equal(t, 0, txResponse.Code, "tx failed code=%d log=%s", txResponse.Code, txResponse.RawLog) + + var ( + balanceOutput = &bytes.Buffer{} + balanceResponse QueryChannels + ) + env.Must(env.Exec("check ibc balance", step.NewSteps( + step.New( + step.Stdout(balanceOutput), + step.Exec( + app.Binary(), + "q", + "bank", + "balances", + receiverAddr, + "--node", marsRPC, + "--home", marsHome, + "--log_format", "json", + "--output", "json", + ), + step.PostExec(func(execErr error) error { + if execErr != nil { + return execErr + } + err := json.Unmarshal(balanceOutput.Bytes(), &balanceResponse) + if err != nil { + return fmt.Errorf("unmarshling tx response: %w", err) + } + return nil + }), + ), + ))) + + // TODO test ibc using the blog post methods: + // step.Exec(app.Binary(), "tx", "blog", "send-ibc-post", "transfer", "channel-0", "Hello", "Hello_Mars-Alice_from_Earth", "--chain-id", earthChainID, "--from", "alice", "--node", earthGRPC, "--output", "json", "--log_format", "json", "--yes") + // TODO test ibc using the hermes ft-transfer: + // step.Exec(envtest.IgniteApp, "relayer", "hermes", "exec", "--", "--config", earthConfig, "tx", "ft-transfer", "--timeout-seconds", "1000", "--dst-chain", earthChainID, "--src-chain", marsChainID, "--src-port", "transfer", "--src-channel", "channel-0", "--amount", "100000", "--denom", "stake", "--output", "json", "--log_format", "json", "--yes") } From 51882479caf9975f608e5a2b63c455d632c9db20 Mon Sep 17 00:00:00 2001 From: Pantani Date: Thu, 18 Jan 2024 15:45:21 -0300 Subject: [PATCH 32/42] check ibc balance --- integration/ibc/cmd_relayer_test.go | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index 0f931dd410..e387f652cf 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -9,10 +9,12 @@ import ( "fmt" "os" "path/filepath" + "strings" "testing" "time" "github.com/cosmos/cosmos-sdk/crypto/keyring" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" "gopkg.in/yaml.v2" @@ -224,14 +226,10 @@ type QueryChannels struct { State string `json:"state"` Version string `json:"version"` } `json:"channels"` - Height struct { - RevisionHeight string `json:"revision_height"` - RevisionNumber string `json:"revision_number"` - } `json:"height"` - Pagination struct { - NextKey interface{} `json:"next_key"` - Total string `json:"total"` - } `json:"pagination"` +} + +type QueryBalances struct { + Balances sdk.Coins `json:"balances"` } func runChain( @@ -592,7 +590,7 @@ func TestBlogIBC(t *testing.T) { var ( balanceOutput = &bytes.Buffer{} - balanceResponse QueryChannels + balanceResponse QueryBalances ) env.Must(env.Exec("check ibc balance", step.NewSteps( step.New( @@ -616,6 +614,10 @@ func TestBlogIBC(t *testing.T) { if err != nil { return fmt.Errorf("unmarshling tx response: %w", err) } + if len(balanceResponse.Balances) == 0 && + !strings.Contains(balanceResponse.Balances[0].Denom, "ibc") { + return fmt.Errorf("invalid ibc balance: %v", balanceResponse.Balances[0]) + } return nil }), ), From cff30eabae9558b04ca951e41cc755201e707ace Mon Sep 17 00:00:00 2001 From: Pantani Date: Thu, 18 Jan 2024 19:49:11 -0300 Subject: [PATCH 33/42] improve test cleanup --- integration/ibc/cmd_relayer_test.go | 86 +++++++++++++++-------------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index e387f652cf..104a86c59f 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -26,7 +26,6 @@ import ( "github.com/ignite/cli/v28/ignite/pkg/cmdrunner/step" "github.com/ignite/cli/v28/ignite/pkg/goanalysis" "github.com/ignite/cli/v28/ignite/pkg/goenv" - "github.com/ignite/cli/v28/ignite/pkg/randstr" yamlmap "github.com/ignite/cli/v28/ignite/pkg/yaml" envtest "github.com/ignite/cli/v28/integration" ) @@ -213,40 +212,44 @@ func (k Keeper) OnTimeoutIbcPostPacket(ctx sdk.Context, packet channeltypes.Pack }` ) -type QueryChannels struct { - Channels []struct { - ChannelId string `json:"channel_id"` - ConnectionHops []string `json:"connection_hops"` - Counterparty struct { - ChannelId string `json:"channel_id"` - PortId string `json:"port_id"` - } `json:"counterparty"` - Ordering string `json:"ordering"` - PortId string `json:"port_id"` - State string `json:"state"` - Version string `json:"version"` - } `json:"channels"` -} +type ( + QueryChannels struct { + Channels []struct { + ChannelId string `json:"channel_id"` + ConnectionHops []string `json:"connection_hops"` + Counterparty struct { + ChannelId string `json:"channel_id"` + PortId string `json:"port_id"` + } `json:"counterparty"` + Ordering string `json:"ordering"` + PortId string `json:"port_id"` + State string `json:"state"` + Version string `json:"version"` + } `json:"channels"` + } -type QueryBalances struct { - Balances sdk.Coins `json:"balances"` -} + QueryBalances struct { + Balances sdk.Coins `json:"balances"` + } +) func runChain( t *testing.T, + ctx context.Context, env envtest.Env, app envtest.App, cfg v1.Config, + tmpDir string, ports []uint, ) (api, rpc, grpc, faucet string) { t.Helper() if len(ports) < 7 { t.Fatalf("invalid number of ports %d", len(ports)) } + var ( - ctx = env.Ctx() - tmpDir = t.TempDir() - homePath = filepath.Join(tmpDir, randstr.Runes(10)) + chainID = cfg.Genesis["chain_id"].(string) + homePath = filepath.Join(tmpDir, chainID) cfgPath = filepath.Join(tmpDir, chain.ConfigFilenames[0]) ) genAddr := func(port uint) string { @@ -270,11 +273,6 @@ func runChain( require.NoError(t, yaml.NewEncoder(file).Encode(cfg)) require.NoError(t, file.Close()) - ctx, cancel := context.WithCancel(ctx) - t.Cleanup(func() { - cancel() - }) - app.SetConfigPath(cfgPath) app.SetHomePath(homePath) go func() { @@ -289,10 +287,17 @@ func runChain( func TestBlogIBC(t *testing.T) { var ( - env = envtest.New(t) - app = env.Scaffold("github.com/test/planet") - ctx = env.Ctx() + env = envtest.New(t) + app = env.Scaffold("github.com/test/planet") + ctx = env.Ctx() + tmpDir = t.TempDir() ) + ctx, cancel := context.WithCancel(ctx) + t.Cleanup(func() { + cancel() + time.Sleep(10 * time.Second) + require.NoError(t, os.RemoveAll(tmpDir)) + }) env.Must(env.Exec("create an IBC module", step.NewSteps(step.New( @@ -407,10 +412,10 @@ func TestBlogIBC(t *testing.T) { availableport.WithMaxPort(5000), ) require.NoError(t, err) - earthAPI, earthRPC, earthGRPC, earthFaucet := runChain(t, env, app, earthConfig, ports[:7]) - marsAPI, marsRPC, marsGRPC, marsFaucet := runChain(t, env, app, marsConfig, ports[7:]) + earthAPI, earthRPC, earthGRPC, earthFaucet := runChain(t, ctx, env, app, earthConfig, tmpDir, ports[:7]) earthChainID := earthConfig.Genesis["chain_id"].(string) earthHome := earthConfig.Validators[0].Home + marsAPI, marsRPC, marsGRPC, marsFaucet := runChain(t, ctx, env, app, marsConfig, tmpDir, ports[7:]) marsChainID := marsConfig.Genesis["chain_id"].(string) marsHome := marsConfig.Validators[0].Home @@ -469,6 +474,7 @@ func TestBlogIBC(t *testing.T) { step.NewSteps(step.New( step.Exec(envtest.IgniteApp, "relayer", "hermes", "start", earthChainID, marsChainID), )), + envtest.ExecCtx(ctx), )) }() time.Sleep(3 * time.Second) @@ -494,8 +500,7 @@ func TestBlogIBC(t *testing.T) { if execErr != nil { return execErr } - err := json.Unmarshal(queryOutput.Bytes(), &queryResponse) - if err != nil { + if err := json.Unmarshal(queryOutput.Bytes(), &queryResponse); err != nil { return fmt.Errorf("unmarshling tx response: %w", err) } if len(queryResponse.Channels) == 0 || @@ -547,8 +552,7 @@ func TestBlogIBC(t *testing.T) { if execErr != nil { return execErr } - err := json.Unmarshal(txOutput.Bytes(), &txResponse) - if err != nil { + if err := json.Unmarshal(txOutput.Bytes(), &txResponse); err != nil { return fmt.Errorf("unmarshling tx response: %w", err) } return cmdrunner.New().Run(ctx, step.New( @@ -563,6 +567,7 @@ func TestBlogIBC(t *testing.T) { "--output", "json", "--log_format", "json", ), + step.Stdout(txOutput), step.PreExec(func() error { txOutput.Reset() return nil @@ -571,13 +576,11 @@ func TestBlogIBC(t *testing.T) { if execErr != nil { return execErr } - - if err := json.NewDecoder(txOutput).Decode(&txResponse); err != nil { + if err := json.Unmarshal(txOutput.Bytes(), &txResponse); err != nil { return err } return nil }), - step.Stdout(txOutput), )) }), ), @@ -610,12 +613,11 @@ func TestBlogIBC(t *testing.T) { if execErr != nil { return execErr } - err := json.Unmarshal(balanceOutput.Bytes(), &balanceResponse) - if err != nil { + if err := json.Unmarshal(balanceOutput.Bytes(), &balanceResponse); err != nil { return fmt.Errorf("unmarshling tx response: %w", err) } - if len(balanceResponse.Balances) == 0 && - !strings.Contains(balanceResponse.Balances[0].Denom, "ibc") { + if len(balanceResponse.Balances) == 0 || + !strings.HasPrefix(balanceResponse.Balances[0].Denom, "ibc/") { return fmt.Errorf("invalid ibc balance: %v", balanceResponse.Balances[0]) } return nil From f67bcb8be0e7c7cee132c607121eca14ff346acd Mon Sep 17 00:00:00 2001 From: Pantani Date: Thu, 18 Jan 2024 19:53:00 -0300 Subject: [PATCH 34/42] fix chain home and config paths --- integration/ibc/cmd_relayer_test.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index 104a86c59f..9364306659 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -249,8 +249,8 @@ func runChain( var ( chainID = cfg.Genesis["chain_id"].(string) - homePath = filepath.Join(tmpDir, chainID) - cfgPath = filepath.Join(tmpDir, chain.ConfigFilenames[0]) + homePath = filepath.Join(tmpDir, chainID, "home") + cfgPath = filepath.Join(tmpDir, chainID, chain.ConfigFilenames[0]) ) genAddr := func(port uint) string { return fmt.Sprintf(":%d", port) @@ -515,7 +515,6 @@ func TestBlogIBC(t *testing.T) { ), ))) - // sign tx to add an item to the list. var ( sender = "alice" receiverAddr = "cosmos1nrksk5swk6lnmlq670a8kwxmsjnu0ezqts39sa" @@ -585,7 +584,7 @@ func TestBlogIBC(t *testing.T) { }), ), ) - if !env.Exec("sign a tx", stepsTx, envtest.ExecRetry()) { + if !env.Exec("send an IBC transfer", stepsTx, envtest.ExecRetry()) { t.FailNow() } require.Equal(t, 0, txResponse.Code, From 6b71b052b4ee71f01f0ae184b2d16bb769c5d7fa Mon Sep 17 00:00:00 2001 From: Pantani Date: Thu, 18 Jan 2024 19:53:33 -0300 Subject: [PATCH 35/42] fix log typo --- integration/ibc/cmd_relayer_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index 9364306659..a42ccada64 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -613,7 +613,7 @@ func TestBlogIBC(t *testing.T) { return execErr } if err := json.Unmarshal(balanceOutput.Bytes(), &balanceResponse); err != nil { - return fmt.Errorf("unmarshling tx response: %w", err) + return fmt.Errorf("unmarshalling tx response: %w", err) } if len(balanceResponse.Balances) == 0 || !strings.HasPrefix(balanceResponse.Balances[0].Denom, "ibc/") { From 5fb402535bd5e4a33cbd724e7de9a7d4001ac707 Mon Sep 17 00:00:00 2001 From: Pantani Date: Thu, 18 Jan 2024 19:57:13 -0300 Subject: [PATCH 36/42] cerate the chain path before use --- integration/ibc/cmd_relayer_test.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index a42ccada64..3549530f9e 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -248,10 +248,13 @@ func runChain( } var ( - chainID = cfg.Genesis["chain_id"].(string) - homePath = filepath.Join(tmpDir, chainID, "home") - cfgPath = filepath.Join(tmpDir, chainID, chain.ConfigFilenames[0]) + chainID = cfg.Genesis["chain_id"].(string) + chainPath = filepath.Join(tmpDir, chainID) + homePath = filepath.Join(chainPath, "home") + cfgPath = filepath.Join(chainPath, chain.ConfigFilenames[0]) ) + require.NoError(t, os.MkdirAll(chainPath, os.ModePerm)) + genAddr := func(port uint) string { return fmt.Sprintf(":%d", port) } From 2bf6024da53c422581fc9fe4422fbb94060544c1 Mon Sep 17 00:00:00 2001 From: Pantani Date: Thu, 18 Jan 2024 19:58:13 -0300 Subject: [PATCH 37/42] remove unused const --- integration/ibc/cmd_relayer_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index 3549530f9e..1b5b871d09 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -31,8 +31,7 @@ import ( ) const ( - keyringTestDirName = "keyring-test" - relayerMnemonic = "great immense still pill defense fetch pencil slow purchase symptom speed arm shoot fence have divorce cigar rapid hen vehicle pear evolve correct nerve" + relayerMnemonic = "great immense still pill defense fetch pencil slow purchase symptom speed arm shoot fence have divorce cigar rapid hen vehicle pear evolve correct nerve" ) var ( From 852e27079efb722d466c3309f54d6ef021b2fee1 Mon Sep 17 00:00:00 2001 From: Pantani Date: Thu, 18 Jan 2024 20:09:58 -0300 Subject: [PATCH 38/42] decrease cleanup time --- integration/ibc/cmd_relayer_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index 1b5b871d09..8c0cb24e6d 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -297,7 +297,7 @@ func TestBlogIBC(t *testing.T) { ctx, cancel := context.WithCancel(ctx) t.Cleanup(func() { cancel() - time.Sleep(10 * time.Second) + time.Sleep(5 * time.Second) require.NoError(t, os.RemoveAll(tmpDir)) }) From 50bcc66013dbc81c974342893c2ff33a3349bfc3 Mon Sep 17 00:00:00 2001 From: Pantani Date: Mon, 22 Jan 2024 11:06:14 -0300 Subject: [PATCH 39/42] setup the remote hermes app url --- integration/ibc/cmd_relayer_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index 8c0cb24e6d..ab9bf1d55d 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -25,7 +25,6 @@ import ( "github.com/ignite/cli/v28/ignite/pkg/cmdrunner" "github.com/ignite/cli/v28/ignite/pkg/cmdrunner/step" "github.com/ignite/cli/v28/ignite/pkg/goanalysis" - "github.com/ignite/cli/v28/ignite/pkg/goenv" yamlmap "github.com/ignite/cli/v28/ignite/pkg/yaml" envtest "github.com/ignite/cli/v28/integration" ) @@ -446,7 +445,8 @@ func TestBlogIBC(t *testing.T) { "app", "install", "-g", - filepath.Join(goenv.GoPath(), "src/github.com/ignite/apps/hermes"), + // filepath.Join(goenv.GoPath(), "src/github.com/ignite/apps/hermes"), // Local path for test proposals + "github.com/ignite/apps/hermes", ), )), )) From 7e10443fa5f92ef0009eb3287f557690de26d5d4 Mon Sep 17 00:00:00 2001 From: Pantani Date: Fri, 26 Jan 2024 16:06:04 -0300 Subject: [PATCH 40/42] use parser.ParseExpr instead parser.ParseExpr --- ignite/pkg/goanalysis/goanalysis.go | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/ignite/pkg/goanalysis/goanalysis.go b/ignite/pkg/goanalysis/goanalysis.go index 7f770af4e7..36f16a472f 100644 --- a/ignite/pkg/goanalysis/goanalysis.go +++ b/ignite/pkg/goanalysis/goanalysis.go @@ -298,12 +298,17 @@ func ReplaceCode(pkgPath, oldFunctionName, newFunction string) (err error) { for _, f := range pkg.Files { found := false ast.Inspect(f, func(n ast.Node) bool { - // Check if the node is a function declaration. if funcDecl, ok := n.(*ast.FuncDecl); ok { // Check if the function has the name you want to replace. if funcDecl.Name.Name == oldFunctionName { // Replace the function body with the replacement code. - funcDecl.Body, err = parseReplacementCode(newFunction) + replacementExpr, err := parser.ParseExpr(newFunction) + if err != nil { + return false + } + funcDecl.Body = &ast.BlockStmt{List: []ast.Stmt{ + &ast.ExprStmt{X: replacementExpr}, + }} found = true return false } @@ -333,19 +338,3 @@ func ReplaceCode(pkgPath, oldFunctionName, newFunction string) (err error) { } return nil } - -// parseReplacementCode parse the replacement code and create a *ast.BlockStmt. -func parseReplacementCode(code string) (*ast.BlockStmt, error) { - fset := token.NewFileSet() - node, err := parser.ParseFile(fset, "", code, parser.ParseComments) - if err != nil { - return nil, err - } - // Assuming there's only one function in the replacement code. - if len(node.Decls) > 0 { - if funcDecl, ok := node.Decls[0].(*ast.FuncDecl); ok { - return funcDecl.Body, nil - } - } - return nil, errors.Errorf("replacement code does not contain a valid function declaration") -} From 2b02b9bfe237b6cf44bf0a969b0ba16a593c8009 Mon Sep 17 00:00:00 2001 From: Pantani Date: Tue, 30 Jan 2024 22:25:48 -0300 Subject: [PATCH 41/42] remove panic from assert error --- integration/ibc/cmd_relayer_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index ab9bf1d55d..4490989789 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -619,7 +619,7 @@ func TestBlogIBC(t *testing.T) { } if len(balanceResponse.Balances) == 0 || !strings.HasPrefix(balanceResponse.Balances[0].Denom, "ibc/") { - return fmt.Errorf("invalid ibc balance: %v", balanceResponse.Balances[0]) + return fmt.Errorf("invalid ibc balance: %v", balanceResponse) } return nil }), From 69a5f692d9d5a4c568b7dc98b847bd1a42d929b9 Mon Sep 17 00:00:00 2001 From: Pantani Date: Tue, 30 Jan 2024 22:39:38 -0300 Subject: [PATCH 42/42] improve error assert --- integration/ibc/cmd_relayer_test.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/integration/ibc/cmd_relayer_test.go b/integration/ibc/cmd_relayer_test.go index 4490989789..30fb207fd9 100644 --- a/integration/ibc/cmd_relayer_test.go +++ b/integration/ibc/cmd_relayer_test.go @@ -617,9 +617,11 @@ func TestBlogIBC(t *testing.T) { if err := json.Unmarshal(balanceOutput.Bytes(), &balanceResponse); err != nil { return fmt.Errorf("unmarshalling tx response: %w", err) } - if len(balanceResponse.Balances) == 0 || - !strings.HasPrefix(balanceResponse.Balances[0].Denom, "ibc/") { - return fmt.Errorf("invalid ibc balance: %v", balanceResponse) + if balanceResponse.Balances.Empty() { + return fmt.Errorf("empty balances") + } + if !strings.HasPrefix(balanceResponse.Balances[0].Denom, "ibc/") { + return fmt.Errorf("invalid ibc balance: %v", balanceResponse.Balances[0]) } return nil }),