Skip to content

Commit

Permalink
[Relay Mining] Foundation for integration test helpers + start integr…
Browse files Browse the repository at this point in the history
…ating Relay Mining into EndBlocker (#571)

**Core changes:**
- Calling `UpdateRelayMiningDifficulty` in the `tokenomics` EndBlockers
- Introduce the infra & helpers for integration tests to be used heavily in the next PRs
- Capture & return a `ServiceToRelayCount` map when settling claims

**Misc changes:**
- Started moving some fixture generation helpers into a shared package
- Minor Makefile cleanup
- Reoder some imports
- Rename s/errorsmod/sdkerrors

**Up next:**
- Update SMT to store the number of leaves/relays (not just compute units)
- Full integration tests + E2E tests
- Emit events
- Update our grafana dashhboards to see how difficulty looks next to resource usage
- Integrate with stress testing


Co-authored-by: Bryan White <[email protected]>
  • Loading branch information
Olshansk and bryanchriswhite authored Jun 11, 2024
1 parent 32c238a commit 58d0abd
Show file tree
Hide file tree
Showing 35 changed files with 1,030 additions and 159 deletions.
10 changes: 7 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ test_e2e_params: test_e2e_env ## Run only the E2E suite that exercises parameter
go test -v ./e2e/tests/... -tags=e2e,test --features-path=update_params.feature

.PHONY: test_load_relays_stress
test_load_relays_stress: ## Run the stress test for E2E relays on a persistent (non-ephemeral) remote chains
test_load_relays_stress: ## Run the stress test for E2E relays on a persistent (non-ephemeral) remote chain
go test -v -count=1 ./load-testing/tests/... \
-tags=load,test -run LoadRelays --log-level=debug --timeout=30m \
--manifest ./load-testing/loadtest_manifest.yaml
Expand All @@ -414,10 +414,14 @@ test_verbose: check_go_version ## Run all go tests verbosely
test_all: check_go_version ## Run all go tests showing detailed output only on failures
go test -count=1 -race -tags test ./...

.PHONY: test_integration
test_integration: check_go_version ## Run all go tests, including integration
.PHONY: test_all_with_integration
test_all_with_integration: check_go_version ## Run all go tests, including those with the integration
go test -count=1 -v -race -tags test,integration ./...

.PHONY: test_integration
test_integration: check_go_version ## Run only the in-memory integration "unit" tests
go test -count=1 -v -race -tags test,integration ./tests/integration/...

.PHONY: itest
itest: check_go_version ## Run tests iteratively (see usage for more)
./tools/scripts/itest.sh $(filter-out $@,$(MAKECMDGOALS))
Expand Down
7 changes: 3 additions & 4 deletions app/app_config.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
package app

import (
sharedmodulev1 "github.com/pokt-network/poktroll/api/poktroll/shared/module"
_ "github.com/pokt-network/poktroll/x/shared/module" // import for side-effects
sharedmoduletypes "github.com/pokt-network/poktroll/x/shared/types"

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

Expand Down Expand Up @@ -81,6 +77,7 @@ import (
proofmodulev1 "github.com/pokt-network/poktroll/api/poktroll/proof/module"
servicemodulev1 "github.com/pokt-network/poktroll/api/poktroll/service/module"
sessionmodulev1 "github.com/pokt-network/poktroll/api/poktroll/session/module"
sharedmodulev1 "github.com/pokt-network/poktroll/api/poktroll/shared/module"
suppliermodulev1 "github.com/pokt-network/poktroll/api/poktroll/supplier/module"
tokenomicsmodulev1 "github.com/pokt-network/poktroll/api/poktroll/tokenomics/module"
_ "github.com/pokt-network/poktroll/x/application/module" // import for side-effects
Expand All @@ -93,6 +90,8 @@ import (
servicemoduletypes "github.com/pokt-network/poktroll/x/service/types"
_ "github.com/pokt-network/poktroll/x/session/module" // import for side-effects
sessionmoduletypes "github.com/pokt-network/poktroll/x/session/types"
_ "github.com/pokt-network/poktroll/x/shared/module" // import for side-effects
sharedmoduletypes "github.com/pokt-network/poktroll/x/shared/types"
_ "github.com/pokt-network/poktroll/x/supplier/module" // import for side-effects
suppliermoduletypes "github.com/pokt-network/poktroll/x/supplier/types"
_ "github.com/pokt-network/poktroll/x/tokenomics/module" // import for side-effects
Expand Down
7 changes: 6 additions & 1 deletion e2e/tests/update_params.feature
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
Feature: Params Namespace

# Why do we have this scenario?
# During development, if one of these tests fails along the way, we get into a
# state where LocalNet is inconsistent w/ expectations and needs to be restarted.
# Rather than using a `Background` set of commands that rerun on every scenario,
# we add one to prepare for everything downstream.
Scenario: All params are reset to their default values
Given the user has the pocketd binary installed
And an authz grant from the "gov" "module" account to the "pnf" "user" account for the "/poktroll.tokenomics.MsgUpdateParams" message exists
And an authz grant from the "gov" "module" account to the "pnf" "user" account for each module MsgUpdateParam message exists
Then all module params are reset to their default values

Scenario: An unauthorized user cannot update a module params
Expand Down
73 changes: 41 additions & 32 deletions e2e/tests/update_params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@ import (
"time"

cometcli "github.com/cometbft/cometbft/libs/cli"
"github.com/cosmos/cosmos-sdk/codec/types"
cosmostypes "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/gogoproto/proto"
"github.com/regen-network/gocuke"
"github.com/stretchr/testify/require"

"github.com/pokt-network/poktroll/api/poktroll/application"
"github.com/pokt-network/poktroll/api/poktroll/gateway"
"github.com/pokt-network/poktroll/api/poktroll/proof"
"github.com/pokt-network/poktroll/api/poktroll/session"
"github.com/pokt-network/poktroll/api/poktroll/shared"
"github.com/pokt-network/poktroll/api/poktroll/supplier"
"github.com/pokt-network/poktroll/api/poktroll/tokenomics"
apptypes "github.com/pokt-network/poktroll/x/application/types"
gatewaytypes "github.com/pokt-network/poktroll/x/gateway/types"
prooftypes "github.com/pokt-network/poktroll/x/proof/types"
Expand Down Expand Up @@ -95,6 +100,39 @@ func (s *suite) AllModuleParamsAreSetToTheirDefaultValues(moduleName string) {
}
}

// AllModuleMsgUpdateParamTypes is a list of all MsgUpdateParams types for each module.
// NB: If you are reading this and any module has a MsgUpdateParams message which is not
// included in this list, please add it.
var AllModuleMsgUpdateParamTypes = []string{
application.Msg_UpdateParams_FullMethodName,
gateway.Msg_UpdateParams_FullMethodName,
proof.Msg_UpdateParams_FullMethodName,
session.Msg_UpdateParams_FullMethodName,
shared.Msg_UpdateParams_FullMethodName,
supplier.Msg_UpdateParams_FullMethodName,
tokenomics.Msg_UpdateParams_FullMethodName,
}

// AnAuthzGrantFromTheAccountToTheAccountForEachModuleMsgupdateparamMessageExists queries the
// authz module for grants with the expected granter & grantee (authz.QueryGrantsRequest) &
// asserts that the expected grants (for each module) are found in the response.
func (s *suite) AnAuthzGrantFromTheAccountToTheAccountForEachModuleMsgupdateparamMessageExists(
granterName string,
granterAddrType string,
granteeName string,
granteeAddrType string,
) {
for _, msgType := range AllModuleMsgUpdateParamTypes {
s.AnAuthzGrantFromTheAccountToTheAccountForTheMessageExists(
granterName,
granterAddrType,
granteeName,
granteeAddrType,
msgType,
)
}
}

// AnAuthzGrantFromTheAccountToTheAccountForTheMessage queries the authz module for grants
// with the expected granter & grantee (authz.QueryGrantsRequest) & asserts that the expected
// grant is found in the response.
Expand Down Expand Up @@ -226,36 +264,7 @@ func (s *suite) TheModuleParamShouldBeUpdated(moduleName, paramName string) {

// AllModuleParamsShouldBeSetToTheirDefaultValues ensures that all module params are set to their default values.
func (s *suite) AllModuleParamsAreResetToTheirDefaultValues() {
var anyMsgs []*types.Any

// List of all module MsgUpdateParams types and their respective default param functions
modules := []struct {
msgUpdateParamsType reflect.Type
defaultParams any
}{
{reflect.TypeOf(&apptypes.MsgUpdateParams{}), apptypes.DefaultParams()},
{reflect.TypeOf(&gatewaytypes.MsgUpdateParams{}), gatewaytypes.DefaultParams()},
{reflect.TypeOf(&prooftypes.MsgUpdateParams{}), prooftypes.DefaultParams()},
{reflect.TypeOf(&servicetypes.MsgUpdateParams{}), servicetypes.DefaultParams()},
{reflect.TypeOf(&sessiontypes.MsgUpdateParams{}), sessiontypes.DefaultParams()},
{reflect.TypeOf(&sharedtypes.MsgUpdateParams{}), sharedtypes.DefaultParams()},
{reflect.TypeOf(&suppliertypes.MsgUpdateParams{}), suppliertypes.DefaultParams()},
{reflect.TypeOf(&tokenomicstypes.MsgUpdateParams{}), tokenomicstypes.DefaultParams()},
}

for _, module := range modules {
msgUpdateParams := reflect.New(module.msgUpdateParamsType.Elem()).Interface().(proto.Message)
msgUpdateParamsValue := reflect.ValueOf(msgUpdateParams).Elem()
msgUpdateParamsValue.FieldByName("Authority").SetString(s.granteeName)
msgUpdateParamsValue.FieldByName("Params").Set(reflect.ValueOf(module.defaultParams))

anyMsg, err := types.NewAnyWithValue(msgUpdateParams)
require.NoError(s, err)
anyMsgs = append(anyMsgs, anyMsg)
}

file := s.newTempTxJSONFile(anyMsgs)
s.sendAuthzExecTx(s.granteeName, file.Name())
s.resetAllModuleParamsToDefaults()
}

// TheModuleParamShouldBeSetToItsDefaultValue asserts that the given param for the
Expand Down
1 change: 1 addition & 0 deletions load-testing/config/errors.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package config

// TODO_TECHDEBT(@bryanchriswhite): Consider replacing all `sdkerrors` with `cosmoserrors` in the codebase.
import sdkerrors "cosmossdk.io/errors"

var (
Expand Down
1 change: 1 addition & 0 deletions load-testing/loadtest_manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ gateways:
# address is the bech32 pokt address of the gateway.
- address: pokt16sty9mjdh4u2fwgj8ptufg42cysvh6gsyx6wfp
# The url used to send relays to the gateway on.
# TODO_INVESTIGATE(@okdas): Why is this port number so low? What should it be?
exposed_url: http://localhost:84
27 changes: 13 additions & 14 deletions pkg/client/supplier/client_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,33 @@
package supplier_test

import (
"context"
"testing"

"github.com/stretchr/testify/require"

"github.com/pokt-network/poktroll/testutil/testclient/testsupplier"
sessiontypes "github.com/pokt-network/poktroll/x/session/types"
)

func TestNewSupplierClient_Localnet(t *testing.T) {
t.Skip("TODO_TECHDEBT: this test depends on some setup which is currently not implemented in this test: staked application and servicer with matching services")

var (
signingKeyName = "app1"
ctx = context.Background()
)
signingKeyName := "app1"

supplierClient := testsupplier.NewLocalnetClient(t, signingKeyName)
require.NotNil(t, supplierClient)

var rootHash []byte
sessionHeader := sessiontypes.SessionHeader{
ApplicationAddress: "",
SessionStartBlockHeight: 1,
SessionId: "",
}
err := supplierClient.CreateClaim(ctx, sessionHeader, rootHash)
require.NoError(t, err)
// TODO_TECHDEBT: The method signature of `CreateClaims` has changed since this test
// was first written, and will need to be tackled as part of the TODO_TECHDEBT
// above.
//
// var rootHash []byte
// sessionHeader := sessiontypes.SessionHeader{
// ApplicationAddress: "",
// SessionStartBlockHeight: 1,
// SessionId: "",
// }
// err := supplierClient.CreateClaims(ctx, sessionHeader, rootHash)
// require.NoError(t, err)

require.True(t, false)
}
6 changes: 5 additions & 1 deletion pkg/client/tx/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,11 @@ func TestTxClient_SignAndBroadcast_CheckTxError(t *testing.T) {
ctx = context.Background()
)

t.Log("TODO_FLAKY: Known flaky test - TestTxClient_SignAndBroadcast_CheckTxError")
t.Log(`TODO_FLAKY: Known flaky test: 'TestTxClient_SignAndBroadcast_CheckTxError'
Run the following command a few times to verify it passes at least once:
$ go test -v -count=1 -run TestTxClient_SignAndBroadcast_CheckTxError ./pkg/client/tx/...`)

keyring, signingKey := testkeyring.NewTestKeyringWithKey(t, testSigningKeyName)

Expand Down
16 changes: 8 additions & 8 deletions pkg/client/tx/errors.go
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
package tx

import errorsmod "cosmossdk.io/errors"
import sdkerrors "cosmossdk.io/errors"

var (
// ErrInvalidMsg signifies that there was an issue in validating the
// transaction message. This could be due to format, content, or other
// constraints imposed on the message.
ErrInvalidMsg = errorsmod.Register(codespace, 4, "failed to validate tx message")
ErrInvalidMsg = sdkerrors.Register(codespace, 4, "failed to validate tx message")

// ErrCheckTx indicates an error occurred during the ABCI check transaction
// process, which verifies the transaction's integrity before it is added
// to the mempool.
ErrCheckTx = errorsmod.Register(codespace, 5, "error during ABCI check tx")
ErrCheckTx = sdkerrors.Register(codespace, 5, "error during ABCI check tx")

// ErrTxTimeout is raised when a transaction has taken too long to
// complete, surpassing a predefined threshold.
ErrTxTimeout = errorsmod.Register(codespace, 6, "tx timed out")
ErrTxTimeout = sdkerrors.Register(codespace, 6, "tx timed out")

// ErrQueryTx indicates an error occurred while trying to query for the status
// of a specific transaction, likely due to issues with the query parameters
// or the state of the blockchain network.
ErrQueryTx = errorsmod.Register(codespace, 7, "error encountered while querying for tx")
ErrQueryTx = sdkerrors.Register(codespace, 7, "error encountered while querying for tx")

// ErrInvalidTxHash represents an error which is triggered when the
// transaction hash provided does not adhere to the expected format or
// constraints, implying it may be corrupted or tampered with.
ErrInvalidTxHash = errorsmod.Register(codespace, 8, "invalid tx hash")
ErrInvalidTxHash = sdkerrors.Register(codespace, 8, "invalid tx hash")

// ErrNonTxEventBytes indicates an attempt to deserialize bytes that do not
// correspond to a transaction event. This error is triggered when the provided
// byte data isn't recognized as a valid transaction event representation.
ErrNonTxEventBytes = errorsmod.Register(codespace, 9, "attempted to deserialize non-tx event bytes")
ErrNonTxEventBytes = sdkerrors.Register(codespace, 9, "attempted to deserialize non-tx event bytes")

// ErrUnmarshalTx signals a failure in the unmarshaling process of a transaction.
// This error is triggered when the system encounters issues translating a set of
// bytes into the corresponding Tx structure or object.
ErrUnmarshalTx = errorsmod.Register(codespace, 10, "failed to unmarshal tx")
ErrUnmarshalTx = sdkerrors.Register(codespace, 10, "failed to unmarshal tx")

codespace = "tx_client"
)
4 changes: 2 additions & 2 deletions pkg/observable/errors.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package observable

import errorsmod "cosmossdk.io/errors"
import sdkerrors "cosmossdk.io/errors"

var (
ErrObserverClosed = errorsmod.Register(codespace, 1, "observer is closed")
ErrObserverClosed = sdkerrors.Register(codespace, 1, "observer is closed")
codespace = "observable"
)
4 changes: 2 additions & 2 deletions pkg/relayer/protocol/errors.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package protocol

import errorsmod "cosmossdk.io/errors"
import sdkerrors "cosmossdk.io/errors"

var (
ErrDifficulty = errorsmod.New(codespace, 1, "difficulty error")
ErrDifficulty = sdkerrors.New(codespace, 1, "difficulty error")
codespace = "relayer/protocol"
)
3 changes: 2 additions & 1 deletion pkg/relayer/proxy/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,8 @@ func sendRequestWithDifferentSession(
test *testproxy.TestBehavior,
) (errCode int32, errorMessage string) {
// Use a block height that generates a different session ID
blockHeightAfterSessionGracePeriod := int64(blockHeight + shared.SessionGracePeriodBlocks)
sharedParams := sharedtypes.DefaultParams()
blockHeightAfterSessionGracePeriod := int64(blockHeight + sharedParams.NumBlocksPerSession + 1)
req := testproxy.GenerateRelayRequest(
test,
appPrivateKey,
Expand Down
23 changes: 23 additions & 0 deletions tests/integration/tokenomics/relay_mining_difficulty_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package integration_test

import (
"testing"

"github.com/pokt-network/poktroll/cmd/poktrolld/cmd"
)

// TODO_UPNEXT(@Olshansk, #571): Implement these tests

func init() {
cmd.InitSDKConfig()
}

func TestUpdateRelayMiningDifficulty_NewServiceSeenForTheFirstTime(t *testing.T) {}

func UpdateRelayMiningDifficulty_UpdatingMultipleServicesAtOnce(t *testing.T) {}

func UpdateRelayMiningDifficulty_UpdateServiceIsNotSeenForAWhile(t *testing.T) {}

func UpdateRelayMiningDifficulty_UpdateServiceIsIncreasing(t *testing.T) {}

func UpdateRelayMiningDifficulty_UpdateServiceIsDecreasing(t *testing.T) {}
Loading

0 comments on commit 58d0abd

Please sign in to comment.