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

[Application] Enforce minimum stake when burning #848

Merged
merged 139 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from 136 commits
Commits
Show all changes
139 commits
Select commit Hold shift + click to select a range
d1cd5e6
scaffold: message update-param --module gateway --signer authority na…
bryanchriswhite Sep 9, 2024
91eecfc
chore: update gateway MsgUpdateParam fields
bryanchriswhite Sep 9, 2024
ef62280
chore: update MsgUpdateParamResponse fields
bryanchriswhite Sep 23, 2024
f7a6e5b
chore: comment out autocli for gateway module param updates
bryanchriswhite Sep 10, 2024
8957f1c
fix: linter error
bryanchriswhite Sep 26, 2024
3016ca3
revert: premature changes
bryanchriswhite Sep 26, 2024
899effb
feat: add min_stake gateway module param
bryanchriswhite Sep 26, 2024
83c1d74
chore: cleanup makefiles and param update JSON files
bryanchriswhite Sep 23, 2024
55e6a31
chore: add gateway module param make targets
bryanchriswhite Sep 23, 2024
ddd68bb
refctor: consolidate param config types
bryanchriswhite Sep 26, 2024
fa8caf6
tests: improve error messaging
bryanchriswhite Sep 26, 2024
ae006e2
tests: add coverage over gateway min stake param updates
bryanchriswhite Sep 26, 2024
e92e3b1
chore: add as_coin as_type type 😉
bryanchriswhite Sep 26, 2024
b2e1267
chore: add app MsgUpdateParam to genesis authorizations
bryanchriswhite Sep 26, 2024
0373fa2
fix: typo
bryanchriswhite Sep 26, 2024
da7894a
chore: cleanup makefiles
bryanchriswhite Sep 26, 2024
015c537
wip: fixing tests
bryanchriswhite Sep 26, 2024
1ac6c48
tests: add tests
bryanchriswhite Sep 26, 2024
db366f6
tests: remove erroneous case
bryanchriswhite Sep 26, 2024
60bef17
test: gateway staking below minimum fails
bryanchriswhite Sep 27, 2024
a21687f
feat: gateway min stake validation & grpc status error returns
bryanchriswhite Sep 27, 2024
7e9f857
chore: cleanup comments
bryanchriswhite Sep 27, 2024
4140710
scaffold: message update-param --module examplemod --signer authority…
bryanchriswhite Sep 27, 2024
0a8d922
chore: update MsgUpdateParam fields
bryanchriswhite Sep 27, 2024
c88edd6
chore: comment out application MsgUpdateParam autocli
bryanchriswhite Sep 27, 2024
da51239
chore: add application MsgUpdateParam to dao genesis authorizations
bryanchriswhite Sep 27, 2024
45c5a99
chore: update NewMsgUpdateParam constructor
bryanchriswhite Sep 27, 2024
d987e09
fix: simulations generated code
bryanchriswhite Sep 27, 2024
0da255d
chore: add min_stake param to application module params
bryanchriswhite Sep 27, 2024
4542628
chore: update params config for param updates test suite
bryanchriswhite Sep 27, 2024
b81ca9e
chore: add parameter validation
bryanchriswhite Sep 27, 2024
cdff4b3
chore: add param update make targets and JSON msgs
bryanchriswhite Sep 27, 2024
be24753
chore: add default application min_stake param of 1 POKT to genesis c…
bryanchriswhite Sep 27, 2024
45b6e5c
chore: update MsgUpdateParamResponse & add AsUint64 AsType type
bryanchriswhite Sep 27, 2024
b3e139a
feat: implement MsgUpdateParam handler
bryanchriswhite Sep 27, 2024
872202b
test: MsgUpdateParam handler
bryanchriswhite Sep 27, 2024
a49d69b
feat: implement NewMsgUpdateParam constructor
bryanchriswhite Sep 27, 2024
d63a429
chore: add min_stake validation
bryanchriswhite Sep 27, 2024
9040bf0
chore: tidy up
bryanchriswhite Sep 27, 2024
4340590
chore: review feedback improvements
bryanchriswhite Sep 30, 2024
4b8e95b
Merge branch 'main' into issues/612/chore/gateway-msg-update-param
bryanchriswhite Sep 30, 2024
352afa1
chore: review feedback improvements
bryanchriswhite Sep 30, 2024
6afdaef
fix: linter errors
bryanchriswhite Sep 30, 2024
0839ae4
chore: review feedback improvements
bryanchriswhite Sep 30, 2024
34b0d6d
Merge remote-tracking branch 'pokt/issues/612/chore/gateway-msg-updat…
bryanchriswhite Sep 30, 2024
f48fa66
Merge branch 'issues/612/param/min-stake-gateway' into issues/612/gat…
bryanchriswhite Sep 30, 2024
6c5e13f
chore: review feedback improvements
bryanchriswhite Sep 30, 2024
a77877b
fix: test error message
bryanchriswhite Sep 30, 2024
9f65d25
Merge branch 'issues/612/param/min-stake-gateway' into issues/612/gat…
bryanchriswhite Sep 30, 2024
28962ba
Merge remote-tracking branch 'pokt/main' into issues/612/param/min-st…
bryanchriswhite Sep 30, 2024
497ecd9
Merge branch 'issues/612/app/msg-update-param' into issues/612/applic…
bryanchriswhite Sep 30, 2024
d92eb59
Merge branch 'issues/612/gateway/logic' into issues/612/app/msg-updat…
bryanchriswhite Sep 30, 2024
941b801
Merge branch 'issues/612/app/msg-update-param' into issues/612/applic…
bryanchriswhite Sep 30, 2024
36e5f2e
chore: update message_update_param_test.go
bryanchriswhite Sep 30, 2024
2baa173
fix: genesis tests
bryanchriswhite Sep 30, 2024
7018149
chore: use AsInt64 to update MaxDelegatedGateways for consistency
bryanchriswhite Sep 30, 2024
c36fe79
chore: ensure application stake handler returns grpc status errors
bryanchriswhite Sep 30, 2024
eab9417
tests: update app stake msg handler unit tests
bryanchriswhite Sep 30, 2024
da9b322
feat: enforce application min stake when staking
bryanchriswhite Sep 30, 2024
5e47c98
fix: failing unit tests
bryanchriswhite Sep 30, 2024
323299e
chore: add PreGeneratedAccountIterator#MustNext()
bryanchriswhite Oct 1, 2024
d888548
chore: update require deps for RingClient
bryanchriswhite Oct 1, 2024
e87564d
refactor: extract application unbonding to method
bryanchriswhite Oct 1, 2024
7d5c17b
test: app is unbonded when settlement lowers stake below min
bryanchriswhite Oct 1, 2024
030f2ef
feat: unbond app when stake drops below min when settling
bryanchriswhite Oct 1, 2024
3e77f7c
chore: add TODO_NEXT comments
bryanchriswhite Oct 1, 2024
090ca9a
fix: failing tests
bryanchriswhite Oct 1, 2024
c14ad46
chore: add TODOs & update comments
bryanchriswhite Oct 1, 2024
d0b4187
chore: add TODOs & update comments
bryanchriswhite Oct 1, 2024
891a858
chore: review feedback improvements
bryanchriswhite Oct 2, 2024
08e99ba
Merge branch 'issues/612/param/min-stake-gateway' into issues/612/gat…
bryanchriswhite Oct 2, 2024
da9a240
Merge branch 'issues/612/gateway/logic' into issues/612/app/msg-updat…
bryanchriswhite Oct 2, 2024
d85d969
Merge branch 'issues/612/app/msg-update-param' into issues/612/applic…
bryanchriswhite Oct 2, 2024
47da555
Merge branch 'issues/612/application/min-stake-param' into issues/612…
bryanchriswhite Oct 2, 2024
0f55e91
Merge branch 'issues/612/application/staking' into issues/612/applica…
bryanchriswhite Oct 2, 2024
d98b22b
test: simplify
bryanchriswhite Oct 2, 2024
ccc3f53
fix: e2e test
bryanchriswhite Oct 2, 2024
47e0993
Merge branch 'issues/612/param/min-stake-gateway' into issues/612/gat…
bryanchriswhite Oct 2, 2024
c08abfd
Merge branch 'issues/612/gateway/logic' into issues/612/app/msg-updat…
bryanchriswhite Oct 2, 2024
8336d76
Merge branch 'issues/612/app/msg-update-param' into issues/612/applic…
bryanchriswhite Oct 2, 2024
9386791
Merge branch 'issues/612/application/min-stake-param' into issues/612…
bryanchriswhite Oct 2, 2024
0a72a83
Merge branch 'issues/612/application/staking' into issues/612/applica…
bryanchriswhite Oct 2, 2024
ce5b693
chore: increase genesis app stakes so E2E tests don't burn them out
bryanchriswhite Oct 2, 2024
b29843e
Empty commit
bryanchriswhite Oct 2, 2024
8c25061
Empty commit
bryanchriswhite Oct 2, 2024
3f59041
Merge branch 'issues/612/param/min-stake-gateway' into issues/612/gat…
bryanchriswhite Oct 2, 2024
4e259c9
chore: apply improvements
bryanchriswhite Oct 2, 2024
2808925
chore: add godoc style comment to min_stake params field
bryanchriswhite Oct 2, 2024
197af04
chore: add godoc style comment to min_stake params field
bryanchriswhite Oct 2, 2024
2a33127
chore: improvements:
bryanchriswhite Oct 4, 2024
3280142
chore: improve logging & ensure gRPC status error returns
bryanchriswhite Oct 4, 2024
98d1c96
chore: improve logging & ensure gRPC status error returns
bryanchriswhite Oct 4, 2024
c256eae
chore: review feedback improvements
bryanchriswhite Oct 4, 2024
0d36e0f
Merge remote-tracking branch 'pokt/main' into issues/612/param/min-st…
bryanchriswhite Oct 4, 2024
00914b0
Merge branch 'issues/612/param/min-stake-gateway' into issues/612/gat…
bryanchriswhite Oct 4, 2024
f3fa183
Merge branch 'issues/612/gateway/logic' into issues/612/app/msg-updat…
bryanchriswhite Oct 4, 2024
f4b8284
Merge branch 'issues/612/app/msg-update-param' into issues/612/applic…
bryanchriswhite Oct 4, 2024
12d1b43
Merge branch 'issues/612/application/min-stake-param' into issues/612…
bryanchriswhite Oct 4, 2024
30b48f4
test: simplify coin equality assertions
bryanchriswhite Oct 4, 2024
b3a3236
Merge branch 'issues/612/application/staking' into issues/612/applica…
bryanchriswhite Oct 4, 2024
1c309b8
Empty commit
bryanchriswhite Oct 4, 2024
e7ff959
Merge branch 'issues/612/param/min-stake-gateway' into issues/612/gat…
bryanchriswhite Oct 4, 2024
1257f6e
Merge branch 'main' into issues/612/gateway/logic
bryanchriswhite Oct 4, 2024
b972e3b
Merge branch 'issues/612/gateway/logic' into issues/612/app/msg-updat…
bryanchriswhite Oct 4, 2024
0f4a82d
chore: add review feedback TODOs
bryanchriswhite Oct 4, 2024
44257f3
Merge branch 'issues/612/app/msg-update-param' into issues/612/applic…
bryanchriswhite Oct 4, 2024
561a1aa
Merge branch 'issues/612/application/min-stake-param' into issues/612…
bryanchriswhite Oct 4, 2024
f176fe4
Merge branch 'issues/612/application/staking' into issues/612/applica…
bryanchriswhite Oct 4, 2024
ef4e0ad
chore: reconcile PreGeneratedAccountIterator#MustNext()
bryanchriswhite Oct 4, 2024
4d2c2d9
chore: review feedback improvements
bryanchriswhite Oct 4, 2024
5ba2a48
fix: typo
bryanchriswhite Oct 4, 2024
3e4ef9e
fix: linter errors
bryanchriswhite Oct 4, 2024
8c7eadf
Empty commit
bryanchriswhite Oct 4, 2024
a28ff88
Empty commit
bryanchriswhite Oct 4, 2024
cd5e420
chore: review feedback improvements
bryanchriswhite Oct 4, 2024
cc95ebf
Merge branch 'issues/612/gateway/logic' into issues/612/app/msg-updat…
bryanchriswhite Oct 4, 2024
65158ad
Merge branch 'main' into issues/612/gateway/logic
bryanchriswhite Oct 4, 2024
70f8985
Merge branch 'issues/612/gateway/logic' into issues/612/app/msg-updat…
bryanchriswhite Oct 4, 2024
698991a
Empty commit
bryanchriswhite Oct 4, 2024
6c689e8
Merge branch 'issues/612/gateway/logic' into issues/612/app/msg-updat…
bryanchriswhite Oct 4, 2024
c2bf664
Merge branch 'main' into issues/612/app/msg-update-param
bryanchriswhite Oct 4, 2024
0d63e07
fix: linter error
bryanchriswhite Oct 4, 2024
7753572
Merge branch 'issues/612/app/msg-update-param' into issues/612/applic…
bryanchriswhite Oct 4, 2024
5556f4a
Merge remote-tracking branch 'pokt/main' into issues/612/application/…
bryanchriswhite Oct 4, 2024
1faf4ab
chore: regenerate protobufs
bryanchriswhite Oct 4, 2024
48ba5dd
Merge branch 'issues/612/application/min-stake-param' into issues/612…
bryanchriswhite Oct 4, 2024
d91dde7
Merge branch 'main' into issues/612/application/staking
bryanchriswhite Oct 4, 2024
5e5d8a4
Merge branch 'issues/612/application/staking' into issues/612/applica…
bryanchriswhite Oct 7, 2024
7e9bd33
Empty commit
bryanchriswhite Oct 7, 2024
69c2755
Empty commit
bryanchriswhite Oct 9, 2024
1f7e201
Merge branch 'main' into issues/612/application/staking
bryanchriswhite Oct 9, 2024
0fa9ab8
Merge remote-tracking branch 'pokt/issues/612/application/staking' in…
bryanchriswhite Oct 10, 2024
d91671e
Merge remote-tracking branch 'pokt/main' into issues/612/application/…
bryanchriswhite Oct 10, 2024
c89ee93
chore: quick fixes
bryanchriswhite Oct 10, 2024
ed0d795
fix: linter error
bryanchriswhite Oct 10, 2024
0be55c6
Empty commit
bryanchriswhite Oct 10, 2024
14a5c79
chore: review feedback improvements
bryanchriswhite Oct 11, 2024
735ca2a
test: fix application min stake integration test
bryanchriswhite Oct 11, 2024
b220177
Empty commit
bryanchriswhite Oct 11, 2024
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
6 changes: 3 additions & 3 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ genesis:
max_delegated_gateways: "7"
min_stake:
# TODO_MAINNET: Determine realistic amount for minimum application stake amount.
amount: "1000000" # 1 POKT
amount: "100000000" # 100 POKT
denom: upokt
applicationList:
- address: pokt1mrqt5f7qh8uxs27cjm9t7v9e74a9vvdnq5jva4
Expand All @@ -179,7 +179,7 @@ genesis:
stake:
# NB: This value should be exactly 1upokt smaller than the value in
# `supplier1_stake_config.yaml` so that the stake command causes a state change.
amount: "1000068"
amount: "100000068" # ~100 POKT
denom: upokt
- address: pokt1ad28jdap2zfanjd7hpkh984yveney6k9a42man
delegatee_gateway_addresses: []
Expand All @@ -190,7 +190,7 @@ genesis:
stake:
# NB: This value should be exactly 1upokt smaller than the value in
# `supplier1_stake_config.yaml` so that the stake command causes a state change.
amount: "1000068"
amount: "100000068" # ~100 POKT
denom: upokt
supplier:
supplierList:
Expand Down
1 change: 1 addition & 0 deletions pkg/crypto/rings/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type ringClient struct {
// - polylog.Logger
// - client.ApplicationQueryClient
// - client.AccountQueryClient
// - client.SharedQueryClient
func NewRingClient(deps depinject.Config) (_ crypto.RingClient, err error) {
rc := new(ringClient)

Expand Down
177 changes: 177 additions & 0 deletions tests/integration/application/min_stake_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package application

import (
"context"
"testing"

cosmoslog "cosmossdk.io/log"
"cosmossdk.io/math"
cosmostypes "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"

"github.com/pokt-network/poktroll/app/volatile"
"github.com/pokt-network/poktroll/cmd/poktrolld/cmd"
_ "github.com/pokt-network/poktroll/pkg/polylog/polyzero"
"github.com/pokt-network/poktroll/testutil/keeper"
testproof "github.com/pokt-network/poktroll/testutil/proof"
"github.com/pokt-network/poktroll/testutil/sample"
apptypes "github.com/pokt-network/poktroll/x/application/types"
prooftypes "github.com/pokt-network/poktroll/x/proof/types"
sessiontypes "github.com/pokt-network/poktroll/x/session/types"
sharedtypes "github.com/pokt-network/poktroll/x/shared/types"
)

type applicationMinStakeTestSuite struct {
suite.Suite

ctx context.Context
keepers keeper.TokenomicsModuleKeepers
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a comment on why we are using TokenomicsModuleKeepers here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should have a struct that includes all our keepers.

Copy link
Contributor Author

@bryanchriswhite bryanchriswhite Oct 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should have a struct that includes all our keepers.

That's essentially what TokenomicsModuleKeepers is (see testutil/keeper/tokenomics.go:52). We also have ProofModuleKeepers which omits the tokenomics module.

Perhaps we only really need one which integrates all poktroll modules (and their dependencies) and we can name it something different and move it somewhere more appropriate.

These are 1 step down from the "integration app" tests in that the modules and keepers are all instantiated and connected to the same in-memory DB but there's no message processing. Tests using these structures involve calling keeper methods directly and/or instantiating individual modules' message servers if necessary.

I'm making a note to open a docs PR regarding the different levels of testing, when and why to use each, what tools to use for each, etc. 📝

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


serviceId,
appBech32,
supplierBech32 string

appStake *cosmostypes.Coin

numRelays,
numComputeUnitsPerRelay uint64
}

func TestApplicationMinStakeTestSuite(t *testing.T) {
cmd.InitSDKConfig()

suite.Run(t, new(applicationMinStakeTestSuite))
}

func (s *applicationMinStakeTestSuite) SetupTest() {
s.keepers, s.ctx = keeper.NewTokenomicsModuleKeepers(s.T(), cosmoslog.NewNopLogger())

s.serviceId = "svc1"
s.appBech32 = sample.AccAddress()
s.supplierBech32 = sample.AccAddress()
s.appStake = &apptypes.DefaultMinStake
s.numRelays = 10
s.numComputeUnitsPerRelay = 1

// Set block height to 1.
s.ctx = cosmostypes.UnwrapSDKContext(s.ctx).WithBlockHeight(1)
}

func (s *applicationMinStakeTestSuite) TestAppCannotStakeLessThanMinStake() {
s.T().Skip("this case is well covered in x/application/keeper/msg_server_stake_application_test.go")
}

func (s *applicationMinStakeTestSuite) TestAppIsUnbondedIfBelowMinStakeWhenSettling() {
// Assert that the application's initial bank balance is 0.
appBalance := s.getAppBalance()
require.Equal(s.T(), int64(0), appBalance.Amount.Int64())

// Add service 1
s.addService()

// Stake an application for service 1 with min stake.
s.stakeApp()

// Stake a supplier for service 1.
s.stakeSupplier()

// Get the session header.
sessionHeader := s.getSessionHeader()

// Create a claim whose settlement amount drops the application below min stake
claim := s.getClaim(sessionHeader)

// Process TLMs for the claim.
err := s.keepers.Keeper.ProcessTokenLogicModules(s.ctx, claim)
require.NoError(s.T(), err)

// Assert that the application was unbonded.
_, isAppFound := s.keepers.ApplicationKeeper.GetApplication(s.ctx, s.appBech32)
require.False(s.T(), isAppFound)

// Assert that the application's stake was returned to its bank balance.
expectedAppBurn := math.NewInt(int64(s.numRelays * s.numComputeUnitsPerRelay * sharedtypes.DefaultComputeUnitsToTokensMultiplier))
expectedAppBalance := s.appStake.SubAmount(expectedAppBurn)
appBalance = s.getAppBalance()
require.Equal(s.T(), expectedAppBalance.Amount.Int64(), appBalance.Amount.Int64())

}

// addService adds the test service to the service module state.
func (s *applicationMinStakeTestSuite) addService() {
s.keepers.ServiceKeeper.SetService(s.ctx, sharedtypes.Service{
Id: s.serviceId,
ComputeUnitsPerRelay: 1,
OwnerAddress: sample.AccAddress(), // random address.
})
}

// stakeApp stakes an application for service 1 with min stake.
func (s *applicationMinStakeTestSuite) stakeApp() {
s.keepers.ApplicationKeeper.SetApplication(s.ctx, apptypes.Application{
Address: s.appBech32,
Stake: s.appStake,
ServiceConfigs: []*sharedtypes.ApplicationServiceConfig{{ServiceId: s.serviceId}},
})
}

// stakeSupplier stakes a supplier for service 1.
func (s *applicationMinStakeTestSuite) stakeSupplier() {
// TODO_UPNEXT(@bryanchriswhite, #612): Replace supplierStake with suppleirtypes.DefaultMinStake.
supplierStake := cosmostypes.NewInt64Coin(volatile.DenomuPOKT, 1000000) // 1 POKT.
s.keepers.SupplierKeeper.SetSupplier(s.ctx, sharedtypes.Supplier{
OwnerAddress: s.supplierBech32,
OperatorAddress: s.supplierBech32,
Stake: &supplierStake,
Services: []*sharedtypes.SupplierServiceConfig{
{
ServiceId: s.serviceId,
RevShare: []*sharedtypes.ServiceRevenueShare{
{
Address: s.supplierBech32,
RevSharePercentage: 1,
},
},
},
},
})
}

// getSessionHeader gets the session header for the test session.
func (s *applicationMinStakeTestSuite) getSessionHeader() *sessiontypes.SessionHeader {
sdkCtx := cosmostypes.UnwrapSDKContext(s.ctx)
currentHeight := sdkCtx.BlockHeight()
sessionRes, err := s.keepers.SessionKeeper.GetSession(s.ctx, &sessiontypes.QueryGetSessionRequest{
ApplicationAddress: s.appBech32,
ServiceId: s.serviceId,
BlockHeight: currentHeight,
})
require.NoError(s.T(), err)

return sessionRes.GetSession().GetHeader()
}

// getClaim creates a claim whose settlement amount drops the application below min stake.
func (s *applicationMinStakeTestSuite) getClaim(
sessionHeader *sessiontypes.SessionHeader,
) *prooftypes.Claim {
claimRoot := testproof.SmstRootWithSumAndCount(s.numRelays*s.numComputeUnitsPerRelay, s.numRelays)

return &prooftypes.Claim{
SupplierOperatorAddress: s.supplierBech32,
SessionHeader: sessionHeader,
RootHash: claimRoot,
}
}

// getAppBalance returns the bank module balance for the application.
func (s *applicationMinStakeTestSuite) getAppBalance() *cosmostypes.Coin {
appBalRes, err := s.keepers.BankKeeper.Balance(s.ctx, &banktypes.QueryBalanceRequest{
Address: s.appBech32, Denom: volatile.DenomuPOKT,
})
require.NoError(s.T(), err)

return appBalRes.GetBalance()
}
4 changes: 4 additions & 0 deletions testutil/keeper/tokenomics.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ func TokenomicsKeeperWithActorAddrs(t testing.TB) (
mockApplicationKeeper.EXPECT().
SetApplication(gomock.Any(), gomock.Any()).
AnyTimes()
mockApplicationKeeper.EXPECT().
UnbondApplication(gomock.Any(), gomock.Any()).
Return(nil).
AnyTimes()

// Mock the supplier keeper.
mockSupplierKeeper := mocks.NewMockSupplierKeeper(ctrl)
Expand Down
4 changes: 3 additions & 1 deletion testutil/testkeyring/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,12 @@ func (iter *PreGeneratedAccountIterator) Next() (_ *PreGeneratedAccount, ok bool
return iter.accounts[currentIndex], true
}

// MustNext returns the next account in the iterator. It panics if the iterator
// is out of accounts; see testutil/testkeyring/gen_accounts.
func (iter *PreGeneratedAccountIterator) MustNext() *PreGeneratedAccount {
account, ok := iter.Next()
if !ok {
panic("insufficient number of pre-generated accounts")
panic("insufficient number of pre-generated accounts; see testutil/testkeyring/gen_accounts")
}
return account
}
Expand Down
9 changes: 6 additions & 3 deletions x/application/keeper/msg_server_stake_application.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func (k msgServer) StakeApplication(ctx context.Context, msg *types.MsgStakeAppl
logger.Info(fmt.Sprintf("Application is going to escrow an additional %+v coins", coinsToEscrow))

// If the application has initiated an unstake action, cancel it since it is staking again.
// TODO_UPNEXT:(@bryanchriswhite): assert that an EventApplicationUnbondingCanceled event was emitted.
foundApp.UnstakeSessionEndHeight = types.ApplicationNotUnstaking
}

Expand All @@ -67,12 +68,14 @@ func (k msgServer) StakeApplication(ctx context.Context, msg *types.MsgStakeAppl

// MUST ALWAYS have at least minimum stake.
minStake := k.GetParams(ctx).MinStake
// TODO_CONSIDERATION: If we support multiple native tokens, we will need to
// start checking the denom here.
if msg.Stake.Amount.LT(minStake.Amount) {
errFmt := "application %q must stake at least %s"
logger.Info(fmt.Sprintf(errFmt, msg.Address, minStake))
err = fmt.Errorf("application %q must stake at least %s", msg.GetAddress(), minStake)
logger.Info(err.Error())
return nil, status.Error(
codes.InvalidArgument,
types.ErrAppInvalidStake.Wrapf(errFmt, msg.Address, minStake).Error(),
types.ErrAppInvalidStake.Wrapf("%s", err).Error(),
)
}

Expand Down
2 changes: 2 additions & 0 deletions x/application/keeper/msg_server_unstake_application.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ func (k msgServer) UnstakeApplication(
foundApp.UnstakeSessionEndHeight = uint64(shared.GetSessionEndHeight(&sharedParams, currentHeight))
k.SetApplication(ctx, foundApp)

// TODO_UPNEXT:(@bryanchriswhite): emit a new EventApplicationUnbondingBegin event.

isSuccessful = true
return &types.MsgUnstakeApplicationResponse{}, nil
}
8 changes: 8 additions & 0 deletions x/application/keeper/msg_server_unstake_application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ func TestMsgServer_UnstakeApplication_Success(t *testing.T) {
_, err = srv.UnstakeApplication(ctx, unstakeMsg)
require.NoError(t, err)

// TODO_UPNEXT:(@bryanchriswhite): assert that an EventApplicationUnbondingBegin event was emitted.

// Make sure the application entered the unbonding period
foundApp, isAppFound = applicationModuleKeepers.GetApplication(ctx, unstakingAppAddr)
require.True(t, isAppFound)
Expand All @@ -70,6 +72,8 @@ func TestMsgServer_UnstakeApplication_Success(t *testing.T) {
err = applicationModuleKeepers.EndBlockerUnbondApplications(ctx)
require.NoError(t, err)

// TODO_UPNEXT:(@bryanchriswhite): assert that an EventApplicationUnbondingEnd event was emitted.

// Make sure the unstaking application is removed from the applications list when
// the unbonding period is over.
_, isAppFound = applicationModuleKeepers.GetApplication(ctx, unstakingAppAddr)
Expand Down Expand Up @@ -105,6 +109,8 @@ func TestMsgServer_UnstakeApplication_CancelUnbondingIfRestaked(t *testing.T) {
_, err = srv.UnstakeApplication(ctx, unstakeMsg)
require.NoError(t, err)

// TODO_UPNEXT:(@bryanchriswhite): assert that an EventApplicationUnbondingBegin event was emitted.

// Make sure the application entered the unbonding period
foundApp, isAppFound = applicationModuleKeepers.GetApplication(ctx, appAddr)
require.True(t, isAppFound)
Expand All @@ -117,6 +123,8 @@ func TestMsgServer_UnstakeApplication_CancelUnbondingIfRestaked(t *testing.T) {
_, err = srv.StakeApplication(ctx, stakeMsg)
require.NoError(t, err)

// TODO_UPNEXT:(@bryanchriswhite): assert that an EventApplicationUnbondingCanceled event was emitted.

// Make sure the application is no longer in the unbonding period
foundApp, isAppFound = applicationModuleKeepers.GetApplication(ctx, appAddr)
require.True(t, isAppFound)
Expand Down
56 changes: 34 additions & 22 deletions x/application/keeper/unbond_applications.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
cosmostypes "github.com/cosmos/cosmos-sdk/types"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/pokt-network/poktroll/x/application/types"
apptypes "github.com/pokt-network/poktroll/x/application/types"
"github.com/pokt-network/poktroll/x/shared"
)

Expand All @@ -22,8 +22,6 @@ func (k Keeper) EndBlockerUnbondApplications(ctx context.Context) error {
return nil
}

logger := k.Logger().With("method", "UnbondApplication")

// Iterate over all applications and unbond the ones that have finished the unbonding period.
// TODO_IMPROVE: Use an index to iterate over the applications that have initiated
// the unbonding action instead of iterating over all of them.
Expand All @@ -33,37 +31,51 @@ func (k Keeper) EndBlockerUnbondApplications(ctx context.Context) error {
continue
}

unbondingHeight := types.GetApplicationUnbondingHeight(&sharedParams, &application)
unbondingHeight := apptypes.GetApplicationUnbondingHeight(&sharedParams, &application)

// If the unbonding height is ahead of the current height, the application
// stays in the unbonding state.
if unbondingHeight > currentHeight {
continue
}

// Retrieve the account address of the application.
applicationAccAddress, err := cosmostypes.AccAddressFromBech32(application.Address)
if err != nil {
logger.Error(fmt.Sprintf("could not parse address %s", application.Address))
if err := k.UnbondApplication(ctx, &application); err != nil {
return err
}

// Send the coins from the application pool back to the application
err = k.bankKeeper.SendCoinsFromModuleToAccount(
ctx, types.ModuleName, applicationAccAddress, []sdk.Coin{*application.Stake},
)
if err != nil {
logger.Error(fmt.Sprintf(
"could not send %v coins from module %s to account %s due to %v",
application.Stake, applicationAccAddress, types.ModuleName, err,
))
return err
}
// TODO_UPNEXT(@bryanchriswhite): emit a new EventApplicationUnbondingEnd event.
}

// Update the Application in the store
k.RemoveApplication(ctx, applicationAccAddress.String())
logger.Info(fmt.Sprintf("Successfully removed the application: %+v", application))
return nil
}

// UnbondApplication transfers the application stake to the bank module balance for the
// corresponding account and removes the application from the application module state.
func (k Keeper) UnbondApplication(ctx context.Context, app *apptypes.Application) error {
logger := k.Logger().With("method", "UnbondApplication")

// Retrieve the account address of the application.
appAddr, err := cosmostypes.AccAddressFromBech32(app.Address)
if err != nil {
logger.Error(fmt.Sprintf("could not parse address %s", app.Address))
return err
}

// Send the coins from the application pool back to the application.
err = k.bankKeeper.SendCoinsFromModuleToAccount(
ctx, apptypes.ModuleName, appAddr, []sdk.Coin{*app.Stake},
)
if err != nil {
logger.Error(fmt.Sprintf(
"could not send %v coins from module %s to account %s due to %v",
app.Stake, appAddr, apptypes.ModuleName, err,
))
return err
}

// Remove the Application from the store.
k.RemoveApplication(ctx, app.GetAddress())
logger.Info(fmt.Sprintf("Successfully removed the application: %+v", app))

return nil
}
Loading
Loading