diff --git a/cmd/axelard/cmd/helpers.go b/cmd/axelard/cmd/helpers.go index 2d60bc87d..f9ea27d31 100644 --- a/cmd/axelard/cmd/helpers.go +++ b/cmd/axelard/cmd/helpers.go @@ -1,7 +1,6 @@ package cmd import ( - "encoding/hex" "encoding/json" "fmt" "io/ioutil" @@ -45,5 +44,5 @@ func getByteCodes(file string) ([]byte, error) { return nil, fmt.Errorf("could not retrieve bytecode from file") } - return hex.DecodeString(str) + return utils.HexDecode(str) } diff --git a/utils/encoding.go b/utils/encoding.go new file mode 100644 index 000000000..a6329fc32 --- /dev/null +++ b/utils/encoding.go @@ -0,0 +1,11 @@ +package utils + +import ( + "encoding/hex" + "strings" +) + +// Decode a hex string. Hex string can be optionally prefixed with 0x. +func HexDecode(input string) ([]byte, error) { + return hex.DecodeString(strings.TrimPrefix(input, "0x")) +} diff --git a/utils/encoding_test.go b/utils/encoding_test.go new file mode 100644 index 000000000..752b39019 --- /dev/null +++ b/utils/encoding_test.go @@ -0,0 +1,59 @@ +package utils + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestHexDecode(t *testing.T) { + tests := []struct { + name string + input string + want []byte + wantErr bool + }{ + { + name: "empty input", + input: "", + want: []byte{}, + wantErr: false, + }, + { + name: "valid input with 0x prefix", + input: "0x68656c6c6f", + want: []byte("hello"), + wantErr: false, + }, + { + name: "valid input without 0x prefix", + input: "68656c6c6f", + want: []byte("hello"), + wantErr: false, + }, + { + name: "invalid input with odd number of characters", + input: "68656c6c6", + want: nil, + wantErr: true, + }, + { + name: "invalid input with non-hex characters", + input: "68656c6c6z", + want: nil, + wantErr: true, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := HexDecode(test.input) + if test.wantErr { + assert.Error(t, err) + return + } + + assert.Equal(t, test.want, got) + }) + } +} diff --git a/vald/sign.go b/vald/sign.go index a628a13e3..e29f927c0 100644 --- a/vald/sign.go +++ b/vald/sign.go @@ -16,6 +16,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/spf13/cobra" + "github.com/axelarnetwork/axelar-core/utils" "github.com/axelarnetwork/axelar-core/vald/config" "github.com/axelarnetwork/axelar-core/vald/tss" evm "github.com/axelarnetwork/axelar-core/x/evm/types" @@ -61,7 +62,7 @@ func GetSignCommand() *cobra.Command { } } - pubKeyRaw, err := hex.DecodeString(pubKeyHex) + pubKeyRaw, err := utils.HexDecode(pubKeyHex) if err != nil { return err } @@ -71,7 +72,7 @@ func GetSignCommand() *cobra.Command { return err } - hashRaw, err := hex.DecodeString(args[2]) + hashRaw, err := utils.HexDecode(args[2]) if err != nil { return err } diff --git a/x/axelarnet/client/cli/tx.go b/x/axelarnet/client/cli/tx.go index 740ae7774..797b59b1a 100644 --- a/x/axelarnet/client/cli/tx.go +++ b/x/axelarnet/client/cli/tx.go @@ -1,7 +1,6 @@ package cli import ( - "encoding/hex" "fmt" "os" "strconv" @@ -316,7 +315,7 @@ func getGeneralMessage() *cobra.Command { } id := utils.NormalizeString(args[0]) - payload, err := hex.DecodeString(args[1]) + payload, err := utils.HexDecode(args[1]) if err != nil { return err } @@ -357,7 +356,7 @@ func getCmdCallContract() *cobra.Command { return err } - payload, err := hex.DecodeString(strings.TrimPrefix(args[2], "0x")) + payload, err := utils.HexDecode(args[2]) if err != nil { return err } diff --git a/x/evm/keeper/grpc_query.go b/x/evm/keeper/grpc_query.go index 45feeaec4..52e2a2cfc 100644 --- a/x/evm/keeper/grpc_query.go +++ b/x/evm/keeper/grpc_query.go @@ -15,6 +15,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "github.com/axelarnetwork/axelar-core/utils" "github.com/axelarnetwork/axelar-core/x/evm/types" multisig "github.com/axelarnetwork/axelar-core/x/multisig/exported" nexustypes "github.com/axelarnetwork/axelar-core/x/nexus/exported" @@ -259,7 +260,7 @@ func (q Querier) BatchedCommands(c context.Context, req *types.BatchedCommandsRe return nil, status.Error(codes.NotFound, sdkerrors.Wrap(types.ErrEVM, fmt.Sprintf("could not get the latest batched commands for chain %s", req.Chain)).Error()) } default: - commandBatchID, err := hex.DecodeString(req.Id) + commandBatchID, err := utils.HexDecode(req.Id) if err != nil { return nil, status.Error(codes.InvalidArgument, sdkerrors.Wrap(types.ErrEVM, fmt.Sprintf("invalid batched commands ID: %v", err)).Error()) } diff --git a/x/evm/keeper/migrate.go b/x/evm/keeper/migrate.go index f485c323d..eaa05998f 100644 --- a/x/evm/keeper/migrate.go +++ b/x/evm/keeper/migrate.go @@ -1,7 +1,6 @@ package keeper import ( - "encoding/hex" "fmt" sdk "github.com/cosmos/cosmos-sdk/types" @@ -140,12 +139,12 @@ func AlwaysMigrateBytecode(k *BaseKeeper, n types.Nexus, otherMigrations func(ct // EVM chain. It's crucial whenever contracts are changed between versions. // DO NOT DELETE func migrateContractsBytecode(ctx sdk.Context, ck chainKeeper) error { - bzToken, err := hex.DecodeString(types.Token) + bzToken, err := utils.HexDecode(types.Token) if err != nil { return err } - bzBurnable, err := hex.DecodeString(types.Burnable) + bzBurnable, err := utils.HexDecode(types.Burnable) if err != nil { return err } diff --git a/x/evm/types/params.go b/x/evm/types/params.go index 45e29bf7f..9b25f2cde 100644 --- a/x/evm/types/params.go +++ b/x/evm/types/params.go @@ -1,7 +1,6 @@ package types import ( - "encoding/hex" "fmt" sdk "github.com/cosmos/cosmos-sdk/types" @@ -39,12 +38,12 @@ func KeyTable() params.KeyTable { // DefaultParams returns the module's parameter set initialized with default values func DefaultParams() []Params { - bzToken, err := hex.DecodeString(Token) + bzToken, err := utils.HexDecode(Token) if err != nil { panic(err) } - bzBurnable, err := hex.DecodeString(Burnable) + bzBurnable, err := utils.HexDecode(Burnable) if err != nil { panic(err) } diff --git a/x/evm/types/testutils/rand.go b/x/evm/types/testutils/rand.go index 939e9de2d..0356d4107 100644 --- a/x/evm/types/testutils/rand.go +++ b/x/evm/types/testutils/rand.go @@ -1,7 +1,6 @@ package testutils import ( - "encoding/hex" "fmt" "math/big" "strings" @@ -323,7 +322,7 @@ func RandomTokens() []types.ERC20TokenMetadata { // RandomToken returns a random (valid) token for testing func RandomToken() types.ERC20TokenMetadata { - bzBurnable, err := hex.DecodeString(types.Burnable) + bzBurnable, err := utils.HexDecode(types.Burnable) if err != nil { panic(err) } @@ -390,7 +389,7 @@ func RandomBurnerInfo() types.BurnerInfo { // RandomParams returns a random (valid) params instance for testing func RandomParams() types.Params { - bzBurnable, err := hex.DecodeString(types.Burnable) + bzBurnable, err := utils.HexDecode(types.Burnable) if err != nil { panic(err) } diff --git a/x/evm/types/types.go b/x/evm/types/types.go index a24929d66..5e50b8e3b 100644 --- a/x/evm/types/types.go +++ b/x/evm/types/types.go @@ -703,7 +703,7 @@ func CommandIDFromTransferID(id nexus.TransferID) CommandID { // HexToCommandID decodes a hex representation of a CommandID func HexToCommandID(id string) (CommandID, error) { - bz, err := hex.DecodeString(id) + bz, err := utils.HexDecode(id) if err != nil { return CommandID{}, err }