Skip to content
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

feat: native immediate unbonding #183

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion demo/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ func NewMeshApp(
keys[meshsecprovtypes.StoreKey],
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
app.BankKeeper,
app.WasmKeeper,
&app.WasmKeeper,
app.StakingKeeper,
)

Expand Down
155 changes: 0 additions & 155 deletions note.json

This file was deleted.

3 changes: 1 addition & 2 deletions tests/e2e/e2e.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"path/filepath"
"testing"

"github.com/CosmWasm/wasmd/x/wasm"
"github.com/CosmWasm/wasmd/x/wasm/ibctesting"
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
Expand Down Expand Up @@ -38,7 +37,7 @@ func buildPathToWasm(fileName string) string {
// NewIBCCoordinator initializes Coordinator with N meshd TestChain instances
func NewIBCCoordinator(t *testing.T, n int, opts ...[]wasmkeeper.Option) *ibctesting.Coordinator {
return ibctesting.NewCoordinatorX(t, n,
func(t *testing.T, valSet *types.ValidatorSet, genAccs []authtypes.GenesisAccount, chainID string, opts []wasm.Option, balances ...banktypes.Balance) ibctesting.ChainApp {
func(t *testing.T, valSet *types.ValidatorSet, genAccs []authtypes.GenesisAccount, chainID string, opts []wasmkeeper.Option, balances ...banktypes.Balance) ibctesting.ChainApp {
return app.SetupWithGenesisValSet(t, valSet, genAccs, chainID, opts, balances...)
},
opts...,
Expand Down
63 changes: 63 additions & 0 deletions tests/e2e/slashing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,66 @@ func TestSlashingScenario3(t *testing.T) {
// Check new free collateral
require.Equal(t, 0, providerCli.QueryVaultFreeBalance()) // 185 - max(32, 185) = 185 - 185 = 0
}

func TestSlasingImmediateUnbond(t *testing.T) {
x := setupExampleChains(t)
_, _, providerCli := setupMeshSecurity(t, x)

// Provider chain
// ==============
// Deposit - A user deposits the vault denom to provide some collateral to their account
execMsg := fmt.Sprintf(`{"bond":{"amount":{"denom":"%s", "amount":"200000000"}}}`, x.ProviderDenom)
providerCli.MustExecVault(execMsg)

// Stake Locally - A user triggers a local staking action to a chosen validator.
myLocalValidatorAddr := sdk.ValAddress(x.ProviderChain.Vals.Validators[0].Address).String()
execLocalStakingMsg := fmt.Sprintf(`{"stake_local":{"amount": {"denom":%q, "amount":"%d"}, "msg":%q}}`,
x.ProviderDenom, 100_000_000,
base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf(`{"validator": "%s"}`, myLocalValidatorAddr))))
providerCli.MustExecVault(execLocalStakingMsg)

assert.Equal(t, 100_000_000, providerCli.QueryVaultFreeBalance())

// Check slashable amount
require.Equal(t, 20_000_000, providerCli.QuerySlashableAmount())
// Check free collateral
require.Equal(t, 100_000_000, providerCli.QueryVaultFreeBalance())

// Validator on the provider chain is jailed
myLocalValidatorConsAddr := sdk.ConsAddress(x.ProviderChain.Vals.Validators[0].PubKey.Address())
jailValidator(t, myLocalValidatorConsAddr, x.Coordinator, x.ProviderChain, x.ProviderApp)

x.ProviderChain.NextBlock()

// Check new collateral
require.Equal(t, 200_000_000, providerCli.QueryVaultBalance())
// Check new max lien
require.Equal(t, 100_000_000, providerCli.QueryMaxLien())
// Check new slashable amount
require.Equal(t, 20_000_000, providerCli.QuerySlashableAmount())
// Check new free collateral
require.Equal(t, 100_000_000, providerCli.QueryVaultFreeBalance())

// Get native staking proxy contract
nativeStakingProxy := providerCli.QueryNativeStakingProxyByOwner(x.ProviderChain.SenderAccount.GetAddress().String())

execMsg = fmt.Sprintf(`{"unstake": {"validator":%q,"amount": {"denom":%q, "amount":"%d"}}}`,
myLocalValidatorAddr, x.ProviderDenom, 10_000_000)
_, err := providerCli.Exec(nativeStakingProxy, execMsg)
require.NoError(t, err)

x.ProviderChain.NextBlock()

_, err = providerCli.Exec(nativeStakingProxy, `{"release_unbonded": {}}`)
require.NoError(t, err)

// Check new collateral
require.Equal(t, 200_000_000, providerCli.QueryVaultBalance())
// Check new max lien
// Max lien decrease as release_unbonded
require.Equal(t, 90_000_001, providerCli.QueryMaxLien())
// Check new slashable amount
require.Equal(t, 18000001, providerCli.QuerySlashableAmount())
// Check new free collateral
require.Equal(t, 109999999, providerCli.QueryVaultFreeBalance())
}
45 changes: 45 additions & 0 deletions tests/e2e/test_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/osmosis-labs/mesh-security-sdk/x/meshsecurity"
"github.com/osmosis-labs/mesh-security-sdk/x/meshsecurity/keeper"
"github.com/osmosis-labs/mesh-security-sdk/x/meshsecurity/types"
providertypes "github.com/osmosis-labs/mesh-security-sdk/x/meshsecurityprovider/types"
)

// Query is a query type used in tests only
Expand Down Expand Up @@ -129,6 +130,7 @@ func (tc *TestChain) SendMsgsWithSigner(privKey cryptotypes.PrivKey, signer *aut

type ProviderContracts struct {
Vault sdk.AccAddress
NativeStaking sdk.AccAddress
ExternalStaking sdk.AccAddress
}

Expand All @@ -153,6 +155,7 @@ func (p *TestProviderClient) BootstrapContracts(provApp *app.MeshApp, connId, po
params := provApp.MeshSecProvKeeper.GetParams(ctx)
params.VaultAddress = vaultContract.String()
provApp.MeshSecProvKeeper.SetParams(ctx, params)

// external staking
extStakingCodeID := p.chain.StoreCodeFile(buildPathToWasm("mesh_external_staking.wasm")).CodeID
initMsg = []byte(fmt.Sprintf(
Expand All @@ -165,6 +168,19 @@ func (p *TestProviderClient) BootstrapContracts(provApp *app.MeshApp, connId, po
ExternalStaking: externalStakingContract,
}
p.Contracts = r

// local staking
vaultConfig := p.QueryVault(Query{
"config": {},
})
require.Contains(p.t, vaultConfig, "local_staking")
nativeStaking, err := sdk.AccAddressFromBech32(vaultConfig["local_staking"].(string))
require.NoError(p.t, err)
r.NativeStaking = nativeStaking
p.Contracts = r

p.MustExecParamsChangeProposal(provApp, vaultContract.String(), nativeStaking.String())

return r
}

Expand Down Expand Up @@ -240,6 +256,19 @@ func (p TestProviderClient) ExecWithSigner(privKey cryptotypes.PrivKey, signer *
return rsp, err
}

// MustExecGovProposal submit and vote yes on proposal
func (p TestProviderClient) MustExecParamsChangeProposal(provApp *app.MeshApp, vault, nativeStaking string) {
msg := &providertypes.MsgUpdateParams{
Authority: provApp.MeshSecKeeper.GetAuthority(),
Params: providertypes.Params{
VaultAddress: vault,
NativeStakingAddress: nativeStaking,
},
}
proposalID := submitGovProposal(p.t, p.chain, msg)
voteAndPassGovProposal(p.t, p.chain, proposalID)
}

func (p TestProviderClient) MustFailExecVault(payload string, funds ...sdk.Coin) error {
rsp, err := p.Exec(p.Contracts.Vault, payload, funds...)
require.Error(p.t, err, "Response: %v", rsp)
Expand Down Expand Up @@ -270,6 +299,18 @@ func (p TestProviderClient) QueryExtStakingAmount(user, validator string) int {
return ParseHighLow(p.t, qRsp["stake"]).Low
}

func (p TestProviderClient) QueryNativeStakingProxyByOwner(user string) sdk.AccAddress {
qRsp := p.QueryNativeStaking(Query{
"proxy_by_owner": {
"owner": user,
},
})
require.Contains(p.t, qRsp, "proxy")
a, err := sdk.AccAddressFromBech32(qRsp["proxy"].(string))
require.NoError(p.t, err)

return a
}
func (p TestProviderClient) QueryExtStaking(q Query) QueryResponse {
return Querier(p.t, p.chain)(p.Contracts.ExternalStaking.String(), q)
}
Expand All @@ -278,6 +319,10 @@ func (p TestProviderClient) QueryVault(q Query) QueryResponse {
return Querier(p.t, p.chain)(p.Contracts.Vault.String(), q)
}

func (p TestProviderClient) QueryNativeStaking(q Query) QueryResponse {
return Querier(p.t, p.chain)(p.Contracts.NativeStaking.String(), q)
}

type HighLowType struct {
High, Low int
}
Expand Down
2 changes: 1 addition & 1 deletion tests/starship/setup/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ func (p *ProviderClient) BootstrapContracts(connId, portID, rewardDenom string)

nativeInitMsg := []byte(fmt.Sprintf(`{"denom": %q, "proxy_code_id": %d, "slash_ratio_dsign": %q, "slash_ratio_offline": %q }`, localTokenDenom, proxyCodeID, localSlashRatioDoubleSign, localSlashRatioOffline))
initMsg := []byte(fmt.Sprintf(`{"denom": %q, "local_staking": {"code_id": %d, "msg": %q}}`, localTokenDenom, nativeStakingCodeID, base64.StdEncoding.EncodeToString(nativeInitMsg)))
contracts, err := InstantiateContract(p.Chain, vaultCodeID, "provider-valut-contract", initMsg)
contracts, err := InstantiateContract(p.Chain, vaultCodeID, "provider-vault-contract", initMsg)
if err != nil {
return nil, err
}
Expand Down
Binary file modified tests/testdata/mesh_converter.wasm.gz
Binary file not shown.
Binary file modified tests/testdata/mesh_external_staking.wasm.gz
Binary file not shown.
Binary file modified tests/testdata/mesh_native_staking.wasm.gz
Binary file not shown.
Binary file modified tests/testdata/mesh_native_staking_proxy.wasm.gz
Binary file not shown.
Binary file modified tests/testdata/mesh_osmosis_price_provider.wasm.gz
Binary file not shown.
Binary file modified tests/testdata/mesh_remote_price_feed.wasm.gz
Binary file not shown.
Binary file modified tests/testdata/mesh_simple_price_feed.wasm.gz
Binary file not shown.
Binary file modified tests/testdata/mesh_vault.wasm.gz
Binary file not shown.
Binary file modified tests/testdata/mesh_virtual_staking.wasm.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion tests/testdata/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ef0e3840b092ed66cd0968e2b9b253ae243ffe52
d9e27c854aaf3bb604d32f5fa8e6c3e42b686edf
10 changes: 8 additions & 2 deletions x/meshsecurityprovider/contract/in_message.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ type (
Provider *ProviderMsg `json:"provider,omitempty"`
}
ProviderMsg struct {
Bond *BondMsg `json:"bond,omitempty"`
Unbond *UnbondMsg `json:"unbond,omitempty"`
Bond *BondMsg `json:"bond,omitempty"`
Unbond *UnbondMsg `json:"unbond,omitempty"`
Unstake *UnstakeMsg `json:"unstake,omitempty"`
}
BondMsg struct {
Amount wasmvmtypes.Coin `json:"amount"`
Expand All @@ -18,4 +19,9 @@ type (
Amount wasmvmtypes.Coin `json:"amount"`
Delegator string `json:"delegator"`
}
UnstakeMsg struct {
Amount wasmvmtypes.Coin `json:"amount"`
Validator string `json:"validator"`
Delegator string `json:"delegator"`
}
)
3 changes: 3 additions & 0 deletions x/meshsecurityprovider/keeper/handle_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ func (h CustomMessenger) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddres
return h.k.HandleBondMsg(ctx, contractAddr, customMsg.Provider.Bond)
case customMsg.Provider.Unbond != nil:
return h.k.HandleUnbondMsg(ctx, contractAddr, customMsg.Provider.Unbond)
case customMsg.Provider.Unstake != nil:
return h.k.HandleUnstakeMsg(ctx, contractAddr, customMsg.Provider.Unstake)
}

return nil, nil, wasmtypes.ErrUnknownMsg
}

Loading
Loading