Skip to content

Commit

Permalink
feat(eth): finish todos for hex.go
Browse files Browse the repository at this point in the history
  • Loading branch information
Unique-Divine committed Jun 25, 2024
1 parent e11195f commit 656e73f
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 29 deletions.
36 changes: 16 additions & 20 deletions eth/hex.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@ import (

/////////// HexAddr

// TODO: UD-DEBUG: The eth.Addr should map to only one HexString
// TODO: UD-DEBUG: The eth.Addr should be derivable from HexString
// TODO: Constructor should be safe (errorable)
// TODO: UD-DEBUG: HexString -> bytes -> eth.Addr == HexString -> eth.Addr
// TODO: UD-DEBUG: validate: HexString === HexString -> HexString(eth.Addr.Hex())

// HexAddr: An ERC55-comlpiant hexadecimal-encoded string representing the 20
// byte address of an Ethereum account.
type HexAddr string
Expand All @@ -22,6 +16,17 @@ func NewHexAddr(addr EthAddr) HexAddr {
return HexAddr(addr.Hex())
}

func NewHexAddrFromStr(addr string) (HexAddr, error) {
hexAddr := HexAddr(gethcommon.HexToAddress(addr).Hex())
if !gethcommon.IsHexAddress(addr) {
return hexAddr, fmt.Errorf(
"%s: input \"%s\" is not an ERC55-compliant, 20 byte hex address",
HexAddrError, addr,
)
}
return hexAddr, hexAddr.Valid()
}

const HexAddrError = "HexAddrError"

func (h HexAddr) Valid() error {
Expand All @@ -31,30 +36,21 @@ func (h HexAddr) Valid() error {

if !gethcommon.IsHexAddress(haveAddr) || haveAddr != wantAddr {
return fmt.Errorf(
"%s: Etherem address is not represented as expected. We have encoding \"%s\" and instead need \"%s\" (gethcommon.Address.Hex)",
"%s: Ethereum address is not represented as expected. We have encoding \"%s\" and instead need \"%s\" (gethcommon.Address.Hex)",
HexAddrError, haveAddr, wantAddr,
)
}

return nil
}

func NewHexAddrFromStr(addr string) HexAddr {
return HexAddr(gethcommon.HexToAddress(addr).Hex())
}

func (h HexAddr) ToAddr() EthAddr {
return gethcommon.HexToAddress(string(h))
}

// func (h HexAddr) Bytes() []byte {
// return gethcommon.Hex2Bytes(
// strings.TrimPrefix(string(h), "0x"),
// )
// }
// ToBytes gets the string representation of the underlying address.
func (h HexAddr) ToBytes() []byte {
return h.ToAddr().Bytes()

Check warning on line 53 in eth/hex.go

View check run for this annotation

Codecov / codecov/patch

eth/hex.go#L52-L53

Added lines #L52 - L53 were not covered by tests
}

func (h HexAddr) String() string { return h.ToAddr().Hex() }

func (h HexAddr) FromBytes(bz []byte) HexAddr {
return HexAddr(gethcommon.BytesToAddress(bz).Hex())
}
55 changes: 50 additions & 5 deletions eth/hex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package eth_test

import (
"fmt"
"strconv"

"github.com/ethereum/go-ethereum/common"
gethcommon "github.com/ethereum/go-ethereum/common"

"github.com/NibiruChain/nibiru/eth"
"github.com/NibiruChain/nibiru/x/common/set"
)

var threeValidAddrs []eth.HexAddr = []eth.HexAddr{
Expand All @@ -14,6 +16,48 @@ var threeValidAddrs []eth.HexAddr = []eth.HexAddr{
eth.HexAddr("0x1111111111111111111112222222222223333323"),
}

func (s *Suite) TestHexAddr_UniqueMapping() {
type CorrectAnswer struct {
gethAddrOut gethcommon.Address
hexAddrOut eth.HexAddr
}

for tcIdx, tc := range []struct {
equivSet set.Set[string]
}{
{
equivSet: set.New(
"0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed",
"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed",
"0x5AAEB6053F3E94C9B9A09F33669435E7EF1BEAED",
"5aaeb6053f3e94c9b9a09f33669435e7ef1beaed",
"0X5AAEB6053F3E94C9B9A09F33669435E7EF1BEAED",
),
},
} {
s.Run(strconv.Itoa(tcIdx), func() {
s.T().Log("Show that each member of the set is equivalent")
var answer CorrectAnswer
for idx, equivHexAddrString := range tc.equivSet.ToSlice() {
gethAddrOut := gethcommon.HexToAddress(equivHexAddrString)
hexAddrOut, err := eth.NewHexAddrFromStr(equivHexAddrString)
s.NoError(err)
if idx == 0 {
answer = CorrectAnswer{
gethAddrOut: gethAddrOut,
hexAddrOut: hexAddrOut,
}
continue
}

s.Equal(answer.gethAddrOut, gethAddrOut)
s.Equal(answer.gethAddrOut, hexAddrOut.ToAddr())
s.Equal(answer.hexAddrOut, hexAddrOut)
}
})
}
}

// TestHexAddr_NewHexAddr: Test to showcase the flexibility of inputs that can be
// passed to `eth.NewHexAddrFromStr` and result in a "valid" `HexAddr` that preserves
// bijectivity with `gethcommon.Address` and has a canonical string
Expand Down Expand Up @@ -94,23 +138,24 @@ func (s *Suite) TestHexAddr_NewHexAddr() {
for _, tc := range tcGroup.hexAddrs {
tcName := fmt.Sprintf("want %s, %s", want, tc.testCaseName)
s.Run(tcName, func() {
got := eth.NewHexAddrFromStr(tc.hexAddr)
err := got.Valid()
got, err := eth.NewHexAddrFromStr(tc.hexAddr)

// gethcommon.Address input should give the same thing
got2 := eth.NewHexAddr(common.HexToAddress(tc.hexAddr))
got2 := eth.NewHexAddr(gethcommon.HexToAddress(tc.hexAddr))
if tc.wantNotEqual {
s.NotEqual(want, got)
s.NotEqual(want.ToAddr(), got.ToAddr())
s.NotEqual(want, got2)
s.NotEqual(want.ToAddr(), got2.ToAddr())
s.Require().Error(err)
return
} else {
// string input should give the canonical HexAddr
s.Equal(want, got)
s.Equal(want.ToAddr(), got.ToAddr())

// gethcommon.Address input should give the same thing
got2 := eth.NewHexAddr(common.HexToAddress(tc.hexAddr))
got2 := eth.NewHexAddr(gethcommon.HexToAddress(tc.hexAddr))
s.Equal(want, got2)
s.Equal(want.ToAddr(), got2.ToAddr())
}
Expand Down
2 changes: 1 addition & 1 deletion x/evm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (fun FunToken) Validate() error {
haveAddr := fun.Erc20Addr
if haveAddr != wantAddr {
return errValidateFunToken(fmt.Sprintf(
"ERC20 addr is not represented as expected. We have encoding \"%s\" and instead need \"%s\" (gethcommon.Address.Hex)",
"Etherem address is not represented as expected. We have encoding \"%s\" and instead need \"%s\" (gethcommon.Address.Hex)",
haveAddr, wantAddr,
))
}
Expand Down
3 changes: 2 additions & 1 deletion x/evm/evm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"strconv"
"testing"

gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/suite"

"github.com/NibiruChain/nibiru/eth"
Expand Down Expand Up @@ -37,7 +38,7 @@ func (s *TestSuite) TestFunToken() {
},
{
bankDenom: "unibi",
erc20Addr: eth.NewHexAddrFromStr("5aaeb6053f3e94c9b9a09f33669435e7ef1beaed").String(),
erc20Addr: eth.NewHexAddr(gethcommon.HexToAddress("5aaeb6053f3e94c9b9a09f33669435e7ef1beaed")).String(),
wantErr: "",
},
{
Expand Down
6 changes: 4 additions & 2 deletions x/evm/keeper/funtoken_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ import (
funtoken "github.com/NibiruChain/nibiru/x/evm"
)

type funtokenPrimaryKeyType = []byte
type funtokenValueType = funtoken.FunToken
type (
funtokenPrimaryKeyType = []byte
funtokenValueType = funtoken.FunToken
)

// FunTokenState isolates the key-value stores (collections) for fungible token
// mappings. This struct is written as an extension of the default indexed map to
Expand Down

0 comments on commit 656e73f

Please sign in to comment.