Skip to content

Commit

Permalink
[Supplier] Implement unbonding period (#666)
Browse files Browse the repository at this point in the history
Co-authored-by: Daniel Olshansky <[email protected]>
  • Loading branch information
red-0ne and Olshansk authored Jul 25, 2024
1 parent 1268edb commit 6d466c6
Show file tree
Hide file tree
Showing 26 changed files with 597 additions and 116 deletions.
94 changes: 78 additions & 16 deletions api/poktroll/shared/supplier.pulsar.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 60 additions & 0 deletions e2e/tests/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
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"
shared "github.com/pokt-network/poktroll/x/shared"
sharedtypes "github.com/pokt-network/poktroll/x/shared/types"
suppliertypes "github.com/pokt-network/poktroll/x/supplier/types"
)
Expand Down Expand Up @@ -457,6 +458,24 @@ func (s *suite) AModuleEndBlockEventIsBroadcast(module, eventType string) {
s.waitForNewBlockEvent(newEventTypeMatchFn(module, eventType))
}

func (s *suite) TheSupplierForAccountIsUnbonding(accName string) {
_, ok := accNameToSupplierMap[accName]
require.True(s, ok, "supplier %s not found", accName)

s.waitForTxResultEvent(newEventMsgTypeMatchFn("supplier", "UnstakeSupplier"))

supplier := s.getSupplierInfo(accName)
require.True(s, supplier.IsUnbonding())
}

func (s *suite) TheUserWaitsForUnbondingPeriodToFinish(accName string) {
_, ok := accNameToSupplierMap[accName]
require.True(s, ok, "supplier %s not found", accName)

unbondingHeight := s.getSupplierUnbondingHeight(accName)
s.waitForBlockHeight(unbondingHeight)
}

