-
Notifications
You must be signed in to change notification settings - Fork 193
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: fun token state marshalling #1947
Changes from all commits
0ca249b
944d4c0
870e35c
7378486
7e1e5b2
d2d745a
325a2e4
f3ac2f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,7 @@ | |
|
||
var _ sdk.CustomProtobufType = (*HexAddr)(nil) | ||
|
||
func NewHexAddr(addr EthAddr) HexAddr { | ||
func NewHexAddr(addr gethcommon.Address) HexAddr { | ||
return HexAddr(addr.Hex()) | ||
} | ||
|
||
|
@@ -58,7 +58,7 @@ | |
return nil | ||
} | ||
|
||
func (h HexAddr) ToAddr() EthAddr { | ||
func (h HexAddr) ToAddr() gethcommon.Address { | ||
return gethcommon.HexToAddress(string(h)) | ||
} | ||
|
||
|
@@ -88,7 +88,7 @@ | |
// Implements the gogo proto custom type interface. | ||
// Ref: https://github.com/cosmos/gogoproto/blob/v1.5.0/custom_types.md | ||
func (h *HexAddr) MarshalTo(data []byte) (n int, err error) { | ||
bz := []byte{} | ||
bz := []byte(*h) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Potential issue in The - hexAddr, err := NewHexAddrFromStr(string(bz))
- *h = hexAddr
+ // Removed unnecessary conversion
+ err = nil Additionally, this line was flagged by codecov as not covered by tests. Would you like me to help add a test case for this method?
ToolsGitHub Check: codecov/patch
|
||
copy(data, bz) | ||
hexAddr, err := NewHexAddrFromStr(string(bz)) | ||
*h = hexAddr | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,29 +15,24 @@ | |
// tokens that are valid ERC20s with the same address. | ||
// https://github.com/NibiruChain/nibiru/issues/1933 | ||
func (fun FunToken) ID() []byte { | ||
return newFunTokenIDFromStr(fun.Erc20Addr.String(), fun.BankDenom) | ||
return NewFunTokenID(fun.Erc20Addr, fun.BankDenom) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tip Codebase Verification Add test coverage for the The method is crucial for generating unique identifiers but lacks test coverage. Ensure to include test cases that validate the correctness of the
Analysis chainAdd test coverage for the The method is crucial for generating unique identifiers but lacks test coverage. Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Description: Verify the test coverage for `ID` method in `x/evm/evm.go`.
# Test: Search for test cases covering the `ID` method. Expect: At least one test case.
rg --type python $'test.*ID' x/evm/evm_test.go
Length of output: 78 Script: #!/bin/bash
# Description: Verify the test coverage for `ID` method in `x/evm/evm.go`.
# Test: Search for test cases covering the `ID` method. Expect: At least one test case.
rg --type go 'ID' x/evm/evm_test.go
Length of output: 35 Script: #!/bin/bash
# Description: Verify the test coverage for `ID` method in `x/evm/evm.go`.
# Test: Search for test cases covering the `ID` method across all Go test files. Expect: At least one test case.
rg --type go 'ID' --glob '*.go'
Length of output: 57772 ToolsGitHub Check: codecov/patch
|
||
} | ||
|
||
func NewFunTokenID(erc20 gethcommon.Address, bankDenom string) []byte { | ||
erc20Addr := erc20.Hex() | ||
return newFunTokenIDFromStr(erc20Addr, bankDenom) | ||
func NewFunTokenID(erc20 eth.HexAddr, bankDenom string) []byte { | ||
return tmhash.Sum([]byte(erc20.String() + "|" + bankDenom)) | ||
} | ||
|
||
func newFunTokenIDFromStr(erc20AddrHex string, bankDenom string) []byte { | ||
return tmhash.Sum([]byte(erc20AddrHex + "|" + bankDenom)) | ||
} | ||
|
||
func errValidateFunToken(errMsg string) error { | ||
return fmt.Errorf("FunTokenError: %s", errMsg) | ||
func funTokenValidationError(err error) error { | ||
return fmt.Errorf("FunTokenError: %s", err.Error()) | ||
} | ||
|
||
func (fun FunToken) Validate() error { | ||
if err := sdk.ValidateDenom(fun.BankDenom); err != nil { | ||
return errValidateFunToken(err.Error()) | ||
return funTokenValidationError(err) | ||
} | ||
|
||
if err := fun.Erc20Addr.Valid(); err != nil { | ||
return errValidateFunToken(err.Error()) | ||
return funTokenValidationError(err) | ||
} | ||
|
||
return nil | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,27 +10,21 @@ import ( | |
|
||
"github.com/NibiruChain/nibiru/eth" | ||
"github.com/NibiruChain/nibiru/x/evm" | ||
funtoken "github.com/NibiruChain/nibiru/x/evm" | ||
) | ||
|
||
type ( | ||
funtokenPrimaryKeyType = []byte | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the primary key type is easier to follow when reading the collections below than using |
||
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 | ||
// add utility functions. | ||
type FunTokenState struct { | ||
collections.IndexedMap[funtokenPrimaryKeyType, funtokenValueType, IndexesFunToken] | ||
collections.IndexedMap[[]byte, evm.FunToken, IndexesFunToken] | ||
} | ||
|
||
func NewFunTokenState( | ||
cdc sdkcodec.BinaryCodec, | ||
storeKey storetypes.StoreKey, | ||
) FunTokenState { | ||
primaryKeyEncoder := eth.KeyEncoderBytes | ||
valueEncoder := collections.ProtoValueEncoder[funtokenValueType](cdc) | ||
valueEncoder := collections.ProtoValueEncoder[evm.FunToken](cdc) | ||
idxMap := collections.NewIndexedMap( | ||
storeKey, evm.KeyPrefixFunTokens, primaryKeyEncoder, valueEncoder, | ||
IndexesFunToken{ | ||
|
@@ -53,8 +47,8 @@ func NewFunTokenState( | |
return FunTokenState{IndexedMap: idxMap} | ||
} | ||
|
||
func (idxs IndexesFunToken) IndexerList() []collections.Indexer[funtokenPrimaryKeyType, funtokenValueType] { | ||
return []collections.Indexer[funtokenPrimaryKeyType, funtokenValueType]{ | ||
func (idxs IndexesFunToken) IndexerList() []collections.Indexer[[]byte, evm.FunToken] { | ||
return []collections.Indexer[[]byte, evm.FunToken]{ | ||
idxs.ERC20Addr, | ||
idxs.BankDenom, | ||
} | ||
|
@@ -66,13 +60,13 @@ type IndexesFunToken struct { | |
// - indexing key (IK): ERC-20 addr | ||
// - primary key (PK): FunToken ID | ||
// - value (V): FunToken value | ||
ERC20Addr collections.MultiIndex[gethcommon.Address, funtokenPrimaryKeyType, funtokenValueType] | ||
ERC20Addr collections.MultiIndex[gethcommon.Address, []byte, evm.FunToken] | ||
|
||
// BankDenom (MultiIndex): Index FunToken by coin denomination | ||
// - indexing key (IK): Coin denom | ||
// - primary key (PK): FunToken ID | ||
// - value (V): FunToken value | ||
BankDenom collections.MultiIndex[string, funtokenPrimaryKeyType, funtokenValueType] | ||
BankDenom collections.MultiIndex[string, []byte, evm.FunToken] | ||
} | ||
|
||
// Insert adds an [evm.FunToken] to state with defensive validation. Errors if | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package keeper_test | ||
|
||
import ( | ||
gethcommon "github.com/ethereum/go-ethereum/common" | ||
|
||
"github.com/NibiruChain/nibiru/eth" | ||
"github.com/NibiruChain/nibiru/x/evm" | ||
"github.com/NibiruChain/nibiru/x/evm/evmtest" | ||
) | ||
|
||
func (s *KeeperSuite) TestInsertAndGet() { | ||
deps := evmtest.NewTestDeps() | ||
|
||
erc20Addr := gethcommon.HexToAddress("0xAEf9437FF23D48D73271a41a8A094DEc9ac71477") | ||
err := deps.K.FunTokens.SafeInsert( | ||
deps.Ctx, | ||
erc20Addr, | ||
"unibi", | ||
true, | ||
) | ||
s.Require().NoError(err) | ||
|
||
// test Get | ||
funToken, err := deps.K.FunTokens.Get(deps.Ctx, evm.NewFunTokenID(eth.NewHexAddr(erc20Addr), "unibi")) | ||
s.Require().NoError(err) | ||
s.Require().Equal(eth.HexAddr("0xAEf9437FF23D48D73271a41a8A094DEc9ac71477"), funToken.Erc20Addr) | ||
s.Require().Equal("unibi", funToken.BankDenom) | ||
s.Require().True(funToken.IsMadeFromCoin) | ||
|
||
// iter := deps.K.FunTokens.Indexes.BankDenom.ExactMatch(deps.Ctx, "unibi") | ||
// deps.K.FunTokens.Collect(ctx) | ||
} | ||
|
||
func (s *KeeperSuite) TestCollect() { | ||
deps := evmtest.NewTestDeps() | ||
|
||
erc20Addr := gethcommon.HexToAddress("0xAEf9437FF23D48D73271a41a8A094DEc9ac71477") | ||
err := deps.K.FunTokens.SafeInsert( | ||
deps.Ctx, | ||
erc20Addr, | ||
"unibi", | ||
true, | ||
) | ||
s.Require().NoError(err) | ||
|
||
// test Collect by bank denom | ||
iter := deps.K.FunTokens.Indexes.BankDenom.ExactMatch(deps.Ctx, "unibi") | ||
funTokens := deps.K.FunTokens.Collect(deps.Ctx, iter) | ||
s.Require().Len(funTokens, 1) | ||
s.Require().Equal(eth.HexAddr("0xAEf9437FF23D48D73271a41a8A094DEc9ac71477"), funTokens[0].Erc20Addr) | ||
s.Require().Equal("unibi", funTokens[0].BankDenom) | ||
s.Require().True(funTokens[0].IsMadeFromCoin) | ||
|
||
// test Collect by erc20 addr | ||
iter2 := deps.K.FunTokens.Indexes.ERC20Addr.ExactMatch(deps.Ctx, erc20Addr) | ||
funTokens = deps.K.FunTokens.Collect(deps.Ctx, iter2) | ||
s.Require().Len(funTokens, 1) | ||
s.Require().Equal(eth.HexAddr("0xAEf9437FF23D48D73271a41a8A094DEc9ac71477"), funTokens[0].Erc20Addr) | ||
s.Require().Equal("unibi", funTokens[0].BankDenom) | ||
s.Require().True(funTokens[0].IsMadeFromCoin) | ||
} | ||
|
||
func (s *KeeperSuite) TestDelete() { | ||
deps := evmtest.NewTestDeps() | ||
|
||
erc20Addr := gethcommon.HexToAddress("0xAEf9437FF23D48D73271a41a8A094DEc9ac71477") | ||
err := deps.K.FunTokens.SafeInsert( | ||
deps.Ctx, | ||
erc20Addr, | ||
"unibi", | ||
true, | ||
) | ||
s.Require().NoError(err) | ||
|
||
// test Delete | ||
err = deps.K.FunTokens.Delete(deps.Ctx, evm.NewFunTokenID(eth.NewHexAddr(erc20Addr), "unibi")) | ||
s.Require().NoError(err) | ||
|
||
// test Get | ||
_, err = deps.K.FunTokens.Get(deps.Ctx, evm.NewFunTokenID(eth.NewHexAddr(erc20Addr), "unibi")) | ||
s.Require().Error(err) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enhance the changelog entry for better clarity.
The current changelog entry for PR 1947 is a bit vague. It would be beneficial for users and developers if the entry could provide a bit more context about what exactly was fixed with the FunToken state marshalling and why it was significant.