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/payable proof submission #780

Merged
merged 11 commits into from
Sep 6, 2024
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))
red-0ne marked this conversation as resolved.
Show resolved Hide resolved

// 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" {
Copy link
Member

Choose a reason for hiding this comment

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

I see what you're doing here, but this is a "hidden side effect".

I think you should just either:

  1. Add a step call EnsureBalanceIsHighEnoughForProofSubmission
    OR
  2. Update the default configs of LocalNet to give everyone high enough balances that this doesn't matter

My preference is (2).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is actually not about having enough funds.

It is to make the step Then the account balance of "supplier1" should be "420" uPOKT "more" than before succeed without making it more complicated

  • fee > reward -> lower balance
  • proof not required -> no fee
  • step needing to know about previous ones
  • ...

There's actually an elegant solution without side effect.
Take a snapshot of the balance after the proof submission.

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
Loading