From 9be4332cbf83e6d2aebf90310d02527e4e713655 Mon Sep 17 00:00:00 2001 From: Goran Rojovic <100121253+goran-ethernal@users.noreply.github.com> Date: Mon, 19 Feb 2024 13:54:35 +0100 Subject: [PATCH] `Hex` package cleanup (#122) * cleanup and UTs * Lint fix --- helper/hex/hex.go | 20 ------ helper/hex/hex_test.go | 137 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+), 20 deletions(-) diff --git a/helper/hex/hex.go b/helper/hex/hex.go index 7ab38d903d..8a61a17c83 100644 --- a/helper/hex/hex.go +++ b/helper/hex/hex.go @@ -8,10 +8,6 @@ import ( "strings" ) -type DecError struct{ msg string } - -func (err DecError) Error() string { return err.msg } - // EncodeToHex generates a hex string based on the byte representation, with the '0x' prefix func EncodeToHex(str []byte) string { return "0x" + hex.EncodeToString(str) @@ -60,22 +56,6 @@ func DecodeUint64(hexStr string) (uint64, error) { return strconv.ParseUint(cleaned, 16, 64) } -const BadNibble = ^uint64(0) - -// DecodeNibble decodes a byte into a uint64 -func DecodeNibble(in byte) uint64 { - switch { - case in >= '0' && in <= '9': - return uint64(in - '0') - case in >= 'A' && in <= 'F': - return uint64(in - 'A' + 10) - case in >= 'a' && in <= 'f': - return uint64(in - 'a' + 10) - default: - return BadNibble - } -} - // EncodeBig encodes bigint as a hex string with 0x prefix. // The sign of the integer is ignored. func EncodeBig(bigint *big.Int) string { diff --git a/helper/hex/hex_test.go b/helper/hex/hex_test.go index 9717281fa6..01d27ca930 100644 --- a/helper/hex/hex_test.go +++ b/helper/hex/hex_test.go @@ -2,6 +2,7 @@ package hex import ( "fmt" + "math/big" "testing" "github.com/stretchr/testify/assert" @@ -67,3 +68,139 @@ func TestDecodeHexToBig(t *testing.T) { require.Equal(t, uint64(512), big.Uint64()) }) } + +func TestEncodeToHex(t *testing.T) { + t.Parallel() + + testCases := []struct { + input []byte + expected string + }{ + {[]byte{}, "0x"}, + {[]byte{0x00}, "0x00"}, + {[]byte{0x01}, "0x01"}, + {[]byte{0x0A, 0x0B, 0x0C}, "0x0a0b0c"}, + {[]byte{0xFF, 0xFE, 0xFD}, "0xfffefd"}, + } + + for _, tc := range testCases { + actual := EncodeToHex(tc.input) + assert.Equal(t, tc.expected, actual) + } +} + +func TestEncodeToString(t *testing.T) { + t.Parallel() + + testCases := []struct { + input []byte + expected string + }{ + {[]byte{}, ""}, + {[]byte{0x00}, "00"}, + {[]byte{0x01}, "01"}, + {[]byte{0x0A, 0x0B, 0x0C}, "0a0b0c"}, + {[]byte{0xFF, 0xFE, 0xFD}, "fffefd"}, + } + + for _, tc := range testCases { + actual := EncodeToString(tc.input) + assert.Equal(t, tc.expected, actual) + } +} + +func TestMustDecodeHex(t *testing.T) { + t.Parallel() + + t.Run("Valid hex string", func(t *testing.T) { + t.Parallel() + + str := "0x48656c6c6f20576f726c64" + expected := []byte{0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64} + + actual := MustDecodeHex(str) + assert.Equal(t, expected, actual) + }) + + t.Run("Empty hex string", func(t *testing.T) { + t.Parallel() + + str := "" + expected := []byte{} + + actual := MustDecodeHex(str) + assert.Equal(t, expected, actual) + }) + + t.Run("Invalid hex string", func(t *testing.T) { + t.Parallel() + + str := "0x12345q" + + require.PanicsWithError(t, "could not decode hex: encoding/hex: invalid byte: U+0071 'q'", func() { + MustDecodeHex(str) + }) + }) +} + +func TestEncodeUint64(t *testing.T) { + t.Parallel() + + testCases := []struct { + input uint64 + expected string + }{ + {0, "0x0"}, + {1, "0x1"}, + {11, "0xb"}, + {67312, "0x106f0"}, + {80604, "0x13adc"}, + {^uint64(0), "0xffffffffffffffff"}, // max uint64 + } + + for _, tc := range testCases { + actual := EncodeUint64(tc.input) + assert.Equal(t, tc.expected, actual) + } +} + +func TestEncodeBig(t *testing.T) { + t.Parallel() + + testCases := []struct { + input *big.Int + expected string + }{ + {big.NewInt(0), "0x0"}, + {big.NewInt(1), "0x1"}, + {big.NewInt(11), "0xb"}, + {big.NewInt(67312), "0x106f0"}, + {big.NewInt(80604), "0x13adc"}, + {new(big.Int).SetUint64(^uint64(0)), "0xffffffffffffffff"}, // max uint64 + } + + for _, tc := range testCases { + actual := EncodeBig(tc.input) + assert.Equal(t, tc.expected, actual) + } +} + +func TestDecodeString(t *testing.T) { + t.Parallel() + + testCases := []struct { + input string + expected []byte + }{ + {"", []byte{}}, + {"48656c6c6f20576f726c64", []byte{0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64}}, + {"0123456789abcdef", []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}}, + {"fffe", []byte{0xff, 0xfe}}, + } + + for _, tc := range testCases { + actual, err := DecodeString(tc.input) + assert.NoError(t, err) + assert.Equal(t, tc.expected, actual) + } +}