Skip to content

Commit

Permalink
Problem: token mapping state is not exported to genesis (#113)
Browse files Browse the repository at this point in the history
* Problem: token mapping state is not exported to genesis

Closes: #101

- add fields in genesis and init/export genesis logic

* changelog

* add validation

* unittests
  • Loading branch information
yihuang committed Sep 28, 2021
1 parent 2171ef3 commit d3098de
Show file tree
Hide file tree
Showing 11 changed files with 557 additions and 37 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
### Features

- [cronos#110](https://github.com/crypto-org-chain/cronos/pull/110) embed swagger doc ui
- [cronos#113](https://github.com/crypto-org-chain/cronos/pull/113) export token mapping state to genesis

*September 22, 2021*
## v0.5.4
Expand Down
24 changes: 21 additions & 3 deletions docs/api/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- [cronos/cronos.proto](#cronos/cronos.proto)
- [Params](#cronos.Params)
- [TokenMapping](#cronos.TokenMapping)
- [TokenMappingChangeProposal](#cronos.TokenMappingChangeProposal)

- [cronos/genesis.proto](#cronos/genesis.proto)
Expand Down Expand Up @@ -47,6 +48,23 @@ Params defines the parameters for the cronos module.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `ibc_cro_denom` | [string](#string) | | |
| `ibc_timeout` | [uint64](#uint64) | | |






<a name="cronos.TokenMapping"></a>

### TokenMapping
TokenMapping defines a mapping between native denom and contract


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `denom` | [string](#string) | | |
| `contract` | [string](#string) | | |



Expand Down Expand Up @@ -95,9 +113,9 @@ GenesisState defines the cronos module's genesis state.

| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `params` | [Params](#cronos.Params) | | params defines all the paramaters of the module.

this line is used by starport scaffolding # genesis/proto/state this line is used by starport scaffolding # ibc/genesis/proto |
| `params` | [Params](#cronos.Params) | | params defines all the paramaters of the module. |
| `external_contracts` | [TokenMapping](#cronos.TokenMapping) | repeated | |
| `auto_contracts` | [TokenMapping](#cronos.TokenMapping) | repeated | this line is used by starport scaffolding # genesis/proto/state this line is used by starport scaffolding # ibc/genesis/proto |



Expand Down
7 changes: 7 additions & 0 deletions integration_tests/configs/genesis_token_mapping.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ cronos_777-1:
mnemonic: "notable error gospel wave pair ugly measure elite toddler cost various fly make eye ketchup despair slab throw tribe swarm word fruit into inmate"
genesis:
app_state:
cronos:
external_contracts:
- denom: gravity0x0000000000000000000000000000000000000000
contract: "0x68542BD12B41F5D51D6282Ec7D91D7d0D78E4503"
auto_contracts:
- denom: gravity0x0000000000000000000000000000000000000000
contract: "0x68542BD12B41F5D51D6282Ec7D91D7d0D78E4503"
auth:
accounts:
- "@type": "/ethermint.types.v1.EthAccount"
Expand Down
9 changes: 9 additions & 0 deletions integration_tests/test_exported_genesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,12 @@ def test_exported_contract(custom_cronos):
address="0x68542BD12B41F5D51D6282Ec7D91D7d0D78E4503", abi=abi
)
assert erc20.caller.balanceOf(ADDRS["validator"]) == 100000000000000000000000000


def test_exported_token_mapping(custom_cronos):
cli = custom_cronos.cosmos_cli(0)
rsp = cli.query_contract_by_denom(
"gravity0x0000000000000000000000000000000000000000"
)
assert rsp["contract"] == "0x68542BD12B41F5D51D6282Ec7D91D7d0D78E4503"
assert rsp["auto_contract"] == "0x68542BD12B41F5D51D6282Ec7D91D7d0D78E4503"
6 changes: 6 additions & 0 deletions proto/cronos/cronos.proto
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,9 @@ message TokenMappingChangeProposal {
string denom = 3;
string contract = 4;
}

// TokenMapping defines a mapping between native denom and contract
message TokenMapping {
string denom = 1;
string contract = 2;
}
2 changes: 2 additions & 0 deletions proto/cronos/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ option go_package = "github.com/crypto-org-chain/cronos/x/cronos/types";
message GenesisState {
// params defines all the paramaters of the module.
Params params = 1 [(gogoproto.nullable) = false];
repeated TokenMapping external_contracts = 2 [(gogoproto.nullable) = false];
repeated TokenMapping auto_contracts = 3 [(gogoproto.nullable) = false];
// this line is used by starport scaffolding # genesis/proto/state
// this line is used by starport scaffolding # ibc/genesis/proto
}
28 changes: 27 additions & 1 deletion x/cronos/genesis.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,39 @@
package cronos

import (
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/crypto-org-chain/cronos/x/cronos/keeper"
"github.com/crypto-org-chain/cronos/x/cronos/types"
"github.com/ethereum/go-ethereum/common"
)

// InitGenesis initializes the capability module's state from a provided genesis
// state.
func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) {
k.SetParams(ctx, genState.Params)

for _, m := range genState.ExternalContracts {
if !types.IsValidDenomToWrap(m.Denom) {
panic(fmt.Sprintf("Invalid denom to map to contract: %s", m.Denom))
}
if !common.IsHexAddress(m.Contract) {
panic(fmt.Sprintf("Invalid contract address: %s", m.Contract))
}
k.SetExternalContractForDenom(ctx, m.Denom, common.HexToAddress(m.Contract))
}

for _, m := range genState.AutoContracts {
if !types.IsValidDenomToWrap(m.Denom) {
panic(fmt.Sprintf("Invalid denom to map to contract: %s", m.Denom))
}
if !common.IsHexAddress(m.Contract) {
panic(fmt.Sprintf("Invalid contract address: %s", m.Contract))
}
k.SetAutoContractForDenom(ctx, m.Denom, common.HexToAddress(m.Contract))
}

// this line is used by starport scaffolding # genesis/module/init

// this line is used by starport scaffolding # ibc/genesis/init
Expand All @@ -22,6 +46,8 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState {
// this line is used by starport scaffolding # ibc/genesis/export

return &types.GenesisState{
Params: k.GetParams(ctx),
Params: k.GetParams(ctx),
ExternalContracts: k.GetExternalContracts(ctx),
AutoContracts: k.GetAutoContracts(ctx),
}
}
72 changes: 72 additions & 0 deletions x/cronos/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,78 @@ func (suite *CronosTestSuite) TestInitGenesis() {
}},
true,
},
{
"Wrong denom in external token mapping",
func() {},
&types.GenesisState{
ExternalContracts: []types.TokenMapping{
{
Denom: "aaa/6B5A664BF0AF4F71B2F0BAA33141E2F1321242FBD5D19762F541EC971ACB0865",
Contract: "0x0000000000000000000000000000000000000000",
},
},
},
true,
},
{
"Wrong denom in auto token mapping",
func() {},
&types.GenesisState{
AutoContracts: []types.TokenMapping{
{
Denom: "aaa/6B5A664BF0AF4F71B2F0BAA33141E2F1321242FBD5D19762F541EC971ACB0865",
Contract: "0x0000000000000000000000000000000000000000",
},
},
},
true,
},
{
"Wrong contract in external token mapping",
func() {},
&types.GenesisState{
ExternalContracts: []types.TokenMapping{
{
Denom: "ibc/6B5A664BF0AF4F71B2F0BAA33141E2F1321242FBD5D19762F541EC971ACB0865",
Contract: "0x00000000000000000000000000000000000000",
},
},
},
true,
},
{
"Wrong contract in auto token mapping",
func() {},
&types.GenesisState{
AutoContracts: []types.TokenMapping{
{
Denom: "ibc/6B5A664BF0AF4F71B2F0BAA33141E2F1321242FBD5D19762F541EC971ACB0865",
Contract: "0x00000000000000000000000000000000000000",
},
},
},
true,
},
{
"Correct token mapping",
func() {},
&types.GenesisState{
Params: types.DefaultParams(),
ExternalContracts: []types.TokenMapping{
{
Denom: "ibc/6B5A664BF0AF4F71B2F0BAA33141E2F1321242FBD5D19762F541EC971ACB0865",
Contract: "0x0000000000000000000000000000000000000000",
},
},
AutoContracts: []types.TokenMapping{
{
Denom: "gravity0x0000000000000000000000000000000000000000",
Contract: "0x0000000000000000000000000000000000000000",
},
},
},
false,
},
}

for _, tc := range testCases {
Expand Down
27 changes: 27 additions & 0 deletions x/cronos/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/tendermint/tendermint/libs/log"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/crypto-org-chain/cronos/x/cronos/types"
"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -125,6 +126,32 @@ func (k Keeper) SetExternalContractForDenom(ctx sdk.Context, denom string, addre
store.Set(types.ContractToDenomKey(address.Bytes()), []byte(denom))
}

// GetExternalContracts returns all external contract mappings
func (k Keeper) GetExternalContracts(ctx sdk.Context) (out []types.TokenMapping) {
store := ctx.KVStore(k.storeKey)
iter := prefix.NewStore(store, types.KeyPrefixDenomToExternalContract).Iterator(nil, nil)
for ; iter.Valid(); iter.Next() {
out = append(out, types.TokenMapping{
Denom: string(iter.Key()),
Contract: common.BytesToAddress(iter.Value()).Hex(),
})
}
return
}

// GetAutoContracts returns all auto-deployed contract mappings
func (k Keeper) GetAutoContracts(ctx sdk.Context) (out []types.TokenMapping) {
store := ctx.KVStore(k.storeKey)
iter := prefix.NewStore(store, types.KeyPrefixDenomToAutoContract).Iterator(nil, nil)
for ; iter.Valid(); iter.Next() {
out = append(out, types.TokenMapping{
Denom: string(iter.Key()),
Contract: common.BytesToAddress(iter.Value()).Hex(),
})
}
return
}

// DeleteExternalContractForDenom delete the external contract mapping for native denom,
// returns false if mapping not exists.
func (k Keeper) DeleteExternalContractForDenom(ctx sdk.Context, denom string) bool {
Expand Down
Loading

0 comments on commit d3098de

Please sign in to comment.