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] Implement difficulty proportional rewards #840

Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
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
393 changes: 194 additions & 199 deletions api/poktroll/proof/event.pulsar.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions api/poktroll/service/relay_mining_difficulty.pulsar.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

296 changes: 147 additions & 149 deletions api/poktroll/tokenomics/event.pulsar.go

Large diffs are not rendered by default.

14 changes: 12 additions & 2 deletions docusaurus/docs/develop/developer_guide/adding_params.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,19 @@ with the default value for the new parameter.
"@type": "/poktroll.proof.MsgUpdateParams",
"authority": "pokt10d07y265gmmuvt4z0w9aw880jnsr700j8yv32t",
"params": {
"min_relay_difficulty_bits": "0",
"proof_request_probability": "0.25",
"proof_requirement_threshold": "20",
"proof_requirement_threshold": {
"denom": "upokt",
"amount": "20000000"
},
"proof_missing_penalty": {
"amount": "320000000",
"denom": "upokt"
},
"proof_submission_fee": {
"amount": "1000000",
"denom": "upokt"
},
"new_parameter_name": "100" // Add this line
}
}
Expand Down
4 changes: 0 additions & 4 deletions makefiles/params.mk
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ params_get_proof: ## Get the proof module params
params_update_proof_all: ## Update the proof module params
poktrolld tx authz exec ./tools/scripts/params/proof_all.json $(PARAM_FLAGS)

.PHONY: params_update_proof_min_relay_difficulty_bits
params_update_proof_min_relay_difficulty_bits: ## Update the proof module min_relay_difficulty_bits param
poktrolld tx authz exec ./tools/scripts/params/proof_min_relay_difficulty_bits.json $(PARAM_FLAGS)

