Skip to content

Commit

Permalink
[Relay Mining] Emit events and refactor test helpers (#610)
Browse files Browse the repository at this point in the history
- `Event` - Emitting an event when the relay mining difficulty is updated
- `Flaky` - Added some flaky comments/pointers in different places
- `Refactor` -  the event filtering function into a shared location
- `Utils` - Updated testing to support a signed mined relay

Co-authored-by: Bryan White <[email protected]>
Co-authored-by: Dima K <[email protected]>
  • Loading branch information
3 people authored Jun 20, 2024
1 parent e7dad9b commit 7146146
Show file tree
Hide file tree
Showing 23 changed files with 2,490 additions and 2,282 deletions.
784 changes: 764 additions & 20 deletions api/poktroll/tokenomics/event.pulsar.go

Large diffs are not rendered by default.

2,474 changes: 585 additions & 1,889 deletions docs/static/openapi.yml

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions e2e/tests/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ func (s *suite) getConfigFileContent(amount int64, actorType, serviceId string)
rpc_type: json_rpc`,
amount, serviceId)
default:
s.Fatalf("unknown actor type %s", actorType)
s.Fatalf("ERROR: unknown actor type %s", actorType)
}
fmt.Println(yaml.NormalizeYAMLIndentation(configContent))
return yaml.NormalizeYAMLIndentation(configContent)
Expand Down Expand Up @@ -339,7 +339,7 @@ func (s *suite) TheApplicationIsStakedForService(appName string, serviceId strin
return
}
}
s.Fatalf("application %s is not staked for service %s", appName, serviceId)
s.Fatalf("ERROR: application %s is not staked for service %s", appName, serviceId)
}

func (s *suite) TheSupplierIsStakedForService(supplierName string, serviceId string) {
Expand All @@ -348,7 +348,7 @@ func (s *suite) TheSupplierIsStakedForService(supplierName string, serviceId str
return
}
}
s.Fatalf("supplier %s is not staked for service %s", supplierName, serviceId)
s.Fatalf("ERROR: supplier %s is not staked for service %s", supplierName, serviceId)
}

func (s *suite) TheSessionForApplicationAndServiceContainsTheSupplier(appName string, serviceId string, supplierName string) {
Expand Down Expand Up @@ -377,7 +377,7 @@ func (s *suite) TheSessionForApplicationAndServiceContainsTheSupplier(appName st
return
}
}
s.Fatalf("session for app %s and service %s does not contain supplier %s", appName, serviceId, supplierName)
s.Fatalf("ERROR: session for app %s and service %s does not contain supplier %s", appName, serviceId, supplierName)
}

func (s *suite) TheApplicationSendsTheSupplierARequestForServiceWithPathAndData(appName, supplierName, serviceId, path, requestData string) {
Expand Down Expand Up @@ -572,7 +572,7 @@ func (s *suite) validateAmountChange(prevAmount, currAmount int, expectedAmountC
require.LessOrEqual(s, currAmount, prevAmount, "%s %s expected to have less upokt but actually had more", accName, balanceType)
require.Equal(s, expectedAmountChange, deltaAmount, "%s %s expected) decrease in upokt was incorrect", accName, balanceType)
default:
s.Fatalf("unknown condition %s", condition)
s.Fatalf("ERROR: unknown condition %s", condition)
}

}
Expand Down
12 changes: 6 additions & 6 deletions e2e/tests/parse_params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (s *suite) parseParam(table gocuke.DataTable, rowIdx int) paramAny {
coinValue := cosmostypes.NewCoin(volatile.DenomuPOKT, math.NewInt(coinAmount))
paramValue = &coinValue
default:
s.Fatalf("unexpected param type %q", paramType)
s.Fatalf("ERROR: unexpected param type %q", paramType)
}

return paramAny{
Expand Down Expand Up @@ -116,7 +116,7 @@ func (s *suite) newTokenomicsMsgUpdateParams(params paramsMap) cosmostypes.Msg {
case tokenomicstypes.ParamComputeUnitsToTokensMultiplier:
msgUpdateParams.Params.ComputeUnitsToTokensMultiplier = uint64(paramValue.value.(int64))
default:
s.Fatalf("unexpected %q type param name %q", paramValue.typeStr, paramName)
s.Fatalf("ERROR: unexpected %q type param name %q", paramValue.typeStr, paramName)
}
}
return proto.Message(msgUpdateParams)
Expand All @@ -141,7 +141,7 @@ func (s *suite) newProofMsgUpdateParams(params paramsMap) cosmostypes.Msg {
case prooftypes.ParamProofMissingPenalty:
msgUpdateParams.Params.ProofMissingPenalty = paramValue.value.(*cosmostypes.Coin)
default:
s.Fatalf("unexpected %q type param name %q", paramValue.typeStr, paramName)
s.Fatalf("ERROR: unexpected %q type param name %q", paramValue.typeStr, paramName)
}
}
return proto.Message(msgUpdateParams)
Expand All @@ -168,7 +168,7 @@ func (s *suite) newSharedMsgUpdateParams(params paramsMap) cosmostypes.Msg {
case sharedtypes.ParamProofWindowCloseOffsetBlocks:
msgUpdateParams.Params.ProofWindowCloseOffsetBlocks = uint64(paramValue.value.(int64))
default:
s.Fatalf("unexpected %q type param name %q", paramValue.typeStr, paramName)
s.Fatalf("ERROR: unexpected %q type param name %q", paramValue.typeStr, paramName)
}
}
return proto.Message(msgUpdateParams)
Expand All @@ -188,7 +188,7 @@ func (s *suite) newAppMsgUpdateParams(params paramsMap) cosmostypes.Msg {
case apptypes.ParamMaxDelegatedGateways:
msgUpdateParams.Params.MaxDelegatedGateways = uint64(paramValue.value.(int64))
default:
s.Fatalf("unexpected %q type param name %q", paramValue.typeStr, paramName)
s.Fatalf("ERROR: unexpected %q type param name %q", paramValue.typeStr, paramName)
}
}
return proto.Message(msgUpdateParams)
Expand All @@ -208,7 +208,7 @@ func (s *suite) newServiceMsgUpdateParams(params paramsMap) cosmostypes.Msg {
case servicetypes.ParamAddServiceFee:
msgUpdateParams.Params.AddServiceFee = uint64(paramValue.value.(int64))
default:
s.Fatalf("unexpected %q type param name %q", paramValue.typeStr, paramName)
s.Fatalf("ERROR: unexpected %q type param name %q", paramValue.typeStr, paramName)
}
}
return proto.Message(msgUpdateParams)
Expand Down
2 changes: 1 addition & 1 deletion e2e/tests/reset_params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func (s *suite) msgUpdateParamsToDefaultsAny(moduleName string) *codectypes.Any
},
)
default:
s.Fatalf("unknown module name: %s", moduleName)
s.Fatalf("ERROR: unknown module name: %s", moduleName)
}
require.NoError(s, err)

Expand Down
59 changes: 16 additions & 43 deletions e2e/tests/session_steps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import (

"cosmossdk.io/depinject"
abci "github.com/cometbft/cometbft/abci/types"
cosmostypes "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"

"github.com/pokt-network/poktroll/pkg/client"
"github.com/pokt-network/poktroll/pkg/client/block"
"github.com/pokt-network/poktroll/pkg/client/events"
"github.com/pokt-network/poktroll/pkg/client/tx"
"github.com/pokt-network/poktroll/pkg/observable/channel"
testutilevents "github.com/pokt-network/poktroll/testutil/events"
"github.com/pokt-network/poktroll/testutil/testclient"
prooftypes "github.com/pokt-network/poktroll/x/proof/types"
tokenomicstypes "github.com/pokt-network/poktroll/x/tokenomics/types"
Expand All @@ -25,7 +27,7 @@ import (
const (
// eventTimeout is the duration of time to wait after sending a valid tx
// before the test should time out (fail).
eventTimeout = 60 * time.Second
eventTimeout = 100 * time.Second
// testServiceId is the service ID used for testing purposes that is
// expected to be available in LocalNet.
testServiceId = "anvil"
Expand Down Expand Up @@ -166,13 +168,23 @@ func (s *suite) TheClaimCreatedBySupplierForServiceForApplicationShouldBeSuccess
if event.Type != "poktroll.tokenomics.EventClaimSettled" {
return false
}
claimSettledEvent := s.abciToClaimSettledEvent(event)

// Parse the event
testutilevents.QuoteEventMode(event)
typedEvent, err := cosmostypes.ParseTypedEvent(*event)
require.NoError(s, err)
require.NotNil(s, typedEvent)
claimSettledEvent, ok := typedEvent.(*tokenomicstypes.EventClaimSettled)
require.True(s, ok)

// Assert that the claim was settled for the correct application, supplier, and service.
claim := claimSettledEvent.Claim
require.Equal(s, app.Address, claim.SessionHeader.ApplicationAddress)
require.Equal(s, supplier.Address, claim.SupplierAddress)
require.Equal(s, serviceId, claim.SessionHeader.Service.Id)
require.Greater(s, claimSettledEvent.ComputeUnits, uint64(0), "compute units should be greater than 0")
s.Logf("Claim settled for %d compute units w/ proof requirement: %t\n", claimSettledEvent.ComputeUnits, claimSettledEvent.ProofRequired)

return true
}

Expand Down Expand Up @@ -235,7 +247,7 @@ func (s *suite) waitForTxResultEvent(targetAction string) {

select {
case <-time.After(eventTimeout):
s.Fatalf("timed out waiting for message with action %q", targetAction)
s.Fatalf("ERROR: timed out waiting for message with action %q", targetAction)
case <-ctx.Done():
s.Log("Success; message detected before timeout.")
}
Expand Down Expand Up @@ -280,47 +292,8 @@ func (s *suite) waitForNewBlockEvent(

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

// abciToClaimSettledEvent converts an abci.Event to a tokenomics.EventClaimSettled
//

func (s *suite) abciToClaimSettledEvent(event *abci.Event) *tokenomicstypes.EventClaimSettled {
var claimSettledEvent tokenomicstypes.EventClaimSettled

// TODO_TECHDEBT: Investigate why `cosmostypes.ParseTypedEvent(*event)` throws
// an error where cosmostypes is imported from "github.com/cosmos/cosmos-sdk/types"
// resulting in the following error:
// 'json: error calling MarshalJSON for type json.RawMessage: invalid character 'E' looking for beginning of value'
// typedEvent, err := cosmostypes.ParseTypedEvent(*event)

for _, attr := range event.Attributes {
switch string(attr.Key) {
case "claim":
var claim prooftypes.Claim
if err := s.cdc.UnmarshalJSON([]byte(attr.Value), &claim); err != nil {
s.Fatalf("Failed to unmarshal claim: %v", err)
}
claimSettledEvent.Claim = &claim
case "compute_units":
value := string(attr.Value)
value = value[1 : len(value)-1] // Remove surrounding quotes
computeUnits, err := strconv.ParseUint(value, 10, 64)
if err != nil {
s.Fatalf("Failed to parse compute_units: %v", err)
}
claimSettledEvent.ComputeUnits = computeUnits
case "proof_required":
proofRequired, err := strconv.ParseBool(string(attr.Value))
if err != nil {
s.Fatalf("Failed to parse proof_required: %v", err)
}
claimSettledEvent.ProofRequired = proofRequired
}
}
return &claimSettledEvent
}
2 changes: 1 addition & 1 deletion pkg/relayer/miner/miner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func TestMiner_MinedRelays(t *testing.T) {

// Assert that all minable relay fixtures were published to minedRelays.
actualMinedRelaysMu.Lock()
require.EqualValues(t, expectedMinedRelays, actualMinedRelays)
require.EqualValues(t, expectedMinedRelays, actualMinedRelays, "TODO_FLAKY: Try re-running with 'go test -v -count=1 -run TestMiner_MinedRelays ./pkg/relayer/miner/...'")
actualMinedRelaysMu.Unlock()
}

Expand Down
19 changes: 13 additions & 6 deletions pkg/relayer/session/session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,28 @@ import (
"github.com/pokt-network/poktroll/testutil/testclient/testsupplier"
"github.com/pokt-network/poktroll/testutil/testpolylog"
"github.com/pokt-network/poktroll/testutil/testrelayer"
sessiontypes "github.com/pokt-network/poktroll/x/session/types"
"github.com/pokt-network/poktroll/x/shared"
sharedtypes "github.com/pokt-network/poktroll/x/shared/types"
)

func TestRelayerSessionsManager_Start(t *testing.T) {
const (
sessionStartHeight = 1
sessionEndHeight = 2
)

// TODO_TECHDEBT(#446): Centralize the configuration for the SMT spec.
var (
_, ctx = testpolylog.NewLoggerWithCtx(context.Background(), polyzero.DebugLevel)
spec = smt.NewTrieSpec(sha256.New(), true)
emptyBlockHash = make([]byte, spec.PathHasherSize())
activeSession *sessiontypes.Session
)

activeSession = &sessiontypes.Session{
Header: &sessiontypes.SessionHeader{
SessionStartBlockHeight: 1,
SessionEndBlockHeight: 2,
},
}
sessionHeader := activeSession.GetHeader()

// Set up dependencies.
blocksObs, blockPublishCh := channel.NewReplayObservable[client.Block](ctx, 1)
blockClient := testblock.NewAnyTimesCommittedBlocksSequenceBlockClient(t, emptyBlockHash, blocksObs)
Expand Down Expand Up @@ -94,20 +99,22 @@ func TestRelayerSessionsManager_Start(t *testing.T) {
relayerSessionsManager.Start(ctx)

// Publish a mined relay to the minedRelaysPublishCh to insert into the session tree.
minedRelay := testrelayer.NewMinedRelay(t, sessionStartHeight, sessionEndHeight, supplierAddress)
minedRelay := testrelayer.NewUnsignedMinedRelay(t, activeSession, supplierAddress)
minedRelaysPublishCh <- minedRelay

// Wait a tick to allow the relayer sessions manager to process asynchronously.
// It should have created a session tree for the relay.
time.Sleep(10 * time.Millisecond)

// Publish a block to the blockPublishCh to simulate non-actionable blocks.
sessionStartHeight := sessionHeader.GetSessionStartBlockHeight()
noopBlock := testblock.NewAnyTimesBlock(t, emptyBlockHash, sessionStartHeight)
blockPublishCh <- noopBlock

// Calculate the session grace period end block height to emit that block height
// to the blockPublishCh to trigger claim creation for the session.
sharedParams := sharedtypes.DefaultParams()
sessionEndHeight := sessionHeader.GetSessionEndBlockHeight()
sessionClaimWindowOpenHeight := shared.GetClaimWindowOpenHeight(&sharedParams, sessionEndHeight)

// Publish a block to the blockPublishCh to trigger claim creation for the session.
Expand Down
10 changes: 10 additions & 0 deletions proto/poktroll/tokenomics/event.proto
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,13 @@ message EventClaimSettled {
uint64 compute_units = 2;
bool proof_required = 3;
}

// EventRelayMiningDifficultyUpdated is an event emitted whenever the relay mining difficulty is updated
// for a given service.
message EventRelayMiningDifficultyUpdated {
string service_id = 1;
string prev_target_hash_hex_encoded = 2;
string new_target_hash_hex_encoded = 3;
uint64 prev_num_relays_ema = 4;
uint64 new_num_relays_ema = 5;
}
Loading

0 comments on commit 7146146

Please sign in to comment.