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

[Tokenomics] SettleSessionAccounting first implementation (emissions=burn) #323

Merged
merged 68 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from 59 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
6f32dac
move protox to the right place
Olshansk Dec 10, 2023
1d4e475
Merge branch 'main' into issues/243/update_tokenomics_module
Olshansk Dec 20, 2023
86cca4f
Fix proto imports
Olshansk Dec 20, 2023
f317d89
Merge branch 'main' into issues/243/update_tokenomics_module
Olshansk Dec 21, 2023
2c44d26
Documented the plan for this PR before I forget
Olshansk Dec 22, 2023
4b1d025
Merge branch 'main' into issues/243/update_tokenomics_module
Olshansk Jan 5, 2024
f2519ea
Merge branch 'main' into issues/243/update_tokenomics_module
Olshansk Jan 5, 2024
c8b4b6b
Merge branch 'main' into issues/243/update_tokenomics_module
Olshansk Jan 8, 2024
6364101
Update deps
Olshansk Jan 8, 2024
9620a24
Unit test for updating tokenomic params succeeds
Olshansk Jan 8, 2024
5b4949d
Added a placeholder for SettleSessionAccounting
Olshansk Jan 8, 2024
565195b
Rename Compute to ComputeUnits
Olshansk Jan 8, 2024
ee71f7d
Remove some unused comments
Olshansk Jan 8, 2024
7fe5ecb
Before scaffold
Olshansk Jan 8, 2024
0079a32
Ran the following command to fill in some missing gaps: ignite scaffo…
Olshansk Jan 10, 2024
581c947
Merge branch 'main' into issues/243/update_tokenomics_module
Olshansk Jan 10, 2024
7939b4c
Incomplete unit tests for parameter update passing
Olshansk Jan 10, 2024
1c32614
Checkpoint for the day
Olshansk Jan 11, 2024
fa80df8
Merge with main
Olshansk Jan 15, 2024
ee787d0
Update /msg_server_update_params_test.go and figurign some stuff out …
Olshansk Jan 15, 2024
4aca865
Unit tests passing
Olshansk Jan 16, 2024
fe9a645
Remove session accounting implementation
Olshansk Jan 16, 2024
4176971
Add session accounting implementation
Olshansk Jan 16, 2024
e32bc93
Completed self review
Olshansk Jan 16, 2024
ebf5a79
Merge branch 'issues/243/update_tokenomics_module' into issues/243/se…
Olshansk Jan 16, 2024
7d7cc8e
Unit tests in progress
Olshansk Jan 17, 2024
398e4d6
Update x/tokenomics/client/cli/tx_update_params.go
Olshansk Jan 18, 2024
cab8bee
change k8s DNS endpoint for celestia secret (#314)
okdas Jan 16, 2024
d95e1f7
[LocalNet] Add sequencer block persistence (#277)
okdas Jan 17, 2024
fd9662c
[Config, Docs] Add supplier staking config documentation (#318)
red-0ne Jan 18, 2024
4eeda85
[Docs] Add AppGateServer config documentation (#317)
red-0ne Jan 18, 2024
6d566eb
[Config, Docs] Add gateway staking config documentation (#321)
red-0ne Jan 18, 2024
eda0816
[Config, Docs] Add application staking config documentation (#320)
red-0ne Jan 18, 2024
629bf6c
Fixed some tests
Olshansk Jan 18, 2024
9a79163
Update proto/pocket/tokenomics/query.proto
Olshansk Jan 19, 2024
fa45776
Update Makefile
Olshansk Jan 19, 2024
f149a74
Update x/tokenomics/client/cli/tx_update_params.go
Olshansk Jan 19, 2024
4b8a5b5
Update x/tokenomics/keeper/keeper.go
Olshansk Jan 19, 2024
de19c54
Reply to some review comments
Olshansk Jan 19, 2024
1871007
Ran make go_imports and make go_lint
Olshansk Jan 19, 2024
526d90e
Merge with main
Olshansk Jan 19, 2024
bdbbcc8
Start multi-lining
Olshansk Jan 19, 2024
d1fcf9b
Renamed some tokenomics errors
Olshansk Jan 19, 2024
23fb106
Reply to PR review comments
Olshansk Jan 19, 2024
7972eef
foundation/pnf
Olshansk Jan 19, 2024
3f92915
Ran make go_imports and make go_lint
Olshansk Jan 19, 2024
d708df0
Fix outdated test
Olshansk Jan 19, 2024
90b5255
Merge with main
Olshansk Jan 19, 2024
9faf89c
Fix log usage
Olshansk Jan 19, 2024
05a8924
Update Makefile
Olshansk Jan 22, 2024
70eea62
fix: add yarn.lock (#334)
bryanchriswhite Jan 22, 2024
4b92864
[Off-chain] Simplify `TxClient` with `EventsQueryClient` (#330)
bryanchriswhite Jan 22, 2024
3e447db
Merge branch 'main' into issues/243/update_tokenomics_module
Olshansk Jan 22, 2024
3b74750
Merge with issues/243/update_tokenomics_module
Olshansk Jan 22, 2024
e980a64
Added x/session/types/session_header_test.go
Olshansk Jan 22, 2024
691f236
Unit tests passing
Olshansk Jan 23, 2024
a92ce85
Merge with master - not compiling yet
Olshansk Jan 24, 2024
db43050
Merge branch 'main' into issues/243/settle_session_accounting_impleme…
Olshansk Jan 24, 2024
5b90116
Reply to some review comments
Olshansk Jan 24, 2024
1d11fa2
Make go_test works again
Olshansk Jan 24, 2024
abe5173
Enforce smstRootSize
Olshansk Jan 24, 2024
aab2413
Merge branch 'main' into issues/243/settle_session_accounting_impleme…
Olshansk Jan 25, 2024
e1c8913
Update go.mod
Olshansk Jan 25, 2024
3082237
Merge branch 'main' into issues/243/settle_session_accounting_impleme…
Olshansk Jan 31, 2024
40a21f2
Added a WIP E2E test
Olshansk Feb 1, 2024
31aa811
Merge branch 'main' into issues/243/settle_session_accounting_impleme…
Olshansk Feb 1, 2024
ba4d76b
Update a couple comments
Olshansk Feb 1, 2024
6697a09
Merge with main and reply to some comments
Olshansk Feb 2, 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
7 changes: 5 additions & 2 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"os"
"path/filepath"

// this line is used by starport scaffolding # stargate/app/moduleImport

autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1"
dbm "github.com/cometbft/cometbft-db"
Expand Down Expand Up @@ -108,8 +110,6 @@ import (
ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper"
solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine"
ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint"
"github.com/spf13/cast"

appparams "github.com/pokt-network/poktroll/app/params"
"github.com/pokt-network/poktroll/docs"
applicationmodule "github.com/pokt-network/poktroll/x/application"
Expand All @@ -133,6 +133,7 @@ import (
tokenomicsmodule "github.com/pokt-network/poktroll/x/tokenomics"
tokenomicsmodulekeeper "github.com/pokt-network/poktroll/x/tokenomics/keeper"
tokenomicsmoduletypes "github.com/pokt-network/poktroll/x/tokenomics/types"
"github.com/spf13/cast"
)

const (
Expand Down Expand Up @@ -651,6 +652,8 @@ func New(
keys[tokenomicsmoduletypes.MemStoreKey],
app.GetSubspace(tokenomicsmoduletypes.ModuleName),
app.BankKeeper,
app.ApplicationKeeper,
app.SupplierKeeper,
authority,
)
tokenomicsModule := tokenomicsmodule.NewAppModule(appCodec, app.TokenomicsKeeper, app.AccountKeeper, app.BankKeeper)
Expand Down
7 changes: 6 additions & 1 deletion pkg/sdk/errors.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package sdk

import sdkerrors "cosmossdk.io/errors"
import (
sdkerrors "cosmossdk.io/errors"
)

// TODO_TECHDEBT: Do a source code wise find-replace using regex pattern match
// of `sdkerrors\.Wrapf\(([a-zA-Z]+), ` with `$1.Wrapf(`

var (
codespace = "poktrollsdk"
Expand Down
68 changes: 60 additions & 8 deletions testutil/keeper/tokenomics.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,76 @@ import (
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"

"github.com/pokt-network/poktroll/cmd/pocketd/cmd"
"github.com/pokt-network/poktroll/testutil/sample"
mocks "github.com/pokt-network/poktroll/testutil/tokenomics/mocks"
apptypes "github.com/pokt-network/poktroll/x/application/types"
sharedtypes "github.com/pokt-network/poktroll/x/shared/types"
suppliertypes "github.com/pokt-network/poktroll/x/supplier/types"
"github.com/pokt-network/poktroll/x/tokenomics/keeper"
"github.com/pokt-network/poktroll/x/tokenomics/types"
)

func TokenomicsKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) {
func init() {
cmd.InitSDKConfig()
}

func TokenomicsKeeper(t testing.TB) (
k *keeper.Keeper, s sdk.Context,
appAddr, supplierAddr string,
) {
storeKey := sdk.NewKVStoreKey(types.StoreKey)
memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey)

// Initialize the in-memory tendermint database
db := tmdb.NewMemDB()
stateStore := store.NewCommitMultiStore(db)
stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db)
stateStore.MountStoreWithDB(memStoreKey, storetypes.StoreTypeMemory, nil)
require.NoError(t, stateStore.LoadLatestVersion())

// Initialize the codec and other necessary components
registry := codectypes.NewInterfaceRegistry()
cdc := codec.NewProtoCodec(registry)
ctrl := gomock.NewController(t)

// The on-chain governance address
authority := authtypes.NewModuleAddress("gov").String()

ctrl := gomock.NewController(t)
// Prepare the test application
Copy link
Contributor

Choose a reason for hiding this comment

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

I think referencing:

So you can control applications/suppliers in tests and modify the methods with custom DoAndReturn methods will help you better catch some errors. Maybe not applicable here, just a thought.

Copy link
Member Author

Choose a reason for hiding this comment

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

tl;dr Thought about it but do not believe it is worth the tradeoff in this chase.

cc @bryanchriswhite for additional thoughts or pushback.


I can steelman both sides here.

Firstly, I always bias to writing less code wherever possible: less code => less bugs => less to maintain => less to learn => more time on other things.

With that said, Complex state management in mocks is nice when you're testing some business logic, but in this specific instance, I feel that:

  1. I would spend a lot of time implementing this business logic, which will be quickly deprecated by in-memory testing network
  2. A single e2e test might provide just as much benefit
  3. I documented the unit tests (in x/tokenomics/keeper/settle_session_accounting_test.go) that I want to add once we have (1)
  4. There is the risk of that logic having bugs too.

It's a very delicate balance and don't think there's a definitive answer to when to do which one.

application := apptypes.Application{
Address: sample.AccAddress(),
Stake: &sdk.Coin{Denom: "upokt", Amount: sdk.NewInt(100000)},
}

// Prepare the test supplier
supplier := sharedtypes.Supplier{
Address: sample.AccAddress(),
Stake: &sdk.Coin{Denom: "upokt", Amount: sdk.NewInt(100000)},
}

// Mock the application keeper
mockApplicationKeeper := mocks.NewMockApplicationKeeper(ctrl)
mockApplicationKeeper.EXPECT().
GetApplication(gomock.Any(), gomock.Eq(application.Address)).
Return(application, true).
AnyTimes()
mockApplicationKeeper.EXPECT().
GetApplication(gomock.Any(), gomock.Not(application.Address)).
Return(apptypes.Application{}, false).
AnyTimes()
mockApplicationKeeper.EXPECT().
SetApplication(gomock.Any(), gomock.Any()).
AnyTimes()
Olshansk marked this conversation as resolved.
Show resolved Hide resolved

// Mock the supplier keeper
mockSupplierKeeper := mocks.NewMockSupplierKeeper(ctrl)
mockSupplierKeeper.EXPECT().
GetSupplier(gomock.Any(), supplier.Address).
Return(supplier, true).
AnyTimes()

// Mock the bank keeper
mockBankKeeper := mocks.NewMockBankKeeper(ctrl)
mockBankKeeper.EXPECT().
MintCoins(gomock.Any(), gomock.Any(), gomock.Any()).
Expand All @@ -45,36 +94,39 @@ func TokenomicsKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) {
BurnCoins(gomock.Any(), gomock.Any(), gomock.Any()).
AnyTimes()
mockBankKeeper.EXPECT().
SendCoinsFromModuleToAccount(gomock.Any(), gomock.Any(), types.ModuleName, gomock.Any()).
SendCoinsFromModuleToAccount(gomock.Any(), suppliertypes.ModuleName, gomock.Any(), gomock.Any()).
AnyTimes()
mockBankKeeper.EXPECT().
SendCoinsFromModuleToModule(gomock.Any(), types.ModuleName, gomock.Any(), gomock.Any()).
SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), apptypes.ModuleName, gomock.Any()).
AnyTimes()
mockBankKeeper.EXPECT().
SendCoinsFromAccountToModule(gomock.Any(), types.ModuleName, gomock.Any(), gomock.Any()).
UndelegateCoinsFromModuleToAccount(gomock.Any(), apptypes.ModuleName, gomock.Any(), gomock.Any()).
AnyTimes()

// Initialize the tokenomics keeper
paramsSubspace := typesparams.NewSubspace(cdc,
types.Amino,
storeKey,
memStoreKey,
"TokenomicsParams",
)
k := keeper.NewKeeper(
tokenomicsKeeper := keeper.NewKeeper(
cdc,
storeKey,
memStoreKey,
paramsSubspace,

mockBankKeeper,
mockApplicationKeeper,
mockSupplierKeeper,

authority,
)

ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger())

// Initialize params
k.SetParams(ctx, types.DefaultParams())
tokenomicsKeeper.SetParams(ctx, types.DefaultParams())

return k, ctx
return tokenomicsKeeper, ctx, application.Address, supplier.Address
}
1 change: 1 addition & 0 deletions x/session/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ var (
ErrSessionInvalidAppAddress = sdkerrors.Register(ModuleName, 5, "invalid application address for session")
ErrSessionInvalidService = sdkerrors.Register(ModuleName, 6, "invalid service in session")
ErrSessionInvalidBlockHeight = sdkerrors.Register(ModuleName, 7, "invalid block height for session")
ErrSessionInvalidSessionId = sdkerrors.Register(ModuleName, 8, "invalid sessionId")
)
7 changes: 3 additions & 4 deletions x/session/types/query_get_session_request.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package types

import (
sdkerrors "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"

sharedhelpers "github.com/pokt-network/poktroll/x/shared/helpers"
Expand All @@ -24,17 +23,17 @@ func NewQueryGetSessionRequest(appAddress, serviceId string, blockHeight int64)
func (query *QueryGetSessionRequest) ValidateBasic() error {
// Validate the application address
if _, err := sdk.AccAddressFromBech32(query.ApplicationAddress); err != nil {
return sdkerrors.Wrapf(ErrSessionInvalidAppAddress, "invalid app address for session being retrieved %s; (%v)", query.ApplicationAddress, err)
return ErrSessionInvalidAppAddress.Wrapf("invalid app address for session being retrieved %s; (%v)", query.ApplicationAddress, err)
}

// Validate the Service ID
if !sharedhelpers.IsValidService(query.Service) {
return sdkerrors.Wrapf(ErrSessionInvalidService, "invalid service for session being retrieved %s;", query.Service)
return ErrSessionInvalidService.Wrapf("invalid service for session being retrieved %s;", query.Service)
}

// Validate the height for which a session is being retrieved
if query.BlockHeight < 0 { // Note that `0` defaults to the latest height rather than genesis
return sdkerrors.Wrapf(ErrSessionInvalidBlockHeight, "invalid block height for session being retrieved %d;", query.BlockHeight)
return ErrSessionInvalidBlockHeight.Wrapf("invalid block height for session being retrieved %d;", query.BlockHeight)
}
return nil
}
34 changes: 34 additions & 0 deletions x/session/types/session_header.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package types

import (
sdkerrors "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
)

// TODO_TECHDEBT: Make sure this is used everywhere we validate components
// of the session header.
func (sh *SessionHeader) ValidateBasic() error {
// Validate the application address
if _, err := sdk.AccAddressFromBech32(sh.ApplicationAddress); err != nil {
return sdkerrors.Wrapf(ErrSessionInvalidAppAddress, "invalid application address: %s; (%v)", sh.ApplicationAddress, err)
Olshansk marked this conversation as resolved.
Show resolved Hide resolved
}

// Validate the session ID
// TODO_TECHDEBT: Introduce a `SessionId#ValidateBasic` method.
if sh.SessionId == "" {
return sdkerrors.Wrapf(ErrSessionInvalidSessionId, "invalid session ID: %s", sh.SessionId)
}

// Validate the service
// TODO_TECHDEBT: Introduce a `Service#ValidateBasic` method.
if sh.Service == nil {
return sdkerrors.Wrapf(ErrSessionInvalidService, "invalid service: %s", sh.Service)
}

// Check if session end height is greater than session start height
if sh.SessionEndBlockHeight <= sh.SessionStartBlockHeight {
return sdkerrors.Wrapf(ErrSessionInvalidBlockHeight, "session end block height cannot be less than or equal to session start block height")
}

return nil
}
86 changes: 86 additions & 0 deletions x/session/types/session_header_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package types_test

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/pokt-network/poktroll/testutil/sample"
"github.com/pokt-network/poktroll/x/session/types"
sharedtypes "github.com/pokt-network/poktroll/x/shared/types"
)

func TestSessionHeader_ValidateBasic(t *testing.T) {
tests := []struct {
desc string
sh types.SessionHeader
err error
}{
{
desc: "invalid - invalid application address",
sh: types.SessionHeader{
ApplicationAddress: "invalid_address",
SessionId: "valid_session_id",
Service: &sharedtypes.Service{},
SessionStartBlockHeight: 100,
SessionEndBlockHeight: 101,
},
err: types.ErrSessionInvalidAppAddress,
},
{
desc: "invalid - empty session id",
sh: types.SessionHeader{
ApplicationAddress: sample.AccAddress(),
SessionId: "",
Service: &sharedtypes.Service{},
SessionStartBlockHeight: 100,
SessionEndBlockHeight: 101,
},
err: types.ErrSessionInvalidSessionId,
},
{
desc: "invalid - nil service",
sh: types.SessionHeader{
ApplicationAddress: sample.AccAddress(),
SessionId: "valid_session_id",
Service: nil,
SessionStartBlockHeight: 100,
SessionEndBlockHeight: 101,
},
err: types.ErrSessionInvalidService,
},
{
desc: "invalid - start block height greater than end block height",
sh: types.SessionHeader{
ApplicationAddress: sample.AccAddress(),
SessionId: "valid_session_id",
Service: &sharedtypes.Service{},
SessionStartBlockHeight: 100,
SessionEndBlockHeight: 99,
},
err: types.ErrSessionInvalidBlockHeight,
},
{
desc: "valid",
sh: types.SessionHeader{
ApplicationAddress: sample.AccAddress(),
SessionId: "valid_session_id",
Service: &sharedtypes.Service{},
SessionStartBlockHeight: 100,
SessionEndBlockHeight: 101,
},
err: nil,
},
}

for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
err := tt.sh.ValidateBasic()
if tt.err != nil {
require.ErrorIs(t, err, tt.err)
} else {
require.NoError(t, err)
}
})
}
}
2 changes: 1 addition & 1 deletion x/tokenomics/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func TestGenesis(t *testing.T) {
// this line is used by starport scaffolding # genesis/test/state
}

k, ctx := keepertest.TokenomicsKeeper(t)
k, ctx, _, _ := keepertest.TokenomicsKeeper(t)
tokenomics.InitGenesis(ctx, *k, genesisState)
got := tokenomics.ExportGenesis(ctx, *k)
require.NotNil(t, got)
Expand Down
10 changes: 9 additions & 1 deletion x/tokenomics/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ type Keeper struct {
paramstore paramtypes.Subspace

// keeper dependencies
bankKeeper types.BankKeeper
appKeeper types.ApplicationKeeper
supplierKeeper types.SupplierKeeper
bankKeeper types.BankKeeper

// the address capable of executing a MsgUpdateParams message. Typically, this
// should be the x/gov module account.
Expand All @@ -39,6 +41,8 @@ func NewKeeper(

// keeper dependencies
bankKeeper types.BankKeeper,
appKeeper types.ApplicationKeeper,
supplierKeeper types.SupplierKeeper,

authority string,
) *Keeper {
Expand All @@ -53,6 +57,10 @@ func NewKeeper(
memKey: memKey,
paramstore: ps,

bankKeeper: bankKeeper,
appKeeper: appKeeper,
supplierKeeper: supplierKeeper,

authority: authority,
}
}
Expand Down
2 changes: 1 addition & 1 deletion x/tokenomics/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

func setupMsgServer(t testing.TB) (types.MsgServer, context.Context) {
k, ctx := testkeeper.TokenomicsKeeper(t)
k, ctx, _, _ := testkeeper.TokenomicsKeeper(t)
return keeper.NewMsgServerImpl(*k), sdk.WrapSDKContext(ctx)
}

Expand Down
4 changes: 2 additions & 2 deletions x/tokenomics/keeper/msg_server_update_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (k Keeper) SetParams(ctx sdk.Context, params types.Params) {
}

// ComputeUnitsToTokensMultiplier returns the ComputeUnitsToTokensMultiplier param
func (k Keeper) ComputeUnitsToTokensMultiplier(ctx sdk.Context) (res uint64) {
k.paramstore.Get(ctx, types.KeyComputeUnitsToTokensMultiplier, &res)
func (k Keeper) ComputeUnitsToTokensMultiplier(ctx sdk.Context) (param uint64) {
k.paramstore.Get(ctx, types.KeyComputeUnitsToTokensMultiplier, &param)
return
}
Loading
Loading