.PHONY: params_update_proof_proof_request_probability
params_update_proof_proof_request_probability: ## Update the proof module proof_request_probability param
poktrolld tx authz exec ./tools/scripts/params/proof_proof_request_probability.json $(PARAM_FLAGS)
Expand Down
2 changes: 1 addition & 1 deletion pkg/client/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ type ProofQueryClient interface {
type ServiceQueryClient interface {
// GetService queries the chain for the details of the service provided
GetService(ctx context.Context, serviceId string) (sharedtypes.Service, error)
GetServiceRelayDifficultyTargetHash(ctx context.Context, serviceId string) (servicetypes.RelayMiningDifficulty, error)
GetServiceRelayDifficulty(ctx context.Context, serviceId string) (servicetypes.RelayMiningDifficulty, error)
}

// BankQueryClient defines an interface that enables the querying of the
Expand Down
18 changes: 16 additions & 2 deletions pkg/client/query/servicequerier.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import (

"cosmossdk.io/depinject"
"github.com/cosmos/gogoproto/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

"github.com/pokt-network/poktroll/pkg/client"
"github.com/pokt-network/poktroll/pkg/crypto/protocol"
servicetypes "github.com/pokt-network/poktroll/x/service/types"
sharedtypes "github.com/pokt-network/poktroll/x/shared/types"
)
Expand Down Expand Up @@ -61,9 +64,9 @@ func (servq *serviceQuerier) GetService(
return res.Service, nil
}

// GetServiceRelayDifficultyTargetHash queries the onchain data for
// GetServiceRelayDifficulty queries the onchain data for
// the relay mining difficulty associated with the given service.
func (servq *serviceQuerier) GetServiceRelayDifficultyTargetHash(
func (servq *serviceQuerier) GetServiceRelayDifficulty(
ctx context.Context,
serviceId string,
) (servicetypes.RelayMiningDifficulty, error) {
Expand All @@ -72,8 +75,19 @@ func (servq *serviceQuerier) GetServiceRelayDifficultyTargetHash(
}

res, err := servq.serviceQuerier.RelayMiningDifficulty(ctx, req)
if status.Code(err) == codes.NotFound {
newServiceDifficulty := servicetypes.RelayMiningDifficulty{
ServiceId: serviceId,
BlockHeight: 0,
NumRelaysEma: 0,
TargetHash: protocol.BaseRelayDifficultyHashBz,
}

return newServiceDifficulty, nil
}
if err != nil {
return servicetypes.RelayMiningDifficulty{}, err
}

return res.RelayMiningDifficulty, nil
}
1 change: 1 addition & 0 deletions pkg/crypto/rings/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type ringClient struct {
// - polylog.Logger
// - client.ApplicationQueryClient
// - client.AccountQueryClient
// - client.SharedQueryClient
red-0ne marked this conversation as resolved.
Show resolved Hide resolved
func NewRingClient(deps depinject.Config) (_ crypto.RingClient, err error) {
rc := new(ringClient)

Expand Down
1 change: 0 additions & 1 deletion pkg/relayer/miner/gen/gen_fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ const (
defaultSvcID = "svc1"
)

// TODO_FOLLOWUP(@olshansk, #690): Do a global anycase grep for "DifficultyBits" and update/remove things appropriately.
var (
// flagDifficultyThresholdHashStr is the difficulty threshold hash, as a hex string, that a
// randomized, serialized relay must be greater than to be included in the
Expand Down
6 changes: 2 additions & 4 deletions pkg/relayer/miner/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,9 @@ func (mnr *miner) getServiceRelayDifficultyTargetHash(ctx context.Context, req *
return nil, fmt.Errorf("invalid session header: %w", err)
}

serviceRelayDifficulty, err := mnr.serviceQueryClient.GetServiceRelayDifficultyTargetHash(ctx, sessionHeader.ServiceId)
serviceRelayDifficulty, err := mnr.serviceQueryClient.GetServiceRelayDifficulty(ctx, sessionHeader.ServiceId)
if err != nil {
// TODO_IMPROVE: log the error and a message saying the default relay difficulty target hash
// is being used.
return protocol.BaseRelayDifficultyHashBz, nil
return nil, err
}

return serviceRelayDifficulty.GetTargetHash(), nil
Expand Down
4 changes: 1 addition & 3 deletions pkg/relayer/miner/miner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,10 @@ func TestMiner_MinedRelays(t *testing.T) {
expectedMinedRelays = unmarshalHexMinedRelays(t, marshaledMinableRelaysHex)
)

proofQueryClientMock := testqueryclients.NewTestProofQueryClient(t)

testqueryclients.SetServiceRelayDifficultyTargetHash(t, testSvcId, testRelayMiningTargetHash)
serviceQueryClientMock := testqueryclients.NewTestServiceQueryClient(t)

deps := depinject.Supply(proofQueryClientMock, serviceQueryClientMock)
deps := depinject.Supply(serviceQueryClientMock)
mnr, err := miner.NewMiner(deps)
require.NoError(t, err)

Expand Down
10 changes: 6 additions & 4 deletions pkg/relayer/session/claim.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,10 +315,12 @@ func (rs *relayerSessionsManager) payableProofsSessionTrees(
).Warn().Msg("supplier operator cannot afford to submit proof for claim, skipping")
}

logger.Warn().Msgf(
"Supplier operator %q can only afford %d out of %d claims",
supplierOpeartorAddress, len(claimableSessionTrees), len(sessionTrees),
)
if len(claimableSessionTrees) < len(sessionTrees) {
logger.Warn().Msgf(
"Supplier operator %q can only afford %d out of %d claims",
supplierOpeartorAddress, len(claimableSessionTrees), len(sessionTrees),
)
}

return claimableSessionTrees, nil
}
12 changes: 6 additions & 6 deletions pkg/relayer/session/proof.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"github.com/pokt-network/poktroll/x/proof/types"
prooftypes "github.com/pokt-network/poktroll/x/proof/types"
"github.com/pokt-network/poktroll/x/shared"
tokenomics "github.com/pokt-network/poktroll/x/tokenomics"
)

// submitProofs maps over the given claimedSessions observable.
Expand Down Expand Up @@ -277,24 +276,25 @@ func (rs *relayerSessionsManager) isProofRequired(
// Create the claim object and use its methods to determine if a proof is required.
claim := claimFromSessionTree(sessionTree)

// Get the number of compute units accumulated through the given session.
numClaimComputeUnits, err := claim.GetNumClaimedComputeUnits()
proofParams, err := rs.proofQueryClient.GetParams(ctx)
if err != nil {
return false, err
}

proofParams, err := rs.proofQueryClient.GetParams(ctx)
sharedParams, err := rs.sharedQueryClient.GetParams(ctx)
if err != nil {
return false, err
}

sharedParams, err := rs.sharedQueryClient.GetParams(ctx)
// Retrieving the relay mining difficulty for the service at hand
serviceId := claim.GetSessionHeader().GetServiceId()
relayMiningDifficulty, err := rs.serviceQueryClient.GetServiceRelayDifficulty(ctx, serviceId)
if err != nil {
return false, err
}

// The amount of uPOKT being claimed.
claimedAmount, err := tokenomics.NumComputeUnitsToCoin(*sharedParams, numClaimComputeUnits)
claimedAmount, err := claim.GetClaimeduPOKT(*sharedParams, relayMiningDifficulty)
if err != nil {
return false, err
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/relayer/session/session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ func requireProofCountEqualsExpectedValueFromProofParams(t *testing.T, proofPara
Id: "svc",
ComputeUnitsPerRelay: 2,
}

testqueryclients.SetServiceRelayDifficultyTargetHash(t, service.Id, protocol.BaseRelayDifficultyHashBz)
// Add the service to the existing services.
testqueryclients.AddToExistingServices(t, service)

Expand Down Expand Up @@ -157,12 +159,14 @@ func TestRelayerSessionsManager_InsufficientBalanceForProofSubmission(t *testing
ComputeUnitsPerRelay: 1,
}
testqueryclients.AddToExistingServices(t, lowCUPRService)
testqueryclients.SetServiceRelayDifficultyTargetHash(t, lowCUPRService.Id, protocol.BaseRelayDifficultyHashBz)

highCUPRService := sharedtypes.Service{
Id: "highCUPRService",
ComputeUnitsPerRelay: 2,
}
testqueryclients.AddToExistingServices(t, highCUPRService)
testqueryclients.SetServiceRelayDifficultyTargetHash(t, highCUPRService.Id, protocol.BaseRelayDifficultyHashBz)

lowCUPRServiceActiveSession := &sessiontypes.Session{
Header: &sessiontypes.SessionHeader{
Expand Down
8 changes: 4 additions & 4 deletions proto/poktroll/proof/event.proto
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ message EventClaimCreated {
uint64 num_relays = 2 [(gogoproto.jsontag) = "num_relays"];
uint64 num_claimed_compute_units = 4 [(gogoproto.jsontag) = "num_claimed_compute_units"];
uint64 num_estimated_compute_units = 5 [(gogoproto.jsontag) = "num_estimated_compute_units"];
cosmos.base.v1beta1.Coin claimed_amount_upokt = 6 [(gogoproto.jsontag) = "claimed_amount_upokt"];
cosmos.base.v1beta1.Coin claimed_upokt = 6 [(gogoproto.jsontag) = "claimed_upokt"];
}

// TODO_TEST: Add coverage for claim updates.
Expand All @@ -22,7 +22,7 @@ message EventClaimUpdated {
uint64 num_relays = 2 [(gogoproto.jsontag) = "num_relays"];
uint64 num_claimed_compute_units = 4 [(gogoproto.jsontag) = "num_claimed_compute_units"];
uint64 num_estimated_compute_units = 5 [(gogoproto.jsontag) = "num_estimated_compute_units"];
cosmos.base.v1beta1.Coin claimed_amount_upokt = 6 [(gogoproto.jsontag) = "claimed_amount_upokt"];
cosmos.base.v1beta1.Coin claimed_upokt = 6 [(gogoproto.jsontag) = "claimed_upokt"];
}

message EventProofSubmitted {
Expand All @@ -31,7 +31,7 @@ message EventProofSubmitted {
uint64 num_relays = 3 [(gogoproto.jsontag) = "num_relays"];
uint64 num_claimed_compute_units = 4 [(gogoproto.jsontag) = "num_claimed_compute_units"];
uint64 num_estimated_compute_units = 5 [(gogoproto.jsontag) = "num_estimated_compute_units"];
cosmos.base.v1beta1.Coin claimed_amount_upokt = 6 [(gogoproto.jsontag) = "claimed_amount_upokt"];
cosmos.base.v1beta1.Coin claimed_upokt = 6 [(gogoproto.jsontag) = "claimed_upokt"];
}

// TODO_TEST: Add coverage for proof updates.
Expand All @@ -41,5 +41,5 @@ message EventProofUpdated {
uint64 num_relays = 3 [(gogoproto.jsontag) = "num_relays"];
uint64 num_claimed_compute_units = 4 [(gogoproto.jsontag) = "num_claimed_compute_units"];
uint64 num_estimated_compute_units = 5 [(gogoproto.jsontag) = "num_estimated_compute_units"];
cosmos.base.v1beta1.Coin claimed_amount_upokt = 6 [(gogoproto.jsontag) = "claimed_amount_upokt"];
cosmos.base.v1beta1.Coin claimed_upokt = 6 [(gogoproto.jsontag) = "claimed_upokt"];
}
1 change: 1 addition & 0 deletions proto/poktroll/service/relay_mining_difficulty.proto
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import "gogoproto/gogo.proto";

// RelayMiningDifficulty is a message used to store the on-chain Relay Mining
// difficulty associated with a specific service ID.
// TODO_TECHDEBT: Embed this message in the Service message.
message RelayMiningDifficulty {
// The service ID the relay mining difficulty is associated with.
string service_id = 1;
Expand Down
8 changes: 4 additions & 4 deletions proto/poktroll/tokenomics/event.proto
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ message EventClaimExpired {
// Number of estimated compute units claimed as a function of the number of claimed
// compute units and the relay difficulty multiplier for the particular service.
uint64 num_estimated_compute_units = 5 [(gogoproto.jsontag) = "num_estimated_compute_units"];
// The amount of uPOKT claimed to be rewarded for the work done as a function of
// The uPOKT coin claimed to be rewarded for the work done as a function of
// the number of estimated compute units and the compute uints to token multiplier.
cosmos.base.v1beta1.Coin claimed_amount_upokt = 6 [(gogoproto.jsontag) = "claimed_amount_upokt"];
cosmos.base.v1beta1.Coin claimed_upokt = 6 [(gogoproto.jsontag) = "claimed_upokt"];
}

// EventClaimSettled is an event emitted whenever a claim is settled.
Expand All @@ -48,9 +48,9 @@ message EventClaimSettled {
// Number of estimated compute units claimed as a function of the number of claimed
// compute units and the relay difficulty multiplier for the particular service.
uint64 num_estimated_compute_units = 5 [(gogoproto.jsontag) = "num_estimated_compute_units"];
// The amount of uPOKT claimed to be rewarded for the work done as a function of
// The uPOKT coin claimed to be rewarded for the work done as a function of
// the number of estimated compute units and the compute uints to token multiplier.
cosmos.base.v1beta1.Coin claimed_amount_upokt = 6 [(gogoproto.jsontag) = "claimed_amount_upokt"];
cosmos.base.v1beta1.Coin claimed_upokt = 6 [(gogoproto.jsontag) = "claimed_upokt"];
}

// EventApplicationOverserviced is emitted when an application has less stake than
Expand Down
32 changes: 32 additions & 0 deletions tests/integration/service/relay_mining_difficulty_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ package integration_test

import (
"context"
"math"
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/pokt-network/smt"
"github.com/pokt-network/smt/kvstore/pebble"
"github.com/stretchr/testify/require"

"github.com/pokt-network/poktroll/app/volatile"
"github.com/pokt-network/poktroll/cmd/poktrolld/cmd"
"github.com/pokt-network/poktroll/pkg/crypto/protocol"
testutilevents "github.com/pokt-network/poktroll/testutil/events"
Expand Down Expand Up @@ -38,6 +41,20 @@ func TestUpdateRelayMiningDifficulty_NewServiceSeenForTheFirstTime(t *testing.T)
// Get the current session and shared params
session := getSession(t, integrationApp)
sharedParams := getSharedParams(t, integrationApp)
proofParams := getProofParams(t, integrationApp)

// Update the proof parameters to never require a proof, since this test is not
// submitting any proofs.
lowProofRequirementThreshold := sdk.NewInt64Coin(volatile.DenomuPOKT, math.MaxInt64)
red-0ne marked this conversation as resolved.
Show resolved Hide resolved
proofParams.ProofRequirementThreshold = &lowProofRequirementThreshold
proofParams.ProofRequestProbability = 0

msgProofParams := prooftypes.MsgUpdateParams{
Authority: integrationApp.GetAuthority(),
Params: proofParams,
}
_, err := integrationApp.RunMsg(t, &msgProofParams)
require.NoError(t, err)

// Prepare the trie with several mined relays
expectedNumRelays := uint64(100)
Expand Down Expand Up @@ -138,6 +155,21 @@ func getSharedParams(t *testing.T, integrationApp *testutil.App) sharedtypes.Par
return sharedQueryRes.Params
}

// getProofParams returns the proof parameters for the current block height.
func getProofParams(t *testing.T, integrationApp *testutil.App) prooftypes.Params {
t.Helper()

sdkCtx := integrationApp.GetSdkCtx()

proofQueryClient := prooftypes.NewQueryClient(integrationApp.QueryHelper())
proofParamsReq := prooftypes.QueryParamsRequest{}

proofQueryRes, err := proofQueryClient.Params(sdkCtx, &proofParamsReq)
require.NoError(t, err)

return proofQueryRes.Params
}

// getSession returns the current session for the default application and service.
func getSession(t *testing.T, integrationApp *testutil.App) *sessiontypes.Session {
t.Helper()
Expand Down
Loading
Loading