Skip to content

Commit

Permalink
Feat/payable proof submission (#780)
Browse files Browse the repository at this point in the history
## Summary

This PR implements payable proof submission given the proof submission
governance param.

This is a follow-up feature PR to #779 which adds the proof submission
governance param.

## Issue

Proof messages take up significant block space. We need to deter
submitting non-required ones by making proof submission payable by a
governance adjusted parameter.

- #758 

## Type of change

Select one or more:

- [x] New feature, functionality or library
- [ ] Bug fix
- [ ] Code health or cleanup
- [ ] Documentation
- [ ] Other (specify)

## Testing

- [ ] **Documentation**: `make docusaurus_start`; only needed if you
make doc changes
- [x] **Unit Tests**: `make go_develop_and_test`
- [x] **LocalNet E2E Tests**: `make test_e2e`
- [ ] **DevNet E2E Tests**: Add the `devnet-test-e2e` label to the PR.

## Sanity Checklist

- [x] I have tested my changes using the available tooling
- [x] I have commented my code
- [x] I have performed a self-review of my own code; both comments &
source code
- [ ] I create and reference any new tickets, if applicable
- [x] I have left TODOs throughout the codebase, if applicable
  • Loading branch information
red-0ne authored Sep 6, 2024
1 parent 7bca3d1 commit 5ec51be
Show file tree
Hide file tree
Showing 13 changed files with 223 additions and 39 deletions.
1 change: 1 addition & 0 deletions app/app_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ var (
{Account: suppliermoduletypes.ModuleName, Permissions: []string{authtypes.Minter, authtypes.Burner, authtypes.Staking}},
{Account: sessionmoduletypes.ModuleName, Permissions: []string{authtypes.Minter, authtypes.Burner, authtypes.Staking}},
{Account: tokenomicsmoduletypes.ModuleName, Permissions: []string{authtypes.Minter, authtypes.Burner, authtypes.Staking}},
{Account: proofmoduletypes.ModuleName, Permissions: []string{authtypes.Minter, authtypes.Burner, authtypes.Staking}},
// this line is used by starport scaffolding # stargate/app/maccPerms }
}

Expand Down
4 changes: 2 additions & 2 deletions e2e/tests/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ func (s *suite) TheStakeOfShouldBeUpoktThanBefore(actorType string, accName stri
s.validateAmountChange(prevStake, currStake, expectedStakeChange, accName, condition, "stake")
}

func (s *suite) TheAccountBalanceOfShouldBeUpoktThanBefore(accName string, expectedStakeChange int64, condition string) {
func (s *suite) TheAccountBalanceOfShouldBeUpoktThanBefore(accName string, expectedBalanceChange int64, condition string) {
// Get previous balance
balanceKey := accBalanceKey(accName)
prevBalanceAny, ok := s.scenarioState[balanceKey]
Expand All @@ -235,7 +235,7 @@ func (s *suite) TheAccountBalanceOfShouldBeUpoktThanBefore(accName string, expec
s.scenarioState[balanceKey] = currBalance // save the balance for later

// Validate the change in stake
s.validateAmountChange(prevBalance, currBalance, expectedStakeChange, accName, condition, "balance")
s.validateAmountChange(prevBalance, currBalance, expectedBalanceChange, accName, condition, "balance")
}

func (s *suite) TheUserShouldWaitForSeconds(dur int64) {
Expand Down
32 changes: 30 additions & 2 deletions e2e/tests/session_steps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package e2e
import (
"context"
"fmt"
"slices"
"strconv"
"time"

Expand Down Expand Up @@ -42,7 +43,22 @@ const (
)

func (s *suite) TheUserShouldWaitForTheModuleMessageToBeSubmitted(module, msgType string) {
s.waitForTxResultEvent(newEventMsgTypeMatchFn(module, msgType))
event := s.waitForTxResultEvent(newEventMsgTypeMatchFn(module, msgType))

// If the message type is "SubmitProof", save the supplier balance
// so that next steps that assert on supplier rewards can do it without having
// the proof submission fee skewing the results.
if msgType == "SubmitProof" {
supplierOperatorAddress := getMsgSubmitProofSenderAddress(event)
require.NotEmpty(s, supplierOperatorAddress)

supplierAccName := accAddrToNameMap[supplierOperatorAddress]

// Get current balance
balanceKey := accBalanceKey(supplierAccName)
currBalance := s.getAccBalance(supplierAccName)
s.scenarioState[balanceKey] = currBalance // save the balance for later
}
}

func (s *suite) TheUserShouldWaitForTheModuleTxEventToBeBroadcast(module, eventType string) {
Expand Down Expand Up @@ -173,7 +189,7 @@ func (s *suite) sendRelaysForSession(
}

// waitForTxResultEvent waits for an event to be observed which has the given message action.
func (s *suite) waitForTxResultEvent(eventIsMatch func(*abci.Event) bool) {
func (s *suite) waitForTxResultEvent(eventIsMatch func(*abci.Event) bool) (matchedEvent *abci.Event) {
ctx, cancel := context.WithCancel(s.ctx)

// For each observed event, **asynchronously** check if it contains the given action.
Expand All @@ -188,6 +204,7 @@ func (s *suite) waitForTxResultEvent(eventIsMatch func(*abci.Event) bool) {
// and compare its value to that of the action provided.
for _, event := range txResult.Result.Events {
if eventIsMatch(&event) {
matchedEvent = &event
cancel()
}
}
Expand All @@ -200,6 +217,8 @@ func (s *suite) waitForTxResultEvent(eventIsMatch func(*abci.Event) bool) {
case <-ctx.Done():
s.Log("Success; message detected before timeout.")
}

return matchedEvent
}

// waitForNewBlockEvent waits for an event to be observed whose type and data
Expand Down Expand Up @@ -336,3 +355,12 @@ func combineEventMatchFns(fns ...func(*abci.Event) bool) func(*abci.Event) bool
return true
}
}

// getMsgSubmitProofSenderAddress returns the sender address from the given event.
func getMsgSubmitProofSenderAddress(event *abci.Event) string {
senderAttrIdx := slices.IndexFunc(event.Attributes, func(attr abci.EventAttribute) bool {
return attr.Key == "sender"
})

return event.Attributes[senderAttrIdx].Value
}
27 changes: 27 additions & 0 deletions testutil/integration/app.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package integration

import (
"context"
"testing"
"time"

Expand Down Expand Up @@ -38,6 +39,7 @@ import (
"github.com/stretchr/testify/require"

"github.com/pokt-network/poktroll/app"
"github.com/pokt-network/poktroll/app/volatile"
"github.com/pokt-network/poktroll/pkg/crypto"
"github.com/pokt-network/poktroll/pkg/crypto/rings"
"github.com/pokt-network/poktroll/pkg/polylog/polyzero"
Expand Down Expand Up @@ -246,6 +248,7 @@ func NewCompleteIntegrationApp(t *testing.T) *App {
sessiontypes.ModuleName: {authtypes.Minter, authtypes.Burner},
apptypes.ModuleName: {authtypes.Minter, authtypes.Burner, authtypes.Staking},
suppliertypes.ModuleName: {authtypes.Minter, authtypes.Burner, authtypes.Staking},
prooftypes.ModuleName: {authtypes.Minter, authtypes.Burner},
}

// Prepare the account keeper and module
Expand Down Expand Up @@ -390,6 +393,7 @@ func NewCompleteIntegrationApp(t *testing.T) *App {
logger,
authority.String(),

bankKeeper,
sessionKeeper,
applicationKeeper,
accountKeeper,
Expand All @@ -400,6 +404,7 @@ func NewCompleteIntegrationApp(t *testing.T) *App {
cdc,
proofKeeper,
accountKeeper,
bankKeeper,
)

// Prepare the tokenomics keeper and module
Expand Down Expand Up @@ -593,6 +598,9 @@ func NewCompleteIntegrationApp(t *testing.T) *App {
err = bankKeeper.MintCoins(integrationApp.sdkCtx, apptypes.ModuleName, moduleBaseMint)
require.NoError(t, err)

// Fund the supplier operator account to be able to submit proofs
fundAccount(t, integrationApp.sdkCtx, bankKeeper, supplierOperatorAddr)

// Commit all the changes above by committing, finalizing and moving
// to the next block.
integrationApp.NextBlock(t)
Expand Down Expand Up @@ -762,3 +770,22 @@ func CreateMultiStore(keys map[string]*storetypes.KVStoreKey, logger log.Logger)
_ = cms.LoadLatestVersion()
return cms
}

func fundAccount(
t *testing.T,
ctx context.Context,
bankKeeper bankkeeper.Keeper,
supplierOperatorAddr sdk.AccAddress,
) {

fundingCoins := types.NewCoins(types.NewCoin(volatile.DenomuPOKT, math.NewInt(100000000)))

err := bankKeeper.MintCoins(ctx, banktypes.ModuleName, fundingCoins)
require.NoError(t, err)

err = bankKeeper.SendCoinsFromModuleToAccount(ctx, banktypes.ModuleName, supplierOperatorAddr, fundingCoins)
require.NoError(t, err)

coin := bankKeeper.SpendableCoin(ctx, supplierOperatorAddr, volatile.DenomuPOKT)
require.Equal(t, coin.Amount, math.NewInt(100000000))
}
63 changes: 49 additions & 14 deletions testutil/keeper/proof.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

"cosmossdk.io/log"
"cosmossdk.io/math"
"cosmossdk.io/store"
"cosmossdk.io/store/metrics"
storetypes "cosmossdk.io/store/types"
Expand All @@ -19,18 +20,15 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"

"github.com/pokt-network/poktroll/app"
applicationmocks "github.com/pokt-network/poktroll/testutil/application/mocks"
gatewaymocks "github.com/pokt-network/poktroll/testutil/gateway/mocks"
"github.com/pokt-network/poktroll/testutil/proof/mocks"
servicemocks "github.com/pokt-network/poktroll/testutil/service/mocks"
sessionmocks "github.com/pokt-network/poktroll/testutil/session/mocks"
suppliermocks "github.com/pokt-network/poktroll/testutil/supplier/mocks"
appkeeper "github.com/pokt-network/poktroll/x/application/keeper"
apptypes "github.com/pokt-network/poktroll/x/application/types"
gatewaykeeper "github.com/pokt-network/poktroll/x/gateway/keeper"
Expand All @@ -56,6 +54,7 @@ import (
// MUST be specified (e.g. `keepers.AccountKeeper#SetParams()`).
type ProofModuleKeepers struct {
*keeper.Keeper
prooftypes.BankKeeper
prooftypes.SessionKeeper
prooftypes.SupplierKeeper
prooftypes.ApplicationKeeper
Expand Down Expand Up @@ -86,6 +85,20 @@ func ProofKeeper(t testing.TB) (keeper.Keeper, context.Context) {
authority := authtypes.NewModuleAddress(govtypes.ModuleName)

ctrl := gomock.NewController(t)
mockBankKeeper := mocks.NewMockBankKeeper(ctrl)
mockBankKeeper.EXPECT().
SpendableCoins(gomock.Any(), gomock.Any()).
DoAndReturn(
func(ctx context.Context, addr sdk.AccAddress) sdk.Coins {
mapMu.RLock()
defer mapMu.RUnlock()
if coins, ok := mapAccAddrCoins[addr.String()]; ok {
return coins
}
return sdk.Coins{}
},
).AnyTimes()

mockSessionKeeper := mocks.NewMockSessionKeeper(ctrl)
mockAppKeeper := mocks.NewMockApplicationKeeper(ctrl)
mockAccountKeeper := mocks.NewMockAccountKeeper(ctrl)
Expand All @@ -97,6 +110,7 @@ func ProofKeeper(t testing.TB) (keeper.Keeper, context.Context) {
runtime.NewKVStoreService(storeKey),
log.NewNopLogger(),
authority.String(),
mockBankKeeper,
mockSessionKeeper,
mockAppKeeper,
mockAccountKeeper,
Expand All @@ -118,6 +132,7 @@ func NewProofModuleKeepers(t testing.TB, opts ...ProofKeepersOpt) (_ *ProofModul
// Collect store keys for all keepers which be constructed & interact with the state store.
keys := storetypes.NewKVStoreKeys(
types.StoreKey,
banktypes.StoreKey,
sessiontypes.StoreKey,
suppliertypes.StoreKey,
apptypes.StoreKey,
Expand All @@ -140,20 +155,34 @@ func NewProofModuleKeepers(t testing.TB, opts ...ProofKeepersOpt) (_ *ProofModul
cdc := codec.NewProtoCodec(registry)
authority := authtypes.NewModuleAddress(govtypes.ModuleName)

// Mock the bank keeper.
ctrl := gomock.NewController(t)

// Construct a real account keeper so that public keys can be queried.
accountKeeper := authkeeper.NewAccountKeeper(
cdc,
runtime.NewKVStoreService(keys[authtypes.StoreKey]),
authtypes.ProtoBaseAccount,
map[string][]string{minttypes.ModuleName: {authtypes.Minter}},
map[string][]string{
minttypes.ModuleName: {authtypes.Minter},
suppliertypes.ModuleName: {authtypes.Minter, authtypes.Burner, authtypes.Staking},
prooftypes.ModuleName: {authtypes.Minter, authtypes.Burner},
},
addresscodec.NewBech32Codec(app.AccountAddressPrefix),
app.AccountAddressPrefix,
authority.String(),
)

// Prepare the bank keeper
blockedAddresses := map[string]bool{
accountKeeper.GetAuthority(): false,
}
bankKeeper := bankkeeper.NewBaseKeeper(
cdc,
runtime.NewKVStoreService(keys[banktypes.StoreKey]),
accountKeeper,
blockedAddresses,
authority.String(),
logger,
)

// Construct a real shared keeper.
sharedKeeper := sharedkeeper.NewKeeper(
cdc,
Expand All @@ -169,7 +198,7 @@ func NewProofModuleKeepers(t testing.TB, opts ...ProofKeepersOpt) (_ *ProofModul
runtime.NewKVStoreService(keys[gatewaytypes.StoreKey]),
logger,
authority.String(),
gatewaymocks.NewMockBankKeeper(ctrl),
bankKeeper,
)
require.NoError(t, gatewayKeeper.SetParams(ctx, gatewaytypes.DefaultParams()))

Expand All @@ -179,7 +208,7 @@ func NewProofModuleKeepers(t testing.TB, opts ...ProofKeepersOpt) (_ *ProofModul
runtime.NewKVStoreService(keys[apptypes.StoreKey]),
logger,
authority.String(),
applicationmocks.NewMockBankKeeper(ctrl),
bankKeeper,
accountKeeper,
gatewayKeeper,
sharedKeeper,
Expand All @@ -192,7 +221,7 @@ func NewProofModuleKeepers(t testing.TB, opts ...ProofKeepersOpt) (_ *ProofModul
runtime.NewKVStoreService(keys[types.StoreKey]),
log.NewNopLogger(),
authority.String(),
servicemocks.NewMockBankKeeper(ctrl),
bankKeeper,
)

// Construct a real supplier keeper to add suppliers to sessions.
Expand All @@ -201,7 +230,7 @@ func NewProofModuleKeepers(t testing.TB, opts ...ProofKeepersOpt) (_ *ProofModul
runtime.NewKVStoreService(keys[suppliertypes.StoreKey]),
log.NewNopLogger(),
authority.String(),
suppliermocks.NewMockBankKeeper(ctrl),
bankKeeper,
sharedKeeper,
serviceKeeper,
)
Expand All @@ -214,7 +243,7 @@ func NewProofModuleKeepers(t testing.TB, opts ...ProofKeepersOpt) (_ *ProofModul
log.NewNopLogger(),
authority.String(),
accountKeeper,
sessionmocks.NewMockBankKeeper(ctrl),
bankKeeper,
appKeeper,
supplierKeeper,
sharedKeeper,
Expand All @@ -227,6 +256,7 @@ func NewProofModuleKeepers(t testing.TB, opts ...ProofKeepersOpt) (_ *ProofModul
runtime.NewKVStoreService(keys[types.StoreKey]),
log.NewNopLogger(),
authority.String(),
bankKeeper,
sessionKeeper,
appKeeper,
accountKeeper,
Expand All @@ -237,6 +267,7 @@ func NewProofModuleKeepers(t testing.TB, opts ...ProofKeepersOpt) (_ *ProofModul

keepers := &ProofModuleKeepers{
Keeper: &proofKeeper,
BankKeeper: &bankKeeper,
SessionKeeper: &sessionKeeper,
SupplierKeeper: &supplierKeeper,
ApplicationKeeper: &appKeeper,
Expand All @@ -247,6 +278,10 @@ func NewProofModuleKeepers(t testing.TB, opts ...ProofKeepersOpt) (_ *ProofModul
Codec: cdc,
}

moduleBaseMint := sdk.NewCoins(sdk.NewCoin("upokt", math.NewInt(690000000000000042)))
err := bankKeeper.MintCoins(ctx, suppliertypes.ModuleName, moduleBaseMint)
require.NoError(t, err)

// Apply any options to update the keepers or context prior to returning them.
for _, opt := range opts {
ctx = opt(ctx, keepers)
Expand Down
1 change: 1 addition & 0 deletions testutil/keeper/tokenomics.go
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ func NewTokenomicsModuleKeepers(
runtime.NewKVStoreService(keys[prooftypes.StoreKey]),
logger,
authority.String(),
bankKeeper,
sessionKeeper,
appKeeper,
accountKeeper,
Expand Down
3 changes: 3 additions & 0 deletions x/proof/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type (
// should be the x/gov module account.
authority string

bankKeeper types.BankKeeper
sessionKeeper types.SessionKeeper
applicationKeeper types.ApplicationKeeper
accountKeeper types.AccountKeeper
Expand All @@ -46,6 +47,7 @@ func NewKeeper(
logger log.Logger,
authority string,

bankKeeper types.BankKeeper,
sessionKeeper types.SessionKeeper,
applicationKeeper types.ApplicationKeeper,
accountKeeper types.AccountKeeper,
Expand Down Expand Up @@ -89,6 +91,7 @@ func NewKeeper(
authority: authority,
logger: logger,

bankKeeper: bankKeeper,
sessionKeeper: sessionKeeper,
applicationKeeper: applicationKeeper,
accountKeeper: accountKeeper,
Expand Down
Loading

0 comments on commit 5ec51be

Please sign in to comment.