From a3bf612c77760ac6224419224d6e0a2da83d6118 Mon Sep 17 00:00:00 2001 From: mfbz Date: Sat, 5 Apr 2025 00:02:07 +0200 Subject: [PATCH 1/5] Added get-system command to retrieve a system transaction from block id --- internal/transactions/get-system.go | 54 ++++++++++++++++++++++ internal/transactions/transactions.go | 1 + internal/transactions/transactions_test.go | 31 +++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 internal/transactions/get-system.go diff --git a/internal/transactions/get-system.go b/internal/transactions/get-system.go new file mode 100644 index 000000000..4a7c98a7e --- /dev/null +++ b/internal/transactions/get-system.go @@ -0,0 +1,54 @@ +package transactions + +import ( + "context" + "strings" + + flowsdk "github.com/onflow/flow-go-sdk" + "github.com/spf13/cobra" + + "github.com/onflow/flowkit/v2" + "github.com/onflow/flowkit/v2/output" + + "github.com/onflow/flow-cli/internal/command" +) + +type flagsGetSystem struct { + Include []string `default:"" flag:"include" info:"Fields to include in the output. Valid values: signatures, code, payload, fee-events."` + Exclude []string `default:"" flag:"exclude" info:"Fields to exclude from the output. Valid values: events."` +} + +var getSystemFlags = flagsGetSystem{} + +var getSystemCommand = &command.Command{ + Cmd: &cobra.Command{ + Use: "get-system ", + Short: "Get the system transaction by block ID", + Example: "flow transactions get-system a1b2c3...", + Args: cobra.ExactArgs(1), + }, + Flags: &getSystemFlags, + Run: getSystemTransaction, +} + +func getSystemTransaction( + args []string, + _ command.GlobalFlags, + _ output.Logger, + _ flowkit.ReaderWriter, + flow flowkit.Services, +) (command.Result, error) { + blockID := flowsdk.HexToID(strings.TrimPrefix(args[0], "0x")) + + tx, result, err := flow.GetSystemTransaction(context.Background(), blockID) + if err != nil { + return nil, err + } + + return &transactionResult{ + result: result, + tx: tx, + include: getSystemFlags.Include, + exclude: getSystemFlags.Exclude, + }, nil +} diff --git a/internal/transactions/transactions.go b/internal/transactions/transactions.go index fb195fb2b..63da701c0 100644 --- a/internal/transactions/transactions.go +++ b/internal/transactions/transactions.go @@ -49,6 +49,7 @@ func init() { signCommand.AddToParent(Cmd) buildCommand.AddToParent(Cmd) sendSignedCommand.AddToParent(Cmd) + getSystemCommand.AddToParent(Cmd) decodeCommand.AddToParent(Cmd) } diff --git a/internal/transactions/transactions_test.go b/internal/transactions/transactions_test.go index fd7d635c4..054593fd9 100644 --- a/internal/transactions/transactions_test.go +++ b/internal/transactions/transactions_test.go @@ -138,6 +138,37 @@ func Test_Get(t *testing.T) { }) } +func Test_GetSystem(t *testing.T) { + srv, _, _ := util.TestMocks(t) + + t.Run("Success", func(t *testing.T) { + inArgs := []string{"0xabcdef"} + + // Mocked system transaction and result + tx := &flow.Transaction{} + result := &flow.TransactionResult{} + + srv.GetSystemTransaction.Run(func(args mock.Arguments) { + id := args.Get(1).(flow.Identifier) + assert.Equal(t, flow.HexToID("abcdef"), id) + }).Return(tx, result, nil) + + res, err := getSystemTransaction(inArgs, command.GlobalFlags{}, util.NoLogger, nil, srv.Mock) + assert.NoError(t, err) + assert.NotNil(t, res) + }) + + t.Run("Fail invalid block ID", func(t *testing.T) { + inArgs := []string{""} + + srv.GetSystemTransaction.Return(nil, nil, fmt.Errorf("block not found")) + + res, err := getSystemTransaction(inArgs, command.GlobalFlags{}, util.NoLogger, nil, srv.Mock) + assert.Error(t, err) + assert.Nil(t, res) + }) +} + func Test_Send(t *testing.T) { srv, state, _ := util.TestMocks(t) From 06ec5e68c75e44e9ca1fa42c00b7824f4aecbfb3 Mon Sep 17 00:00:00 2001 From: mfbz Date: Thu, 10 Apr 2025 14:08:44 +0200 Subject: [PATCH 2/5] Updated flowkit to v2.3.0 that includes getSystemTransaction function --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 2f3caa57b..6068f1889 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/onflow/flow-evm-gateway v1.0.3 github.com/onflow/flow-go v0.38.0-util.0.20250203085701-72e6e6235fa5 github.com/onflow/flow-go-sdk v1.4.0 - github.com/onflow/flowkit/v2 v2.2.0 + github.com/onflow/flowkit/v2 v2.3.0 github.com/onflow/go-ethereum v1.14.7 github.com/onflowser/flowser/v3 v3.2.1-0.20240131200229-7d4d22715f48 github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c @@ -148,7 +148,7 @@ require ( github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect - github.com/holiman/uint256 v1.3.0 // indirect + github.com/holiman/uint256 v1.3.1 // indirect github.com/huandu/go-clone v1.6.0 // indirect github.com/huandu/go-clone/generic v1.7.2 // indirect github.com/huin/goupnp v1.3.0 // indirect diff --git a/go.sum b/go.sum index 4959c6163..0ebe1e0f3 100644 --- a/go.sum +++ b/go.sum @@ -529,8 +529,8 @@ github.com/hexops/valast v1.4.4 h1:rETyycw+/L2ZVJHHNxEBgh8KUn+87WugH9MxcEv9PGs= github.com/hexops/valast v1.4.4/go.mod h1:Jcy1pNH7LNraVaAZDLyv21hHg2WBv9Nf9FL6fGxU7o4= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.3.0 h1:4wdcm/tnd0xXdu7iS3ruNvxkWwrb4aeBQv19ayYn8F4= -github.com/holiman/uint256 v1.3.0/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs= +github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= @@ -846,8 +846,8 @@ github.com/onflow/flow-nft/lib/go/templates v1.2.1 h1:SAALMZPDw9Eb9p5kSLnmnFxjyi github.com/onflow/flow-nft/lib/go/templates v1.2.1/go.mod h1:W6hOWU0xltPqNpv9gQX8Pj8Jtf0OmRxc1XX2V0kzJaI= github.com/onflow/flow/protobuf/go/flow v0.4.7 h1:iP6DFx4wZ3ETORsyeqzHu7neFT3d1CXF6wdK+AOOjmc= github.com/onflow/flow/protobuf/go/flow v0.4.7/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk= -github.com/onflow/flowkit/v2 v2.2.0 h1:GrIh+BBiDNcy5jwDf8r0/Tl4xHI28Ap/2VrZnWNKpQ8= -github.com/onflow/flowkit/v2 v2.2.0/go.mod h1:CDnB5cBqVYw4LYTv2OSRjJ2r5eHh6iy2gAjgQYI62nA= +github.com/onflow/flowkit/v2 v2.3.0 h1:XgxTgClgOyvijpJnqlygz0XrOIBbpqRscW7YVxjU+Dw= +github.com/onflow/flowkit/v2 v2.3.0/go.mod h1:R2dD8+qM2iYq2idmSDsqxrLQBioVktsrDybbuX1LIdM= github.com/onflow/go-ethereum v1.14.7 h1:gg3awYqI02e3AypRdpJKEvNTJ6kz/OhAqRti0h54Wlc= github.com/onflow/go-ethereum v1.14.7/go.mod h1:zV14QLrXyYu5ucvcwHUA0r6UaqveqbXaehAVQJlSW+I= github.com/onflow/nft-storefront/lib/go/contracts v1.0.0 h1:sxyWLqGm/p4EKT6DUlQESDG1ZNMN9GjPCm1gTq7NGfc= From 65a5e967fe4e6dd6fd30f5f6f3b3816745e1e8d7 Mon Sep 17 00:00:00 2001 From: mfbz Date: Thu, 10 Apr 2025 15:41:31 +0200 Subject: [PATCH 3/5] Fixed tests --- internal/transactions/transactions_test.go | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/internal/transactions/transactions_test.go b/internal/transactions/transactions_test.go index 054593fd9..be93e436c 100644 --- a/internal/transactions/transactions_test.go +++ b/internal/transactions/transactions_test.go @@ -139,21 +139,14 @@ func Test_Get(t *testing.T) { } func Test_GetSystem(t *testing.T) { - srv, _, _ := util.TestMocks(t) + srv, _, rw := util.TestMocks(t) t.Run("Success", func(t *testing.T) { - inArgs := []string{"0xabcdef"} - - // Mocked system transaction and result - tx := &flow.Transaction{} - result := &flow.TransactionResult{} + inArgs := []string{"0x01"} - srv.GetSystemTransaction.Run(func(args mock.Arguments) { - id := args.Get(1).(flow.Identifier) - assert.Equal(t, flow.HexToID("abcdef"), id) - }).Return(tx, result, nil) + srv.GetSystemTransaction.Return(nil, nil, nil) - res, err := getSystemTransaction(inArgs, command.GlobalFlags{}, util.NoLogger, nil, srv.Mock) + res, err := getSystemTransaction(inArgs, command.GlobalFlags{}, util.NoLogger, rw, srv.Mock) assert.NoError(t, err) assert.NotNil(t, res) }) @@ -163,7 +156,7 @@ func Test_GetSystem(t *testing.T) { srv.GetSystemTransaction.Return(nil, nil, fmt.Errorf("block not found")) - res, err := getSystemTransaction(inArgs, command.GlobalFlags{}, util.NoLogger, nil, srv.Mock) + res, err := getSystemTransaction(inArgs, command.GlobalFlags{}, util.NoLogger, rw, srv.Mock) assert.Error(t, err) assert.Nil(t, res) }) From ec4c4d071fd7ea552a8bef4623925978c180f676 Mon Sep 17 00:00:00 2001 From: mfbz Date: Thu, 10 Apr 2025 15:44:45 +0200 Subject: [PATCH 4/5] Added license header --- internal/transactions/get-system.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/internal/transactions/get-system.go b/internal/transactions/get-system.go index 4a7c98a7e..ecebdcf88 100644 --- a/internal/transactions/get-system.go +++ b/internal/transactions/get-system.go @@ -1,3 +1,21 @@ +/* + * Flow CLI + * + * Copyright Flow Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package transactions import ( From 853d21b382400360b7d2d504d739358d0a5b0889 Mon Sep 17 00:00:00 2001 From: mfbz Date: Fri, 11 Apr 2025 00:00:00 +0200 Subject: [PATCH 5/5] Added support to to get-system command --- internal/transactions/get-system.go | 22 +++++++++++++++------- internal/transactions/transactions_test.go | 16 +++++++++++++++- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/internal/transactions/get-system.go b/internal/transactions/get-system.go index ecebdcf88..ac1856085 100644 --- a/internal/transactions/get-system.go +++ b/internal/transactions/get-system.go @@ -20,9 +20,7 @@ package transactions import ( "context" - "strings" - flowsdk "github.com/onflow/flow-go-sdk" "github.com/spf13/cobra" "github.com/onflow/flowkit/v2" @@ -40,8 +38,8 @@ var getSystemFlags = flagsGetSystem{} var getSystemCommand = &command.Command{ Cmd: &cobra.Command{ - Use: "get-system ", - Short: "Get the system transaction by block ID", + Use: "get-system ", + Short: "Get the system transaction by block info", Example: "flow transactions get-system a1b2c3...", Args: cobra.ExactArgs(1), }, @@ -52,13 +50,23 @@ var getSystemCommand = &command.Command{ func getSystemTransaction( args []string, _ command.GlobalFlags, - _ output.Logger, + logger output.Logger, _ flowkit.ReaderWriter, flow flowkit.Services, ) (command.Result, error) { - blockID := flowsdk.HexToID(strings.TrimPrefix(args[0], "0x")) + query, err := flowkit.NewBlockQuery(args[0]) + if err != nil { + return nil, err + } + + logger.StartProgress("Fetching Block...") + defer logger.StopProgress() + block, err := flow.GetBlock(context.Background(), query) + if err != nil { + return nil, err + } - tx, result, err := flow.GetSystemTransaction(context.Background(), blockID) + tx, result, err := flow.GetSystemTransaction(context.Background(), block.ID) if err != nil { return nil, err } diff --git a/internal/transactions/transactions_test.go b/internal/transactions/transactions_test.go index be93e436c..b69eb0d14 100644 --- a/internal/transactions/transactions_test.go +++ b/internal/transactions/transactions_test.go @@ -142,7 +142,14 @@ func Test_GetSystem(t *testing.T) { srv, _, rw := util.TestMocks(t) t.Run("Success", func(t *testing.T) { - inArgs := []string{"0x01"} + inArgs := []string{"100"} + + returnBlock := tests.NewBlock() + returnBlock.Height = uint64(100) + + srv.GetBlock.Run(func(args mock.Arguments) { + assert.Equal(t, uint64(100), args.Get(1).(flowkit.BlockQuery).Height) + }).Return(returnBlock, nil) srv.GetSystemTransaction.Return(nil, nil, nil) @@ -154,6 +161,13 @@ func Test_GetSystem(t *testing.T) { t.Run("Fail invalid block ID", func(t *testing.T) { inArgs := []string{""} + returnBlock := tests.NewBlock() + returnBlock.Height = uint64(100) + + srv.GetBlock.Run(func(args mock.Arguments) { + assert.Equal(t, uint64(100), args.Get(1).(flowkit.BlockQuery).Height) + }).Return(returnBlock, nil) + srv.GetSystemTransaction.Return(nil, nil, fmt.Errorf("block not found")) res, err := getSystemTransaction(inArgs, command.GlobalFlags{}, util.NoLogger, rw, srv.Mock)