func (s *suite) getStakedAmount(actorType, accName string) (int, bool) {
s.Helper()
args := []string{
Expand Down Expand Up @@ -581,6 +600,47 @@ func (s *suite) validateAmountChange(prevAmount, currAmount int, expectedAmountC

}

// getSupplierInfo returns the supplier information for a given supplier address
func (s *suite) getSupplierInfo(supplierAddr string) *sharedtypes.Supplier {
args := []string{
"query",
"supplier",
"show-supplier",
accNameToAddrMap[supplierAddr],
"--output=json",
}

res, err := s.pocketd.RunCommandOnHostWithRetry("", numQueryRetries, args...)
require.NoError(s, err, "error getting supplier %s", supplierAddr)
s.pocketd.result = res

var resp suppliertypes.QueryGetSupplierResponse
responseBz := []byte(strings.TrimSpace(res.Stdout))
s.cdc.MustUnmarshalJSON(responseBz, &resp)
return &resp.Supplier
}

// getSupplierUnbondingHeight returns the height at which the supplier will be unbonded.
func (s *suite) getSupplierUnbondingHeight(accName string) int64 {
supplier := s.getSupplierInfo(accName)

args := []string{
"query",
"shared",
"params",
"--output=json",
}

res, err := s.pocketd.RunCommandOnHostWithRetry("", numQueryRetries, args...)
require.NoError(s, err, "error getting shared module params")

var resp sharedtypes.QueryParamsResponse
responseBz := []byte(strings.TrimSpace(res.Stdout))
s.cdc.MustUnmarshalJSON(responseBz, &resp)
unbondingHeight := shared.GetSupplierUnbondingHeight(&resp.Params, supplier)
return unbondingHeight
}

// TODO_IMPROVE: use `sessionId` and `supplierName` since those are the two values
// used to create the primary composite key on-chain to uniquely distinguish relays.
func relayReferenceKey(appName, supplierName string) string {
Expand Down
29 changes: 29 additions & 0 deletions e2e/tests/session_steps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,35 @@ func (s *suite) waitForNewBlockEvent(
}
}

// waitForBlockHeight waits for a NewBlock event to be observed whose height is
// greater than or equal to the target height.
func (s *suite) waitForBlockHeight(targetHeight int64) {
ctx, done := context.WithCancel(s.ctx)

// For each observed event, **asynchronously** check if it is greater than
// or equal to the target height
channel.ForEach[*block.CometNewBlockEvent](
ctx, s.newBlockEventsReplayClient.EventsSequence(ctx),
func(_ context.Context, newBlockEvent *block.CometNewBlockEvent) {
if newBlockEvent == nil {
return
}

if newBlockEvent.Data.Value.Block.Header.Height >= targetHeight {
done()
return
}
},
)

select {
case <-time.After(eventTimeout):
s.Fatalf("ERROR: timed out waiting for block height", targetHeight)
case <-ctx.Done():
s.Log("Success; height detected before timeout.")
}
}

// newEventTypeMatchFn returns a function that matches an event based on its type
// field. The type URL is constructed from the given module and eventType arguments
// where module is the module name and eventType is the protobuf message type name
Expand Down
5 changes: 2 additions & 3 deletions e2e/tests/stake_app.feature
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ Feature: Stake App Namespaces
Then the user should be able to see standard output containing "txhash:"
And the user should be able to see standard output containing "code: 0"
And the pocketd binary should exit without error
# TODO_TECHDEBT(@red-0ne): Wait for an admitted stake event instead of a time based waiting.
And the user should wait for "5" seconds
And the user should wait for the "application" module "StakeApplication" message to be submitted
And the "application" for account "app2" is staked with "1000070" uPOKT
And the account balance of "app2" should be "1000070" uPOKT "less" than before

Expand All @@ -23,6 +22,6 @@ Feature: Stake App Namespaces
Then the user should be able to see standard output containing "txhash:"
And the user should be able to see standard output containing "code: 0"
And the pocketd binary should exit without error
And the user should wait for "5" seconds
And the user should wait for the "application" module "UnstakeApplication" message to be submitted
And the "application" for account "app2" is not staked
And the account balance of "app2" should be "1000070" uPOKT "more" than before
5 changes: 2 additions & 3 deletions e2e/tests/stake_gateway.feature
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ Feature: Stake Gateway Namespaces
Then the user should be able to see standard output containing "txhash:"
And the user should be able to see standard output containing "code: 0"
And the pocketd binary should exit without error
# TODO_TECHDEBT(@red-0ne): Replace these time-based waits with event listening waits
And the user should wait for "5" seconds
And the user should wait for the "gateway" module "StakeGateway" message to be submitted
And the "gateway" for account "gateway2" is staked with "1000070" uPOKT
And the account balance of "gateway2" should be "1000070" uPOKT "less" than before

Expand All @@ -21,6 +20,6 @@ Feature: Stake Gateway Namespaces
Then the user should be able to see standard output containing "txhash:"
And the user should be able to see standard output containing "code: 0"
And the pocketd binary should exit without error
And the user should wait for "5" seconds
And the user should wait for the "gateway" module "UnstakeGateway" message to be submitted
And the "gateway" for account "gateway2" is not staked
And the account balance of "gateway2" should be "1000070" uPOKT "more" than before
8 changes: 4 additions & 4 deletions e2e/tests/stake_supplier.feature
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ Feature: Stake Supplier Namespace
Then the user should be able to see standard output containing "txhash:"
And the user should be able to see standard output containing "code: 0"
And the pocketd binary should exit without error
# TODO_TECHDEBT(@red-0ne): Replace these time-based waits with event listening waits
And the user should wait for "5" seconds
And the user should wait for the "supplier" module "StakeSupplier" message to be submitted
And the "supplier" for account "supplier2" is staked with "1000070" uPOKT
And the account balance of "supplier2" should be "1000070" uPOKT "less" than before

Expand All @@ -23,6 +22,7 @@ Feature: Stake Supplier Namespace
Then the user should be able to see standard output containing "txhash:"
And the user should be able to see standard output containing "code: 0"
And the pocketd binary should exit without error
And the user should wait for "5" seconds
And the "supplier" for account "supplier2" is not staked
And the supplier for account "supplier2" is unbonding
When the user waits for "supplier2" unbonding period to finish
Then the "supplier" for account "supplier2" is not staked
And the account balance of "supplier2" should be "1000070" uPOKT "more" than before
3 changes: 3 additions & 0 deletions proto/poktroll/shared/supplier.proto
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,8 @@ message Supplier {
string address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // The Bech32 address of the supplier using cosmos' ScalarDescriptor to ensure deterministic encoding
cosmos.base.v1beta1.Coin stake = 2; // The total amount of uPOKT the supplier has staked
repeated SupplierServiceConfig services = 3; // The service configs this supplier can support
// The session end height at which an actively unbonding supplier unbonds its stake.
// If the supplier did not unstake, this value will be 0.
uint64 unstake_session_end_height = 4;
}

Loading

0 comments on commit 6d466c6

Please sign in to comment.