diff --git a/Dockerfile.release b/Dockerfile.release index f14eab4f5..07ccbb433 100644 --- a/Dockerfile.release +++ b/Dockerfile.release @@ -1,13 +1,10 @@ # This Dockerfile is used to build container image for production workloads. -# It relies on the binaries produced by `cosmovisor_cross_compile`, `ignite_release` and `ignite_release_extract_binaries` make targets. -FROM alpine:3.19 +# The image depends on `cosmovisor_cross_compile`, `ignite_release` and `ignite_release_extract_binaries` make targets. +FROM debian:bookworm ARG TARGETARCH # Use `1025` G/UID so users can switch between this and `heighliner` image without a need to chown the files. -RUN addgroup --gid 1025 -S pocket && adduser --uid 1025 -S pocket -G pocket - -# Install gcompat to provide compatibility with glibc binary on amd64 -RUN apk add --no-cache gcompat +RUN groupadd -g 1025 pocket && useradd -u 1025 -g pocket -m -s /sbin/nologin pocket COPY --chown=pocket:pocket release_binaries/poktroll_linux_$TARGETARCH /bin/poktrolld COPY --chown=pocket:pocket tmp/cosmovisor-linux-$TARGETARCH /bin/cosmovisor diff --git a/api/poktroll/proof/params.pulsar.go b/api/poktroll/proof/params.pulsar.go index 27f3273c8..f5d9f9c75 100644 --- a/api/poktroll/proof/params.pulsar.go +++ b/api/poktroll/proof/params.pulsar.go @@ -113,8 +113,8 @@ func (x *fastReflection_Params) Range(f func(protoreflect.FieldDescriptor, proto return } } - if x.ProofRequirementThreshold != uint64(0) { - value := protoreflect.ValueOfUint64(x.ProofRequirementThreshold) + if x.ProofRequirementThreshold != nil { + value := protoreflect.ValueOfMessage(x.ProofRequirementThreshold.ProtoReflect()) if !f(fd_Params_proof_requirement_threshold, value) { return } @@ -151,7 +151,7 @@ func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { case "poktroll.proof.Params.proof_request_probability": return x.ProofRequestProbability != float32(0) || math.Signbit(float64(x.ProofRequestProbability)) case "poktroll.proof.Params.proof_requirement_threshold": - return x.ProofRequirementThreshold != uint64(0) + return x.ProofRequirementThreshold != nil case "poktroll.proof.Params.proof_missing_penalty": return x.ProofMissingPenalty != nil case "poktroll.proof.Params.proof_submission_fee": @@ -177,7 +177,7 @@ func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { case "poktroll.proof.Params.proof_request_probability": x.ProofRequestProbability = float32(0) case "poktroll.proof.Params.proof_requirement_threshold": - x.ProofRequirementThreshold = uint64(0) + x.ProofRequirementThreshold = nil case "poktroll.proof.Params.proof_missing_penalty": x.ProofMissingPenalty = nil case "poktroll.proof.Params.proof_submission_fee": @@ -206,7 +206,7 @@ func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) pro return protoreflect.ValueOfFloat32(value) case "poktroll.proof.Params.proof_requirement_threshold": value := x.ProofRequirementThreshold - return protoreflect.ValueOfUint64(value) + return protoreflect.ValueOfMessage(value.ProtoReflect()) case "poktroll.proof.Params.proof_missing_penalty": value := x.ProofMissingPenalty return protoreflect.ValueOfMessage(value.ProtoReflect()) @@ -238,7 +238,7 @@ func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value proto case "poktroll.proof.Params.proof_request_probability": x.ProofRequestProbability = float32(value.Float()) case "poktroll.proof.Params.proof_requirement_threshold": - x.ProofRequirementThreshold = value.Uint() + x.ProofRequirementThreshold = value.Message().Interface().(*v1beta1.Coin) case "poktroll.proof.Params.proof_missing_penalty": x.ProofMissingPenalty = value.Message().Interface().(*v1beta1.Coin) case "poktroll.proof.Params.proof_submission_fee": @@ -263,6 +263,11 @@ func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value proto // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { + case "poktroll.proof.Params.proof_requirement_threshold": + if x.ProofRequirementThreshold == nil { + x.ProofRequirementThreshold = new(v1beta1.Coin) + } + return protoreflect.ValueOfMessage(x.ProofRequirementThreshold.ProtoReflect()) case "poktroll.proof.Params.proof_missing_penalty": if x.ProofMissingPenalty == nil { x.ProofMissingPenalty = new(v1beta1.Coin) @@ -277,8 +282,6 @@ func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protore panic(fmt.Errorf("field relay_difficulty_target_hash of message poktroll.proof.Params is not mutable")) case "poktroll.proof.Params.proof_request_probability": panic(fmt.Errorf("field proof_request_probability of message poktroll.proof.Params is not mutable")) - case "poktroll.proof.Params.proof_requirement_threshold": - panic(fmt.Errorf("field proof_requirement_threshold of message poktroll.proof.Params is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.proof.Params")) @@ -297,7 +300,8 @@ func (x *fastReflection_Params) NewField(fd protoreflect.FieldDescriptor) protor case "poktroll.proof.Params.proof_request_probability": return protoreflect.ValueOfFloat32(float32(0)) case "poktroll.proof.Params.proof_requirement_threshold": - return protoreflect.ValueOfUint64(uint64(0)) + m := new(v1beta1.Coin) + return protoreflect.ValueOfMessage(m.ProtoReflect()) case "poktroll.proof.Params.proof_missing_penalty": m := new(v1beta1.Coin) return protoreflect.ValueOfMessage(m.ProtoReflect()) @@ -380,8 +384,9 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { if x.ProofRequestProbability != 0 || math.Signbit(float64(x.ProofRequestProbability)) { n += 5 } - if x.ProofRequirementThreshold != 0 { - n += 1 + runtime.Sov(uint64(x.ProofRequirementThreshold)) + if x.ProofRequirementThreshold != nil { + l = options.Size(x.ProofRequirementThreshold) + n += 1 + l + runtime.Sov(uint64(l)) } if x.ProofMissingPenalty != nil { l = options.Size(x.ProofMissingPenalty) @@ -448,10 +453,19 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { i-- dAtA[i] = 0x22 } - if x.ProofRequirementThreshold != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.ProofRequirementThreshold)) + if x.ProofRequirementThreshold != nil { + encoded, err := options.Marshal(x.ProofRequirementThreshold) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) i-- - dAtA[i] = 0x18 + dAtA[i] = 0x1a } if x.ProofRequestProbability != 0 || math.Signbit(float64(x.ProofRequestProbability)) { i -= 4 @@ -561,10 +575,10 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { iNdEx += 4 x.ProofRequestProbability = float32(math.Float32frombits(v)) case 3: - if wireType != 0 { + if wireType != 2 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ProofRequirementThreshold", wireType) } - x.ProofRequirementThreshold = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow @@ -574,11 +588,28 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { } b := dAtA[iNdEx] iNdEx++ - x.ProofRequirementThreshold |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.ProofRequirementThreshold == nil { + x.ProofRequirementThreshold = &v1beta1.Coin{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.ProofRequirementThreshold); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex case 4: if wireType != 2 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ProofMissingPenalty", wireType) @@ -716,16 +747,18 @@ type Params struct { // is equal to or above the threshold. This is in contrast to the this requirement // being determined probabilistically via ProofRequestProbability. // - // TODO_MAINNET: Consider renaming this to `proof_requirement_threshold_compute_units`. - ProofRequirementThreshold uint64 `protobuf:"varint,3,opt,name=proof_requirement_threshold,json=proofRequirementThreshold,proto3" json:"proof_requirement_threshold,omitempty"` + // TODO_MAINNET: Consider renaming this to `proof_requirement_threshold_upokt`. + ProofRequirementThreshold *v1beta1.Coin `protobuf:"bytes,3,opt,name=proof_requirement_threshold,json=proofRequirementThreshold,proto3" json:"proof_requirement_threshold,omitempty"` // proof_missing_penalty is the number of tokens (uPOKT) which should be slashed from a supplier // when a proof is required (either via proof_requirement_threshold or proof_missing_penalty) // but is not provided. + // TODO_MAINNET: Consider renaming this to `proof_missing_penalty_upokt`. ProofMissingPenalty *v1beta1.Coin `protobuf:"bytes,4,opt,name=proof_missing_penalty,json=proofMissingPenalty,proto3" json:"proof_missing_penalty,omitempty"` // proof_submission_fee is the number of tokens (uPOKT) which should be paid by // the supplier operator when submitting a proof. // This is needed to account for the cost of storing proofs on-chain and prevent // spamming (i.e. sybil bloat attacks) the network with non-required proofs. + // TODO_MAINNET: Consider renaming this to `proof_submission_fee_upokt`. ProofSubmissionFee *v1beta1.Coin `protobuf:"bytes,5,opt,name=proof_submission_fee,json=proofSubmissionFee,proto3" json:"proof_submission_fee,omitempty"` } @@ -763,11 +796,11 @@ func (x *Params) GetProofRequestProbability() float32 { return 0 } -func (x *Params) GetProofRequirementThreshold() uint64 { +func (x *Params) GetProofRequirementThreshold() *v1beta1.Coin { if x != nil { return x.ProofRequirementThreshold } - return 0 + return nil } func (x *Params) GetProofMissingPenalty() *v1beta1.Coin { @@ -794,7 +827,7 @@ var file_poktroll_proof_params_proto_rawDesc = []byte{ 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x63, 0x6f, 0x69, 0x6e, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9a, 0x04, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb5, 0x04, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x61, 0x0a, 0x1c, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x20, 0xea, 0xde, 0x1f, 0x1c, 0x72, 0x65, 0x6c, @@ -807,38 +840,40 @@ var file_poktroll_proof_params_proto_rawDesc = []byte{ 0x6f, 0x66, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x17, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x62, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, - 0x5f, 0x0a, 0x1b, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x7a, 0x0a, 0x1b, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x04, 0x42, 0x1f, 0xea, 0xde, 0x1f, 0x1b, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, - 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x68, 0x72, 0x65, - 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x52, 0x19, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, - 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, - 0x12, 0x68, 0x0a, 0x15, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, - 0x67, 0x5f, 0x70, 0x65, 0x6e, 0x61, 0x6c, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x19, 0xea, 0xde, 0x1f, 0x15, - 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x65, - 0x6e, 0x61, 0x6c, 0x74, 0x79, 0x52, 0x13, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x4d, 0x69, 0x73, 0x73, - 0x69, 0x6e, 0x67, 0x50, 0x65, 0x6e, 0x61, 0x6c, 0x74, 0x79, 0x12, 0x65, 0x0a, 0x14, 0x70, 0x72, - 0x6f, 0x6f, 0x66, 0x5f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x66, - 0x65, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, - 0x6f, 0x69, 0x6e, 0x42, 0x18, 0xea, 0xde, 0x1f, 0x14, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x73, - 0x75, 0x62, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x66, 0x65, 0x65, 0x52, 0x12, 0x70, - 0x72, 0x6f, 0x6f, 0x66, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x65, - 0x65, 0x3a, 0x20, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, 0xe7, 0xb0, 0x2a, 0x17, 0x70, 0x6f, 0x6b, 0x74, - 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x78, 0x2f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x2f, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x73, 0x42, 0x9f, 0x01, 0xd8, 0xe2, 0x1e, 0x01, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, - 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x42, 0x0b, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x1f, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0xa2, 0x02, - 0x03, 0x50, 0x50, 0x58, 0xaa, 0x02, 0x0e, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, - 0x50, 0x72, 0x6f, 0x6f, 0x66, 0xca, 0x02, 0x0e, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x5c, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0xe2, 0x02, 0x1a, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, - 0x6c, 0x5c, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0xea, 0x02, 0x0f, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x3a, 0x3a, - 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, + 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, + 0x1f, 0xea, 0xde, 0x1f, 0x1b, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, + 0x52, 0x19, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x68, 0x0a, 0x15, 0x70, + 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x65, 0x6e, + 0x61, 0x6c, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x19, 0xea, 0xde, 0x1f, 0x15, 0x70, 0x72, 0x6f, 0x6f, 0x66, + 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x65, 0x6e, 0x61, 0x6c, 0x74, 0x79, + 0x52, 0x13, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x50, 0x65, + 0x6e, 0x61, 0x6c, 0x74, 0x79, 0x12, 0x65, 0x0a, 0x14, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x73, + 0x75, 0x62, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x66, 0x65, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, + 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x18, + 0xea, 0xde, 0x1f, 0x14, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x66, 0x65, 0x65, 0x52, 0x12, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x53, + 0x75, 0x62, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x65, 0x65, 0x3a, 0x20, 0xe8, 0xa0, + 0x1f, 0x01, 0x8a, 0xe7, 0xb0, 0x2a, 0x17, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, + 0x78, 0x2f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x2f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x9f, + 0x01, 0xd8, 0xe2, 0x1e, 0x01, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x42, 0x0b, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x1f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x6f, 0x6b, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0xa2, 0x02, 0x03, 0x50, 0x50, 0x58, 0xaa, + 0x02, 0x0e, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x50, 0x72, 0x6f, 0x6f, 0x66, + 0xca, 0x02, 0x0e, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x5c, 0x50, 0x72, 0x6f, 0x6f, + 0x66, 0xe2, 0x02, 0x1a, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x5c, 0x50, 0x72, 0x6f, + 0x6f, 0x66, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, + 0x0f, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x3a, 0x3a, 0x50, 0x72, 0x6f, 0x6f, 0x66, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -859,13 +894,14 @@ var file_poktroll_proof_params_proto_goTypes = []interface{}{ (*v1beta1.Coin)(nil), // 1: cosmos.base.v1beta1.Coin } var file_poktroll_proof_params_proto_depIdxs = []int32{ - 1, // 0: poktroll.proof.Params.proof_missing_penalty:type_name -> cosmos.base.v1beta1.Coin - 1, // 1: poktroll.proof.Params.proof_submission_fee:type_name -> cosmos.base.v1beta1.Coin - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 1, // 0: poktroll.proof.Params.proof_requirement_threshold:type_name -> cosmos.base.v1beta1.Coin + 1, // 1: poktroll.proof.Params.proof_missing_penalty:type_name -> cosmos.base.v1beta1.Coin + 1, // 2: poktroll.proof.Params.proof_submission_fee:type_name -> cosmos.base.v1beta1.Coin + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_poktroll_proof_params_proto_init() } diff --git a/api/poktroll/shared/params.pulsar.go b/api/poktroll/shared/params.pulsar.go index f39c65780..c567709c1 100644 --- a/api/poktroll/shared/params.pulsar.go +++ b/api/poktroll/shared/params.pulsar.go @@ -24,6 +24,7 @@ var ( fd_Params_proof_window_close_offset_blocks protoreflect.FieldDescriptor fd_Params_supplier_unbonding_period_sessions protoreflect.FieldDescriptor fd_Params_application_unbonding_period_sessions protoreflect.FieldDescriptor + fd_Params_compute_units_to_tokens_multiplier protoreflect.FieldDescriptor ) func init() { @@ -37,6 +38,7 @@ func init() { fd_Params_proof_window_close_offset_blocks = md_Params.Fields().ByName("proof_window_close_offset_blocks") fd_Params_supplier_unbonding_period_sessions = md_Params.Fields().ByName("supplier_unbonding_period_sessions") fd_Params_application_unbonding_period_sessions = md_Params.Fields().ByName("application_unbonding_period_sessions") + fd_Params_compute_units_to_tokens_multiplier = md_Params.Fields().ByName("compute_units_to_tokens_multiplier") } var _ protoreflect.Message = (*fastReflection_Params)(nil) @@ -152,6 +154,12 @@ func (x *fastReflection_Params) Range(f func(protoreflect.FieldDescriptor, proto return } } + if x.ComputeUnitsToTokensMultiplier != uint64(0) { + value := protoreflect.ValueOfUint64(x.ComputeUnitsToTokensMultiplier) + if !f(fd_Params_compute_units_to_tokens_multiplier, value) { + return + } + } } // Has reports whether a field is populated. @@ -183,6 +191,8 @@ func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { return x.SupplierUnbondingPeriodSessions != uint64(0) case "poktroll.shared.Params.application_unbonding_period_sessions": return x.ApplicationUnbondingPeriodSessions != uint64(0) + case "poktroll.shared.Params.compute_units_to_tokens_multiplier": + return x.ComputeUnitsToTokensMultiplier != uint64(0) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.shared.Params")) @@ -215,6 +225,8 @@ func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { x.SupplierUnbondingPeriodSessions = uint64(0) case "poktroll.shared.Params.application_unbonding_period_sessions": x.ApplicationUnbondingPeriodSessions = uint64(0) + case "poktroll.shared.Params.compute_units_to_tokens_multiplier": + x.ComputeUnitsToTokensMultiplier = uint64(0) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.shared.Params")) @@ -255,6 +267,9 @@ func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) pro case "poktroll.shared.Params.application_unbonding_period_sessions": value := x.ApplicationUnbondingPeriodSessions return protoreflect.ValueOfUint64(value) + case "poktroll.shared.Params.compute_units_to_tokens_multiplier": + value := x.ComputeUnitsToTokensMultiplier + return protoreflect.ValueOfUint64(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.shared.Params")) @@ -291,6 +306,8 @@ func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value proto x.SupplierUnbondingPeriodSessions = value.Uint() case "poktroll.shared.Params.application_unbonding_period_sessions": x.ApplicationUnbondingPeriodSessions = value.Uint() + case "poktroll.shared.Params.compute_units_to_tokens_multiplier": + x.ComputeUnitsToTokensMultiplier = value.Uint() default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.shared.Params")) @@ -327,6 +344,8 @@ func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protore panic(fmt.Errorf("field supplier_unbonding_period_sessions of message poktroll.shared.Params is not mutable")) case "poktroll.shared.Params.application_unbonding_period_sessions": panic(fmt.Errorf("field application_unbonding_period_sessions of message poktroll.shared.Params is not mutable")) + case "poktroll.shared.Params.compute_units_to_tokens_multiplier": + panic(fmt.Errorf("field compute_units_to_tokens_multiplier of message poktroll.shared.Params is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.shared.Params")) @@ -356,6 +375,8 @@ func (x *fastReflection_Params) NewField(fd protoreflect.FieldDescriptor) protor return protoreflect.ValueOfUint64(uint64(0)) case "poktroll.shared.Params.application_unbonding_period_sessions": return protoreflect.ValueOfUint64(uint64(0)) + case "poktroll.shared.Params.compute_units_to_tokens_multiplier": + return protoreflect.ValueOfUint64(uint64(0)) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.shared.Params")) @@ -449,6 +470,9 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { if x.ApplicationUnbondingPeriodSessions != 0 { n += 1 + runtime.Sov(uint64(x.ApplicationUnbondingPeriodSessions)) } + if x.ComputeUnitsToTokensMultiplier != 0 { + n += 1 + runtime.Sov(uint64(x.ComputeUnitsToTokensMultiplier)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -478,6 +502,11 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if x.ComputeUnitsToTokensMultiplier != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.ComputeUnitsToTokensMultiplier)) + i-- + dAtA[i] = 0x48 + } if x.ApplicationUnbondingPeriodSessions != 0 { i = runtime.EncodeVarint(dAtA, i, uint64(x.ApplicationUnbondingPeriodSessions)) i-- @@ -719,6 +748,25 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { break } } + case 9: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ComputeUnitsToTokensMultiplier", wireType) + } + x.ComputeUnitsToTokensMultiplier = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.ComputeUnitsToTokensMultiplier |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -802,6 +850,9 @@ type Params struct { // On-chain business logic requires, and ensures, that the corresponding block count of the // application unbonding period will exceed the end of its corresponding proof window close height. ApplicationUnbondingPeriodSessions uint64 `protobuf:"varint,8,opt,name=application_unbonding_period_sessions,json=applicationUnbondingPeriodSessions,proto3" json:"application_unbonding_period_sessions,omitempty"` + // The amount of upokt that a compute unit should translate to when settling a session. + // DEV_NOTE: This used to be under x/tokenomics but has been moved here to avoid cyclic dependencies. + ComputeUnitsToTokensMultiplier uint64 `protobuf:"varint,9,opt,name=compute_units_to_tokens_multiplier,json=computeUnitsToTokensMultiplier,proto3" json:"compute_units_to_tokens_multiplier,omitempty"` } func (x *Params) Reset() { @@ -880,6 +931,13 @@ func (x *Params) GetApplicationUnbondingPeriodSessions() uint64 { return 0 } +func (x *Params) GetComputeUnitsToTokensMultiplier() uint64 { + if x != nil { + return x.ComputeUnitsToTokensMultiplier + } + return 0 +} + var File_poktroll_shared_params_proto protoreflect.FileDescriptor var file_poktroll_shared_params_proto_rawDesc = []byte{ @@ -888,7 +946,7 @@ var file_poktroll_shared_params_proto_rawDesc = []byte{ 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x1a, 0x11, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, - 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x89, 0x07, 0x0a, 0x06, 0x50, 0x61, 0x72, + 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xab, 0x08, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x4f, 0x0a, 0x16, 0x6e, 0x75, 0x6d, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x42, 0x1a, 0xea, 0xde, 0x1f, 0x16, 0x6e, 0x75, 0x6d, 0x5f, 0x62, 0x6c, 0x6f, @@ -943,20 +1001,30 @@ var file_poktroll_shared_params_proto_rawDesc = []byte{ 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x22, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x73, 0x3a, 0x21, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, 0xe7, 0xb0, 0x2a, 0x18, 0x70, 0x6f, 0x6b, 0x74, - 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x78, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, 0x50, 0x61, - 0x72, 0x61, 0x6d, 0x73, 0x42, 0xa5, 0x01, 0xd8, 0xe2, 0x1e, 0x01, 0x0a, 0x13, 0x63, 0x6f, 0x6d, - 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, - 0x42, 0x0b, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, - 0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, - 0x64, 0xa2, 0x02, 0x03, 0x50, 0x53, 0x58, 0xaa, 0x02, 0x0f, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, - 0x6c, 0x6c, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0xca, 0x02, 0x0f, 0x50, 0x6f, 0x6b, 0x74, - 0x72, 0x6f, 0x6c, 0x6c, 0x5c, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0xe2, 0x02, 0x1b, 0x50, 0x6f, - 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x5c, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x5c, 0x47, 0x50, - 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x10, 0x50, 0x6f, 0x6b, 0x74, - 0x72, 0x6f, 0x6c, 0x6c, 0x3a, 0x3a, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x12, 0x9f, 0x01, 0x0a, 0x22, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x5f, 0x75, 0x6e, + 0x69, 0x74, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5f, 0x6d, 0x75, + 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x42, 0x53, + 0xea, 0xde, 0x1f, 0x22, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x74, + 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, + 0x69, 0x70, 0x6c, 0x69, 0x65, 0x72, 0xf2, 0xde, 0x1f, 0x29, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, + 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x5f, 0x74, 0x6f, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, + 0x65, 0x72, 0x22, 0x52, 0x1e, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x55, 0x6e, 0x69, 0x74, + 0x73, 0x54, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, + 0x69, 0x65, 0x72, 0x3a, 0x21, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, 0xe7, 0xb0, 0x2a, 0x18, 0x70, 0x6f, + 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x78, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0xa5, 0x01, 0xd8, 0xe2, 0x1e, 0x01, 0x0a, 0x13, 0x63, + 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x68, 0x61, 0x72, + 0x65, 0x64, 0x42, 0x0b, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x73, 0x68, 0x61, + 0x72, 0x65, 0x64, 0xa2, 0x02, 0x03, 0x50, 0x53, 0x58, 0xaa, 0x02, 0x0f, 0x50, 0x6f, 0x6b, 0x74, + 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0xca, 0x02, 0x0f, 0x50, 0x6f, + 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x5c, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0xe2, 0x02, 0x1b, + 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x5c, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x5c, + 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x10, 0x50, 0x6f, + 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x3a, 0x3a, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/poktroll/tokenomics/event.pulsar.go b/api/poktroll/tokenomics/event.pulsar.go index da158aacd..0090b4632 100644 --- a/api/poktroll/tokenomics/event.pulsar.go +++ b/api/poktroll/tokenomics/event.pulsar.go @@ -2459,6 +2459,553 @@ func (x *fastReflection_EventApplicationOverserviced) ProtoMethods() *protoiface } } +var ( + md_EventSupplierSlashed protoreflect.MessageDescriptor + fd_EventSupplierSlashed_supplier_operator_addr protoreflect.FieldDescriptor + fd_EventSupplierSlashed_num_expired_claims protoreflect.FieldDescriptor + fd_EventSupplierSlashed_slashing_amount protoreflect.FieldDescriptor +) + +func init() { + file_poktroll_tokenomics_event_proto_init() + md_EventSupplierSlashed = File_poktroll_tokenomics_event_proto.Messages().ByName("EventSupplierSlashed") + fd_EventSupplierSlashed_supplier_operator_addr = md_EventSupplierSlashed.Fields().ByName("supplier_operator_addr") + fd_EventSupplierSlashed_num_expired_claims = md_EventSupplierSlashed.Fields().ByName("num_expired_claims") + fd_EventSupplierSlashed_slashing_amount = md_EventSupplierSlashed.Fields().ByName("slashing_amount") +} + +var _ protoreflect.Message = (*fastReflection_EventSupplierSlashed)(nil) + +type fastReflection_EventSupplierSlashed EventSupplierSlashed + +func (x *EventSupplierSlashed) ProtoReflect() protoreflect.Message { + return (*fastReflection_EventSupplierSlashed)(x) +} + +func (x *EventSupplierSlashed) slowProtoReflect() protoreflect.Message { + mi := &file_poktroll_tokenomics_event_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_EventSupplierSlashed_messageType fastReflection_EventSupplierSlashed_messageType +var _ protoreflect.MessageType = fastReflection_EventSupplierSlashed_messageType{} + +type fastReflection_EventSupplierSlashed_messageType struct{} + +func (x fastReflection_EventSupplierSlashed_messageType) Zero() protoreflect.Message { + return (*fastReflection_EventSupplierSlashed)(nil) +} +func (x fastReflection_EventSupplierSlashed_messageType) New() protoreflect.Message { + return new(fastReflection_EventSupplierSlashed) +} +func (x fastReflection_EventSupplierSlashed_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_EventSupplierSlashed +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_EventSupplierSlashed) Descriptor() protoreflect.MessageDescriptor { + return md_EventSupplierSlashed +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_EventSupplierSlashed) Type() protoreflect.MessageType { + return _fastReflection_EventSupplierSlashed_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_EventSupplierSlashed) New() protoreflect.Message { + return new(fastReflection_EventSupplierSlashed) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_EventSupplierSlashed) Interface() protoreflect.ProtoMessage { + return (*EventSupplierSlashed)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_EventSupplierSlashed) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.SupplierOperatorAddr != "" { + value := protoreflect.ValueOfString(x.SupplierOperatorAddr) + if !f(fd_EventSupplierSlashed_supplier_operator_addr, value) { + return + } + } + if x.NumExpiredClaims != uint64(0) { + value := protoreflect.ValueOfUint64(x.NumExpiredClaims) + if !f(fd_EventSupplierSlashed_num_expired_claims, value) { + return + } + } + if x.SlashingAmount != nil { + value := protoreflect.ValueOfMessage(x.SlashingAmount.ProtoReflect()) + if !f(fd_EventSupplierSlashed_slashing_amount, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_EventSupplierSlashed) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "poktroll.tokenomics.EventSupplierSlashed.supplier_operator_addr": + return x.SupplierOperatorAddr != "" + case "poktroll.tokenomics.EventSupplierSlashed.num_expired_claims": + return x.NumExpiredClaims != uint64(0) + case "poktroll.tokenomics.EventSupplierSlashed.slashing_amount": + return x.SlashingAmount != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.tokenomics.EventSupplierSlashed")) + } + panic(fmt.Errorf("message poktroll.tokenomics.EventSupplierSlashed does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_EventSupplierSlashed) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "poktroll.tokenomics.EventSupplierSlashed.supplier_operator_addr": + x.SupplierOperatorAddr = "" + case "poktroll.tokenomics.EventSupplierSlashed.num_expired_claims": + x.NumExpiredClaims = uint64(0) + case "poktroll.tokenomics.EventSupplierSlashed.slashing_amount": + x.SlashingAmount = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.tokenomics.EventSupplierSlashed")) + } + panic(fmt.Errorf("message poktroll.tokenomics.EventSupplierSlashed does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_EventSupplierSlashed) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "poktroll.tokenomics.EventSupplierSlashed.supplier_operator_addr": + value := x.SupplierOperatorAddr + return protoreflect.ValueOfString(value) + case "poktroll.tokenomics.EventSupplierSlashed.num_expired_claims": + value := x.NumExpiredClaims + return protoreflect.ValueOfUint64(value) + case "poktroll.tokenomics.EventSupplierSlashed.slashing_amount": + value := x.SlashingAmount + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.tokenomics.EventSupplierSlashed")) + } + panic(fmt.Errorf("message poktroll.tokenomics.EventSupplierSlashed does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_EventSupplierSlashed) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "poktroll.tokenomics.EventSupplierSlashed.supplier_operator_addr": + x.SupplierOperatorAddr = value.Interface().(string) + case "poktroll.tokenomics.EventSupplierSlashed.num_expired_claims": + x.NumExpiredClaims = value.Uint() + case "poktroll.tokenomics.EventSupplierSlashed.slashing_amount": + x.SlashingAmount = value.Message().Interface().(*v1beta1.Coin) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.tokenomics.EventSupplierSlashed")) + } + panic(fmt.Errorf("message poktroll.tokenomics.EventSupplierSlashed does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_EventSupplierSlashed) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "poktroll.tokenomics.EventSupplierSlashed.slashing_amount": + if x.SlashingAmount == nil { + x.SlashingAmount = new(v1beta1.Coin) + } + return protoreflect.ValueOfMessage(x.SlashingAmount.ProtoReflect()) + case "poktroll.tokenomics.EventSupplierSlashed.supplier_operator_addr": + panic(fmt.Errorf("field supplier_operator_addr of message poktroll.tokenomics.EventSupplierSlashed is not mutable")) + case "poktroll.tokenomics.EventSupplierSlashed.num_expired_claims": + panic(fmt.Errorf("field num_expired_claims of message poktroll.tokenomics.EventSupplierSlashed is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.tokenomics.EventSupplierSlashed")) + } + panic(fmt.Errorf("message poktroll.tokenomics.EventSupplierSlashed does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_EventSupplierSlashed) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "poktroll.tokenomics.EventSupplierSlashed.supplier_operator_addr": + return protoreflect.ValueOfString("") + case "poktroll.tokenomics.EventSupplierSlashed.num_expired_claims": + return protoreflect.ValueOfUint64(uint64(0)) + case "poktroll.tokenomics.EventSupplierSlashed.slashing_amount": + m := new(v1beta1.Coin) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.tokenomics.EventSupplierSlashed")) + } + panic(fmt.Errorf("message poktroll.tokenomics.EventSupplierSlashed does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_EventSupplierSlashed) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in poktroll.tokenomics.EventSupplierSlashed", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_EventSupplierSlashed) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_EventSupplierSlashed) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_EventSupplierSlashed) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_EventSupplierSlashed) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*EventSupplierSlashed) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.SupplierOperatorAddr) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.NumExpiredClaims != 0 { + n += 1 + runtime.Sov(uint64(x.NumExpiredClaims)) + } + if x.SlashingAmount != nil { + l = options.Size(x.SlashingAmount) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*EventSupplierSlashed) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.SlashingAmount != nil { + encoded, err := options.Marshal(x.SlashingAmount) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x1a + } + if x.NumExpiredClaims != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.NumExpiredClaims)) + i-- + dAtA[i] = 0x10 + } + if len(x.SupplierOperatorAddr) > 0 { + i -= len(x.SupplierOperatorAddr) + copy(dAtA[i:], x.SupplierOperatorAddr) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.SupplierOperatorAddr))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*EventSupplierSlashed) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: EventSupplierSlashed: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: EventSupplierSlashed: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field SupplierOperatorAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.SupplierOperatorAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field NumExpiredClaims", wireType) + } + x.NumExpiredClaims = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.NumExpiredClaims |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field SlashingAmount", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.SlashingAmount == nil { + x.SlashingAmount = &v1beta1.Coin{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.SlashingAmount); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.27.0 @@ -2783,6 +3330,62 @@ func (x *EventApplicationOverserviced) GetEffectiveBurn() *v1beta1.Coin { return nil } +// EventSupplierSlashed is emitted when a supplier is slashed for not providing, +// or provided invalid required proofs for claims. +type EventSupplierSlashed struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SupplierOperatorAddr string `protobuf:"bytes,1,opt,name=supplier_operator_addr,json=supplierOperatorAddr,proto3" json:"supplier_operator_addr,omitempty"` + // Number of expired claims (due to missing or invalid proof) that led to slashing. + NumExpiredClaims uint64 `protobuf:"varint,2,opt,name=num_expired_claims,json=numExpiredClaims,proto3" json:"num_expired_claims,omitempty"` + // Amount slashed from the supplier's stake due to the expired claims. + // This is a function of the number of expired claims and proof missing penalty. + SlashingAmount *v1beta1.Coin `protobuf:"bytes,3,opt,name=slashing_amount,json=slashingAmount,proto3" json:"slashing_amount,omitempty"` +} + +func (x *EventSupplierSlashed) Reset() { + *x = EventSupplierSlashed{} + if protoimpl.UnsafeEnabled { + mi := &file_poktroll_tokenomics_event_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EventSupplierSlashed) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EventSupplierSlashed) ProtoMessage() {} + +// Deprecated: Use EventSupplierSlashed.ProtoReflect.Descriptor instead. +func (*EventSupplierSlashed) Descriptor() ([]byte, []int) { + return file_poktroll_tokenomics_event_proto_rawDescGZIP(), []int{4} +} + +func (x *EventSupplierSlashed) GetSupplierOperatorAddr() string { + if x != nil { + return x.SupplierOperatorAddr + } + return "" +} + +func (x *EventSupplierSlashed) GetNumExpiredClaims() uint64 { + if x != nil { + return x.NumExpiredClaims + } + return 0 +} + +func (x *EventSupplierSlashed) GetSlashingAmount() *v1beta1.Coin { + if x != nil { + return x.SlashingAmount + } + return nil +} + var File_poktroll_tokenomics_event_proto protoreflect.FileDescriptor var file_poktroll_tokenomics_event_proto_rawDesc = []byte{ @@ -2866,25 +3469,38 @@ var file_poktroll_tokenomics_event_proto_rawDesc = []byte{ 0x76, 0x65, 0x5f, 0x62, 0x75, 0x72, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x0d, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, - 0x69, 0x76, 0x65, 0x42, 0x75, 0x72, 0x6e, 0x2a, 0x60, 0x0a, 0x15, 0x43, 0x6c, 0x61, 0x69, 0x6d, - 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, - 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x58, 0x50, 0x49, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, - 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x5f, 0x4d, 0x49, 0x53, - 0x53, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x5f, - 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x02, 0x42, 0xbc, 0x01, 0xd8, 0xe2, 0x1e, 0x01, - 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x73, 0x42, 0x0a, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x24, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, - 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, - 0x6c, 0x6c, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x73, 0xa2, 0x02, 0x03, - 0x50, 0x54, 0x58, 0xaa, 0x02, 0x13, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x73, 0xca, 0x02, 0x13, 0x50, 0x6f, 0x6b, 0x74, - 0x72, 0x6f, 0x6c, 0x6c, 0x5c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x73, 0xe2, - 0x02, 0x1f, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x5c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x6f, 0x6d, 0x69, 0x63, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0xea, 0x02, 0x14, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x3a, 0x3a, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x76, 0x65, 0x42, 0x75, 0x72, 0x6e, 0x22, 0xbe, 0x01, 0x0a, 0x14, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x65, 0x64, + 0x12, 0x34, 0x0a, 0x16, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x5f, 0x6f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x14, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x12, 0x2c, 0x0a, 0x12, 0x6e, 0x75, 0x6d, 0x5f, 0x65, 0x78, + 0x70, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x10, 0x6e, 0x75, 0x6d, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x43, 0x6c, + 0x61, 0x69, 0x6d, 0x73, 0x12, 0x42, 0x0a, 0x0f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, + 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x0e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x69, + 0x6e, 0x67, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x2a, 0x60, 0x0a, 0x15, 0x43, 0x6c, 0x61, 0x69, + 0x6d, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x73, 0x6f, + 0x6e, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x58, 0x50, 0x49, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, + 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x5f, 0x4d, 0x49, + 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x52, 0x4f, 0x4f, 0x46, + 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x02, 0x42, 0xbc, 0x01, 0xd8, 0xe2, 0x1e, + 0x01, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x73, 0x42, 0x0a, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x24, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x6f, 0x6b, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x73, 0xa2, 0x02, + 0x03, 0x50, 0x54, 0x58, 0xaa, 0x02, 0x13, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x73, 0xca, 0x02, 0x13, 0x50, 0x6f, 0x6b, + 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x5c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x73, + 0xe2, 0x02, 0x1f, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x5c, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0xea, 0x02, 0x14, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x3a, 0x3a, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -2900,29 +3516,31 @@ func file_poktroll_tokenomics_event_proto_rawDescGZIP() []byte { } var file_poktroll_tokenomics_event_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_poktroll_tokenomics_event_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_poktroll_tokenomics_event_proto_msgTypes = make([]protoimpl.MessageInfo, 5) var file_poktroll_tokenomics_event_proto_goTypes = []interface{}{ (ClaimExpirationReason)(0), // 0: poktroll.tokenomics.ClaimExpirationReason (*EventClaimExpired)(nil), // 1: poktroll.tokenomics.EventClaimExpired (*EventClaimSettled)(nil), // 2: poktroll.tokenomics.EventClaimSettled (*EventRelayMiningDifficultyUpdated)(nil), // 3: poktroll.tokenomics.EventRelayMiningDifficultyUpdated (*EventApplicationOverserviced)(nil), // 4: poktroll.tokenomics.EventApplicationOverserviced - (*proof.Claim)(nil), // 5: poktroll.proof.Claim - (proof.ProofRequirementReason)(0), // 6: poktroll.proof.ProofRequirementReason - (*v1beta1.Coin)(nil), // 7: cosmos.base.v1beta1.Coin + (*EventSupplierSlashed)(nil), // 5: poktroll.tokenomics.EventSupplierSlashed + (*proof.Claim)(nil), // 6: poktroll.proof.Claim + (proof.ProofRequirementReason)(0), // 7: poktroll.proof.ProofRequirementReason + (*v1beta1.Coin)(nil), // 8: cosmos.base.v1beta1.Coin } var file_poktroll_tokenomics_event_proto_depIdxs = []int32{ - 5, // 0: poktroll.tokenomics.EventClaimExpired.claim:type_name -> poktroll.proof.Claim + 6, // 0: poktroll.tokenomics.EventClaimExpired.claim:type_name -> poktroll.proof.Claim 0, // 1: poktroll.tokenomics.EventClaimExpired.expiration_reason:type_name -> poktroll.tokenomics.ClaimExpirationReason - 5, // 2: poktroll.tokenomics.EventClaimSettled.claim:type_name -> poktroll.proof.Claim - 6, // 3: poktroll.tokenomics.EventClaimSettled.proof_requirement:type_name -> poktroll.proof.ProofRequirementReason - 7, // 4: poktroll.tokenomics.EventApplicationOverserviced.expected_burn:type_name -> cosmos.base.v1beta1.Coin - 7, // 5: poktroll.tokenomics.EventApplicationOverserviced.effective_burn:type_name -> cosmos.base.v1beta1.Coin - 6, // [6:6] is the sub-list for method output_type - 6, // [6:6] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 6, // 2: poktroll.tokenomics.EventClaimSettled.claim:type_name -> poktroll.proof.Claim + 7, // 3: poktroll.tokenomics.EventClaimSettled.proof_requirement:type_name -> poktroll.proof.ProofRequirementReason + 8, // 4: poktroll.tokenomics.EventApplicationOverserviced.expected_burn:type_name -> cosmos.base.v1beta1.Coin + 8, // 5: poktroll.tokenomics.EventApplicationOverserviced.effective_burn:type_name -> cosmos.base.v1beta1.Coin + 8, // 6: poktroll.tokenomics.EventSupplierSlashed.slashing_amount:type_name -> cosmos.base.v1beta1.Coin + 7, // [7:7] is the sub-list for method output_type + 7, // [7:7] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name } func init() { file_poktroll_tokenomics_event_proto_init() } @@ -2979,6 +3597,18 @@ func file_poktroll_tokenomics_event_proto_init() { return nil } } + file_poktroll_tokenomics_event_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EventSupplierSlashed); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -2986,7 +3616,7 @@ func file_poktroll_tokenomics_event_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_poktroll_tokenomics_event_proto_rawDesc, NumEnums: 1, - NumMessages: 4, + NumMessages: 5, NumExtensions: 0, NumServices: 0, }, diff --git a/api/poktroll/tokenomics/params.pulsar.go b/api/poktroll/tokenomics/params.pulsar.go index 2f2db226a..cec03c7ba 100644 --- a/api/poktroll/tokenomics/params.pulsar.go +++ b/api/poktroll/tokenomics/params.pulsar.go @@ -15,14 +15,12 @@ import ( ) var ( - md_Params protoreflect.MessageDescriptor - fd_Params_compute_units_to_tokens_multiplier protoreflect.FieldDescriptor + md_Params protoreflect.MessageDescriptor ) func init() { file_poktroll_tokenomics_params_proto_init() md_Params = File_poktroll_tokenomics_params_proto.Messages().ByName("Params") - fd_Params_compute_units_to_tokens_multiplier = md_Params.Fields().ByName("compute_units_to_tokens_multiplier") } var _ protoreflect.Message = (*fastReflection_Params)(nil) @@ -90,12 +88,6 @@ func (x *fastReflection_Params) Interface() protoreflect.ProtoMessage { // While iterating, mutating operations may only be performed // on the current field descriptor. func (x *fastReflection_Params) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.ComputeUnitsToTokensMultiplier != uint64(0) { - value := protoreflect.ValueOfUint64(x.ComputeUnitsToTokensMultiplier) - if !f(fd_Params_compute_units_to_tokens_multiplier, value) { - return - } - } } // Has reports whether a field is populated. @@ -111,8 +103,6 @@ func (x *fastReflection_Params) Range(f func(protoreflect.FieldDescriptor, proto // a repeated field is populated if it is non-empty. func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "poktroll.tokenomics.Params.compute_units_to_tokens_multiplier": - return x.ComputeUnitsToTokensMultiplier != uint64(0) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.tokenomics.Params")) @@ -129,8 +119,6 @@ func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "poktroll.tokenomics.Params.compute_units_to_tokens_multiplier": - x.ComputeUnitsToTokensMultiplier = uint64(0) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.tokenomics.Params")) @@ -147,9 +135,6 @@ func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "poktroll.tokenomics.Params.compute_units_to_tokens_multiplier": - value := x.ComputeUnitsToTokensMultiplier - return protoreflect.ValueOfUint64(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.tokenomics.Params")) @@ -170,8 +155,6 @@ func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) pro // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "poktroll.tokenomics.Params.compute_units_to_tokens_multiplier": - x.ComputeUnitsToTokensMultiplier = value.Uint() default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.tokenomics.Params")) @@ -192,8 +175,6 @@ func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value proto // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "poktroll.tokenomics.Params.compute_units_to_tokens_multiplier": - panic(fmt.Errorf("field compute_units_to_tokens_multiplier of message poktroll.tokenomics.Params is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.tokenomics.Params")) @@ -207,8 +188,6 @@ func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protore // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_Params) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "poktroll.tokenomics.Params.compute_units_to_tokens_multiplier": - return protoreflect.ValueOfUint64(uint64(0)) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.tokenomics.Params")) @@ -278,9 +257,6 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { var n int var l int _ = l - if x.ComputeUnitsToTokensMultiplier != 0 { - n += 1 + runtime.Sov(uint64(x.ComputeUnitsToTokensMultiplier)) - } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -310,11 +286,6 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } - if x.ComputeUnitsToTokensMultiplier != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.ComputeUnitsToTokensMultiplier)) - i-- - dAtA[i] = 0x8 - } if input.Buf != nil { input.Buf = append(input.Buf, dAtA...) } else { @@ -364,25 +335,6 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ComputeUnitsToTokensMultiplier", wireType) - } - x.ComputeUnitsToTokensMultiplier = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - x.ComputeUnitsToTokensMultiplier |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -436,9 +388,6 @@ type Params struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - - // The amount of upokt that a compute unit should translate to when settling a session. - ComputeUnitsToTokensMultiplier uint64 `protobuf:"varint,1,opt,name=compute_units_to_tokens_multiplier,json=computeUnitsToTokensMultiplier,proto3" json:"compute_units_to_tokens_multiplier,omitempty"` } func (x *Params) Reset() { @@ -461,13 +410,6 @@ func (*Params) Descriptor() ([]byte, []int) { return file_poktroll_tokenomics_params_proto_rawDescGZIP(), []int{0} } -func (x *Params) GetComputeUnitsToTokensMultiplier() uint64 { - if x != nil { - return x.ComputeUnitsToTokensMultiplier - } - return 0 -} - var File_poktroll_tokenomics_params_proto protoreflect.FileDescriptor var file_poktroll_tokenomics_params_proto_rawDesc = []byte{ @@ -477,32 +419,22 @@ var file_poktroll_tokenomics_params_proto_rawDesc = []byte{ 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x73, 0x1a, 0x11, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0xd1, 0x01, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x9f, 0x01, 0x0a, 0x22, - 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x5f, 0x74, 0x6f, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, - 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x42, 0x53, 0xea, 0xde, 0x1f, 0x22, 0x63, 0x6f, - 0x6d, 0x70, 0x75, 0x74, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, 0x65, 0x72, - 0xf2, 0xde, 0x1f, 0x29, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, - 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x22, 0x52, 0x1e, 0x63, - 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x54, 0x6f, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x3a, 0x25, 0xe8, - 0xa0, 0x1f, 0x01, 0x8a, 0xe7, 0xb0, 0x2a, 0x1c, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x2f, 0x78, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x73, 0x2f, 0x50, 0x61, - 0x72, 0x61, 0x6d, 0x73, 0x42, 0xbd, 0x01, 0xd8, 0xe2, 0x1e, 0x01, 0x0a, 0x17, 0x63, 0x6f, 0x6d, - 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x6f, - 0x6d, 0x69, 0x63, 0x73, 0x42, 0x0b, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x50, 0x01, 0x5a, 0x24, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, - 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x73, 0xa2, 0x02, 0x03, 0x50, 0x54, 0x58, 0xaa, - 0x02, 0x13, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x6f, 0x6d, 0x69, 0x63, 0x73, 0xca, 0x02, 0x13, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x5c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x73, 0xe2, 0x02, 0x1f, 0x50, 0x6f, - 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x5c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, - 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x14, - 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x3a, 0x3a, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x6f, - 0x6d, 0x69, 0x63, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x22, 0x2f, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x25, 0xe8, 0xa0, 0x1f, 0x01, + 0x8a, 0xe7, 0xb0, 0x2a, 0x1c, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x78, 0x2f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x73, 0x2f, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x42, 0xbd, 0x01, 0xd8, 0xe2, 0x1e, 0x01, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, + 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, + 0x73, 0x42, 0x0b, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x24, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x73, 0xa2, 0x02, 0x03, 0x50, 0x54, 0x58, 0xaa, 0x02, 0x13, 0x50, + 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, + 0x63, 0x73, 0xca, 0x02, 0x13, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x5c, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x73, 0xe2, 0x02, 0x1f, 0x50, 0x6f, 0x6b, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x5c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, 0x73, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x14, 0x50, 0x6f, 0x6b, + 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x3a, 0x3a, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x63, + 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/app/app_config.go b/app/app_config.go index d115acc24..76cc7b5b2 100644 --- a/app/app_config.go +++ b/app/app_config.go @@ -191,12 +191,17 @@ var ( ibcfeetypes.ModuleName, // chain modules servicemoduletypes.ModuleName, - gatewaymoduletypes.ModuleName, - applicationmoduletypes.ModuleName, - suppliermoduletypes.ModuleName, sessionmoduletypes.ModuleName, proofmoduletypes.ModuleName, tokenomicsmoduletypes.ModuleName, + // CRITICAL: THE ORDER HERE IS IMPORTANT AND MUST BE CAREFULLY MAINTAINED. + // Gateway, Application and Supplier end blockers should be called after the + // tokenomics module end blocker to ensure that the tokenomics module has + // processed all the pending claims, minting, burning or slashing before + // any of the actors have a chance to withdraw their tokens. + gatewaymoduletypes.ModuleName, + applicationmoduletypes.ModuleName, + suppliermoduletypes.ModuleName, sharedmoduletypes.ModuleName, // this line is used by starport scaffolding # stargate/app/endBlockers } diff --git a/config.yml b/config.yml index fcdde93e8..7921b0573 100644 --- a/config.yml +++ b/config.yml @@ -251,9 +251,11 @@ genesis: proof: params: proof_request_probability: "0.25" - proof_requirement_threshold: 20 + proof_requirement_threshold: + amount: "20000000" + denom: upokt proof_missing_penalty: - amount: "320" + amount: "320000000" denom: upokt proof_submission_fee: amount: "1000000" diff --git a/e2e/tests/0_settlement.feature b/e2e/tests/0_settlement.feature index 72d4c4a41..28278474d 100644 --- a/e2e/tests/0_settlement.feature +++ b/e2e/tests/0_settlement.feature @@ -16,15 +16,17 @@ Feature: Tokenomics Namespace And the "application" account for "app1" is staked And the service "anvil" registered for application "app1" has a compute units per relay of "1" # Start servicing relays - # Set proof_requirement_threshold to 19 < num_relays (20) * compute_units_per_relay (1) + # Set proof_requirement_threshold to 839 < num_relays (20) * compute_units_per_relay (1) * compute_units_to_tokens_multiplier (42) # to make sure a proof is required. And the "proof" module parameters are set as follows | name | value | type | | relay_difficulty_target_hash | ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff | bytes | | proof_request_probability | 0.25 | float | - | proof_requirement_threshold | 19 | int64 | + | proof_requirement_threshold | 839 | coin | | proof_missing_penalty | 320 | coin | | proof_submission_fee | 1000000 | coin | + And the "tokenomics" module parameters are set as follows + | compute_units_to_tokens_multiplier | 42 | int64 | When the supplier "supplier1" has serviced a session with "20" relays for service "anvil" for application "app1" # Wait for the Claim & Proof lifecycle And the user should wait for the "proof" module "CreateClaim" Message to be submitted @@ -46,14 +48,18 @@ Feature: Tokenomics Namespace And an account exists for "app1" And the "application" account for "app1" is staked And the service "anvil" registered for application "app1" has a compute units per relay of "1" - # Set proof_request_probability to 0 and proof_requirement_threshold to 100 to make sure a proof is not required. + # Set proof_request_probability to 0 and proof_requirement_threshold to + # 421 > num_relays (10) * compute_units_per_relay (1) * compute_units_to_tokens_multiplier (42) + # to make sure a proof is not required. And the "proof" module parameters are set as follows | name | value | type | | relay_difficulty_target_hash | ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff | bytes | | proof_request_probability | 0 | float | - | proof_requirement_threshold | 100 | int64 | + | proof_requirement_threshold | 421 | coin | | proof_missing_penalty | 320 | coin | | proof_submission_fee | 1000000 | coin | + And the "tokenomics" module parameters are set as follows + | compute_units_to_tokens_multiplier | 42 | int64 | # Start servicing When the supplier "supplier1" has serviced a session with "10" relays for service "anvil" for application "app1" # Wait for the Claim & Proof lifecycle diff --git a/e2e/tests/parse_params_test.go b/e2e/tests/parse_params_test.go index e33e1e423..abc14f5b6 100644 --- a/e2e/tests/parse_params_test.go +++ b/e2e/tests/parse_params_test.go @@ -114,8 +114,6 @@ func (s *suite) newTokenomicsMsgUpdateParams(params paramsMap) cosmostypes.Msg { for paramName, paramValue := range params { switch paramName { - case tokenomicstypes.ParamComputeUnitsToTokensMultiplier: - msgUpdateParams.Params.ComputeUnitsToTokensMultiplier = uint64(paramValue.value.(int64)) default: s.Fatalf("ERROR: unexpected %q type param name %q", paramValue.typeStr, paramName) } @@ -138,7 +136,7 @@ func (s *suite) newProofMsgUpdateParams(params paramsMap) cosmostypes.Msg { case prooftypes.ParamProofRequestProbability: msgUpdateParams.Params.ProofRequestProbability = paramValue.value.(float32) case prooftypes.ParamProofRequirementThreshold: - msgUpdateParams.Params.ProofRequirementThreshold = uint64(paramValue.value.(int64)) + msgUpdateParams.Params.ProofRequirementThreshold = paramValue.value.(*cosmostypes.Coin) case prooftypes.ParamProofMissingPenalty: msgUpdateParams.Params.ProofMissingPenalty = paramValue.value.(*cosmostypes.Coin) case prooftypes.ParamProofSubmissionFee: @@ -176,6 +174,8 @@ func (s *suite) newSharedMsgUpdateParams(params paramsMap) cosmostypes.Msg { msgUpdateParams.Params.SupplierUnbondingPeriodSessions = uint64(paramValue.value.(int64)) case sharedtypes.ParamApplicationUnbondingPeriodSessions: msgUpdateParams.Params.ApplicationUnbondingPeriodSessions = uint64(paramValue.value.(int64)) + case sharedtypes.ParamComputeUnitsToTokensMultiplier: + msgUpdateParams.Params.ComputeUnitsToTokensMultiplier = uint64(paramValue.value.(int64)) default: s.Fatalf("ERROR: unexpected %q type param name %q", paramValue.typeStr, paramName) } diff --git a/e2e/tests/session.feature b/e2e/tests/session.feature index 37d3e279c..067ce14b8 100644 --- a/e2e/tests/session.feature +++ b/e2e/tests/session.feature @@ -2,15 +2,17 @@ Feature: Session Namespace Scenario: Supplier completes claim/proof lifecycle for a valid session Given the user has the pocketd binary installed - # Set proof_requirement_threshold to 4 < num_relays (5) * compute_units_per_relay (1) + # Set proof_requirement_threshold to 209 < num_relays (5) * compute_units_per_relay (1) * compute_units_to_tokens_multiplier (42) # to make sure a proof is required. And the "proof" module parameters are set as follows | name | value | type | | relay_difficulty_target_hash | ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff | bytes | | proof_request_probability | 0.25 | float | - | proof_requirement_threshold | 4 | int64 | + | proof_requirement_threshold | 209 | coin | | proof_missing_penalty | 320 | coin | | proof_submission_fee | 1000000 | coin | + And the "tokenomics" module parameters are set as follows + | compute_units_to_tokens_multiplier | 42 | int64 | When the supplier "supplier1" has serviced a session with "5" relays for service "anvil" for application "app1" And the user should wait for the "proof" module "CreateClaim" Message to be submitted And the user should wait for the "proof" module "ClaimCreated" tx event to be broadcast diff --git a/e2e/tests/update_params.feature b/e2e/tests/update_params.feature index f0df8beaa..c1a9b77f9 100644 --- a/e2e/tests/update_params.feature +++ b/e2e/tests/update_params.feature @@ -10,26 +10,6 @@ Feature: Params Namespace 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 - Given the user has the pocketd binary installed - And all "tokenomics" module params are set to their default values - And an authz grant from the "gov" "module" account to the "pnf" "user" account for the "/poktroll.tokenomics.MsgUpdateParams" message exists - When the "unauthorized" account sends an authz exec message to update all "tokenomics" module params - | name | value | type | - | compute_units_to_tokens_multiplier | 666 | int64 | - Then all "tokenomics" module params should be set to their default values - - # NB: If you are reading this and the tokenomics module has parameters - # that are not being updated in this test, please update the test. - Scenario: An authorized user updates all "tokenomics" module params - Given the user has the pocketd binary installed - And all "tokenomics" module params are set to their default values - And an authz grant from the "gov" "module" account to the "pnf" "user" account for the "/poktroll.tokenomics.MsgUpdateParams" message exists - When the "pnf" account sends an authz exec message to update all "tokenomics" module params - | name | value | type | - | compute_units_to_tokens_multiplier | 420 | int64 | - Then all "tokenomics" module params should be updated - # NB: If you are reading this and the proof module has parameters # that are not being updated in this test, please update the test. Scenario: An authorized user updates all "proof" module params @@ -40,7 +20,7 @@ Feature: Params Namespace | name | value | type | | relay_difficulty_target_hash | 00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff | bytes | | proof_request_probability | 0.1 | float | - | proof_requirement_threshold | 100 | int64 | + | proof_requirement_threshold | 100 | coin | | proof_missing_penalty | 500 | coin | | proof_submission_fee | 5000000 | coin | Then all "proof" module params should be updated @@ -61,6 +41,7 @@ Feature: Params Namespace | proof_window_close_offset_blocks | 5 | int64 | | supplier_unbonding_period_sessions | 5 | int64 | | application_unbonding_period_sessions | 5 | int64 | + | compute_units_to_tokens_multiplier | 666 | int64 | Then all "shared" module params should be updated @@ -87,22 +68,22 @@ Feature: Params Namespace Then the "" module param "" should be updated Examples: - | module | message_type | param_name | param_value | param_type | - | tokenomics | /poktroll.tokenomics.MsgUpdateParam | compute_units_to_tokens_multiplier | 68 | int64 | - | proof | /poktroll.proof.MsgUpdateParam | min_relay_difficulty_bits | 12 | int64 | - | proof | /poktroll.proof.MsgUpdateParam | proof_request_probability | 0.1 | float | - | proof | /poktroll.proof.MsgUpdateParam | proof_requirement_threshold | 100 | int64 | - | proof | /poktroll.proof.MsgUpdateParam | proof_missing_penalty | 500 | coin | - | proof | /poktroll.proof.MsgUpdateParam | proof_submission_fee | 5000000 | coin | - | shared | /poktroll.shared.MsgUpdateParam | num_blocks_per_session | 5 | int64 | - | shared | /poktroll.shared.MsgUpdateParam | grace_period_end_offset_blocks | 2 | int64 | - | shared | /poktroll.shared.MsgUpdateParam | claim_window_open_offset_blocks | 2 | int64 | - | shared | /poktroll.shared.MsgUpdateParam | claim_window_close_offset_blocks | 3 | int64 | - | shared | /poktroll.shared.MsgUpdateParam | proof_window_open_offset_blocks | 1 | int64 | - | shared | /poktroll.shared.MsgUpdateParam | proof_window_close_offset_blocks | 5 | int64 | - | shared | /poktroll.shared.MsgUpdateParam | supplier_unbonding_period_sessions | 5 | int64 | - | shared | /poktroll.shared.MsgUpdateParam | application_unbonding_period_sessions | 5 | int64 | - | service | /poktroll.service.MsgUpdateParam | add_service_fee | 1000000001 | coin | + | module | message_type | param_name | param_value | param_type | + | proof | /poktroll.proof.MsgUpdateParam | min_relay_difficulty_bits | 12 | int64 | + | proof | /poktroll.proof.MsgUpdateParam | proof_request_probability | 0.1 | float | + | proof | /poktroll.proof.MsgUpdateParam | proof_requirement_threshold | 100 | coin | + | proof | /poktroll.proof.MsgUpdateParam | proof_missing_penalty | 500 | coin | + | proof | /poktroll.proof.MsgUpdateParam | proof_submission_fee | 5000000 | coin | + | shared | /poktroll.shared.MsgUpdateParam | num_blocks_per_session | 5 | int64 | + | shared | /poktroll.shared.MsgUpdateParam | grace_period_end_offset_blocks | 2 | int64 | + | shared | /poktroll.shared.MsgUpdateParam | claim_window_open_offset_blocks | 2 | int64 | + | shared | /poktroll.shared.MsgUpdateParam | claim_window_close_offset_blocks | 3 | int64 | + | shared | /poktroll.shared.MsgUpdateParam | proof_window_open_offset_blocks | 1 | int64 | + | shared | /poktroll.shared.MsgUpdateParam | proof_window_close_offset_blocks | 5 | int64 | + | shared | /poktroll.shared.MsgUpdateParam | supplier_unbonding_period_sessions | 5 | int64 | + | shared | /poktroll.shared.MsgUpdateParam | application_unbonding_period_sessions | 5 | int64 | + | shared | /poktroll.shared.MsgUpdateParam | compute_units_to_tokens_multiplier | 68 | int64 | + | service | /poktroll.service.MsgUpdateParam | add_service_fee | 1000000001 | coin | Scenario: An unauthorized user cannot update individual module params Given the user has the pocketd binary installed diff --git a/e2e/tests/update_params_test.go b/e2e/tests/update_params_test.go index c13b1dfc6..78b9b5453 100644 --- a/e2e/tests/update_params_test.go +++ b/e2e/tests/update_params_test.go @@ -262,7 +262,7 @@ func (s *suite) TheModuleParamShouldBeUpdated(moduleName, paramName string) { require.True(s, ok, "module %q params expectation not set on the test suite", moduleName) var foundExpectedParam bool - for expectedParamName, _ := range moduleParamsMap { + for expectedParamName := range moduleParamsMap { if paramName == expectedParamName { foundExpectedParam = true break @@ -360,13 +360,10 @@ func (s *suite) assertExpectedModuleParamsUpdated(moduleName string) { switch moduleName { case tokenomicstypes.ModuleName: - computeUnitsToTokensMultiplier := uint64(s.expectedModuleParams[moduleName][tokenomicstypes.ParamComputeUnitsToTokensMultiplier].value.(int64)) assertUpdatedParams(s, []byte(res.Stdout), &tokenomicstypes.QueryParamsResponse{ - Params: tokenomicstypes.Params{ - ComputeUnitsToTokensMultiplier: computeUnitsToTokensMultiplier, - }, + Params: tokenomicstypes.Params{}, }, ) case prooftypes.ModuleName: @@ -385,7 +382,7 @@ func (s *suite) assertExpectedModuleParamsUpdated(moduleName string) { proofRequirementThreshold, ok := paramsMap[prooftypes.ParamProofRequirementThreshold] if ok { - params.ProofRequirementThreshold = uint64(proofRequirementThreshold.value.(int64)) + params.ProofRequirementThreshold = proofRequirementThreshold.value.(*cosmostypes.Coin) } proofMissingPenalty, ok := paramsMap[prooftypes.ParamProofMissingPenalty] @@ -448,6 +445,11 @@ func (s *suite) assertExpectedModuleParamsUpdated(moduleName string) { params.ApplicationUnbondingPeriodSessions = uint64(applicationUnbondingPeriodSessions.value.(int64)) } + computeUnitsToTokensMultiplier, ok := paramsMap[sharedtypes.ParamComputeUnitsToTokensMultiplier] + if ok { + params.ComputeUnitsToTokensMultiplier = uint64(computeUnitsToTokensMultiplier.value.(int64)) + } + assertUpdatedParams(s, []byte(res.Stdout), &sharedtypes.QueryParamsResponse{ diff --git a/load-testing/tests/relays_stress_helpers_test.go b/load-testing/tests/relays_stress_helpers_test.go index 4c034ba04..a6e618d9b 100644 --- a/load-testing/tests/relays_stress_helpers_test.go +++ b/load-testing/tests/relays_stress_helpers_test.go @@ -28,7 +28,6 @@ import ( "github.com/regen-network/gocuke" "github.com/stretchr/testify/require" - "github.com/pokt-network/poktroll/api/poktroll/tokenomics" "github.com/pokt-network/poktroll/load-testing/config" "github.com/pokt-network/poktroll/pkg/client" "github.com/pokt-network/poktroll/pkg/client/events" @@ -1185,9 +1184,9 @@ func (s *relaysSuite) getRelayCost() int64 { // Set up the tokenomics client. flagSet := testclient.NewLocalnetFlagSet(s) clientCtx := testclient.NewLocalnetClientCtx(s, flagSet) - tokenomicsClient := tokenomics.NewQueryClient(clientCtx) + sharedClient := sharedtypes.NewQueryClient(clientCtx) - res, err := tokenomicsClient.Params(s.ctx, &tokenomics.QueryParamsRequest{}) + res, err := sharedClient.Params(s.ctx, &sharedtypes.QueryParamsRequest{}) require.NoError(s, err) return int64(res.Params.ComputeUnitsToTokensMultiplier) diff --git a/pkg/client/interface.go b/pkg/client/interface.go index 9b0b476e9..e240eba9a 100644 --- a/pkg/client/interface.go +++ b/pkg/client/interface.go @@ -324,6 +324,8 @@ type SharedQueryClient interface { // GetEarliestSupplierProofCommitHeight returns the earliest block height at which a proof // for the session that includes queryHeight can be committed for a given supplier. GetEarliestSupplierProofCommitHeight(ctx context.Context, queryHeight int64, supplierOperatorAddr string) (int64, error) + // GetComputeUnitsToTokensMultiplier returns the multiplier used to convert compute units to tokens. + GetComputeUnitsToTokensMultiplier(ctx context.Context) (uint64, error) } // BlockQueryClient defines an interface that enables the querying of @@ -338,8 +340,9 @@ type BlockQueryClient interface { // is necessary to prevent dependency cycles. type ProofParams interface { GetProofRequestProbability() float32 - GetProofRequirementThreshold() uint64 + GetProofRequirementThreshold() *cosmostypes.Coin GetProofMissingPenalty() *cosmostypes.Coin + GetProofSubmissionFee() *cosmostypes.Coin } // ProofQueryClient defines an interface that enables the querying of the @@ -355,8 +358,11 @@ type TokenomicsRelayMiningDifficulty interface { GetTargetHash() []byte } +// TokenomicsQueryClient defines an interface that enables the querying of the +// on-chain tokenomics information type TokenomicsQueryClient interface { GetServiceRelayDifficultyTargetHash(ctx context.Context, serviceId string) (TokenomicsRelayMiningDifficulty, error) + // GetParams queries the chain for the current tokenomics module parameters. } // ServiceQueryClient defines an interface that enables the querying of the diff --git a/pkg/client/query/sharedquerier.go b/pkg/client/query/sharedquerier.go index e3fa78d87..4f0fb7691 100644 --- a/pkg/client/query/sharedquerier.go +++ b/pkg/client/query/sharedquerier.go @@ -173,3 +173,18 @@ func (sq *sharedQuerier) GetEarliestSupplierProofCommitHeight(ctx context.Contex supplierOperatorAddr, ), nil } + +// GetComputeUnitsToTokensMultiplier returns the multiplier used to convert compute units to tokens. +// +// TODO_TECHDEBT(#543): We don't really want to have to query the params for every method call. +// Once `ModuleParamsClient` is implemented, use its replay observable's `#Last()` method +// to get the most recently (asynchronously) observed (and cached) value. +// TODO_BLOCKER(@bryanchriswhite, #543): We also don't really want to use the current value of the params. +// Instead, we should be using the value that the params had for the session which includes queryHeight. +func (sq *sharedQuerier) GetComputeUnitsToTokensMultiplier(ctx context.Context) (uint64, error) { + sharedParams, err := sq.GetParams(ctx) + if err != nil { + return 0, err + } + return sharedParams.GetComputeUnitsToTokensMultiplier(), nil +} diff --git a/pkg/relayer/session/claim.go b/pkg/relayer/session/claim.go index 44ef4edc7..08421517a 100644 --- a/pkg/relayer/session/claim.go +++ b/pkg/relayer/session/claim.go @@ -180,6 +180,11 @@ func (rs *relayerSessionsManager) newMapClaimSessionsFn( return either.Success(sessionTrees), false } + // TODO_FOLLOWUP(@red-0ne): Ensure that the supplier operator account + // has enough funds to cover for any potential proof submission in order to + // avoid slashing due to missing proofs. + // We should order the claimMsgs by reward amount and include claims up to + // whatever the supplier can afford to cover. claimMsgs := make([]client.MsgCreateClaim, len(sessionTrees)) for idx, sessionTree := range sessionTrees { claimMsgs[idx] = &prooftypes.MsgCreateClaim{ diff --git a/pkg/relayer/session/proof.go b/pkg/relayer/session/proof.go index da8347c0b..1b97e838e 100644 --- a/pkg/relayer/session/proof.go +++ b/pkg/relayer/session/proof.go @@ -15,6 +15,7 @@ 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. @@ -287,14 +288,25 @@ func (rs *relayerSessionsManager) isProofRequired( return false, err } + sharedParams, err := rs.sharedQueryClient.GetParams(ctx) + if err != nil { + return false, err + } + + // The amount of uPOKT being claimed. + claimedAmount, err := tokenomics.NumComputeUnitsToCoin(*sharedParams, numClaimComputeUnits) + if err != nil { + return false, err + } + logger = logger.With( - "num_claim_compute_units", numClaimComputeUnits, - "proof_requirement_threshold", proofParams.GetProofRequirementThreshold(), + "claimed_amount_upokt", claimedAmount.Amount.Uint64(), + "proof_requirement_threshold_upokt", proofParams.GetProofRequirementThreshold(), ) - // Require a proof if the claim's compute units meets or exceeds the threshold. + // Require a proof if the claimed amount meets or exceeds the threshold. // TODO_MAINNET: This should be proportional to the supplier's stake as well. - if numClaimComputeUnits >= proofParams.GetProofRequirementThreshold() { + if claimedAmount.Amount.GTE(proofParams.GetProofRequirementThreshold().Amount) { logger.Info().Msg("compute units is above threshold, claim requires proof") return true, nil diff --git a/pkg/relayer/session/session.go b/pkg/relayer/session/session.go index e03a95a55..625d09433 100644 --- a/pkg/relayer/session/session.go +++ b/pkg/relayer/session/session.go @@ -64,6 +64,9 @@ type relayerSessionsManager struct { // requirement probability governance parameters to determine whether a submitted // claim requires a proof. proofQueryClient client.ProofQueryClient + + // tokenomicsQueryClient is used to query for the tokenomics module parameters. + tokenomicsQueryClient client.TokenomicsQueryClient } // NewRelayerSessions creates a new relayerSessions. @@ -94,6 +97,7 @@ func NewRelayerSessions( &rs.sharedQueryClient, &rs.serviceQueryClient, &rs.proofQueryClient, + &rs.tokenomicsQueryClient, ); err != nil { return nil, err } diff --git a/pkg/relayer/session/session_test.go b/pkg/relayer/session/session_test.go index 44a52ffb3..baea42f2d 100644 --- a/pkg/relayer/session/session_test.go +++ b/pkg/relayer/session/session_test.go @@ -8,12 +8,15 @@ import ( "time" "cosmossdk.io/depinject" + sdkmath "cosmossdk.io/math" coretypes "github.com/cometbft/cometbft/rpc/core/types" cmttypes "github.com/cometbft/cometbft/types" + sdktypes "github.com/cosmos/cosmos-sdk/types" "github.com/golang/mock/gomock" "github.com/pokt-network/smt" "github.com/stretchr/testify/require" + "github.com/pokt-network/poktroll/app/volatile" "github.com/pokt-network/poktroll/pkg/client" "github.com/pokt-network/poktroll/pkg/observable/channel" "github.com/pokt-network/poktroll/pkg/polylog/polyzero" @@ -103,6 +106,7 @@ func requireProofCountEqualsExpectedValueFromProofParams(t *testing.T, proofPara serviceQueryClientMock := testqueryclients.NewTestServiceQueryClient(t) proofQueryClientMock := testqueryclients.NewTestProofQueryClientWithParams(t, &proofParams) + tokenomicsQueryClient := testqueryclients.NewTestTokenomicsQueryClient(t) deps := depinject.Supply( blockClient, @@ -111,6 +115,7 @@ func requireProofCountEqualsExpectedValueFromProofParams(t *testing.T, proofPara sharedQueryClientMock, serviceQueryClientMock, proofQueryClientMock, + tokenomicsQueryClient, ) storesDirectoryOpt := testrelayer.WithTempStoresDirectory(t) @@ -192,7 +197,7 @@ func TestRelayerSessionsManager_ProofThresholdRequired(t *testing.T) { proofParams := prooftypes.DefaultParams() // Set proof requirement threshold to a low enough value so a proof is always requested. - proofParams.ProofRequirementThreshold = 1 + proofParams.ProofRequirementThreshold = &sdktypes.Coin{Denom: volatile.DenomuPOKT, Amount: sdkmath.NewInt(1)} // The test is submitting a single claim. Having the proof requirement threshold // set to 1 results in exactly 1 proof being requested. @@ -204,8 +209,8 @@ func TestRelayerSessionsManager_ProofThresholdRequired(t *testing.T) { func TestRelayerSessionsManager_ProofProbabilityRequired(t *testing.T) { proofParams := prooftypes.DefaultParams() - // Set proof requirement threshold to max uint64 to skip the threshold check. - proofParams.ProofRequirementThreshold = math.MaxUint64 + // Set proof requirement threshold to max int64 to skip the threshold check. + proofParams.ProofRequirementThreshold = &sdktypes.Coin{Denom: volatile.DenomuPOKT, Amount: sdkmath.NewInt(math.MaxInt64)} // Set proof request probability to 1 so a proof is always requested. proofParams.ProofRequestProbability = 1 @@ -219,8 +224,8 @@ func TestRelayerSessionsManager_ProofProbabilityRequired(t *testing.T) { func TestRelayerSessionsManager_ProofNotRequired(t *testing.T) { proofParams := prooftypes.DefaultParams() - // Set proof requirement threshold to max uint64 to skip the threshold check. - proofParams.ProofRequirementThreshold = math.MaxUint64 + // Set proof requirement threshold to max int64 to skip the threshold check. + proofParams.ProofRequirementThreshold = &sdktypes.Coin{Denom: volatile.DenomuPOKT, Amount: sdkmath.NewInt(math.MaxInt64)} // Set proof request probability to 0 so a proof is never requested. proofParams.ProofRequestProbability = 0 diff --git a/proto/poktroll/proof/params.proto b/proto/poktroll/proof/params.proto index a92205188..2b8a97a22 100644 --- a/proto/poktroll/proof/params.proto +++ b/proto/poktroll/proof/params.proto @@ -26,18 +26,20 @@ message Params { // is equal to or above the threshold. This is in contrast to the this requirement // being determined probabilistically via ProofRequestProbability. // - // TODO_MAINNET: Consider renaming this to `proof_requirement_threshold_compute_units`. - uint64 proof_requirement_threshold = 3 [(gogoproto.jsontag) = "proof_requirement_threshold"]; + // TODO_MAINNET: Consider renaming this to `proof_requirement_threshold_upokt`. + cosmos.base.v1beta1.Coin proof_requirement_threshold = 3 [(gogoproto.jsontag) = "proof_requirement_threshold"]; // proof_missing_penalty is the number of tokens (uPOKT) which should be slashed from a supplier // when a proof is required (either via proof_requirement_threshold or proof_missing_penalty) // but is not provided. + // TODO_MAINNET: Consider renaming this to `proof_missing_penalty_upokt`. cosmos.base.v1beta1.Coin proof_missing_penalty = 4 [(gogoproto.jsontag) = "proof_missing_penalty"]; // proof_submission_fee is the number of tokens (uPOKT) which should be paid by // the supplier operator when submitting a proof. // This is needed to account for the cost of storing proofs on-chain and prevent // spamming (i.e. sybil bloat attacks) the network with non-required proofs. + // TODO_MAINNET: Consider renaming this to `proof_submission_fee_upokt`. cosmos.base.v1beta1.Coin proof_submission_fee = 5 [(gogoproto.jsontag) = "proof_submission_fee"]; // IMPORTANT: Make sure to update all related files if you're modifying or adding a new parameter. diff --git a/proto/poktroll/shared/params.proto b/proto/poktroll/shared/params.proto index 765f456f1..327491922 100644 --- a/proto/poktroll/shared/params.proto +++ b/proto/poktroll/shared/params.proto @@ -41,4 +41,7 @@ message Params { // On-chain business logic requires, and ensures, that the corresponding block count of the // application unbonding period will exceed the end of its corresponding proof window close height. uint64 application_unbonding_period_sessions = 8 [(gogoproto.jsontag) = "application_unbonding_period_sessions"]; + // The amount of upokt that a compute unit should translate to when settling a session. + // DEV_NOTE: This used to be under x/tokenomics but has been moved here to avoid cyclic dependencies. + uint64 compute_units_to_tokens_multiplier = 9 [(gogoproto.jsontag) = "compute_units_to_tokens_multiplier", (gogoproto.moretags) = "yaml:\"compute_units_to_tokens_multiplier\""]; } diff --git a/proto/poktroll/tokenomics/event.proto b/proto/poktroll/tokenomics/event.proto index 11d8f1b0b..4c6f319b5 100644 --- a/proto/poktroll/tokenomics/event.proto +++ b/proto/poktroll/tokenomics/event.proto @@ -59,4 +59,15 @@ message EventApplicationOverserviced { // is a function of the relay mining algorithm. // E.g. The application's stake divided by the number of suppliers in a session. cosmos.base.v1beta1.Coin effective_burn = 4; +} + +// EventSupplierSlashed is emitted when a supplier is slashed for not providing, +// or provided invalid required proofs for claims. +message EventSupplierSlashed { + string supplier_operator_addr = 1; + // Number of expired claims (due to missing or invalid proof) that led to slashing. + uint64 num_expired_claims = 2; + // Amount slashed from the supplier's stake due to the expired claims. + // This is a function of the number of expired claims and proof missing penalty. + cosmos.base.v1beta1.Coin slashing_amount = 3; } \ No newline at end of file diff --git a/proto/poktroll/tokenomics/params.proto b/proto/poktroll/tokenomics/params.proto index 636787cb0..b36c48403 100644 --- a/proto/poktroll/tokenomics/params.proto +++ b/proto/poktroll/tokenomics/params.proto @@ -12,9 +12,6 @@ message Params { option (amino.name) = "poktroll/x/tokenomics/Params"; option (gogoproto.equal) = true; - // The amount of upokt that a compute unit should translate to when settling a session. - uint64 compute_units_to_tokens_multiplier = 1 [(gogoproto.jsontag) = "compute_units_to_tokens_multiplier", (gogoproto.moretags) = "yaml:\"compute_units_to_tokens_multiplier\""]; - // IMPORTANT: Make sure to update all related files if you're modifying or adding a new parameter. // Try the following grep to find all related places: `grep -r compute_units_to_tokens_multiplier` // TODO_IMPROVE: Look into an opportunity to use an enum to avoid using strings throughout the codebase. diff --git a/tests/integration/tokenomics/relay_mining_difficulty_test.go b/tests/integration/tokenomics/relay_mining_difficulty_test.go index 6e7b86f2a..f64c8a2d8 100644 --- a/tests/integration/tokenomics/relay_mining_difficulty_test.go +++ b/tests/integration/tokenomics/relay_mining_difficulty_test.go @@ -26,7 +26,7 @@ func init() { } func TestUpdateRelayMiningDifficulty_NewServiceSeenForTheFirstTime(t *testing.T) { - var claimWindowOpenBlockHash, proofWindowOpenBlockHash, proofPathSeedBlockHash []byte + var claimWindowOpenBlockHash, proofWindowOpenBlockHash []byte // Create a new integration app integrationApp := integration.NewCompleteIntegrationApp(t) @@ -85,19 +85,6 @@ func TestUpdateRelayMiningDifficulty_NewServiceSeenForTheFirstTime(t *testing.T) require.Greater(t, numBlocksUntilProofWindowOpenHeight, int64(0), "unexpected non-positive number of blocks until the earliest proof commit height") integrationApp.NextBlocks(t, int(numBlocksUntilProofWindowOpenHeight)) - // Construct a new proof message and commit it - createProofMsg := prooftypes.MsgSubmitProof{ - SupplierOperatorAddress: integrationApp.DefaultSupplier.OperatorAddress, - SessionHeader: session.Header, - Proof: getProof(t, trie, proofPathSeedBlockHash, session.GetHeader().GetSessionId()), - } - result = integrationApp.RunMsg(t, - &createProofMsg, - integration.WithAutomaticFinalizeBlock(), - integration.WithAutomaticCommit(), - ) - require.NotNil(t, result, "unexpected nil result when submitting a MsgSubmitProof tx") - // Wait until the proof window is closed currentBlockHeight = sdkCtx.BlockHeight() numBlocksUntilProofWindowCloseHeight := proofWindowCloseHeight - currentBlockHeight @@ -202,24 +189,3 @@ func prepareSMST( return trie } - -// getProof returns a proof for the given session for the empty path. -// If there is only one relay in the trie, the proof will be for that single -// relay since it is "closest" to any path provided, empty or not. -func getProof( - t *testing.T, - trie *smt.SMST, - pathSeedBlockHash []byte, - sessionId string, -) []byte { - t.Helper() - - path := protocol.GetPathForProof(pathSeedBlockHash, sessionId) - proof, err := trie.ProveClosest(path) - require.NoError(t, err) - - proofBz, err := proof.Marshal() - require.NoError(t, err) - - return proofBz -} diff --git a/tests/integration/tokenomics/tokenomics_example_test.go b/tests/integration/tokenomics/tokenomics_example_test.go index fbd611e3e..6fcaf2451 100644 --- a/tests/integration/tokenomics/tokenomics_example_test.go +++ b/tests/integration/tokenomics/tokenomics_example_test.go @@ -12,7 +12,6 @@ import ( 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" - tokenomicstypes "github.com/pokt-network/poktroll/x/tokenomics/types" ) func init() { @@ -38,27 +37,6 @@ func TestTokenomicsIntegrationExample(t *testing.T) { sharedParams := sharedQueryRes.GetParams() - // Prepare a request to update the compute_units_to_tokens_multiplier - updateTokenomicsParamMsg := &tokenomicstypes.MsgUpdateParam{ - Authority: integrationApp.GetAuthority(), - Name: tokenomicstypes.ParamComputeUnitsToTokensMultiplier, - AsType: &tokenomicstypes.MsgUpdateParam_AsInt64{AsInt64: 11}, - } - - // Run the request - result := integrationApp.RunMsg(t, - updateTokenomicsParamMsg, - integration.WithAutomaticFinalizeBlock(), - integration.WithAutomaticCommit(), - ) - require.NotNil(t, result, "unexpected nil result") - - // Validate the response is correct and that the value was updated - updateTokenomicsParamRes := tokenomicstypes.MsgUpdateParamResponse{} - err = integrationApp.GetCodec().Unmarshal(result.Value, &updateTokenomicsParamRes) - require.NoError(t, err) - require.EqualValues(t, uint64(11), uint64(updateTokenomicsParamRes.Params.ComputeUnitsToTokensMultiplier)) - // Prepare a request to query a session so it can be used to create a claim. sessionQueryClient := sessiontypes.NewQueryClient(integrationApp.QueryHelper()) getSessionReq := sessiontypes.QueryGetSessionRequest{ @@ -99,7 +77,7 @@ func TestTokenomicsIntegrationExample(t *testing.T) { } // Run the message to create the claim - result = integrationApp.RunMsg(t, + result := integrationApp.RunMsg(t, &createClaimMsg, integration.WithAutomaticFinalizeBlock(), integration.WithAutomaticCommit(), diff --git a/testutil/keeper/tokenomics.go b/testutil/keeper/tokenomics.go index d9e9f7d4a..9105981c8 100644 --- a/testutil/keeper/tokenomics.go +++ b/testutil/keeper/tokenomics.go @@ -201,6 +201,10 @@ func TokenomicsKeeperWithActorAddrs(t testing.TB) ( // Mock the shared keeper mockSharedKeeper := mocks.NewMockSharedKeeper(ctrl) mockSharedKeeper.EXPECT().GetProofWindowCloseHeight(gomock.Any(), gomock.Any()).AnyTimes() + mockSharedKeeper.EXPECT(). + GetParams(gomock.Any()). + Return(sharedtypes.DefaultParams()). + AnyTimes() // Mock the session keeper mockSessionKeeper := mocks.NewMockSessionKeeper(ctrl) diff --git a/tools/scripts/params/proof_all.json b/tools/scripts/params/proof_all.json index 97fc0e2dd..182ce6316 100644 --- a/tools/scripts/params/proof_all.json +++ b/tools/scripts/params/proof_all.json @@ -7,9 +7,12 @@ "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": "320", + "amount": "320000000", "denom": "upokt" }, "proof_submission_fee": { diff --git a/tools/scripts/params/proof_proof_missing_penalty.json b/tools/scripts/params/proof_proof_missing_penalty.json index f0b564f3f..fca5a010a 100644 --- a/tools/scripts/params/proof_proof_missing_penalty.json +++ b/tools/scripts/params/proof_proof_missing_penalty.json @@ -7,7 +7,7 @@ "name": "proof_missing_penalty", "as_coin": { "denom": "upokt", - "amount": "320" + "amount": "320000000" } } ] diff --git a/tools/scripts/params/proof_proof_requirement_threshold.json b/tools/scripts/params/proof_proof_requirement_threshold.json index f237a8b0b..94155c57f 100644 --- a/tools/scripts/params/proof_proof_requirement_threshold.json +++ b/tools/scripts/params/proof_proof_requirement_threshold.json @@ -5,7 +5,10 @@ "@type": "/poktroll.proof.MsgUpdateParam", "authority": "pokt10d07y265gmmuvt4z0w9aw880jnsr700j8yv32t", "name": "proof_requirement_threshold", - "as_int64": "20" + "as_coin": { + "denom": "upokt", + "amount": "20000000" + } } ] } diff --git a/x/proof/keeper/msg_server_submit_proof.go b/x/proof/keeper/msg_server_submit_proof.go index 84b52c1f2..2ddcdb348 100644 --- a/x/proof/keeper/msg_server_submit_proof.go +++ b/x/proof/keeper/msg_server_submit_proof.go @@ -15,7 +15,9 @@ import ( "github.com/pokt-network/poktroll/telemetry" "github.com/pokt-network/poktroll/x/proof/types" + "github.com/pokt-network/poktroll/x/shared" sharedtypes "github.com/pokt-network/poktroll/x/shared/types" + "github.com/pokt-network/poktroll/x/tokenomics" ) // SubmitProof is the server handler to submit and store a proof on-chain. @@ -103,6 +105,16 @@ func (k msgServer) SubmitProof( return nil, status.Error(codes.Internal, types.ErrProofClaimNotFound.Wrap(err.Error()).Error()) } + // Check if a proof is required for the claim. + proofRequirement, err := k.ProofRequirementForClaim(ctx, claim) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + if proofRequirement == types.ProofRequirementReason_NOT_REQUIRED { + logger.Warn("trying to submit a proof for a claim that does not require one") + return nil, status.Error(codes.FailedPrecondition, types.ErrProofNotRequired.Error()) + } + // Get metadata for the event we want to emit numRelays, err = claim.GetNumRelays() if err != nil { @@ -191,3 +203,121 @@ func (k Keeper) deductProofSubmissionFee(ctx context.Context, supplierOperatorAd return nil } + +// ProofRequirementForClaim checks if a proof is required for a claim. +// If it is not, the claim will be settled without a proof. +// If it is, the claim will only be settled if a valid proof is available. +// TODO_BLOCKER(@olshansk, #419): Document safety assumptions of the probabilistic proofs mechanism. +func (k Keeper) ProofRequirementForClaim(ctx context.Context, claim *types.Claim) (_ types.ProofRequirementReason, err error) { + logger := k.logger.With("method", "proofRequirementForClaim") + + var requirementReason = types.ProofRequirementReason_NOT_REQUIRED + + // Defer telemetry calls so that they reference the final values the relevant variables. + defer func() { + telemetry.ProofRequirementCounter(requirementReason, err) + }() + + // NB: Assumption that claim is non-nil and has a valid root sum because it + // is retrieved from the store and validated, on-chain, at time of creation. + var numClaimComputeUnits uint64 + numClaimComputeUnits, err = claim.GetNumComputeUnits() + if err != nil { + return requirementReason, err + } + + proofParams := k.GetParams(ctx) + sharedParams := k.sharedKeeper.GetParams(ctx) + + // Retrieve the number of tokens claimed to compare against the threshold. + // Different services have varying compute_unit -> token multipliers, so the + // threshold value is done in a common unit denomination. + claimeduPOKT, err := tokenomics.NumComputeUnitsToCoin(sharedParams, numClaimComputeUnits) + if err != nil { + return requirementReason, err + } + + // Require a proof if the claim's compute units meets or exceeds the threshold. + // + // TODO_BLOCKER(@Olshansk, #419): This is just VERY BASIC placeholder logic to have something + // in place while we implement proper probabilistic proofs. If you're reading it, + // do not overthink it and look at the documents linked in #419. + // + // TODO_IMPROVE(@bryanchriswhite, @red-0ne): It might make sense to include + // whether there was a proof submission error downstream from here. This would + // require a more comprehensive metrics API. + if claimeduPOKT.Amount.GTE(proofParams.GetProofRequirementThreshold().Amount) { + requirementReason = types.ProofRequirementReason_THRESHOLD + + logger.Info(fmt.Sprintf( + "claim requires proof due to compute units (%s) exceeding threshold (%s)", + claimeduPOKT, + proofParams.GetProofRequirementThreshold(), + )) + return requirementReason, nil + } + + // Hash of block when proof submission is allowed. + earliestProofCommitBlockHash, err := k.getEarliestSupplierProofCommitBlockHash(ctx, claim) + if err != nil { + return requirementReason, err + } + + // The probability that a proof is required. + proofRequirementSampleValue, err := claim.GetProofRequirementSampleValue(earliestProofCommitBlockHash) + if err != nil { + return requirementReason, err + } + + // Require a proof probabilistically based on the proof_request_probability param. + // NB: A random value between 0 and 1 will be less than or equal to proof_request_probability + // with probability equal to the proof_request_probability. + if proofRequirementSampleValue <= proofParams.GetProofRequestProbability() { + requirementReason = types.ProofRequirementReason_PROBABILISTIC + + logger.Info(fmt.Sprintf( + "claim requires proof due to random sample (%.2f) being less than or equal to probability (%.2f)", + proofRequirementSampleValue, + proofParams.GetProofRequestProbability(), + )) + return requirementReason, nil + } + + logger.Info(fmt.Sprintf( + "claim does not require proof due to claimed amount (%s) being less than the threshold (%s) and random sample (%.2f) being greater than probability (%.2f)", + claimeduPOKT, + proofParams.GetProofRequirementThreshold(), + proofRequirementSampleValue, + proofParams.GetProofRequestProbability(), + )) + return requirementReason, nil +} + +// getEarliestSupplierProofCommitBlockHash returns the block hash of the earliest +// block at which a claim may have its proof committed. +func (k Keeper) getEarliestSupplierProofCommitBlockHash( + ctx context.Context, + claim *types.Claim, +) (blockHash []byte, err error) { + sharedParams, err := k.sharedQuerier.GetParams(ctx) + if err != nil { + return nil, err + } + + sessionEndHeight := claim.GetSessionHeader().GetSessionEndBlockHeight() + supplierOperatorAddress := claim.GetSupplierOperatorAddress() + + proofWindowOpenHeight := shared.GetProofWindowOpenHeight(sharedParams, sessionEndHeight) + proofWindowOpenBlockHash := k.sessionKeeper.GetBlockHash(ctx, proofWindowOpenHeight) + + // TODO_TECHDEBT(@red-0ne): Update the method header of this function to accept (sharedParams, Claim, BlockHash). + // After doing so, please review all calling sites and simplify them accordingly. + earliestSupplierProofCommitHeight := shared.GetEarliestSupplierProofCommitHeight( + sharedParams, + sessionEndHeight, + proofWindowOpenBlockHash, + supplierOperatorAddress, + ) + + return k.sessionKeeper.GetBlockHash(ctx, earliestSupplierProofCommitHeight), nil +} diff --git a/x/proof/keeper/msg_server_submit_proof_test.go b/x/proof/keeper/msg_server_submit_proof_test.go index 7827a701e..11eafd54d 100644 --- a/x/proof/keeper/msg_server_submit_proof_test.go +++ b/x/proof/keeper/msg_server_submit_proof_test.go @@ -692,6 +692,143 @@ func TestMsgServer_SubmitProof_Error(t *testing.T) { } } +func TestMsgServer_SubmitProof_FailSubmittingNonRequiredProof(t *testing.T) { + opts := []keepertest.ProofKeepersOpt{ + // Set block hash so we can have a deterministic expected on-chain proof requested by the protocol. + keepertest.WithBlockHash(blockHeaderHash), + // Set block height to 1 so there is a valid session on-chain. + keepertest.WithBlockHeight(1), + } + keepers, ctx := keepertest.NewProofModuleKeepers(t, opts...) + sharedParams := keepers.SharedKeeper.GetParams(ctx) + + // Set proof keeper params to disable relay mining but never require a proof. + proofParams := keepers.Keeper.GetParams(ctx) + proofParams.ProofRequestProbability = 0 + proofParams.RelayDifficultyTargetHash = testProofParams.RelayDifficultyTargetHash + err := keepers.Keeper.SetParams(ctx, proofParams) + require.NoError(t, err) + + // Construct a keyring to hold the keypairs for the accounts used in the test. + keyRing := keyring.NewInMemory(keepers.Codec) + + // Create a pre-generated account iterator to create accounts for the test. + preGeneratedAccts := testkeyring.PreGeneratedAccounts() + + // Create accounts in the account keeper with corresponding keys in the + // keyring for the application and supplier. + supplierOperatorAddr := testkeyring.CreateOnChainAccount( + ctx, t, + supplierOperatorUid, + keyRing, + keepers, + preGeneratedAccts, + ).String() + appAddr := testkeyring.CreateOnChainAccount( + ctx, t, + "app", + keyRing, + keepers, + preGeneratedAccts, + ).String() + + fundSupplierOperatorAccount(t, ctx, keepers, supplierOperatorAddr) + + service := &sharedtypes.Service{ + Id: testServiceId, + ComputeUnitsPerRelay: computeUnitsPerRelay, + OwnerAddress: sample.AccAddress(), + } + + // Add a supplier and application pair that are expected to be in the session. + keepers.AddServiceActors(ctx, t, service, supplierOperatorAddr, appAddr) + + // Get the session for the application/supplier pair which is expected + // to be claimed and for which a valid proof would be accepted. + // Given the setup above, it is guaranteed that the supplier created + // will be part of the session. + sessionHeader := keepers.GetSessionHeader(ctx, t, appAddr, service, 1) + + // Construct a proof message server from the proof keeper. + srv := keeper.NewMsgServerImpl(*keepers.Keeper) + + // Prepare a ring client to sign & validate relays. + ringClient, err := rings.NewRingClient(depinject.Supply( + polyzero.NewLogger(), + prooftypes.NewAppKeeperQueryClient(keepers.ApplicationKeeper), + prooftypes.NewAccountKeeperQueryClient(keepers.AccountKeeper), + prooftypes.NewSharedKeeperQueryClient(keepers.SharedKeeper, keepers.SessionKeeper), + )) + require.NoError(t, err) + + // Submit the corresponding proof. + numRelays := uint64(5) + sessionTree := testtree.NewFilledSessionTree( + ctx, t, + numRelays, service.ComputeUnitsPerRelay, + supplierOperatorUid, supplierOperatorAddr, + sessionHeader, sessionHeader, sessionHeader, + keyRing, + ringClient, + ) + + // Advance the block height to the test claim msg height. + claimMsgHeight := shared.GetEarliestSupplierClaimCommitHeight( + &sharedParams, + sessionHeader.GetSessionEndBlockHeight(), + blockHeaderHash, + supplierOperatorAddr, + ) + ctx = keepertest.SetBlockHeight(ctx, claimMsgHeight) + + // Create a valid claim. + createClaimAndStoreBlockHash( + ctx, t, 1, + supplierOperatorAddr, + appAddr, + service, + sessionTree, + sessionHeader, + srv, + keepers, + ) + + // Advance the block height to the proof path seed height. + earliestSupplierProofCommitHeight := shared.GetEarliestSupplierProofCommitHeight( + &sharedParams, + sessionHeader.GetSessionEndBlockHeight(), + blockHeaderHash, + supplierOperatorAddr, + ) + ctx = keepertest.SetBlockHeight(ctx, earliestSupplierProofCommitHeight-1) + + // Store proof path seed block hash in the session keeper so that it can + // look it up during proof validation. + keepers.StoreBlockHash(ctx) + + // Compute expected proof path. + expectedMerkleProofPath = protocol.GetPathForProof(blockHeaderHash, sessionHeader.GetSessionId()) + + // Advance the block height to the test proof msg height. + proofMsgHeight := shared.GetEarliestSupplierProofCommitHeight( + &sharedParams, + sessionHeader.GetSessionEndBlockHeight(), + blockHeaderHash, + supplierOperatorAddr, + ) + ctx = keepertest.SetBlockHeight(ctx, proofMsgHeight) + + proofMsg := newTestProofMsg(t, + supplierOperatorAddr, + sessionHeader, + sessionTree, + expectedMerkleProofPath, + ) + submitProofRes, err := srv.SubmitProof(ctx, proofMsg) + require.Nil(t, submitProofRes) + require.ErrorIs(t, err, status.Error(codes.FailedPrecondition, prooftypes.ErrProofNotRequired.Error())) +} + // newTestProofMsg creates a new submit proof message that can be submitted // to be validated and stored on-chain. func newTestProofMsg( diff --git a/x/proof/keeper/msg_server_update_param.go b/x/proof/keeper/msg_server_update_param.go index 1f1c2d112..03828492a 100644 --- a/x/proof/keeper/msg_server_update_param.go +++ b/x/proof/keeper/msg_server_update_param.go @@ -48,11 +48,11 @@ func (k msgServer) UpdateParam( params.ProofRequestProbability = proofRequestProbability case types.ParamProofRequirementThreshold: - value, ok := msg.AsType.(*types.MsgUpdateParam_AsInt64) + value, ok := msg.AsType.(*types.MsgUpdateParam_AsCoin) if !ok { return nil, types.ErrProofParamInvalid.Wrapf("unsupported value type for %s param: %T", msg.Name, msg.AsType) } - proofRequirementThreshold := uint64(value.AsInt64) + proofRequirementThreshold := value.AsCoin if err := types.ValidateProofRequirementThreshold(proofRequirementThreshold); err != nil { return nil, err diff --git a/x/proof/keeper/msg_server_update_param_test.go b/x/proof/keeper/msg_server_update_param_test.go index d32eead82..3b6ba5c58 100644 --- a/x/proof/keeper/msg_server_update_param_test.go +++ b/x/proof/keeper/msg_server_update_param_test.go @@ -6,6 +6,7 @@ import ( "cosmossdk.io/math" cosmostypes "github.com/cosmos/cosmos-sdk/types" + sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/stretchr/testify/require" @@ -70,7 +71,7 @@ func TestMsgUpdateParam_UpdateProofRequestProbabilityOnly(t *testing.T) { } func TestMsgUpdateParam_UpdateProofRequirementThresholdOnly(t *testing.T) { - var expectedProofRequirementThreshold uint64 = 100 + var expectedProofRequirementThreshold = sdk.NewCoin(volatile.DenomuPOKT, math.NewInt(100)) // Set the parameters to their default values k, msgSrv, ctx := setupMsgServer(t) @@ -84,13 +85,13 @@ func TestMsgUpdateParam_UpdateProofRequirementThresholdOnly(t *testing.T) { updateParamMsg := &prooftypes.MsgUpdateParam{ Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), Name: prooftypes.ParamProofRequirementThreshold, - AsType: &prooftypes.MsgUpdateParam_AsInt64{AsInt64: int64(expectedProofRequirementThreshold)}, + AsType: &prooftypes.MsgUpdateParam_AsCoin{AsCoin: &expectedProofRequirementThreshold}, } res, err := msgSrv.UpdateParam(ctx, updateParamMsg) require.NoError(t, err) require.NotEqual(t, defaultParams.ProofRequirementThreshold, res.Params.ProofRequirementThreshold) - require.Equal(t, expectedProofRequirementThreshold, res.Params.ProofRequirementThreshold) + require.Equal(t, &expectedProofRequirementThreshold, res.Params.ProofRequirementThreshold) // Ensure the other parameters are unchanged testkeeper.AssertDefaultParamsEqualExceptFields(t, &defaultParams, res.Params, "ProofRequirementThreshold") diff --git a/x/proof/keeper/params_test.go b/x/proof/keeper/params_test.go index a22a99a41..50370a3d2 100644 --- a/x/proof/keeper/params_test.go +++ b/x/proof/keeper/params_test.go @@ -102,7 +102,7 @@ func TestParams_ValidateProofRequirementThreshold(t *testing.T) { }, { desc: "valid ProofRequirementThreshold", - proofRequirementThreshold: uint64(20), + proofRequirementThreshold: &cosmostypes.Coin{Denom: volatile.DenomuPOKT, Amount: math.NewInt(20)}, }, } diff --git a/x/tokenomics/keeper/proof_requirement_test.go b/x/proof/keeper/proof_requirement_test.go similarity index 75% rename from x/tokenomics/keeper/proof_requirement_test.go rename to x/proof/keeper/proof_requirement_test.go index c77c205f4..fb413e564 100644 --- a/x/tokenomics/keeper/proof_requirement_test.go +++ b/x/proof/keeper/proof_requirement_test.go @@ -4,7 +4,6 @@ import ( "sync/atomic" "testing" - "cosmossdk.io/log" cosmostypes "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" @@ -12,18 +11,21 @@ import ( "github.com/pokt-network/poktroll/testutil/keeper" tetsproof "github.com/pokt-network/poktroll/testutil/proof" "github.com/pokt-network/poktroll/testutil/sample" - prooftypes "github.com/pokt-network/poktroll/x/proof/types" + "github.com/pokt-network/poktroll/x/proof/types" ) func TestKeeper_IsProofRequired(t *testing.T) { - // Set expectedCompute units to be below the proof requirement threshold to only - // exercise the probabilistic branch of the #isProofRequired() logic. - expectedComputeUnits := prooftypes.DefaultProofRequirementThreshold - 1 - keepers, ctx := keeper.NewTokenomicsModuleKeepers(t, log.NewNopLogger()) + keepers, ctx := keeper.NewProofModuleKeepers(t) sdkCtx := cosmostypes.UnwrapSDKContext(ctx) + proofParams := keepers.Keeper.GetParams(sdkCtx) + sharedParams := keepers.SharedKeeper.GetParams(sdkCtx) + // Set expected compute units to be below the proof requirement threshold to only + // exercise the probabilistic branch of the #isProofRequired() logic. + expectedComputeUnits := (proofParams.ProofRequirementThreshold.Amount.Uint64() - 1) / sharedParams.ComputeUnitsToTokensMultiplier + var ( - probability = prooftypes.DefaultProofRequestProbability + probability = types.DefaultProofRequestProbability // This was empirically determined to avoid false negatives in unit tests. // As a maintainer of the codebase, you may need to adjust these. tolerance = 0.10 @@ -40,10 +42,10 @@ func TestKeeper_IsProofRequired(t *testing.T) { for i := int64(0); i < sampleSize; i++ { claim := tetsproof.ClaimWithRandomHash(t, sample.AccAddress(), sample.AccAddress(), expectedComputeUnits) - proofRequirementReason, err := keepers.Keeper.ProofRequirementForClaim(sdkCtx, &claim) + proofRequirementReason, err := keepers.ProofRequirementForClaim(sdkCtx, &claim) require.NoError(t, err) - if proofRequirementReason != prooftypes.ProofRequirementReason_NOT_REQUIRED { + if proofRequirementReason != types.ProofRequirementReason_NOT_REQUIRED { numTrueSamples.Add(1) } } diff --git a/x/proof/types/errors.go b/x/proof/types/errors.go index f15a99b47..966500730 100644 --- a/x/proof/types/errors.go +++ b/x/proof/types/errors.go @@ -37,4 +37,5 @@ var ( ErrProofComputeUnitsMismatch = sdkerrors.Register(ModuleName, 1126, "mismatch: claim compute units != number of relays * service compute units per relay") ErrProofNotEnoughFunds = sdkerrors.Register(ModuleName, 1127, "not enough funds to submit proof") ErrProofFailedToDeductFee = sdkerrors.Register(ModuleName, 1128, "failed to deduct proof submission fee") + ErrProofNotRequired = sdkerrors.Register(ModuleName, 1129, "proof not required") ) diff --git a/x/proof/types/message_update_param.go b/x/proof/types/message_update_param.go index cc261973b..9f1a26539 100644 --- a/x/proof/types/message_update_param.go +++ b/x/proof/types/message_update_param.go @@ -54,7 +54,7 @@ func (msg *MsgUpdateParam) ValidateBasic() error { case ParamProofRequestProbability: return msg.paramTypeIsFloat() case ParamProofRequirementThreshold: - return msg.paramTypeIsInt64() + return msg.paramTypeIsCoin() case ParamProofMissingPenalty: return msg.paramTypeIsCoin() case ParamProofSubmissionFee: @@ -76,18 +76,6 @@ func (msg *MsgUpdateParam) paramTypeIsBytes() error { return nil } -// paramTypeIsInt64 checks if the parameter type is int64, returning an error if not. -func (msg *MsgUpdateParam) paramTypeIsInt64() error { - if _, ok := msg.AsType.(*MsgUpdateParam_AsInt64); !ok { - return ErrProofParamInvalid.Wrapf( - "invalid type for param %q expected %T, got %T", - msg.Name, &MsgUpdateParam_AsInt64{}, - msg.AsType, - ) - } - return nil -} - // paramTypeIsFloat checks if the parameter type is Float, returning an error if not. func (msg *MsgUpdateParam) paramTypeIsFloat() error { if _, ok := msg.AsType.(*MsgUpdateParam_AsFloat); !ok { diff --git a/x/proof/types/params.go b/x/proof/types/params.go index 5de271094..4cc814cce 100644 --- a/x/proof/types/params.go +++ b/x/proof/types/params.go @@ -29,13 +29,17 @@ var ( ParamProofRequestProbability = "proof_request_probability" DefaultProofRequestProbability float32 = 0.25 // See: https://github.com/pokt-network/pocket-core/blob/staging/docs/proposals/probabilistic_proofs.md - KeyProofRequirementThreshold = []byte("ProofRequirementThreshold") - ParamProofRequirementThreshold = "proof_requirement_threshold" - DefaultProofRequirementThreshold uint64 = 20 // See: https://github.com/pokt-network/pocket-core/blob/staging/docs/proposals/probabilistic_proofs.md - - KeyProofMissingPenalty = []byte("ProofMissingPenalty") - ParamProofMissingPenalty = "proof_missing_penalty" - DefaultProofMissingPenalty = cosmostypes.NewCoin(volatile.DenomuPOKT, math.NewInt(320)) // See: https://github.com/pokt-network/pocket-core/blob/staging/docs/proposals/probabilistic_proofs.md + // The probabilistic proofs paper specifies a threshold of 20 POKT. + // TODO_MAINNET(@Olshansk, @RawthiL): Figure out what this value should be. + KeyProofRequirementThreshold = []byte("ProofRequirementThreshold") + ParamProofRequirementThreshold = "proof_requirement_threshold" + DefaultProofRequirementThreshold = cosmostypes.NewCoin(volatile.DenomuPOKT, math.NewInt(20e6)) // See: https://github.com/pokt-network/pocket-core/blob/staging/docs/proposals/probabilistic_proofs.md + + // TODO_DISCUSS: Should ProofMissingPenalty be moved to the tokenomics module? + KeyProofMissingPenalty = []byte("ProofMissingPenalty") + ParamProofMissingPenalty = "proof_missing_penalty" + // As per the probabilistic proofs paper, the penalty for missing a proof is 320 POKT (i.e. 320e6 uPOKT). + DefaultProofMissingPenalty = cosmostypes.NewCoin(volatile.DenomuPOKT, math.NewInt(320e6)) // See: https://github.com/pokt-network/pocket-core/blob/staging/docs/proposals/probabilistic_proofs.md KeyProofSubmissionFee = []byte("ProofSubmissionFee") ParamProofSubmissionFee = "proof_submission_fee" @@ -53,7 +57,7 @@ func ParamKeyTable() paramtypes.KeyTable { func NewParams( relayDifficultyTargetHash []byte, proofRequestProbability float32, - proofRequirementThreshold uint64, + proofRequirementThreshold *cosmostypes.Coin, proofMissingPenalty *cosmostypes.Coin, proofSubmissionFee *cosmostypes.Coin, ) Params { @@ -71,7 +75,7 @@ func DefaultParams() Params { return NewParams( DefaultRelayDifficultyTargetHash, DefaultProofRequestProbability, - DefaultProofRequirementThreshold, + &DefaultProofRequirementThreshold, &DefaultProofMissingPenalty, &MinProofSubmissionFee, ) @@ -172,7 +176,7 @@ func ValidateProofRequestProbability(v interface{}) error { // ValidateProofRequirementThreshold validates the ProofRequirementThreshold param. // NB: The argument is an interface type to satisfy the ParamSetPair function signature. func ValidateProofRequirementThreshold(v interface{}) error { - _, ok := v.(uint64) + _, ok := v.(*cosmostypes.Coin) if !ok { return ErrProofParamInvalid.Wrapf("invalid parameter type: %T", v) } diff --git a/x/proof/types/params.pb.go b/x/proof/types/params.pb.go index 12994f2f5..6302cfa71 100644 --- a/x/proof/types/params.pb.go +++ b/x/proof/types/params.pb.go @@ -40,16 +40,18 @@ type Params struct { // is equal to or above the threshold. This is in contrast to the this requirement // being determined probabilistically via ProofRequestProbability. // - // TODO_MAINNET: Consider renaming this to `proof_requirement_threshold_compute_units`. - ProofRequirementThreshold uint64 `protobuf:"varint,3,opt,name=proof_requirement_threshold,json=proofRequirementThreshold,proto3" json:"proof_requirement_threshold"` + // TODO_MAINNET: Consider renaming this to `proof_requirement_threshold_upokt`. + ProofRequirementThreshold *types.Coin `protobuf:"bytes,3,opt,name=proof_requirement_threshold,json=proofRequirementThreshold,proto3" json:"proof_requirement_threshold"` // proof_missing_penalty is the number of tokens (uPOKT) which should be slashed from a supplier // when a proof is required (either via proof_requirement_threshold or proof_missing_penalty) // but is not provided. + // TODO_MAINNET: Consider renaming this to `proof_missing_penalty_upokt`. ProofMissingPenalty *types.Coin `protobuf:"bytes,4,opt,name=proof_missing_penalty,json=proofMissingPenalty,proto3" json:"proof_missing_penalty"` // proof_submission_fee is the number of tokens (uPOKT) which should be paid by // the supplier operator when submitting a proof. // This is needed to account for the cost of storing proofs on-chain and prevent // spamming (i.e. sybil bloat attacks) the network with non-required proofs. + // TODO_MAINNET: Consider renaming this to `proof_submission_fee_upokt`. ProofSubmissionFee *types.Coin `protobuf:"bytes,5,opt,name=proof_submission_fee,json=proofSubmissionFee,proto3" json:"proof_submission_fee"` } @@ -96,11 +98,11 @@ func (m *Params) GetProofRequestProbability() float32 { return 0 } -func (m *Params) GetProofRequirementThreshold() uint64 { +func (m *Params) GetProofRequirementThreshold() *types.Coin { if m != nil { return m.ProofRequirementThreshold } - return 0 + return nil } func (m *Params) GetProofMissingPenalty() *types.Coin { @@ -125,34 +127,34 @@ func init() { proto.RegisterFile("poktroll/proof/params.proto", fileDescriptor_2 var fileDescriptor_2ad689ad5bf3a2d7 = []byte{ // 439 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0xb1, 0x6e, 0xd4, 0x40, - 0x10, 0x86, 0x6f, 0xc3, 0x91, 0xc2, 0x20, 0x24, 0x4c, 0x50, 0xec, 0x04, 0x6c, 0x8b, 0xea, 0x84, - 0x84, 0x57, 0x81, 0x8e, 0xd2, 0x20, 0x44, 0x01, 0xd2, 0xc9, 0xa4, 0x81, 0x66, 0xb5, 0xbe, 0xcc, - 0xd9, 0xab, 0xd8, 0x1e, 0xb3, 0xbb, 0x07, 0xf8, 0x15, 0xa8, 0xa8, 0xa9, 0x78, 0x04, 0x1e, 0x83, - 0x32, 0x65, 0x2a, 0x0b, 0xdd, 0x15, 0x20, 0x3f, 0x05, 0xba, 0xdd, 0x8b, 0x53, 0x10, 0x8e, 0xc6, - 0x5a, 0xfd, 0xdf, 0xff, 0xcf, 0x58, 0xa3, 0xdf, 0x39, 0x6c, 0xf0, 0x54, 0x4b, 0x2c, 0x4b, 0xda, - 0x48, 0xc4, 0x39, 0x6d, 0xb8, 0xe4, 0x95, 0x8a, 0x1b, 0x89, 0x1a, 0xdd, 0x5b, 0x17, 0x30, 0x36, - 0xf0, 0xe0, 0x36, 0xaf, 0x44, 0x8d, 0xd4, 0x7c, 0xad, 0xe5, 0x60, 0x2f, 0xc7, 0x1c, 0xcd, 0x93, - 0xae, 0x5f, 0x1b, 0x35, 0x98, 0xa1, 0xaa, 0x50, 0xd1, 0x8c, 0x2b, 0xa0, 0x1f, 0x8e, 0x32, 0xd0, - 0xfc, 0x88, 0xce, 0x50, 0xd4, 0x96, 0x3f, 0xf8, 0x3a, 0x76, 0x76, 0xa7, 0x66, 0x93, 0xcb, 0x9d, - 0x7b, 0x12, 0x4a, 0xde, 0xb2, 0x13, 0x31, 0x9f, 0x8b, 0xd9, 0xa2, 0xd4, 0x2d, 0xd3, 0x5c, 0xe6, - 0xa0, 0x59, 0xc1, 0x55, 0xe1, 0x91, 0x88, 0x4c, 0x6e, 0x26, 0x51, 0xdf, 0x85, 0x5b, 0x7d, 0xa9, - 0x6f, 0xe8, 0xf3, 0x01, 0x1e, 0x1b, 0xf6, 0x92, 0xab, 0xc2, 0x7d, 0xeb, 0xf8, 0xe6, 0xff, 0x99, - 0x84, 0xf7, 0x0b, 0x50, 0x9a, 0x35, 0x12, 0x33, 0x9e, 0x89, 0x52, 0xe8, 0xd6, 0xdb, 0x89, 0xc8, - 0x64, 0x27, 0xb9, 0xdf, 0x77, 0xe1, 0xbf, 0x4d, 0xe9, 0xbe, 0x41, 0xa9, 0x25, 0xd3, 0x4b, 0xe0, - 0x32, 0xe7, 0xf0, 0x32, 0x25, 0x24, 0x54, 0x50, 0x6b, 0xa6, 0x0b, 0x09, 0xaa, 0xc0, 0xf2, 0xc4, - 0xbb, 0x16, 0x91, 0xc9, 0x38, 0x09, 0xfb, 0x2e, 0xdc, 0x66, 0x4b, 0xfd, 0x61, 0xfc, 0x86, 0x1d, - 0x5f, 0x20, 0xb7, 0x70, 0xee, 0xda, 0x64, 0x25, 0x94, 0x12, 0x75, 0xce, 0x1a, 0xa8, 0x79, 0xa9, - 0x5b, 0x6f, 0x1c, 0x91, 0xc9, 0x8d, 0xc7, 0x7e, 0x6c, 0x2f, 0x1d, 0xaf, 0x2f, 0x1d, 0x6f, 0x2e, - 0x1d, 0x3f, 0x43, 0x51, 0x27, 0x7e, 0xdf, 0x85, 0x57, 0x67, 0xd3, 0x3b, 0x46, 0x7e, 0x6d, 0xd5, - 0xa9, 0x15, 0x5d, 0x70, 0xf6, 0xac, 0x5b, 0x2d, 0x32, 0x13, 0xc0, 0x9a, 0xcd, 0x01, 0xbc, 0xeb, - 0xff, 0x5b, 0xe4, 0xf5, 0x5d, 0x78, 0x65, 0x34, 0x75, 0x8d, 0xfa, 0x66, 0x10, 0x5f, 0x00, 0x3c, - 0x8d, 0x7e, 0x7f, 0x0b, 0xc9, 0xe7, 0x5f, 0xdf, 0x1f, 0xee, 0x0f, 0xcd, 0xfb, 0xb4, 0xe9, 0x9e, - 0x6d, 0x44, 0xf2, 0xea, 0xc7, 0x32, 0x20, 0x67, 0xcb, 0x80, 0x9c, 0x2f, 0x03, 0xf2, 0x73, 0x19, - 0x90, 0x2f, 0xab, 0x60, 0x74, 0xb6, 0x0a, 0x46, 0xe7, 0xab, 0x60, 0xf4, 0x2e, 0xce, 0x85, 0x2e, - 0x16, 0x59, 0x3c, 0xc3, 0x8a, 0xae, 0x27, 0x3c, 0xaa, 0x41, 0x7f, 0x44, 0x79, 0x4a, 0xff, 0x1a, - 0xa7, 0xdb, 0x06, 0x54, 0xb6, 0x6b, 0x1a, 0xf7, 0xe4, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4c, - 0x34, 0x22, 0xd7, 0xe9, 0x02, 0x00, 0x00, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0x31, 0x6e, 0xd4, 0x40, + 0x14, 0x86, 0x77, 0x42, 0x48, 0x61, 0x10, 0x12, 0x26, 0x28, 0x76, 0x02, 0xb6, 0x45, 0xb5, 0x42, + 0xc2, 0xa3, 0x40, 0x47, 0xb9, 0x20, 0x44, 0x01, 0xd2, 0xca, 0xa4, 0x81, 0x66, 0x34, 0xde, 0xbc, + 0xb5, 0x47, 0xb1, 0xe7, 0x99, 0x99, 0x59, 0xc0, 0x1c, 0x81, 0x8a, 0x23, 0x70, 0x04, 0x1a, 0xee, + 0x40, 0x99, 0x32, 0x95, 0x85, 0x76, 0x0b, 0x90, 0x4f, 0x81, 0x76, 0x66, 0xb3, 0x29, 0x08, 0xd9, + 0xc6, 0x1a, 0xfd, 0xdf, 0xfb, 0xdf, 0x6f, 0x3d, 0xfd, 0xde, 0x41, 0x83, 0x27, 0x46, 0x61, 0x55, + 0xd1, 0x46, 0x21, 0x4e, 0x69, 0xc3, 0x15, 0xaf, 0x75, 0xda, 0x28, 0x34, 0xe8, 0xdf, 0x3a, 0x87, + 0xa9, 0x85, 0xfb, 0xb7, 0x79, 0x2d, 0x24, 0x52, 0xfb, 0x75, 0x23, 0xfb, 0xbb, 0x05, 0x16, 0x68, + 0x9f, 0x74, 0xf9, 0x5a, 0xa9, 0xd1, 0x04, 0x75, 0x8d, 0x9a, 0xe6, 0x5c, 0x03, 0xfd, 0x70, 0x98, + 0x83, 0xe1, 0x87, 0x74, 0x82, 0x42, 0x3a, 0xfe, 0xe0, 0xc7, 0xb6, 0xb7, 0x33, 0xb6, 0x49, 0x3e, + 0xf7, 0xee, 0x29, 0xa8, 0x78, 0xcb, 0x8e, 0xc5, 0x74, 0x2a, 0x26, 0xb3, 0xca, 0xb4, 0xcc, 0x70, + 0x55, 0x80, 0x61, 0x25, 0xd7, 0x65, 0x40, 0x12, 0x32, 0xbc, 0x39, 0x4a, 0xfa, 0x2e, 0xbe, 0x72, + 0x2e, 0x0b, 0x2d, 0x7d, 0xbe, 0x86, 0x47, 0x96, 0xbd, 0xe4, 0xba, 0xf4, 0xdf, 0x7a, 0xa1, 0xfd, + 0x7f, 0xa6, 0xe0, 0xfd, 0x0c, 0xb4, 0x61, 0x8d, 0xc2, 0x9c, 0xe7, 0xa2, 0x12, 0xa6, 0x0d, 0xb6, + 0x12, 0x32, 0xdc, 0x1a, 0xdd, 0xef, 0xbb, 0xf8, 0xff, 0x43, 0xd9, 0x9e, 0x45, 0x99, 0x23, 0xe3, + 0x0b, 0xe0, 0x7f, 0xf6, 0x0e, 0x2e, 0x5c, 0x42, 0x41, 0x0d, 0xd2, 0x30, 0x53, 0x2a, 0xd0, 0x25, + 0x56, 0xc7, 0xc1, 0xb5, 0x84, 0x0c, 0x6f, 0x3c, 0x0e, 0x53, 0x77, 0x8e, 0x74, 0x79, 0x8e, 0x74, + 0x75, 0x8e, 0xf4, 0x19, 0x0a, 0x39, 0x8a, 0xfb, 0x2e, 0xbe, 0x6a, 0x43, 0x16, 0xae, 0x93, 0x57, + 0xec, 0xe8, 0x1c, 0xf9, 0xa5, 0x77, 0xd7, 0x39, 0x6b, 0xa1, 0xb5, 0x90, 0x05, 0x6b, 0x40, 0xf2, + 0xca, 0xb4, 0xc1, 0xf6, 0xa6, 0xd4, 0xb0, 0xef, 0xe2, 0xcb, 0xbd, 0xd9, 0x1d, 0x2b, 0xbf, 0x76, + 0xea, 0xd8, 0x89, 0x3e, 0x78, 0xbb, 0x6e, 0x5a, 0xcf, 0x72, 0x6b, 0x40, 0xc9, 0xa6, 0x00, 0xc1, + 0xf5, 0x4d, 0x41, 0x41, 0xdf, 0xc5, 0x97, 0x5a, 0x33, 0xdf, 0xaa, 0x6f, 0xd6, 0xe2, 0x0b, 0x80, + 0xa7, 0xc9, 0x9f, 0x6f, 0x31, 0xf9, 0xf2, 0xfb, 0xfb, 0xc3, 0xbd, 0x75, 0x29, 0x3f, 0xad, 0x6a, + 0xe9, 0xca, 0x32, 0x7a, 0xf5, 0x73, 0x1e, 0x91, 0xd3, 0x79, 0x44, 0xce, 0xe6, 0x11, 0xf9, 0x35, + 0x8f, 0xc8, 0xd7, 0x45, 0x34, 0x38, 0x5d, 0x44, 0x83, 0xb3, 0x45, 0x34, 0x78, 0x97, 0x16, 0xc2, + 0x94, 0xb3, 0x3c, 0x9d, 0x60, 0x4d, 0x97, 0x1b, 0x1e, 0x49, 0x30, 0x1f, 0x51, 0x9d, 0xd0, 0x7f, + 0xd6, 0x99, 0xb6, 0x01, 0x9d, 0xef, 0xd8, 0x32, 0x3e, 0xf9, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x63, + 0xa4, 0x76, 0xd5, 0x04, 0x03, 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { @@ -180,7 +182,7 @@ func (this *Params) Equal(that interface{}) bool { if this.ProofRequestProbability != that1.ProofRequestProbability { return false } - if this.ProofRequirementThreshold != that1.ProofRequirementThreshold { + if !this.ProofRequirementThreshold.Equal(that1.ProofRequirementThreshold) { return false } if !this.ProofMissingPenalty.Equal(that1.ProofMissingPenalty) { @@ -235,10 +237,17 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x22 } - if m.ProofRequirementThreshold != 0 { - i = encodeVarintParams(dAtA, i, uint64(m.ProofRequirementThreshold)) + if m.ProofRequirementThreshold != nil { + { + size, err := m.ProofRequirementThreshold.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintParams(dAtA, i, uint64(size)) + } i-- - dAtA[i] = 0x18 + dAtA[i] = 0x1a } if m.ProofRequestProbability != 0 { i -= 4 @@ -280,8 +289,9 @@ func (m *Params) Size() (n int) { if m.ProofRequestProbability != 0 { n += 5 } - if m.ProofRequirementThreshold != 0 { - n += 1 + sovParams(uint64(m.ProofRequirementThreshold)) + if m.ProofRequirementThreshold != nil { + l = m.ProofRequirementThreshold.Size() + n += 1 + l + sovParams(uint64(l)) } if m.ProofMissingPenalty != nil { l = m.ProofMissingPenalty.Size() @@ -375,10 +385,10 @@ func (m *Params) Unmarshal(dAtA []byte) error { iNdEx += 4 m.ProofRequestProbability = float32(math.Float32frombits(v)) case 3: - if wireType != 0 { + if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofRequirementThreshold", wireType) } - m.ProofRequirementThreshold = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowParams @@ -388,11 +398,28 @@ func (m *Params) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ProofRequirementThreshold |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ProofRequirementThreshold == nil { + m.ProofRequirementThreshold = &types.Coin{} + } + if err := m.ProofRequirementThreshold.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofMissingPenalty", wireType) diff --git a/x/proof/types/shared_query_client.go b/x/proof/types/shared_query_client.go index afad8894c..b30a5c2f8 100644 --- a/x/proof/types/shared_query_client.go +++ b/x/proof/types/shared_query_client.go @@ -126,3 +126,14 @@ func (sqc *SharedKeeperQueryClient) GetEarliestSupplierProofCommitHeight( supplierOperatorAddr, ), nil } + +// GetComputeUnitsToTokensMultiplier returns the multiplier used to convert compute units to tokens. +// +// TODO_POST_MAINNNET: If this changes mid-session, the cost of the relays at the +// end of the session may differ from what was anticipated at the beginning. +// Since this will be a non-frequent occurrence, accounting for this edge case is +// not an immediate blocker. +func (sqc *SharedKeeperQueryClient) GetComputeUnitsToTokensMultiplier(ctx context.Context) (uint64, error) { + sharedParams := sqc.sharedKeeper.GetParams(ctx) + return sharedParams.GetComputeUnitsToTokensMultiplier(), nil +} diff --git a/x/shared/keeper/msg_server_update_param.go b/x/shared/keeper/msg_server_update_param.go index d83e2fc74..6263d296d 100644 --- a/x/shared/keeper/msg_server_update_param.go +++ b/x/shared/keeper/msg_server_update_param.go @@ -74,6 +74,18 @@ func (k msgServer) UpdateParam(ctx context.Context, msg *types.MsgUpdateParam) ( } params.ApplicationUnbondingPeriodSessions = uint64(value.AsInt64) + case types.ParamComputeUnitsToTokensMultiplier: + value, ok := msg.AsType.(*types.MsgUpdateParam_AsInt64) + if !ok { + return nil, types.ErrSharedParamInvalid.Wrapf("unsupported value type for %s param: %T", msg.Name, msg.AsType) + } + computeUnitsToTokensMultiplier := uint64(value.AsInt64) + + if err := types.ValidateComputeUnitsToTokensMultiplier(computeUnitsToTokensMultiplier); err != nil { + return nil, err + } + + params.ComputeUnitsToTokensMultiplier = computeUnitsToTokensMultiplier default: return nil, types.ErrSharedParamInvalid.Wrapf("unsupported param %q", msg.Name) } diff --git a/x/shared/keeper/msg_server_update_param_test.go b/x/shared/keeper/msg_server_update_param_test.go index fe93eb97c..9554c7019 100644 --- a/x/shared/keeper/msg_server_update_param_test.go +++ b/x/shared/keeper/msg_server_update_param_test.go @@ -331,6 +331,43 @@ func TestMsgUpdateParam_UpdateApplicationUnbondingPeriodSessions(t *testing.T) { require.ErrorIs(t, err, sharedtypes.ErrSharedParamInvalid) } +func TestMsgUpdateParam_ComputeUnitsToTokenMultiplier(t *testing.T) { + var expectedComputeUnitsToTokenMultiplier int64 = 5 + + k, ctx := testkeeper.SharedKeeper(t) + msgSrv := keeper.NewMsgServerImpl(k) + + defaultParams := sharedtypes.DefaultParams() + // Set the parameters to their default values + require.NoError(t, k.SetParams(ctx, defaultParams)) + + // Ensure the default values are different from the new values we want to set + require.NotEqual(t, uint64(expectedComputeUnitsToTokenMultiplier), defaultParams.GetComputeUnitsToTokensMultiplier()) + + // Update the compute units to token multiplier param + updateParamMsg := &sharedtypes.MsgUpdateParam{ + Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + Name: sharedtypes.ParamComputeUnitsToTokensMultiplier, + AsType: &sharedtypes.MsgUpdateParam_AsInt64{AsInt64: expectedComputeUnitsToTokenMultiplier}, + } + res, err := msgSrv.UpdateParam(ctx, updateParamMsg) + require.NoError(t, err) + + require.Equal(t, uint64(expectedComputeUnitsToTokenMultiplier), res.Params.GetComputeUnitsToTokensMultiplier()) + + // Ensure the other parameters are unchanged + testkeeper.AssertDefaultParamsEqualExceptFields(t, &defaultParams, res.Params, "ComputeUnitsToTokensMultiplier") + + // Ensure that compute units to token multiplier that is less than 1 is not allowed. + updateParamMsg = &sharedtypes.MsgUpdateParam{ + Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + Name: sharedtypes.ParamComputeUnitsToTokensMultiplier, + AsType: &sharedtypes.MsgUpdateParam_AsInt64{AsInt64: 0}, + } + _, err = msgSrv.UpdateParam(ctx, updateParamMsg) + require.ErrorIs(t, err, sharedtypes.ErrSharedParamInvalid) +} + // getMinActorUnbondingPeriodSessions returns the actors unbonding period // sessions such that it is greater than the cumulative proof window close blocks // to pass UpdateParam validation. diff --git a/x/shared/types/genesis_test.go b/x/shared/types/genesis_test.go index fa07c23c5..4f3f2597c 100644 --- a/x/shared/types/genesis_test.go +++ b/x/shared/types/genesis_test.go @@ -27,6 +27,7 @@ func TestGenesisState_Validate(t *testing.T) { NumBlocksPerSession: defaultParams.NumBlocksPerSession, SupplierUnbondingPeriodSessions: defaultParams.SupplierUnbondingPeriodSessions, ApplicationUnbondingPeriodSessions: defaultParams.ApplicationUnbondingPeriodSessions, + ComputeUnitsToTokensMultiplier: defaultParams.ComputeUnitsToTokensMultiplier, }, // this line is used by starport scaffolding # types/genesis/validField diff --git a/x/shared/types/message_update_param.go b/x/shared/types/message_update_param.go index 39334b5a8..9ba5f4ac5 100644 --- a/x/shared/types/message_update_param.go +++ b/x/shared/types/message_update_param.go @@ -54,7 +54,8 @@ func (msg *MsgUpdateParam) ValidateBasic() error { ParamProofWindowOpenOffsetBlocks, ParamProofWindowCloseOffsetBlocks, ParamSupplierUnbondingPeriodSessions, - ParamApplicationUnbondingPeriodSessions: + ParamApplicationUnbondingPeriodSessions, + ParamComputeUnitsToTokensMultiplier: return msg.paramTypeIsInt64() default: return ErrSharedParamNameInvalid.Wrapf("unsupported param %q", msg.Name) diff --git a/x/shared/types/message_update_param_test.go b/x/shared/types/message_update_param_test.go index 09acc022e..65f4931b3 100644 --- a/x/shared/types/message_update_param_test.go +++ b/x/shared/types/message_update_param_test.go @@ -45,6 +45,13 @@ func TestMsgUpdateParam_ValidateBasic(t *testing.T) { Name: ParamNumBlocksPerSession, AsType: &MsgUpdateParam_AsInt64{AsInt64: 1}, }, + }, { + desc: "invalid ComputeUnitsToTokensMultiplier", + msg: MsgUpdateParam{ + Authority: sample.AccAddress(), + Name: ParamComputeUnitsToTokensMultiplier, + AsType: &MsgUpdateParam_AsInt64{AsInt64: 0}, + }, }, } for _, tt := range tests { diff --git a/x/shared/types/params.go b/x/shared/types/params.go index 59f179763..3a5afd62d 100644 --- a/x/shared/types/params.go +++ b/x/shared/types/params.go @@ -21,6 +21,8 @@ const ( ParamSupplierUnbondingPeriodSessions = "supplier_unbonding_period_sessions" DefaultApplicationUnbondingPeriodSessions = 4 // 4 sessions ParamApplicationUnbondingPeriodSessions = "application_unbonding_period_sessions" + DefaultComputeUnitsToTokensMultiplier = 42 // TODO_MAINNET: Determine the default value. + ParamComputeUnitsToTokensMultiplier = "compute_units_to_tokens_multiplier" ) var ( @@ -33,6 +35,7 @@ var ( KeyProofWindowCloseOffsetBlocks = []byte("ProofWindowCloseOffsetBlocks") KeySupplierUnbondingPeriodSessions = []byte("SupplierUnbondingPeriodSessions") KeyApplicationUnbondingPeriodSessions = []byte("ApplicationUnbondingPeriodSessions") + KeyComputeUnitsToTokensMultiplier = []byte("ComputeUnitsToTokensMultiplier") ) // ParamKeyTable the param key table for launch module @@ -51,6 +54,7 @@ func NewParams() Params { GracePeriodEndOffsetBlocks: DefaultGracePeriodEndOffsetBlocks, SupplierUnbondingPeriodSessions: DefaultSupplierUnbondingPeriodSessions, ApplicationUnbondingPeriodSessions: DefaultApplicationUnbondingPeriodSessions, + ComputeUnitsToTokensMultiplier: DefaultComputeUnitsToTokensMultiplier, } } @@ -102,6 +106,11 @@ func (params *Params) ParamSetPairs() paramtypes.ParamSetPairs { ¶ms.ApplicationUnbondingPeriodSessions, ValidateApplicationUnbondingPeriodSessions, ), + paramtypes.NewParamSetPair( + KeyComputeUnitsToTokensMultiplier, + ¶ms.ComputeUnitsToTokensMultiplier, + ValidateComputeUnitsToTokensMultiplier, + ), } } @@ -139,6 +148,10 @@ func (params *Params) ValidateBasic() error { return err } + if err := ValidateComputeUnitsToTokensMultiplier(params.ComputeUnitsToTokensMultiplier); err != nil { + return err + } + if err := validateGracePeriodOffsetBlocksIsLessThanNumBlocksPerSession(params); err != nil { return err } @@ -240,6 +253,21 @@ func ValidateApplicationUnbondingPeriodSessions(v interface{}) error { return nil } +// ValidateComputeUnitsToTokensMultiplier validates the ComputeUnitsToTokensMultiplier governance parameter. +// NB: The argument is an interface type to satisfy the ParamSetPair function signature. +func ValidateComputeUnitsToTokensMultiplier(v interface{}) error { + computeUnitsToTokensMultiplier, ok := v.(uint64) + if !ok { + return ErrSharedParamInvalid.Wrapf("invalid parameter type: %T", v) + } + + if computeUnitsToTokensMultiplier <= 0 { + return ErrSharedParamInvalid.Wrapf("invalid ComputeUnitsToTokensMultiplier: (%v)", computeUnitsToTokensMultiplier) + } + + return nil +} + // validateIsUint64 returns the casted uin64 value or an error if value is not // type assertable to uint64. func validateIsUint64(value any) (uint64, error) { diff --git a/x/shared/types/params.pb.go b/x/shared/types/params.pb.go index b62dd85da..7b5863516 100644 --- a/x/shared/types/params.pb.go +++ b/x/shared/types/params.pb.go @@ -55,6 +55,9 @@ type Params struct { // On-chain business logic requires, and ensures, that the corresponding block count of the // application unbonding period will exceed the end of its corresponding proof window close height. ApplicationUnbondingPeriodSessions uint64 `protobuf:"varint,8,opt,name=application_unbonding_period_sessions,json=applicationUnbondingPeriodSessions,proto3" json:"application_unbonding_period_sessions"` + // The amount of upokt that a compute unit should translate to when settling a session. + // DEV_NOTE: This used to be under x/tokenomics but has been moved here to avoid cyclic dependencies. + ComputeUnitsToTokensMultiplier uint64 `protobuf:"varint,9,opt,name=compute_units_to_tokens_multiplier,json=computeUnitsToTokensMultiplier,proto3" json:"compute_units_to_tokens_multiplier" yaml:"compute_units_to_tokens_multiplier"` } func (m *Params) Reset() { *m = Params{} } @@ -142,6 +145,13 @@ func (m *Params) GetApplicationUnbondingPeriodSessions() uint64 { return 0 } +func (m *Params) GetComputeUnitsToTokensMultiplier() uint64 { + if m != nil { + return m.ComputeUnitsToTokensMultiplier + } + return 0 +} + func init() { proto.RegisterType((*Params)(nil), "poktroll.shared.Params") } @@ -149,37 +159,40 @@ func init() { func init() { proto.RegisterFile("poktroll/shared/params.proto", fileDescriptor_ee6189c7aa51bbf5) } var fileDescriptor_ee6189c7aa51bbf5 = []byte{ - // 465 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0xcf, 0x8a, 0xd3, 0x50, - 0x14, 0xc6, 0x1b, 0x1d, 0x3b, 0x92, 0x8d, 0x18, 0x45, 0x4a, 0xa7, 0xe4, 0x8e, 0xf5, 0x0f, 0x2a, - 0xd8, 0x2c, 0xdc, 0xb9, 0xac, 0xb8, 0x94, 0x96, 0x88, 0x08, 0x6e, 0x2e, 0xb7, 0xc9, 0x6d, 0xe6, - 0xd2, 0xe4, 0x9e, 0xcb, 0xbd, 0x09, 0x55, 0xf0, 0x05, 0x74, 0xe5, 0x23, 0xf8, 0x08, 0x3e, 0x86, - 0xcb, 0x59, 0xce, 0x2a, 0x48, 0xba, 0x50, 0xf2, 0x14, 0x92, 0x93, 0xc6, 0x69, 0x3b, 0x76, 0x32, - 0x9b, 0x70, 0x39, 0xdf, 0xef, 0x9c, 0x8f, 0x8f, 0x9c, 0x63, 0x0f, 0x14, 0x2c, 0x52, 0x0d, 0x71, - 0xec, 0x99, 0x13, 0xa6, 0x79, 0xe8, 0x29, 0xa6, 0x59, 0x62, 0x46, 0x4a, 0x43, 0x0a, 0xce, 0xad, - 0x46, 0x1d, 0xd5, 0x6a, 0xff, 0x36, 0x4b, 0x84, 0x04, 0x0f, 0xbf, 0x35, 0xd3, 0xbf, 0x1b, 0x41, - 0x04, 0xf8, 0xf4, 0xaa, 0x57, 0x5d, 0x1d, 0x7e, 0x39, 0xb4, 0xbb, 0x53, 0x1c, 0xe5, 0x4c, 0xec, - 0x7b, 0x32, 0x4b, 0xe8, 0x2c, 0x86, 0x60, 0x61, 0xa8, 0xe2, 0x9a, 0x1a, 0x6e, 0x8c, 0x00, 0xd9, - 0xb3, 0x8e, 0xad, 0x27, 0x07, 0xe3, 0x7e, 0x99, 0x93, 0x3d, 0x84, 0x7f, 0x47, 0x66, 0xc9, 0x18, - 0xcb, 0x53, 0xae, 0xdf, 0xd6, 0x45, 0x67, 0x6e, 0xbb, 0x91, 0x66, 0x01, 0xaf, 0x48, 0x01, 0x21, - 0xe5, 0x32, 0xa4, 0x30, 0x9f, 0x1b, 0x9e, 0xae, 0x47, 0xf4, 0xae, 0xe1, 0xe0, 0x61, 0x99, 0x93, - 0x16, 0xd2, 0xef, 0xa3, 0x3e, 0x45, 0xf9, 0xb5, 0x0c, 0x27, 0x28, 0xd6, 0x8e, 0x8e, 0xb0, 0x49, - 0x10, 0x33, 0x91, 0xd0, 0xa5, 0x90, 0x21, 0x2c, 0x29, 0x28, 0x2e, 0x77, 0x8c, 0xae, 0xa3, 0xd1, - 0x83, 0x32, 0x27, 0x6d, 0xa8, 0x7f, 0x84, 0xc0, 0x7b, 0xd4, 0x27, 0x8a, 0xcb, 0x2d, 0xab, 0xd8, - 0x3e, 0xde, 0xea, 0x0f, 0x62, 0x30, 0x7c, 0xc7, 0xeb, 0x00, 0xbd, 0x1e, 0x96, 0x39, 0x69, 0x65, - 0xfd, 0xc1, 0x86, 0xd9, 0xab, 0x4a, 0xdf, 0x0d, 0xa6, 0x34, 0xc0, 0xfc, 0x92, 0x60, 0x37, 0xce, - 0x83, 0xb5, 0xa0, 0xfe, 0x11, 0x02, 0xfb, 0x83, 0x6d, 0xf5, 0xff, 0x2f, 0x58, 0xf7, 0x3c, 0x58, - 0x1b, 0xeb, 0x0f, 0x36, 0xcc, 0x2e, 0x06, 0x33, 0xf6, 0xd0, 0x64, 0x4a, 0xc5, 0x82, 0x6b, 0x9a, - 0xc9, 0x19, 0xc8, 0x50, 0xc8, 0xa8, 0xf9, 0xf9, 0xeb, 0x9d, 0x32, 0xbd, 0x43, 0xf4, 0x7b, 0x5c, - 0xe6, 0xe4, 0x0a, 0xb4, 0x4f, 0x1a, 0xe6, 0x5d, 0x83, 0xd4, 0xdb, 0xb2, 0xde, 0x46, 0xe3, 0x7c, - 0xb6, 0x1f, 0xb1, 0x8a, 0x08, 0x58, 0x2a, 0x40, 0x5e, 0xe2, 0x7b, 0x13, 0x7d, 0x9f, 0x96, 0x39, - 0xb9, 0x5a, 0x83, 0x3f, 0xdc, 0xc0, 0xf6, 0xb8, 0xbf, 0xbc, 0xff, 0xe7, 0x3b, 0xb1, 0xbe, 0xfe, - 0xfe, 0xf1, 0xac, 0xf7, 0xef, 0x92, 0x3f, 0x36, 0xb7, 0x5c, 0x1f, 0xe0, 0xf8, 0xcd, 0xcf, 0xc2, - 0xb5, 0x4e, 0x0b, 0xd7, 0x3a, 0x2b, 0x5c, 0xeb, 0x57, 0xe1, 0x5a, 0xdf, 0x56, 0x6e, 0xe7, 0x74, - 0xe5, 0x76, 0xce, 0x56, 0x6e, 0xe7, 0x83, 0x17, 0x89, 0xf4, 0x24, 0x9b, 0x8d, 0x02, 0x48, 0xbc, - 0x6a, 0xc4, 0x73, 0xc9, 0xd3, 0x25, 0xe8, 0x85, 0x77, 0x71, 0x5e, 0xfa, 0x49, 0x71, 0x33, 0xeb, - 0xe2, 0x85, 0xbf, 0xf8, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x8a, 0x3c, 0xf1, 0x20, 0x3b, 0x04, 0x00, - 0x00, + // 524 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x94, 0xbf, 0x6e, 0xd3, 0x40, + 0x1c, 0xc7, 0x6b, 0x28, 0xa1, 0x78, 0x41, 0x18, 0x84, 0xac, 0x34, 0xf2, 0x15, 0xf3, 0x47, 0x14, + 0x89, 0x78, 0x60, 0xeb, 0x18, 0xc4, 0x58, 0x25, 0x72, 0x5b, 0x21, 0xb1, 0x9c, 0x1c, 0xfb, 0xe2, + 0x9e, 0x62, 0xdf, 0xef, 0x74, 0x77, 0x56, 0xa8, 0xc4, 0x13, 0x30, 0xf1, 0x06, 0xb0, 0xb3, 0xf0, + 0x18, 0x8c, 0x1d, 0x3b, 0x59, 0x28, 0x19, 0x40, 0x1e, 0x79, 0x02, 0xe4, 0x73, 0xdc, 0x26, 0x29, + 0xa9, 0xb3, 0x44, 0xa7, 0xfb, 0x7e, 0xee, 0xf7, 0xc9, 0x57, 0x3e, 0x9d, 0xd9, 0xe1, 0x30, 0x56, + 0x02, 0x92, 0xc4, 0x93, 0xa7, 0x81, 0x20, 0x91, 0xc7, 0x03, 0x11, 0xa4, 0xb2, 0xcb, 0x05, 0x28, + 0xb0, 0xee, 0xd7, 0x69, 0xb7, 0x4a, 0xdb, 0x0f, 0x82, 0x94, 0x32, 0xf0, 0xf4, 0x6f, 0xc5, 0xb4, + 0x1f, 0xc5, 0x10, 0x83, 0x5e, 0x7a, 0xe5, 0xaa, 0xda, 0x75, 0xbf, 0xef, 0x98, 0xad, 0x81, 0x1e, + 0x65, 0xf5, 0xcd, 0xc7, 0x2c, 0x4b, 0xf1, 0x30, 0x81, 0x70, 0x2c, 0x31, 0x27, 0x02, 0x4b, 0x22, + 0x25, 0x05, 0x66, 0x1b, 0x7b, 0xc6, 0xcb, 0xed, 0x5e, 0xbb, 0xc8, 0xd1, 0x1a, 0xc2, 0x7f, 0xc8, + 0xb2, 0xb4, 0xa7, 0xb7, 0x07, 0x44, 0x1c, 0x55, 0x9b, 0xd6, 0xc8, 0x74, 0x62, 0x11, 0x84, 0xa4, + 0x24, 0x29, 0x44, 0x98, 0xb0, 0x08, 0xc3, 0x68, 0x24, 0x89, 0x9a, 0x8f, 0xb0, 0x6f, 0xe9, 0xc1, + 0x6e, 0x91, 0xa3, 0x06, 0xd2, 0x6f, 0xeb, 0x7c, 0xa0, 0xe3, 0x77, 0x2c, 0xea, 0xeb, 0xb0, 0x32, + 0x5a, 0xd4, 0x44, 0x61, 0x12, 0xd0, 0x14, 0x4f, 0x28, 0x8b, 0x60, 0x82, 0x81, 0x13, 0xb6, 0x22, + 0xba, 0xad, 0x45, 0x4f, 0x8b, 0x1c, 0x35, 0xa1, 0xfe, 0xae, 0x06, 0xde, 0xeb, 0xbc, 0xcf, 0x09, + 0x5b, 0x52, 0x25, 0xe6, 0xde, 0xd2, 0xf9, 0x30, 0x01, 0x49, 0x56, 0x5c, 0xdb, 0xda, 0xf5, 0xac, + 0xc8, 0x51, 0x23, 0xeb, 0x77, 0x16, 0x64, 0x6f, 0xcb, 0x7c, 0xb5, 0x18, 0x17, 0x00, 0xa3, 0x1b, + 0x8a, 0xdd, 0xb9, 0x2a, 0xd6, 0x80, 0xfa, 0xbb, 0x1a, 0x58, 0x5f, 0x6c, 0xe9, 0xfc, 0xff, 0x8a, + 0xb5, 0xae, 0x8a, 0x35, 0xb1, 0x7e, 0x67, 0x41, 0x76, 0xbd, 0x98, 0x34, 0x5d, 0x99, 0x71, 0x9e, + 0x50, 0x22, 0x70, 0xc6, 0x86, 0xc0, 0x22, 0xca, 0xe2, 0xfa, 0xe3, 0xcf, 0xef, 0x94, 0xb4, 0xef, + 0x6a, 0xdf, 0x8b, 0x22, 0x47, 0x1b, 0xd0, 0x3e, 0xaa, 0x99, 0x93, 0x1a, 0xa9, 0x6e, 0xcb, 0xfc, + 0x36, 0x4a, 0xeb, 0x93, 0xf9, 0x3c, 0x28, 0x89, 0x30, 0x50, 0x14, 0xd8, 0x0d, 0xde, 0x1d, 0xed, + 0xdd, 0x2f, 0x72, 0xb4, 0xd9, 0x01, 0xdf, 0x5d, 0xc0, 0xd6, 0xd9, 0xbf, 0x1a, 0xa6, 0x1b, 0x42, + 0xca, 0x33, 0x45, 0x70, 0xc6, 0xa8, 0x92, 0x58, 0x01, 0x56, 0x30, 0x26, 0x4c, 0xe2, 0x34, 0x4b, + 0x14, 0xd5, 0xff, 0xdd, 0xbe, 0xa7, 0xdd, 0x47, 0x65, 0xe7, 0x66, 0xfa, 0x6f, 0x8e, 0xf6, 0xcf, + 0x82, 0x34, 0x39, 0xd8, 0x80, 0x75, 0x7d, 0x67, 0x0e, 0x9d, 0x94, 0xcc, 0x31, 0x1c, 0x6b, 0xe2, + 0xf0, 0x12, 0x38, 0x78, 0xf2, 0xe7, 0x1b, 0x32, 0x3e, 0xff, 0xfe, 0xf1, 0xca, 0xbe, 0x7c, 0x6b, + 0x3e, 0xd6, 0xaf, 0x4d, 0xf5, 0x44, 0xf4, 0x0e, 0x7f, 0x4e, 0x1d, 0xe3, 0x7c, 0xea, 0x18, 0x17, + 0x53, 0xc7, 0xf8, 0x35, 0x75, 0x8c, 0x2f, 0x33, 0x67, 0xeb, 0x7c, 0xe6, 0x6c, 0x5d, 0xcc, 0x9c, + 0xad, 0x0f, 0x5e, 0x4c, 0xd5, 0x69, 0x36, 0xec, 0x86, 0x90, 0x7a, 0xe5, 0x88, 0xd7, 0x8c, 0xa8, + 0x09, 0x88, 0xb1, 0x77, 0x7d, 0x9e, 0x3a, 0xe3, 0x44, 0x0e, 0x5b, 0xfa, 0x0d, 0x7a, 0xf3, 0x2f, + 0x00, 0x00, 0xff, 0xff, 0x80, 0xd1, 0x33, 0x73, 0xdd, 0x04, 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { @@ -225,6 +238,9 @@ func (this *Params) Equal(that interface{}) bool { if this.ApplicationUnbondingPeriodSessions != that1.ApplicationUnbondingPeriodSessions { return false } + if this.ComputeUnitsToTokensMultiplier != that1.ComputeUnitsToTokensMultiplier { + return false + } return true } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -247,6 +263,11 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.ComputeUnitsToTokensMultiplier != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.ComputeUnitsToTokensMultiplier)) + i-- + dAtA[i] = 0x48 + } if m.ApplicationUnbondingPeriodSessions != 0 { i = encodeVarintParams(dAtA, i, uint64(m.ApplicationUnbondingPeriodSessions)) i-- @@ -331,6 +352,9 @@ func (m *Params) Size() (n int) { if m.ApplicationUnbondingPeriodSessions != 0 { n += 1 + sovParams(uint64(m.ApplicationUnbondingPeriodSessions)) } + if m.ComputeUnitsToTokensMultiplier != 0 { + n += 1 + sovParams(uint64(m.ComputeUnitsToTokensMultiplier)) + } return n } @@ -521,6 +545,25 @@ func (m *Params) Unmarshal(dAtA []byte) error { break } } + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ComputeUnitsToTokensMultiplier", wireType) + } + m.ComputeUnitsToTokensMultiplier = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ComputeUnitsToTokensMultiplier |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipParams(dAtA[iNdEx:]) diff --git a/x/tokenomics/keeper/keeper_exports_test.go b/x/tokenomics/keeper/keeper_exports_test.go deleted file mode 100644 index 2f4d7f46f..000000000 --- a/x/tokenomics/keeper/keeper_exports_test.go +++ /dev/null @@ -1,13 +0,0 @@ -// NB: This file contains exports of unexported members for testing purposes only. -package keeper - -import ( - cosmostypes "github.com/cosmos/cosmos-sdk/types" - - prooftypes "github.com/pokt-network/poktroll/x/proof/types" -) - -// ProofRequirementForClaim wraps the unexported proofRequirementForClaim function for testing purposes. -func (k Keeper) ProofRequirementForClaim(ctx cosmostypes.Context, claim *prooftypes.Claim) (prooftypes.ProofRequirementReason, error) { - return k.proofRequirementForClaim(ctx, claim) -} diff --git a/x/tokenomics/keeper/keeper_settle_pending_claims_test.go b/x/tokenomics/keeper/keeper_settle_pending_claims_test.go index 5f7376e94..e845480dc 100644 --- a/x/tokenomics/keeper/keeper_settle_pending_claims_test.go +++ b/x/tokenomics/keeper/keeper_settle_pending_claims_test.go @@ -9,9 +9,11 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/types" cosmostypes "github.com/cosmos/cosmos-sdk/types" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "github.com/pokt-network/poktroll/app/volatile" "github.com/pokt-network/poktroll/cmd/poktrolld/cmd" "github.com/pokt-network/poktroll/pkg/crypto/protocol" "github.com/pokt-network/poktroll/pkg/crypto/rings" @@ -27,10 +29,14 @@ import ( 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" + "github.com/pokt-network/poktroll/x/tokenomics" tokenomicstypes "github.com/pokt-network/poktroll/x/tokenomics/types" ) -const testServiceId = "svc1" +const ( + testServiceId = "svc1" + supplierStake = 1000000 // uPOKT +) func init() { cmd.InitSDKConfig() @@ -96,7 +102,7 @@ func (s *TestSuite) SetupTest() { } s.keepers.SetService(s.ctx, service) - supplierStake := types.NewCoin("upokt", math.NewInt(1000000)) + supplierStake := types.NewCoin("upokt", math.NewInt(supplierStake)) supplier := sharedtypes.Supplier{ OwnerAddress: supplierOwnerAddr, OperatorAddress: supplierOwnerAddr, @@ -238,12 +244,21 @@ func (s *TestSuite) TestSettlePendingClaims_ClaimExpired_ProofRequiredAndNotProv numComputeUnits, err := s.claim.GetNumComputeUnits() require.NoError(t, err) + // -1 to push threshold below s.claim's compute units + proofRequirementThreshold, err := tokenomics.NumComputeUnitsToCoin(sharedParams, numComputeUnits-1) + require.NoError(t, err) + + // Set the proof missing penalty to half the supplier's stake so it is not + // unstaked when being slashed. + belowStakeAmountProofMissingPenalty := sdk.NewCoin(volatile.DenomuPOKT, math.NewInt(supplierStake/2)) + // Set the proof parameters such that s.claim requires a proof because: // - proof_request_probability is 0% // - proof_requirement_threshold is below the claim (i.e. claim is above threshold) err = s.keepers.ProofKeeper.SetParams(ctx, prooftypes.Params{ ProofRequestProbability: 0, - ProofRequirementThreshold: uint64(numComputeUnits - 1), // -1 to push threshold below s.claim's compute units + ProofRequirementThreshold: &proofRequirementThreshold, + ProofMissingPenalty: &belowStakeAmountProofMissingPenalty, }) require.NoError(t, err) @@ -267,16 +282,36 @@ func (s *TestSuite) TestSettlePendingClaims_ClaimExpired_ProofRequiredAndNotProv claims := s.keepers.GetAllClaims(ctx) require.Len(t, claims, 0) - // Confirm an expiration event was emitted + // Slashing should have occurred without unstaking the supplier. + // The supplier is not unstaked because it got slashed by an amount that is + // half its stake (i.e. missing proof penalty == stake / 2), resulting in a + // remaining stake that is above the minimum stake (i.e. new_stake == prev_stake / 2). + slashedSupplier, supplierFound := s.keepers.GetSupplier(sdkCtx, s.claim.SupplierOperatorAddress) + require.True(t, supplierFound) + require.Equal(t, math.NewInt(supplierStake/2), slashedSupplier.Stake.Amount) + require.Equal(t, uint64(0), slashedSupplier.UnstakeSessionEndHeight) + events := sdkCtx.EventManager().Events() - require.Len(t, events, 5) // minting, burning, settling, etc.. - expectedEvents := testutilevents.FilterEvents[*tokenomicstypes.EventClaimExpired](t, events, "poktroll.tokenomics.EventClaimExpired") - require.Len(t, expectedEvents, 1) + require.Len(t, events, 10) // asserting on the length of events so the developer must consciously update it upon changes - // Validate the event - expectedEvent := expectedEvents[0] - require.Equal(t, tokenomicstypes.ClaimExpirationReason_PROOF_MISSING, expectedEvent.GetExpirationReason()) - require.Equal(t, s.numRelays, expectedEvent.GetNumRelays()) + // Confirm an expiration event was emitted + expectedClaimExpiredEvents := testutilevents.FilterEvents[*tokenomicstypes.EventClaimExpired](t, events, "poktroll.tokenomics.EventClaimExpired") + require.Len(t, expectedClaimExpiredEvents, 1) + + // Validate the claim expired event + expectedClaimExpiredEvent := expectedClaimExpiredEvents[0] + require.Equal(t, tokenomicstypes.ClaimExpirationReason_PROOF_MISSING, expectedClaimExpiredEvent.GetExpirationReason()) + require.Equal(t, s.numRelays, expectedClaimExpiredEvent.GetNumRelays()) + + // Confirm that a slashing event was emitted + expectedSlashingEvents := testutilevents.FilterEvents[*tokenomicstypes.EventSupplierSlashed](t, events, "poktroll.tokenomics.EventSupplierSlashed") + require.Len(t, expectedSlashingEvents, 1) + + // Validate the slashing event + expectedSlashingEvent := expectedSlashingEvents[0] + require.Equal(t, slashedSupplier.GetOperatorAddress(), expectedSlashingEvent.GetSupplierOperatorAddr()) + require.Equal(t, uint64(1), expectedSlashingEvent.GetNumExpiredClaims()) + require.Equal(t, &belowStakeAmountProofMissingPenalty, expectedSlashingEvent.GetSlashingAmount()) } func (s *TestSuite) TestSettlePendingClaims_ClaimSettled_ProofRequiredAndProvided_ViaThreshold() { @@ -289,12 +324,16 @@ func (s *TestSuite) TestSettlePendingClaims_ClaimSettled_ProofRequiredAndProvide numComputeUnits, err := s.claim.GetNumComputeUnits() require.NoError(t, err) + // -1 to push threshold below s.claim's compute units + proofRequirementThreshold, err := tokenomics.NumComputeUnitsToCoin(sharedParams, numComputeUnits-1) + require.NoError(t, err) + // Set the proof parameters such that s.claim requires a proof because: // - proof_request_probability is 0% // - proof_requirement_threshold is below the claim (i.e. claim is above threshold) err = s.keepers.ProofKeeper.SetParams(ctx, prooftypes.Params{ ProofRequestProbability: 0, - ProofRequirementThreshold: uint64(numComputeUnits - 1), // -1 to push threshold below s.claim's compute units + ProofRequirementThreshold: &proofRequirementThreshold, }) require.NoError(t, err) @@ -336,11 +375,15 @@ func (s *TestSuite) TestSettlePendingClaims_ClaimExpired_ProofRequired_InvalidOn ctx := s.ctx sharedParams := s.keepers.SharedKeeper.GetParams(ctx) + proofParams := s.keepers.ProofKeeper.GetParams(ctx) // Set the proof parameters such that s.claim DOES NOT require a proof because: // - proof_request_probability is 100% - err := s.keepers.ProofKeeper.SetParams(ctx, prooftypes.Params{ - ProofRequestProbability: 1, - }) + proofParams.ProofRequestProbability = 1 + // Set the proof missing penalty to half the supplier's stake so it is not + // unstaked when being slashed. + belowStakeAmountProofMissingPenalty := sdk.NewCoin(volatile.DenomuPOKT, math.NewInt(supplierStake/2)) + proofParams.ProofMissingPenalty = &belowStakeAmountProofMissingPenalty + err := s.keepers.ProofKeeper.SetParams(ctx, proofParams) require.NoError(t, err) // Create a claim that requires a proof and an invalid proof @@ -372,16 +415,32 @@ func (s *TestSuite) TestSettlePendingClaims_ClaimExpired_ProofRequired_InvalidOn proofs := s.keepers.GetAllProofs(ctx) require.Len(t, proofs, 0) + // Slashing should have occurred without unstaking the supplier. + slashedSupplier, supplierFound := s.keepers.GetSupplier(sdkCtx, s.claim.SupplierOperatorAddress) + require.True(t, supplierFound) + require.Equal(t, math.NewInt(supplierStake/2), slashedSupplier.Stake.Amount) + require.Equal(t, uint64(0), slashedSupplier.UnstakeSessionEndHeight) + // Confirm an expiration event was emitted events := sdkCtx.EventManager().Events() - require.Len(t, events, 5) // minting, burning, settling, etc.. - expectedEvents := testutilevents.FilterEvents[*tokenomicstypes.EventClaimExpired](t, events, "poktroll.tokenomics.EventClaimExpired") - require.Len(t, expectedEvents, 1) + require.Len(t, events, 10) // minting, burning, settling, etc.. + expectedClaimExpiredEvents := testutilevents.FilterEvents[*tokenomicstypes.EventClaimExpired](t, events, "poktroll.tokenomics.EventClaimExpired") + require.Len(t, expectedClaimExpiredEvents, 1) // Validate the event - expectedEvent := expectedEvents[0] - require.Equal(t, tokenomicstypes.ClaimExpirationReason_PROOF_INVALID, expectedEvent.GetExpirationReason()) - require.Equal(t, s.numRelays, expectedEvent.GetNumRelays()) + expectedClaimExpiredEvent := expectedClaimExpiredEvents[0] + require.Equal(t, tokenomicstypes.ClaimExpirationReason_PROOF_INVALID, expectedClaimExpiredEvent.GetExpirationReason()) + require.Equal(t, s.numRelays, expectedClaimExpiredEvent.GetNumRelays()) + + // Confirm that a slashing event was emitted + expectedSlashingEvents := testutilevents.FilterEvents[*tokenomicstypes.EventSupplierSlashed](t, events, "poktroll.tokenomics.EventSupplierSlashed") + require.Len(t, expectedSlashingEvents, 1) + + // Validate the slashing event + expectedSlashingEvent := expectedSlashingEvents[0] + require.Equal(t, slashedSupplier.GetOperatorAddress(), expectedSlashingEvent.GetSupplierOperatorAddr()) + require.Equal(t, uint64(1), expectedSlashingEvent.GetNumExpiredClaims()) + require.Equal(t, &belowStakeAmountProofMissingPenalty, expectedSlashingEvent.GetSlashingAmount()) } func (s *TestSuite) TestClaimSettlement_ClaimSettled_ProofRequiredAndProvided_ViaProbability() { @@ -394,13 +453,17 @@ func (s *TestSuite) TestClaimSettlement_ClaimSettled_ProofRequiredAndProvided_Vi numComputeUnits, err := s.claim.GetNumComputeUnits() require.NoError(t, err) + // +1 so its not required via probability + proofRequirementThreshold, err := tokenomics.NumComputeUnitsToCoin(sharedParams, numComputeUnits+1) + require.NoError(t, err) + // Set the proof parameters such that s.claim requires a proof because: // - proof_request_probability is 100% // - proof_requirement_threshold is 0, should not matter - err = s.keepers.ProofKeeper.SetParams(ctx, prooftypes.Params{ - ProofRequestProbability: 1, - ProofRequirementThreshold: numComputeUnits + 1, // +1 so its not required via probability - }) + proofParams := s.keepers.ProofKeeper.GetParams(ctx) + proofParams.ProofRequestProbability = 1 + proofParams.ProofRequirementThreshold = &proofRequirementThreshold + err = s.keepers.ProofKeeper.SetParams(ctx, proofParams) require.NoError(t, err) // Upsert the claim & proof @@ -445,13 +508,17 @@ func (s *TestSuite) TestSettlePendingClaims_Settles_WhenAProofIsNotRequired() { numComputeUnits, err := s.claim.GetNumComputeUnits() require.NoError(t, err) + // +1 to push threshold above s.claim's compute units + proofRequirementThreshold, err := tokenomics.NumComputeUnitsToCoin(sharedParams, numComputeUnits+1) + require.NoError(t, err) + // Set the proof parameters such that s.claim DOES NOT require a proof because: // - proof_request_probability is 0% AND // - proof_requirement_threshold exceeds s.claim's compute units - err = s.keepers.ProofKeeper.SetParams(ctx, prooftypes.Params{ - ProofRequestProbability: 0, - ProofRequirementThreshold: numComputeUnits + 1, // +1 to push threshold above s.claim's compute units - }) + proofParams := s.keepers.ProofKeeper.GetParams(ctx) + proofParams.ProofRequestProbability = 0 + proofParams.ProofRequirementThreshold = &proofRequirementThreshold + err = s.keepers.ProofKeeper.SetParams(ctx, proofParams) require.NoError(t, err) // Upsert the claim only (not the proof) @@ -512,13 +579,17 @@ func (s *TestSuite) TestSettlePendingClaims_ClaimPendingAfterSettlement() { numComputeUnits, err := s.claim.GetNumComputeUnits() require.NoError(t, err) + // +1 to push threshold above s.claim's compute units + proofRequirementThreshold, err := tokenomics.NumComputeUnitsToCoin(sharedParams, numComputeUnits+1) + require.NoError(t, err) + // Set the proof parameters such that s.claim DOES NOT require a proof // because the proof_request_probability is 0% and the proof_request_threshold // is greater than the claims' compute units. - err = s.keepers.ProofKeeper.SetParams(ctx, prooftypes.Params{ - ProofRequestProbability: 0, - ProofRequirementThreshold: numComputeUnits + 1, // +1 to push threshold above s.claim's compute units - }) + proofParams := s.keepers.ProofKeeper.GetParams(ctx) + proofParams.ProofRequestProbability = 0 + proofParams.ProofRequirementThreshold = &proofRequirementThreshold + err = s.keepers.ProofKeeper.SetParams(ctx, proofParams) require.NoError(t, err) // 0. Add the claims & verify they exists @@ -585,3 +656,63 @@ func (s *TestSuite) TestSettlePendingClaims_ClaimPendingAfterSettlement() { claims = s.keepers.GetAllClaims(ctx) require.Len(t, claims, 1) } + +func (s *TestSuite) TestSettlePendingClaims_ClaimExpired_SupplierUnstaked() { + // Retrieve default values + t := s.T() + ctx := s.ctx + sharedParams := s.keepers.SharedKeeper.GetParams(ctx) + + // Retrieve the number of compute units in the claim + numComputeUnits, err := s.claim.GetNumComputeUnits() + require.NoError(t, err) + + // -1 to push threshold below s.claim's compute units + proofRequirementThreshold, err := tokenomics.NumComputeUnitsToCoin(sharedParams, numComputeUnits-1) + require.NoError(t, err) + + // Set the proof parameters such that s.claim requires a proof because: + // - proof_request_probability is 0% + // - proof_requirement_threshold is below the claim (i.e. claim is above threshold) + proofParams := s.keepers.ProofKeeper.GetParams(ctx) + proofParams.ProofRequestProbability = 0 + proofParams.ProofRequirementThreshold = &proofRequirementThreshold + // Set the proof missing penalty to be equal to the supplier's stake to make + // its stake below the minimum stake requirement and trigger an unstake. + proofParams.ProofMissingPenalty = &sdk.Coin{Denom: volatile.DenomuPOKT, Amount: math.NewInt(supplierStake)} + err = s.keepers.ProofKeeper.SetParams(ctx, proofParams) + require.NoError(t, err) + + // Upsert the claim ONLY because it should be processed without needing a proof. + s.keepers.UpsertClaim(ctx, s.claim) + + // Settle pending claims after proof window closes + // Expectation: All (1) claims should expire. + // NB: proofs should be rejected when the current height equals the proof window close height. + sessionEndHeight := s.claim.SessionHeader.SessionEndBlockHeight + blockHeight := shared.GetProofWindowCloseHeight(&sharedParams, sessionEndHeight) + sdkCtx := cosmostypes.UnwrapSDKContext(ctx).WithBlockHeight(blockHeight) + _, _, err = s.keepers.SettlePendingClaims(sdkCtx) + require.NoError(t, err) + + upcomingSessionEndHeight := uint64(shared.GetNextSessionStartHeight(&sharedParams, int64(blockHeight))) - 1 + + // Slashing should have occurred and the supplier is unstaked but still unbonding. + slashedSupplier, supplierFound := s.keepers.GetSupplier(sdkCtx, s.claim.SupplierOperatorAddress) + require.True(t, supplierFound) + require.Equal(t, math.NewInt(0), slashedSupplier.Stake.Amount) + require.Equal(t, upcomingSessionEndHeight, slashedSupplier.UnstakeSessionEndHeight) + require.True(t, slashedSupplier.IsUnbonding()) + + events := sdkCtx.EventManager().Events() + + // Confirm that a slashing event was emitted + expectedSlashingEvents := testutilevents.FilterEvents[*tokenomicstypes.EventSupplierSlashed](t, events, "poktroll.tokenomics.EventSupplierSlashed") + require.Len(t, expectedSlashingEvents, 1) + + // Validate the slashing event + expectedSlashingEvent := expectedSlashingEvents[0] + require.Equal(t, slashedSupplier.GetOperatorAddress(), expectedSlashingEvent.GetSupplierOperatorAddr()) + require.Equal(t, uint64(1), expectedSlashingEvent.GetNumExpiredClaims()) + require.Equal(t, proofParams.ProofMissingPenalty, expectedSlashingEvent.GetSlashingAmount()) +} diff --git a/x/tokenomics/keeper/msg_server_update_param.go b/x/tokenomics/keeper/msg_server_update_param.go index 469848a42..79f0befa2 100644 --- a/x/tokenomics/keeper/msg_server_update_param.go +++ b/x/tokenomics/keeper/msg_server_update_param.go @@ -22,23 +22,6 @@ func (k msgServer) UpdateParam( params := k.GetParams(ctx) - switch msg.Name { - case types.ParamComputeUnitsToTokensMultiplier: - value, ok := msg.AsType.(*types.MsgUpdateParam_AsInt64) - if !ok { - return nil, types.ErrTokenomicsParamsInvalid.Wrapf("unsupported value type for %s param: %T", msg.Name, msg.AsType) - } - computeUnitsToTokensMultiplier := uint64(value.AsInt64) - - if err := types.ValidateComputeUnitsToTokensMultiplier(computeUnitsToTokensMultiplier); err != nil { - return nil, err - } - - params.ComputeUnitsToTokensMultiplier = computeUnitsToTokensMultiplier - default: - return nil, types.ErrTokenomicsParamsInvalid.Wrapf("unsupported param %q", msg.Name) - } - if err := k.SetParams(ctx, params); err != nil { return nil, err } diff --git a/x/tokenomics/keeper/msg_server_update_param_test.go b/x/tokenomics/keeper/msg_server_update_param_test.go deleted file mode 100644 index 5f3375e16..000000000 --- a/x/tokenomics/keeper/msg_server_update_param_test.go +++ /dev/null @@ -1,40 +0,0 @@ -package keeper_test - -import ( - "testing" - - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - "github.com/stretchr/testify/require" - - testkeeper "github.com/pokt-network/poktroll/testutil/keeper" - tokenomicstypes "github.com/pokt-network/poktroll/x/tokenomics/types" -) - -// TODO_FOLLOWUP(@olshansk, #690): Rename this test. -func TestMsgUpdateParam_UpdateMinRelayDifficultyBitsOnly(t *testing.T) { - var expectedComputeUnitsToTokensMultiplier int64 = 8 - - // Set the parameters to their default values - k, msgSrv, ctx := setupMsgServer(t) - defaultParams := tokenomicstypes.DefaultParams() - require.NoError(t, k.SetParams(ctx, defaultParams)) - - // Ensure the default values are different from the new values we want to set - require.NotEqual(t, uint64(expectedComputeUnitsToTokensMultiplier), defaultParams.ComputeUnitsToTokensMultiplier) - - // Update the min relay difficulty bits - updateParamMsg := &tokenomicstypes.MsgUpdateParam{ - Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), - Name: tokenomicstypes.ParamComputeUnitsToTokensMultiplier, - AsType: &tokenomicstypes.MsgUpdateParam_AsInt64{AsInt64: expectedComputeUnitsToTokensMultiplier}, - } - res, err := msgSrv.UpdateParam(ctx, updateParamMsg) - require.NoError(t, err) - - // Ensure the new values are set correctly - require.Equal(t, uint64(expectedComputeUnitsToTokensMultiplier), res.Params.ComputeUnitsToTokensMultiplier) - - // Ensure the other parameters are unchanged - testkeeper.AssertDefaultParamsEqualExceptFields(t, &defaultParams, res.Params, "ComputeUnitsToTokensMultiplier") -} diff --git a/x/tokenomics/keeper/msg_update_params.go b/x/tokenomics/keeper/msg_update_params.go index 88e496344..cefb8e7d6 100644 --- a/x/tokenomics/keeper/msg_update_params.go +++ b/x/tokenomics/keeper/msg_update_params.go @@ -32,8 +32,3 @@ func (k msgServer) UpdateParams(ctx context.Context, msg *types.MsgUpdateParams) return &types.MsgUpdateParamsResponse{}, nil } - -// ComputeUnitsToTokensMultiplier returns the ComputeUnitsToTokensMultiplier param -func (k Keeper) ComputeUnitsToTokensMultiplier(ctx context.Context) uint64 { - return k.GetParams(ctx).ComputeUnitsToTokensMultiplier -} diff --git a/x/tokenomics/keeper/msg_update_params_test.go b/x/tokenomics/keeper/msg_update_params_test.go index 5f510265c..a112ec5d8 100644 --- a/x/tokenomics/keeper/msg_update_params_test.go +++ b/x/tokenomics/keeper/msg_update_params_test.go @@ -5,9 +5,7 @@ import ( "github.com/stretchr/testify/require" - testkeeper "github.com/pokt-network/poktroll/testutil/keeper" "github.com/pokt-network/poktroll/testutil/sample" - "github.com/pokt-network/poktroll/x/tokenomics/keeper" "github.com/pokt-network/poktroll/x/tokenomics/types" ) @@ -28,9 +26,7 @@ func TestMsgUpdateParams(t *testing.T) { req: &types.MsgUpdateParams{ Authority: "invalid", - Params: types.Params{ - ComputeUnitsToTokensMultiplier: 1, - }, + Params: types.Params{}, }, shouldError: true, @@ -41,37 +37,18 @@ func TestMsgUpdateParams(t *testing.T) { req: &types.MsgUpdateParams{ Authority: sample.AccAddress(), - Params: types.Params{ - ComputeUnitsToTokensMultiplier: 1, - }, + Params: types.Params{}, }, shouldError: true, expectedErrMsg: "the provided authority address does not match the on-chain governance address", }, - { - desc: "invalid ComputeUnitsToTokensMultiplier", - - req: &types.MsgUpdateParams{ - Authority: tokenomicsKeeper.GetAuthority(), - - Params: types.Params{ - ComputeUnitsToTokensMultiplier: 0, - }, - }, - - shouldError: true, - expectedErrMsg: "invalid ComputeUnitsToTokensMultiplier", - }, { desc: "successful param update", req: &types.MsgUpdateParams{ Authority: tokenomicsKeeper.GetAuthority(), - - Params: types.Params{ - ComputeUnitsToTokensMultiplier: 1000000, - }, + Params: types.Params{}, }, shouldError: false, @@ -90,36 +67,3 @@ func TestMsgUpdateParams(t *testing.T) { }) } } - -func TestUpdateParams_ComputeUnitsToTokensMultiplier(t *testing.T) { - tokenomicsKeeper, ctx, _, _, _ := testkeeper.TokenomicsKeeperWithActorAddrs(t) - srv := keeper.NewMsgServerImpl(tokenomicsKeeper) - - // Set the default params - tokenomicsKeeper.SetParams(ctx, types.DefaultParams()) - - getParamsReq := &types.QueryParamsRequest{} - - // Verify the default value for ComputeUnitsToTokensMultiplier - getParamsRes, err := tokenomicsKeeper.Params(ctx, getParamsReq) - require.NoError(t, err) - require.Equal(t, - types.DefaultComputeUnitsToTokensMultiplier, - getParamsRes.Params.GetComputeUnitsToTokensMultiplier(), - ) - - // Update the value for ComputeUnitsToTokensMultiplier - updateParamsReq := &types.MsgUpdateParams{ - Authority: tokenomicsKeeper.GetAuthority(), - Params: types.Params{ - ComputeUnitsToTokensMultiplier: 69, - }, - } - _, err = srv.UpdateParams(ctx, updateParamsReq) - require.NoError(t, err) - - // Verify that ComputeUnitsToTokensMultiplier was updated - getParamsRes, err = tokenomicsKeeper.Params(ctx, getParamsReq) - require.NoError(t, err) - require.Equal(t, uint64(69), getParamsRes.Params.GetComputeUnitsToTokensMultiplier()) -} diff --git a/x/tokenomics/keeper/query_params_test.go b/x/tokenomics/keeper/query_params_test.go index 48e685fda..c8e174fd5 100644 --- a/x/tokenomics/keeper/query_params_test.go +++ b/x/tokenomics/keeper/query_params_test.go @@ -16,7 +16,6 @@ func TestGetParams(t *testing.T) { require.NoError(t, k.SetParams(ctx, params)) require.EqualValues(t, params, k.GetParams(ctx)) - require.EqualValues(t, params.ComputeUnitsToTokensMultiplier, k.ComputeUnitsToTokensMultiplier(ctx)) } func TestParamsQuery(t *testing.T) { diff --git a/x/tokenomics/keeper/settle_pending_claims.go b/x/tokenomics/keeper/settle_pending_claims.go index d378095f8..f8eb3b5da 100644 --- a/x/tokenomics/keeper/settle_pending_claims.go +++ b/x/tokenomics/keeper/settle_pending_claims.go @@ -1,16 +1,18 @@ package keeper import ( - "context" "fmt" + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" - "github.com/pokt-network/poktroll/telemetry" + "github.com/pokt-network/poktroll/app/volatile" prooftypes "github.com/pokt-network/poktroll/x/proof/types" "github.com/pokt-network/poktroll/x/shared" - "github.com/pokt-network/poktroll/x/tokenomics/types" + sharedtypes "github.com/pokt-network/poktroll/x/shared/types" + suppliertypes "github.com/pokt-network/poktroll/x/supplier/types" + tokenomicstypes "github.com/pokt-network/poktroll/x/tokenomics/types" ) // SettlePendingClaims settles all pending (i.e. expiring) claims. @@ -22,8 +24,8 @@ import ( // // TODO_TECHDEBT: Refactor this function to return a struct instead of multiple return values. func (k Keeper) SettlePendingClaims(ctx sdk.Context) ( - settledResult types.PendingClaimsResult, - expiredResult types.PendingClaimsResult, + settledResult tokenomicstypes.PendingClaimsResult, + expiredResult tokenomicstypes.PendingClaimsResult, err error, ) { logger := k.Logger().With("method", "SettlePendingClaims") @@ -38,9 +40,13 @@ func (k Keeper) SettlePendingClaims(ctx sdk.Context) ( logger.Info(fmt.Sprintf("found %d expiring claims at block height %d", len(expiringClaims), blockHeight)) // Initialize results structs. - settledResult = types.NewClaimSettlementResult() - expiredResult = types.NewClaimSettlementResult() + settledResult = tokenomicstypes.NewClaimSettlementResult() + expiredResult = tokenomicstypes.NewClaimSettlementResult() + // A map from a supplier operator address to the number of expired claims that + // supplier has in this session. + // Expired claims due to reasons such as invalid or missing proofs when required. + supplierToExpiredClaimCount := make(map[string]uint64) logger.Debug("settling expiring claims") for _, claim := range expiringClaims { var ( @@ -68,7 +74,7 @@ func (k Keeper) SettlePendingClaims(ctx sdk.Context) ( proof, isProofFound := k.proofKeeper.GetProof(ctx, sessionId, claim.SupplierOperatorAddress) // Using the probabilistic proofs approach, determine if this expiring // claim required an on-chain proof - proofRequirement, err = k.proofRequirementForClaim(ctx, &claim) + proofRequirement, err = k.proofKeeper.ProofRequirementForClaim(ctx, &claim) if err != nil { return settledResult, expiredResult, err } @@ -83,22 +89,22 @@ func (k Keeper) SettlePendingClaims(ctx sdk.Context) ( proofIsRequired := (proofRequirement != prooftypes.ProofRequirementReason_NOT_REQUIRED) if proofIsRequired { - expirationReason := types.ClaimExpirationReason_EXPIRATION_REASON_UNSPECIFIED // EXPIRATION_REASON_UNSPECIFIED is the default + expirationReason := tokenomicstypes.ClaimExpirationReason_EXPIRATION_REASON_UNSPECIFIED // EXPIRATION_REASON_UNSPECIFIED is the default if isProofFound { if err = k.proofKeeper.EnsureValidProof(ctx, &proof); err != nil { logger.Warn(fmt.Sprintf("Proof was found but is invalid due to %v", err)) - expirationReason = types.ClaimExpirationReason_PROOF_INVALID + expirationReason = tokenomicstypes.ClaimExpirationReason_PROOF_INVALID } } else { - expirationReason = types.ClaimExpirationReason_PROOF_MISSING + expirationReason = tokenomicstypes.ClaimExpirationReason_PROOF_MISSING } // If the proof is missing or invalid -> expire it - if expirationReason != types.ClaimExpirationReason_EXPIRATION_REASON_UNSPECIFIED { - // Proof was required but not found. + if expirationReason != tokenomicstypes.ClaimExpirationReason_EXPIRATION_REASON_UNSPECIFIED { + // Proof was required but is invalid or not found. // Emit an event that a claim has expired and being removed without being settled. - claimExpiredEvent := types.EventClaimExpired{ + claimExpiredEvent := tokenomicstypes.EventClaimExpired{ Claim: &claim, NumComputeUnits: numClaimComputeUnits, NumRelays: numClaimRelays, @@ -109,7 +115,17 @@ func (k Keeper) SettlePendingClaims(ctx sdk.Context) ( return settledResult, expiredResult, err } - logger.Info("claim expired; required proof not found") + logger.Info(fmt.Sprintf( + "claim expired due to %s", + tokenomicstypes.ClaimExpirationReason_name[int32(expirationReason)]), + ) + + // Collect all the slashed supplier operator addresses to later check + // if they have to be unstaked because of stake below the minimum. + // The unstaking check is not done here because the slashed supplier may + // have other valid claims and the protocol might want to touch the supplier + // owner or operator balances if the stake is negative. + supplierToExpiredClaimCount[claim.SupplierOperatorAddress]++ // The claim & proof are no longer necessary, so there's no need for them // to take up on-chain space. @@ -135,7 +151,7 @@ func (k Keeper) SettlePendingClaims(ctx sdk.Context) ( return settledResult, expiredResult, err } - claimSettledEvent := types.EventClaimSettled{ + claimSettledEvent := tokenomicstypes.EventClaimSettled{ Claim: &claim, NumRelays: numClaimRelays, NumComputeUnits: numClaimComputeUnits, @@ -176,6 +192,14 @@ func (k Keeper) SettlePendingClaims(ctx sdk.Context) ( logger.Info(fmt.Sprintf("Successfully settled claim for session ID %q at block height %d", claim.SessionHeader.SessionId, blockHeight)) } + // Slash all the suppliers that have been marked for slashing slashingCount times. + for supplierOperatorAddress, slashingCount := range supplierToExpiredClaimCount { + if err := k.slashSupplierStake(ctx, supplierOperatorAddress, slashingCount); err != nil { + logger.Error(fmt.Sprintf("error slashing supplier %s: %s", supplierOperatorAddress, err)) + return settledResult, expiredResult, err + } + } + logger.Info(fmt.Sprintf( "settled %d and expired %d claims at block height %d", settledResult.NumClaims, @@ -195,17 +219,11 @@ func (k Keeper) getExpiringClaims(ctx sdk.Context) (expiringClaims []prooftypes. // NB: This error can be safely ignored as on-chain SharedQueryClient implementation cannot return an error. sharedParams, _ := k.sharedQuerier.GetParams(ctx) - claimWindowSizeBlocks := sharedParams.GetClaimWindowOpenOffsetBlocks() + sharedParams.GetClaimWindowCloseOffsetBlocks() - proofWindowSizeBlocks := sharedParams.GetProofWindowOpenOffsetBlocks() + sharedParams.GetProofWindowCloseOffsetBlocks() // expiringSessionEndHeight is the session end height of the session whose proof // window has most recently closed. - expiringSessionEndHeight := blockHeight - - int64(claimWindowSizeBlocks+ - proofWindowSizeBlocks+1) - - allClaims := k.proofKeeper.GetAllClaims(ctx) - _ = allClaims + sessionEndToProofWindowCloseNumBlocks := sharedtypes.GetSessionEndToProofWindowCloseBlocks(sharedParams) + expiringSessionEndHeight := blockHeight - int64(sessionEndToProofWindowCloseNumBlocks+1) var nextKey []byte for { @@ -236,109 +254,111 @@ func (k Keeper) getExpiringClaims(ctx sdk.Context) (expiringClaims []prooftypes. return expiringClaims, nil } -// proofRequirementForClaim checks if a proof is required for a claim. -// If it is not, the claim will be settled without a proof. -// If it is, the claim will only be settled if a valid proof is available. -// TODO_BLOCKER(@bryanchriswhite, #419): Document safety assumptions of the probabilistic proofs mechanism. -func (k Keeper) proofRequirementForClaim(ctx sdk.Context, claim *prooftypes.Claim) (_ prooftypes.ProofRequirementReason, err error) { - logger := k.logger.With("method", "proofRequirementForClaim") +// slashSupplierStake slashes the stake of a supplier and transfers the total +// slashing amount from the supplier bank module to the tokenomics module account. +func (k Keeper) slashSupplierStake( + ctx sdk.Context, + supplierOperatorAddress string, + slashingCount uint64, +) error { + logger := k.logger.With("method", "slashSupplierStake") - var requirementReason = prooftypes.ProofRequirementReason_NOT_REQUIRED + proofParams := k.proofKeeper.GetParams(ctx) + slashingPenaltyPerExpiredClaim := proofParams.GetProofMissingPenalty() - // Defer telemetry calls so that they reference the final values the relevant variables. - defer func() { - telemetry.ProofRequirementCounter(requirementReason, err) - }() + totalSlashingAmt := slashingPenaltyPerExpiredClaim.Amount.Mul(math.NewIntFromUint64(slashingCount)) + totalSlashingCoin := sdk.NewCoin(volatile.DenomuPOKT, totalSlashingAmt) - // NB: Assumption that claim is non-nil and has a valid root sum because it - // is retrieved from the store and validated, on-chain, at time of creation. - var numClaimComputeUnits uint64 - numClaimComputeUnits, err = claim.GetNumComputeUnits() - if err != nil { - return requirementReason, err + supplierToSlash, supplierFound := k.supplierKeeper.GetSupplier(ctx, supplierOperatorAddress) + if !supplierFound { + return tokenomicstypes.ErrTokenomicsSupplierNotFound.Wrapf( + "cannot slash supplier with operator address: %q", + supplierOperatorAddress, + ) } - proofParams := k.proofKeeper.GetParams(ctx) - - // Require a proof if the claim's compute units meets or exceeds the threshold. - // - // TODO_BLOCKER(@bryanchriswhite, #419): This is just VERY BASIC placeholder logic to have something - // in place while we implement proper probabilistic proofs. If you're reading it, - // do not overthink it and look at the documents linked in #419. - // - // TODO_IMPROVE(@bryanchriswhite, @red-0ne): It might make sense to include - // whether there was a proof submission error downstream from here. This would - // require a more comprehensive metrics API. - if numClaimComputeUnits >= proofParams.GetProofRequirementThreshold() { - requirementReason = prooftypes.ProofRequirementReason_THRESHOLD - - logger.Info(fmt.Sprintf( - "claim requires proof due to compute units (%d) exceeding threshold (%d)", - numClaimComputeUnits, - proofParams.GetProofRequirementThreshold(), + slashedSupplierInitialStakeCoin := supplierToSlash.GetStake() + + var remainingStakeCoin sdk.Coin + if slashedSupplierInitialStakeCoin.IsGTE(totalSlashingCoin) { + remainingStakeCoin = slashedSupplierInitialStakeCoin.Sub(totalSlashingCoin) + } else { + // TODO_MAINNET: Consider emitting an event for this case. + logger.Warn(fmt.Sprintf( + "total slashing amount (%s) is greater than supplier %q stake (%s)", + totalSlashingCoin, + supplierOperatorAddress, + supplierToSlash.GetStake(), )) - return requirementReason, nil - } - earliestProofCommitBlockHash, err := k.getEarliestSupplierProofCommitBlockHash(ctx, claim) - if err != nil { - return requirementReason, err + // Set the remaining stake to 0 if the slashing amount is greater than the stake. + remainingStakeCoin = sdk.NewCoin(volatile.DenomuPOKT, math.NewInt(0)) + // Total slashing amount is the whole supplier's stake. + totalSlashingCoin = sdk.NewCoin(volatile.DenomuPOKT, slashedSupplierInitialStakeCoin.Amount) } - proofRequirementSampleValue, err := claim.GetProofRequirementSampleValue(earliestProofCommitBlockHash) - if err != nil { - return requirementReason, err + // Since staking mints tokens to the supplier module account, to have a correct + // accounting, the slashing amount needs to be sent from the supplier module + // account to the tokenomics module account. + if err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, suppliertypes.ModuleName, tokenomicstypes.ModuleName, sdk.NewCoins(totalSlashingCoin)); err != nil { + return err } - // Require a proof probabilistically based on the proof_request_probability param. - // NB: A random value between 0 and 1 will be less than or equal to proof_request_probability - // with probability equal to the proof_request_probability. - if proofRequirementSampleValue <= proofParams.GetProofRequestProbability() { - requirementReason = prooftypes.ProofRequirementReason_PROBABILISTIC - - logger.Info(fmt.Sprintf( - "claim requires proof due to random sample (%.2f) being less than or equal to probability (%.2f)", - proofRequirementSampleValue, - proofParams.GetProofRequestProbability(), - )) - return requirementReason, nil - } + supplierToSlash.Stake = &remainingStakeCoin logger.Info(fmt.Sprintf( - "claim does not require proof due to compute units (%d) being less than the threshold (%d) and random sample (%.2f) being greater than probability (%.2f)", - numClaimComputeUnits, - proofParams.GetProofRequirementThreshold(), - proofRequirementSampleValue, - proofParams.GetProofRequestProbability(), + "slashing supplier owner with address %q operated by %q by %s, remaining stake: %s", + supplierToSlash.GetOwnerAddress(), + supplierToSlash.GetOperatorAddress(), + totalSlashingCoin, + supplierToSlash.GetStake(), )) - return requirementReason, nil -} -// getEarliestSupplierProofCommitBlockHash returns the block hash of the earliest -// block at which a claim might have its proof committed. -func (k Keeper) getEarliestSupplierProofCommitBlockHash( - ctx context.Context, - claim *prooftypes.Claim, -) (blockHash []byte, err error) { - sharedParams, err := k.sharedQuerier.GetParams(ctx) - if err != nil { - return nil, err + // Check if the supplier's stake is below the minimum and unstake it if necessary. + // TODO_BETA(@bryanchriswhite, #612): Use minimum stake governance parameter once available. + minSupplierStakeCoin := sdk.NewCoin(volatile.DenomuPOKT, math.NewInt(1)) + // TODO_MAINNET(@red-0ne): SettlePendingClaims is called at the end of every block, + // but not every block corresponds to the end of a session. This may lead to a situation + // where a force unstaked supplier may still be able to interact with a Gateway or Application. + // However, claims are only processed when sessions end. + // INVESTIGATION: This requires an investigation if the race condition exists + // at all and fixed only if it does. + if supplierToSlash.GetStake().IsLT(minSupplierStakeCoin) { + sharedParams := k.sharedKeeper.GetParams(ctx) + sdkCtx := sdk.UnwrapSDKContext(ctx) + currentHeight := sdkCtx.BlockHeight() + unstakeSessionEndHeight := uint64(shared.GetSessionEndHeight(&sharedParams, currentHeight)) + + logger.Warn(fmt.Sprintf( + "unstaking supplier %q owned by %q due to stake (%s) below the minimum (%s)", + supplierToSlash.GetOperatorAddress(), + supplierToSlash.GetOwnerAddress(), + supplierToSlash.GetStake(), + minSupplierStakeCoin, + )) + + // TODO_MAINNET: Should we just remove the supplier if the stake is + // below the minimum, at the risk of making the off-chain actors have an + // inconsistent session supplier list? See the comment above for more details. + supplierToSlash.UnstakeSessionEndHeight = unstakeSessionEndHeight + } - sessionEndHeight := claim.GetSessionHeader().GetSessionEndBlockHeight() - supplierOperatorAddress := claim.GetSupplierOperatorAddress() + k.supplierKeeper.SetSupplier(ctx, supplierToSlash) - proofWindowOpenHeight := shared.GetProofWindowOpenHeight(sharedParams, sessionEndHeight) - proofWindowOpenBlockHash := k.sessionKeeper.GetBlockHash(ctx, proofWindowOpenHeight) + // Emit an event that a supplier has been slashed. + supplierSlashedEvent := tokenomicstypes.EventSupplierSlashed{ + SupplierOperatorAddr: supplierOperatorAddress, + NumExpiredClaims: slashingCount, + SlashingAmount: &totalSlashingCoin, + } + if err := ctx.EventManager().EmitTypedEvent(&supplierSlashedEvent); err != nil { + return err + } - // TODO_TECHDEBT: Update the method header of this function to accept (sharedParams, Claim, BlockHash). - // After doing so, please review all calling sites and simplify them accordingly. - earliestSupplierProofCommitHeight := shared.GetEarliestSupplierProofCommitHeight( - sharedParams, - sessionEndHeight, - proofWindowOpenBlockHash, - supplierOperatorAddress, - ) + // TODO_POST_MAINNET: Handle the case where the total slashing amount is + // greater than the supplier's stake. The protocol could take the remaining + // amount from the supplier's owner or operator balances. - return k.sessionKeeper.GetBlockHash(ctx, earliestSupplierProofCommitHeight), nil + return nil } diff --git a/x/tokenomics/keeper/token_logic_modules.go b/x/tokenomics/keeper/token_logic_modules.go index a6efb12d3..0dfe69d39 100644 --- a/x/tokenomics/keeper/token_logic_modules.go +++ b/x/tokenomics/keeper/token_logic_modules.go @@ -20,6 +20,7 @@ import ( sessiontypes "github.com/pokt-network/poktroll/x/session/types" sharedtypes "github.com/pokt-network/poktroll/x/shared/types" suppliertypes "github.com/pokt-network/poktroll/x/supplier/types" + "github.com/pokt-network/poktroll/x/tokenomics" tokenomicstypes "github.com/pokt-network/poktroll/x/tokenomics/types" tokenomictypes "github.com/pokt-network/poktroll/x/tokenomics/types" ) @@ -175,14 +176,14 @@ func (k Keeper) ProcessTokenLogicModules( ) } - // Retrieve the count (i.e. number of relays) to determine the amount of work done - numRelays, err := root.Count() + // Retrieve the sum (i.e. number of compute units) to determine the amount of work done + numClaimComputeUnits, err := claim.GetNumComputeUnits() if err != nil { return tokenomicstypes.ErrTokenomicsRootHashInvalid.Wrapf("%v", err) } // TODO_MAINNET(@bryanchriswhite, @red-0ne): Fix the low-volume exploit here. // https://www.notion.so/buildwithgrove/RelayMiningDifficulty-and-low-volume-7aab3edf6f324786933af369c2fa5f01?pvs=4 - if numRelays == 0 { + if numClaimComputeUnits == 0 { return tokenomicstypes.ErrTokenomicsRootHashInvalid.Wrap("root hash has zero relays") } @@ -228,17 +229,19 @@ func (k Keeper) ProcessTokenLogicModules( return tokenomicstypes.ErrTokenomicsServiceNotFound.Wrapf("service with ID %q not found", sessionHeader.ServiceId) } + sharedParams := k.sharedKeeper.GetParams(ctx) + // Determine the total number of tokens being claimed (i.e. for the work completed) // by the supplier for the amount of work they did to service the application // in the session. - claimSettlementCoin, err = k.numRelaysToCoin(ctx, numRelays, &service) + claimSettlementCoin, err = tokenomics.NumComputeUnitsToCoin(sharedParams, numClaimComputeUnits) if err != nil { return err } // Helpers for logging the same metadata throughout this function calls logger = logger.With( - "num_relays", numRelays, + "num_claim_compute_units", numClaimComputeUnits, "claim_settlement_upokt", claimSettlementCoin.Amount, "session_id", sessionHeader.GetSessionId(), "service_id", sessionHeader.GetServiceId(), @@ -249,6 +252,13 @@ func (k Keeper) ProcessTokenLogicModules( // Retrieving the relay mining difficulty for the service at hand relayMiningDifficulty, found := k.GetRelayMiningDifficulty(ctx, service.Id) if !found { + // If the relay mining difficulty is not found, we initialize it with the + // current number of relays. + numRelays, countErr := claim.GetNumRelays() + if countErr != nil { + return tokenomicstypes.ErrTokenomicsRootHashInvalid.Wrapf("%v", countErr) + } + relayMiningDifficulty = newDefaultRelayMiningDifficulty(ctx, logger, service.Id, numRelays) } @@ -260,7 +270,7 @@ func (k Keeper) ProcessTokenLogicModules( } logger = logger.With("actual_settlement_upokt", actualSettlementCoin) - logger.Info(fmt.Sprintf("About to start processing TLMs for (%d) relays, equal to (%s) claimed", numRelays, actualSettlementCoin)) + logger.Info(fmt.Sprintf("About to start processing TLMs for (%d) compute units, equal to (%s) claimed", numClaimComputeUnits, actualSettlementCoin)) // Execute all the token logic modules processors for tlm, tlmProcessor := range tokenLogicModuleProcessorMap { logger.Info(fmt.Sprintf("Starting TLM processing: %q", tlm)) @@ -563,24 +573,6 @@ func (k Keeper) ensureClaimAmountLimits( return actualSettlementCoins, nil } -// numRelaysToCoin calculates the amount of uPOKT to mint based on the number of compute units. -func (k Keeper) numRelaysToCoin( - ctx context.Context, - numRelays uint64, // numRelays is a session specific parameter - service *sharedtypes.Service, -) (cosmostypes.Coin, error) { - // CUTTM is a GLOBAL network wide parameter - computeUnitsToTokensMultiplier := k.GetParams(ctx).ComputeUnitsToTokensMultiplier - // CUPR is a LOCAL service specific parameter - computeUnitsPerRelay := service.ComputeUnitsPerRelay - upoktAmount := math.NewInt(int64(numRelays * computeUnitsPerRelay * computeUnitsToTokensMultiplier)) - if upoktAmount.IsNegative() { - return cosmostypes.Coin{}, tokenomicstypes.ErrTokenomicsRootHashInvalid.Wrap("sum * compute_units_to_tokens_multiplier is negative") - } - - return cosmostypes.NewCoin(volatile.DenomuPOKT, upoktAmount), nil -} - // distributeSupplierRewardsToShareHolders distributes the supplier rewards to its // shareholders based on the rev share percentage of the supplier service config. func (k Keeper) distributeSupplierRewardsToShareHolders( diff --git a/x/tokenomics/keeper/token_logic_modules_test.go b/x/tokenomics/keeper/token_logic_modules_test.go index 2f6d6bdfd..427573dfe 100644 --- a/x/tokenomics/keeper/token_logic_modules_test.go +++ b/x/tokenomics/keeper/token_logic_modules_test.go @@ -64,7 +64,7 @@ func TestProcessTokenLogicModules_TLMBurnEqualsMint_Valid(t *testing.T) { supplierModuleAddress := authtypes.NewModuleAddress(suppliertypes.ModuleName).String() // Set compute_units_to_tokens_multiplier to simplify expectation calculations. - err := keepers.Keeper.SetParams(ctx, tokenomicstypes.Params{ + err := keepers.SharedKeeper.SetParams(ctx, sharedtypes.Params{ ComputeUnitsToTokensMultiplier: globalComputeUnitsToTokensMultiplier, }) require.NoError(t, err) @@ -194,7 +194,7 @@ func TestProcessTokenLogicModules_TLMBurnEqualsMint_Invalid_SupplierExceedsMaxCl supplierModuleAddress := authtypes.NewModuleAddress(suppliertypes.ModuleName).String() // Set compute_units_to_tokens_multiplier to simplify expectation calculations. - err := keepers.Keeper.SetParams(ctx, tokenomicstypes.Params{ + err := keepers.SharedKeeper.SetParams(ctx, sharedtypes.Params{ ComputeUnitsToTokensMultiplier: globalComputeUnitsToTokensMultiplier, }) require.NoError(t, err) @@ -329,7 +329,7 @@ func TestProcessTokenLogicModules_TLMGlobalMint_Valid_MintDistributionCorrect(t keepers.SetService(ctx, *service) // Set compute_units_to_tokens_multiplier to simplify expectation calculations. - err := keepers.Keeper.SetParams(ctx, tokenomicstypes.Params{ + err := keepers.SharedKeeper.SetParams(ctx, sharedtypes.Params{ ComputeUnitsToTokensMultiplier: globalComputeUnitsToTokensMultiplier, }) require.NoError(t, err) diff --git a/x/tokenomics/module/tx_update_params.go b/x/tokenomics/module/tx_update_params.go index 0f242665d..7ae94faed 100644 --- a/x/tokenomics/module/tx_update_params.go +++ b/x/tokenomics/module/tx_update_params.go @@ -16,22 +16,16 @@ var _ = strconv.Itoa(0) // TODO_BLOCKER(@bryanchriswhite, #322): Update the CLI once we determine settle on how to maintain and update parameters. func CmdUpdateParams() *cobra.Command { cmd := &cobra.Command{ - Use: "update-params ", + Use: "update-params", Short: "Update the parameters of the tokenomics module", Long: `Update the parameters in the tokenomics module.", All parameters must be provided when updating. Example: -$ poktrolld tx tokenomics update-params --from pnf --node $(POCKET_NODE) --home $(POKTROLLD_HOME)`, - Args: cobra.ExactArgs(1), +$ poktrolld tx tokenomics update-params --from pnf --node $(POCKET_NODE) --home $(POKTROLLD_HOME)`, + Args: cobra.ExactArgs(0), RunE: func(cmd *cobra.Command, args []string) (err error) { - // Parse computeUnitsToTokensMultiplier - computeUnitsToTokensMultiplier, err := strconv.ParseUint(args[0], 10, 64) - if err != nil { - return err - } - // Get client context clientCtx, err := client.GetClientTxContext(cmd) if err != nil { @@ -41,7 +35,6 @@ $ poktrolld tx tokenomics update-params --f // Create update params message msg := types.NewMsgUpdateParams( clientCtx.GetFromAddress().String(), - computeUnitsToTokensMultiplier, ) if err := msg.ValidateBasic(); err != nil { return err diff --git a/x/tokenomics/module/tx_update_params_test.go b/x/tokenomics/module/tx_update_params_test.go index e6d135cc5..c21dca4f8 100644 --- a/x/tokenomics/module/tx_update_params_test.go +++ b/x/tokenomics/module/tx_update_params_test.go @@ -13,7 +13,6 @@ import ( "github.com/pokt-network/poktroll/testutil/network" tokenomics "github.com/pokt-network/poktroll/x/tokenomics/module" - "github.com/pokt-network/poktroll/x/tokenomics/types" ) func TestCLI_UpdateParams(t *testing.T) { @@ -36,15 +35,9 @@ func TestCLI_UpdateParams(t *testing.T) { }{ { desc: "valid update of all params", - args: []string{"42"}, + args: []string{}, expectedErr: nil, }, - { - desc: "invalid compute_units_to_tokens_multiplier update", - args: []string{"0"}, - expectedErr: types.ErrTokenomicsParamsInvalid, - expectedExtraErrMsg: "invalid ComputeUnitsToTokensMultiplier", - }, } for _, test := range tests { diff --git a/x/tokenomics/tokenomics.go b/x/tokenomics/tokenomics.go new file mode 100644 index 000000000..3515dfc4a --- /dev/null +++ b/x/tokenomics/tokenomics.go @@ -0,0 +1,27 @@ +package tokenomics + +import ( + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/pokt-network/poktroll/app/volatile" + sharedtypes "github.com/pokt-network/poktroll/x/shared/types" + tokenomicstypes "github.com/pokt-network/poktroll/x/tokenomics/types" +) + +// NumComputeUnitsToCoin converts compute units to uPOKT to mint based on global +// network parameters. +func NumComputeUnitsToCoin(params sharedtypes.Params, numClaimComputeUnits uint64) (sdk.Coin, error) { + // CUTTM is a GLOBAL network wide parameter. + upoktAmount := math.NewInt(int64(numClaimComputeUnits * params.GetComputeUnitsToTokensMultiplier())) + if upoktAmount.IsNegative() { + return sdk.Coin{}, tokenomicstypes.ErrTokenomicsCalculation.Wrapf( + "num compute units to coin (%d) * CUTTM (%d) resulted in a negative amount: %d", + numClaimComputeUnits, + params.GetComputeUnitsToTokensMultiplier(), + upoktAmount, + ) + } + + return sdk.NewCoin(volatile.DenomuPOKT, upoktAmount), nil +} diff --git a/x/tokenomics/types/errors.go b/x/tokenomics/types/errors.go index 043aa95f0..05afa3e9e 100644 --- a/x/tokenomics/types/errors.go +++ b/x/tokenomics/types/errors.go @@ -36,4 +36,5 @@ var ( ErrTokenomicsAmountMismatchTooLarge = sdkerrors.Register(ModuleName, 1127, "an unexpected amount mismatch occurred") ErrTokenomicsMintAmountZero = sdkerrors.Register(ModuleName, 1128, "mint amount cannot be zero") ErrTokenomicsTLMError = sdkerrors.Register(ModuleName, 1129, "failed to process TLM") + ErrTokenomicsCalculation = sdkerrors.Register(ModuleName, 1130, "tokenomics calculation error") ) diff --git a/x/tokenomics/types/event.pb.go b/x/tokenomics/types/event.pb.go index 079bf8198..85e281f24 100644 --- a/x/tokenomics/types/event.pb.go +++ b/x/tokenomics/types/event.pb.go @@ -335,65 +335,131 @@ func (m *EventApplicationOverserviced) GetEffectiveBurn() *types1.Coin { return nil } +// EventSupplierSlashed is emitted when a supplier is slashed for not providing, +// or provided invalid required proofs for claims. +type EventSupplierSlashed struct { + SupplierOperatorAddr string `protobuf:"bytes,1,opt,name=supplier_operator_addr,json=supplierOperatorAddr,proto3" json:"supplier_operator_addr,omitempty"` + // Number of expired claims (due to missing or invalid proof) that led to slashing. + NumExpiredClaims uint64 `protobuf:"varint,2,opt,name=num_expired_claims,json=numExpiredClaims,proto3" json:"num_expired_claims,omitempty"` + // Amount slashed from the supplier's stake due to the expired claims. + // This is a function of the number of expired claims and proof missing penalty. + SlashingAmount *types1.Coin `protobuf:"bytes,3,opt,name=slashing_amount,json=slashingAmount,proto3" json:"slashing_amount,omitempty"` +} + +func (m *EventSupplierSlashed) Reset() { *m = EventSupplierSlashed{} } +func (m *EventSupplierSlashed) String() string { return proto.CompactTextString(m) } +func (*EventSupplierSlashed) ProtoMessage() {} +func (*EventSupplierSlashed) Descriptor() ([]byte, []int) { + return fileDescriptor_a78874bbf91a58c7, []int{4} +} +func (m *EventSupplierSlashed) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventSupplierSlashed) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *EventSupplierSlashed) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventSupplierSlashed.Merge(m, src) +} +func (m *EventSupplierSlashed) XXX_Size() int { + return m.Size() +} +func (m *EventSupplierSlashed) XXX_DiscardUnknown() { + xxx_messageInfo_EventSupplierSlashed.DiscardUnknown(m) +} + +var xxx_messageInfo_EventSupplierSlashed proto.InternalMessageInfo + +func (m *EventSupplierSlashed) GetSupplierOperatorAddr() string { + if m != nil { + return m.SupplierOperatorAddr + } + return "" +} + +func (m *EventSupplierSlashed) GetNumExpiredClaims() uint64 { + if m != nil { + return m.NumExpiredClaims + } + return 0 +} + +func (m *EventSupplierSlashed) GetSlashingAmount() *types1.Coin { + if m != nil { + return m.SlashingAmount + } + return nil +} + func init() { proto.RegisterEnum("poktroll.tokenomics.ClaimExpirationReason", ClaimExpirationReason_name, ClaimExpirationReason_value) proto.RegisterType((*EventClaimExpired)(nil), "poktroll.tokenomics.EventClaimExpired") proto.RegisterType((*EventClaimSettled)(nil), "poktroll.tokenomics.EventClaimSettled") proto.RegisterType((*EventRelayMiningDifficultyUpdated)(nil), "poktroll.tokenomics.EventRelayMiningDifficultyUpdated") proto.RegisterType((*EventApplicationOverserviced)(nil), "poktroll.tokenomics.EventApplicationOverserviced") + proto.RegisterType((*EventSupplierSlashed)(nil), "poktroll.tokenomics.EventSupplierSlashed") } func init() { proto.RegisterFile("poktroll/tokenomics/event.proto", fileDescriptor_a78874bbf91a58c7) } var fileDescriptor_a78874bbf91a58c7 = []byte{ - // 742 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x54, 0xcd, 0x4e, 0xeb, 0x46, - 0x14, 0x8e, 0x43, 0xa8, 0x94, 0xa1, 0x40, 0x62, 0xa0, 0x4d, 0x29, 0x38, 0x90, 0x45, 0x45, 0xa9, - 0xb0, 0x05, 0x54, 0x5d, 0x55, 0xa8, 0x49, 0x30, 0xc5, 0x52, 0x49, 0x52, 0x07, 0xaa, 0xaa, 0x9b, - 0xa9, 0x63, 0x9f, 0x24, 0x53, 0xe2, 0x19, 0x77, 0x3c, 0x4e, 0xc2, 0xb2, 0x6f, 0xd0, 0x07, 0xe8, - 0x0b, 0x74, 0xd1, 0xf7, 0xe8, 0x92, 0x25, 0x2b, 0x74, 0x15, 0x76, 0x3c, 0xc5, 0x95, 0xc7, 0xf9, - 0xbb, 0x81, 0xab, 0xbb, 0xbe, 0x1b, 0x7b, 0xfc, 0x9d, 0xef, 0x3b, 0xe7, 0xcc, 0x37, 0xe3, 0x83, - 0x8a, 0x01, 0xbb, 0x15, 0x9c, 0xf5, 0x7a, 0x86, 0x60, 0xb7, 0x40, 0x99, 0x4f, 0xdc, 0xd0, 0x80, - 0x3e, 0x50, 0xa1, 0x07, 0x9c, 0x09, 0xa6, 0x6e, 0x4c, 0x08, 0xfa, 0x8c, 0xb0, 0xad, 0xb9, 0x2c, - 0xf4, 0x59, 0x68, 0xb4, 0x9c, 0x10, 0x8c, 0xfe, 0x71, 0x0b, 0x84, 0x73, 0x6c, 0xb8, 0x8c, 0xd0, - 0x44, 0xb4, 0xbd, 0xd9, 0x61, 0x1d, 0x26, 0x97, 0x46, 0xbc, 0x1a, 0xa3, 0xdb, 0xd3, 0x5a, 0x01, - 0x67, 0xac, 0x6d, 0x88, 0xbb, 0x00, 0xc2, 0x24, 0x56, 0xfa, 0x2f, 0x8d, 0xf2, 0x66, 0x5c, 0xb6, - 0xda, 0x73, 0x88, 0x6f, 0x0e, 0x03, 0xc2, 0xc1, 0x53, 0xbf, 0x43, 0xcb, 0x6e, 0xfc, 0x5d, 0x50, - 0xf6, 0x94, 0x83, 0x95, 0x93, 0x2d, 0x7d, 0xda, 0x8c, 0xcc, 0xa0, 0x4b, 0x72, 0x25, 0xfb, 0xfc, - 0x58, 0x4c, 0x78, 0x76, 0xf2, 0x52, 0x8f, 0x10, 0xa2, 0x91, 0x8f, 0x39, 0xf4, 0x9c, 0xbb, 0xb0, - 0x90, 0xde, 0x53, 0x0e, 0x32, 0x95, 0xb5, 0xe7, 0xc7, 0xe2, 0x1c, 0x6a, 0x67, 0x69, 0xe4, 0xdb, - 0x72, 0xa9, 0x96, 0x51, 0x3e, 0x0e, 0xb8, 0xcc, 0x0f, 0x22, 0x01, 0x38, 0xa2, 0x44, 0x84, 0x85, - 0x25, 0xa9, 0xda, 0x7a, 0x7e, 0x2c, 0xbe, 0x0c, 0xda, 0xeb, 0x34, 0xf2, 0xab, 0x09, 0x72, 0x13, - 0x03, 0x2a, 0x45, 0x79, 0x88, 0x9b, 0x76, 0x04, 0x61, 0x14, 0x73, 0x70, 0x42, 0x46, 0x0b, 0x99, - 0x3d, 0xe5, 0x60, 0xed, 0xe4, 0x50, 0x7f, 0xc5, 0x42, 0x7d, 0xb6, 0x4f, 0x29, 0xb1, 0xa5, 0x22, - 0x29, 0xf7, 0x22, 0x91, 0x9d, 0x83, 0x05, 0x62, 0xe9, 0xdf, 0x77, 0xfc, 0x6a, 0x82, 0x10, 0xbd, - 0x8f, 0xca, 0xaf, 0x3f, 0x50, 0x5e, 0xb6, 0x84, 0x39, 0xfc, 0x19, 0x11, 0x0e, 0x3e, 0x50, 0x31, - 0xf6, 0xeb, 0xab, 0xc5, 0xae, 0x1b, 0xf1, 0xd3, 0x9e, 0xf1, 0xe6, 0xbd, 0x7a, 0x91, 0xc4, 0xce, - 0x05, 0x0b, 0xf4, 0xd2, 0x3f, 0x69, 0xb4, 0x2f, 0xbd, 0x92, 0xed, 0x5f, 0x11, 0x4a, 0x68, 0xe7, - 0x9c, 0xb4, 0xdb, 0xc4, 0x8d, 0x7a, 0xe2, 0xee, 0x26, 0xf0, 0x1c, 0x01, 0x9e, 0xba, 0x8b, 0x50, - 0x08, 0xbc, 0x4f, 0x5c, 0xc0, 0xc4, 0x93, 0x06, 0x66, 0xed, 0xec, 0x18, 0xb1, 0x3c, 0xf5, 0x0c, - 0xed, 0x04, 0x1c, 0xfa, 0x58, 0x38, 0xbc, 0x03, 0x02, 0x77, 0x9d, 0xb0, 0x8b, 0xbb, 0x30, 0xc4, - 0x40, 0x5d, 0xe6, 0x81, 0x27, 0x4d, 0xcb, 0xda, 0x85, 0x98, 0x73, 0x2d, 0x29, 0x97, 0x4e, 0xd8, - 0xbd, 0x84, 0xa1, 0x99, 0xc4, 0xd5, 0xef, 0xd1, 0x97, 0x14, 0x06, 0xef, 0x95, 0x2f, 0x49, 0xf9, - 0xe7, 0x14, 0x06, 0xaf, 0xaa, 0x8f, 0xd0, 0x86, 0xac, 0x3e, 0x3b, 0x0f, 0x0c, 0xbe, 0x23, 0x0d, - 0xcb, 0xc4, 0x3b, 0x86, 0x7e, 0x6d, 0x72, 0x3a, 0xa6, 0xef, 0xa8, 0xdf, 0x20, 0x35, 0x2e, 0xb6, - 0xc0, 0x5e, 0x96, 0xec, 0x75, 0x0a, 0x83, 0x79, 0x72, 0xe9, 0xaf, 0x34, 0xda, 0x91, 0xf6, 0x94, - 0x83, 0xa0, 0x47, 0x5c, 0x79, 0xcb, 0xea, 0x7d, 0xe0, 0xe3, 0xbd, 0x7b, 0xea, 0xd7, 0x28, 0xe7, - 0xcc, 0x42, 0xd8, 0xf1, 0x3c, 0x3e, 0xf6, 0x67, 0x7d, 0x0e, 0x2f, 0x7b, 0x1e, 0x57, 0xbf, 0x45, - 0x9f, 0x85, 0x51, 0x8c, 0x01, 0xc7, 0x2c, 0x00, 0xee, 0x08, 0xc6, 0x13, 0x41, 0xe2, 0xcf, 0xe6, - 0x24, 0x5a, 0x1f, 0x07, 0xa5, 0xea, 0x0c, 0xad, 0xc2, 0x30, 0x00, 0x57, 0x80, 0x87, 0x5b, 0x11, - 0xa7, 0xd2, 0x8d, 0x95, 0x93, 0x2f, 0xf4, 0x64, 0xcc, 0xe8, 0xf1, 0x98, 0xd1, 0xc7, 0x63, 0x46, - 0xaf, 0x32, 0x42, 0xed, 0x4f, 0x27, 0xfc, 0x4a, 0xc4, 0xa9, 0xfa, 0x03, 0x5a, 0x83, 0x76, 0x1b, - 0x5c, 0x41, 0xfa, 0x90, 0x24, 0xc8, 0x7c, 0x28, 0xc1, 0xea, 0x54, 0x10, 0x67, 0x38, 0xfc, 0x1d, - 0x6d, 0xbd, 0xfa, 0x43, 0xaa, 0xfb, 0x68, 0xd7, 0xfc, 0xb5, 0x61, 0xd9, 0xe5, 0x6b, 0xab, 0x5e, - 0xc3, 0xb6, 0x59, 0x6e, 0xd6, 0x6b, 0xf8, 0xa6, 0xd6, 0x6c, 0x98, 0x55, 0xeb, 0xc2, 0x32, 0xcf, - 0x73, 0x29, 0x35, 0x8f, 0x56, 0x1b, 0x76, 0xbd, 0x7e, 0x81, 0xaf, 0xac, 0x66, 0xd3, 0xaa, 0xfd, - 0x98, 0x53, 0x66, 0x90, 0x55, 0xfb, 0xa5, 0xfc, 0x93, 0x75, 0x9e, 0x4b, 0x57, 0x7e, 0xfe, 0x7f, - 0xa4, 0x29, 0xf7, 0x23, 0x4d, 0x79, 0x18, 0x69, 0xca, 0x9b, 0x91, 0xa6, 0xfc, 0xfd, 0xa4, 0xa5, - 0xee, 0x9f, 0xb4, 0xd4, 0xc3, 0x93, 0x96, 0xfa, 0xed, 0xb4, 0x43, 0x44, 0x37, 0x6a, 0xe9, 0x2e, - 0xf3, 0x8d, 0xf8, 0xf6, 0x1f, 0x51, 0x10, 0x03, 0xc6, 0x6f, 0x8d, 0xe9, 0xc8, 0x1c, 0xce, 0x0f, - 0x68, 0x39, 0x39, 0x5b, 0x9f, 0xc8, 0xd1, 0x79, 0xfa, 0x36, 0x00, 0x00, 0xff, 0xff, 0x81, 0xe5, - 0x22, 0x8a, 0xc4, 0x05, 0x00, 0x00, + // 809 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x55, 0xcf, 0x72, 0xdb, 0x44, + 0x18, 0x8f, 0xdc, 0x94, 0x19, 0x6f, 0x49, 0x62, 0x6f, 0x13, 0x30, 0xa1, 0x55, 0x52, 0x1f, 0x98, + 0x50, 0x88, 0x34, 0x4d, 0x19, 0x4e, 0x4c, 0x07, 0x3b, 0x51, 0xa9, 0x66, 0xa8, 0x1d, 0xe4, 0x86, + 0x61, 0xb8, 0x2c, 0x6b, 0xe9, 0xb3, 0xbd, 0x44, 0xda, 0x15, 0xab, 0x95, 0xe3, 0x1c, 0x79, 0x03, + 0x1e, 0x80, 0x17, 0xe0, 0xc0, 0x2b, 0x70, 0xe6, 0xd8, 0x63, 0x4f, 0x19, 0x26, 0xb9, 0xe5, 0x29, + 0x98, 0x5d, 0xc9, 0xb1, 0x71, 0x42, 0x73, 0xee, 0xc5, 0x5e, 0x7f, 0xdf, 0xef, 0xf7, 0xfd, 0xf9, + 0xc9, 0xfb, 0x13, 0xda, 0x4a, 0xc5, 0xb1, 0x92, 0x22, 0x8e, 0x5d, 0x25, 0x8e, 0x81, 0x8b, 0x84, + 0x85, 0x99, 0x0b, 0x63, 0xe0, 0xca, 0x49, 0xa5, 0x50, 0x02, 0xdf, 0x9f, 0x02, 0x9c, 0x19, 0x60, + 0xd3, 0x0e, 0x45, 0x96, 0x88, 0xcc, 0xed, 0xd3, 0x0c, 0xdc, 0xf1, 0x93, 0x3e, 0x28, 0xfa, 0xc4, + 0x0d, 0x05, 0xe3, 0x05, 0x69, 0x73, 0x7d, 0x28, 0x86, 0xc2, 0x1c, 0x5d, 0x7d, 0x2a, 0xa3, 0x9b, + 0x57, 0xbd, 0x52, 0x29, 0xc4, 0xc0, 0x55, 0xa7, 0x29, 0x64, 0x45, 0xae, 0xf9, 0x67, 0x05, 0xd5, + 0x3d, 0xdd, 0x76, 0x3f, 0xa6, 0x2c, 0xf1, 0x26, 0x29, 0x93, 0x10, 0xe1, 0x2f, 0xd1, 0xdd, 0x50, + 0xff, 0x6e, 0x58, 0xdb, 0xd6, 0xce, 0xbd, 0xbd, 0x0d, 0xe7, 0x6a, 0x18, 0x53, 0xc1, 0x31, 0xe0, + 0x76, 0xf5, 0xf2, 0x6c, 0xab, 0xc0, 0x05, 0xc5, 0x17, 0xde, 0x45, 0x88, 0xe7, 0x09, 0x91, 0x10, + 0xd3, 0xd3, 0xac, 0x51, 0xd9, 0xb6, 0x76, 0x96, 0xdb, 0xab, 0x97, 0x67, 0x5b, 0x73, 0xd1, 0xa0, + 0xca, 0xf3, 0x24, 0x30, 0x47, 0xdc, 0x42, 0x75, 0x9d, 0x08, 0x45, 0x92, 0xe6, 0x0a, 0x48, 0xce, + 0x99, 0xca, 0x1a, 0x77, 0x0c, 0x6b, 0xe3, 0xf2, 0x6c, 0xeb, 0x7a, 0x32, 0x58, 0xe3, 0x79, 0xb2, + 0x5f, 0x44, 0x8e, 0x74, 0x00, 0x73, 0x54, 0x07, 0x3d, 0x34, 0x55, 0x4c, 0x70, 0x22, 0x81, 0x66, + 0x82, 0x37, 0x96, 0xb7, 0xad, 0x9d, 0xd5, 0xbd, 0xc7, 0xce, 0x0d, 0x12, 0x3a, 0xb3, 0x3d, 0x0d, + 0x25, 0x30, 0x8c, 0xa2, 0xdd, 0xb5, 0x42, 0x41, 0x0d, 0x16, 0x80, 0xcd, 0x3f, 0xfe, 0xa3, 0x57, + 0x0f, 0x94, 0x8a, 0xdf, 0x29, 0xbd, 0x7e, 0x46, 0x75, 0x33, 0x12, 0x91, 0xf0, 0x4b, 0xce, 0x24, + 0x24, 0xc0, 0x55, 0xa9, 0xd7, 0x27, 0x8b, 0x53, 0x1f, 0xea, 0xcf, 0x60, 0x86, 0x9b, 0xd7, 0xea, + 0x5a, 0x91, 0xa0, 0x96, 0x2e, 0xc0, 0x9b, 0xbf, 0x57, 0xd0, 0x23, 0xa3, 0x95, 0x19, 0xff, 0x25, + 0xe3, 0x8c, 0x0f, 0x0f, 0xd8, 0x60, 0xc0, 0xc2, 0x3c, 0x56, 0xa7, 0x47, 0x69, 0x44, 0x15, 0x44, + 0xf8, 0x21, 0x42, 0x19, 0xc8, 0x31, 0x0b, 0x81, 0xb0, 0xc8, 0x08, 0x58, 0x0d, 0xaa, 0x65, 0xc4, + 0x8f, 0xf0, 0x33, 0xf4, 0x20, 0x95, 0x30, 0x26, 0x8a, 0xca, 0x21, 0x28, 0x32, 0xa2, 0xd9, 0x88, + 0x8c, 0x60, 0x42, 0x80, 0x87, 0x22, 0x82, 0xc8, 0x88, 0x56, 0x0d, 0x1a, 0x1a, 0xf3, 0xca, 0x40, + 0x5e, 0xd0, 0x6c, 0xf4, 0x02, 0x26, 0x5e, 0x91, 0xc7, 0x5f, 0xa1, 0x8f, 0x39, 0x9c, 0xfc, 0x2f, + 0xfd, 0x8e, 0xa1, 0x7f, 0xc8, 0xe1, 0xe4, 0x46, 0xf6, 0x2e, 0xba, 0x6f, 0xba, 0xcf, 0x9e, 0x07, + 0x81, 0x84, 0x1a, 0xc1, 0x96, 0xf5, 0xc6, 0x30, 0xee, 0x4c, 0x9f, 0x8e, 0x97, 0x50, 0xfc, 0x19, + 0xc2, 0xba, 0xd9, 0x02, 0xfa, 0xae, 0x41, 0xaf, 0x71, 0x38, 0x99, 0x07, 0x37, 0x7f, 0xad, 0xa0, + 0x07, 0x46, 0x9e, 0x56, 0x9a, 0xc6, 0x2c, 0x34, 0xff, 0xb2, 0xee, 0x18, 0x64, 0xb9, 0x7b, 0x84, + 0x3f, 0x45, 0x35, 0x3a, 0x4b, 0x11, 0x1a, 0x45, 0xb2, 0xd4, 0x67, 0x6d, 0x2e, 0xde, 0x8a, 0x22, + 0x89, 0xbf, 0x40, 0x1f, 0x64, 0xb9, 0x8e, 0x81, 0x24, 0x22, 0x05, 0x49, 0x95, 0x90, 0x05, 0xa1, + 0xd0, 0x67, 0x7d, 0x9a, 0xed, 0x96, 0x49, 0xc3, 0x7a, 0x86, 0x56, 0x60, 0x92, 0x42, 0xa8, 0x20, + 0x22, 0xfd, 0x5c, 0x72, 0xa3, 0xc6, 0xbd, 0xbd, 0x8f, 0x9c, 0xc2, 0x66, 0x1c, 0x6d, 0x33, 0x4e, + 0x69, 0x33, 0xce, 0xbe, 0x60, 0x3c, 0x78, 0x7f, 0x8a, 0x6f, 0xe7, 0x92, 0xe3, 0xaf, 0xd1, 0x2a, + 0x0c, 0x06, 0x10, 0x2a, 0x36, 0x86, 0xa2, 0xc0, 0xf2, 0x6d, 0x05, 0x56, 0xae, 0x08, 0xba, 0x42, + 0xf3, 0x2f, 0x0b, 0xad, 0x1b, 0x0d, 0x7a, 0xe5, 0x7c, 0xbd, 0x98, 0x66, 0x23, 0x88, 0xde, 0xb2, + 0x90, 0xf5, 0x96, 0x85, 0x3e, 0x47, 0x58, 0x6b, 0x0f, 0x85, 0x8d, 0x11, 0x73, 0xc9, 0xca, 0x7b, + 0x15, 0xd4, 0x78, 0x3e, 0xf5, 0x37, 0x73, 0x1d, 0x33, 0xdc, 0x46, 0x6b, 0x99, 0x6e, 0xc7, 0xf8, + 0x90, 0xd0, 0x44, 0xe4, 0x5c, 0xdd, 0x2e, 0xc0, 0xea, 0x94, 0xd1, 0x32, 0x84, 0xc7, 0x3f, 0xa1, + 0x8d, 0x1b, 0x1d, 0x05, 0x3f, 0x42, 0x0f, 0xbd, 0x1f, 0x0e, 0xfd, 0xa0, 0xf5, 0xca, 0xef, 0x76, + 0x48, 0xe0, 0xb5, 0x7a, 0xdd, 0x0e, 0x39, 0xea, 0xf4, 0x0e, 0xbd, 0x7d, 0xff, 0xb9, 0xef, 0x1d, + 0xd4, 0x96, 0x70, 0x1d, 0xad, 0x1c, 0x06, 0xdd, 0xee, 0x73, 0xf2, 0xd2, 0xef, 0xf5, 0xfc, 0xce, + 0x37, 0x35, 0x6b, 0x16, 0xf2, 0x3b, 0xdf, 0xb7, 0xbe, 0xf5, 0x0f, 0x6a, 0x95, 0xf6, 0x77, 0x7f, + 0x9f, 0xdb, 0xd6, 0xeb, 0x73, 0xdb, 0x7a, 0x73, 0x6e, 0x5b, 0xff, 0x9c, 0xdb, 0xd6, 0x6f, 0x17, + 0xf6, 0xd2, 0xeb, 0x0b, 0x7b, 0xe9, 0xcd, 0x85, 0xbd, 0xf4, 0xe3, 0xd3, 0x21, 0x53, 0xa3, 0xbc, + 0xef, 0x84, 0x22, 0x71, 0xf5, 0xf5, 0xdd, 0xe5, 0xa0, 0x4e, 0x84, 0x3c, 0x76, 0xaf, 0x3c, 0x7f, + 0x32, 0xff, 0x86, 0x31, 0xd6, 0xdf, 0x7f, 0xcf, 0x78, 0xff, 0xd3, 0x7f, 0x03, 0x00, 0x00, 0xff, + 0xff, 0x69, 0x2d, 0x41, 0xba, 0x85, 0x06, 0x00, 0x00, } func (m *EventClaimExpired) Marshal() (dAtA []byte, err error) { @@ -611,6 +677,53 @@ func (m *EventApplicationOverserviced) MarshalToSizedBuffer(dAtA []byte) (int, e return len(dAtA) - i, nil } +func (m *EventSupplierSlashed) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EventSupplierSlashed) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventSupplierSlashed) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.SlashingAmount != nil { + { + size, err := m.SlashingAmount.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvent(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.NumExpiredClaims != 0 { + i = encodeVarintEvent(dAtA, i, uint64(m.NumExpiredClaims)) + i-- + dAtA[i] = 0x10 + } + if len(m.SupplierOperatorAddr) > 0 { + i -= len(m.SupplierOperatorAddr) + copy(dAtA[i:], m.SupplierOperatorAddr) + i = encodeVarintEvent(dAtA, i, uint64(len(m.SupplierOperatorAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintEvent(dAtA []byte, offset int, v uint64) int { offset -= sovEvent(v) base := offset @@ -718,6 +831,26 @@ func (m *EventApplicationOverserviced) Size() (n int) { return n } +func (m *EventSupplierSlashed) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.SupplierOperatorAddr) + if l > 0 { + n += 1 + l + sovEvent(uint64(l)) + } + if m.NumExpiredClaims != 0 { + n += 1 + sovEvent(uint64(m.NumExpiredClaims)) + } + if m.SlashingAmount != nil { + l = m.SlashingAmount.Size() + n += 1 + l + sovEvent(uint64(l)) + } + return n +} + func sovEvent(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -1380,6 +1513,143 @@ func (m *EventApplicationOverserviced) Unmarshal(dAtA []byte) error { } return nil } +func (m *EventSupplierSlashed) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EventSupplierSlashed: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventSupplierSlashed: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SupplierOperatorAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvent + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvent + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SupplierOperatorAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumExpiredClaims", wireType) + } + m.NumExpiredClaims = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumExpiredClaims |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SlashingAmount", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvent + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvent + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SlashingAmount == nil { + m.SlashingAmount = &types1.Coin{} + } + if err := m.SlashingAmount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvent(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvent + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipEvent(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/tokenomics/types/expected_keepers.go b/x/tokenomics/types/expected_keepers.go index b6e07314a..c8a2aa9e9 100644 --- a/x/tokenomics/types/expected_keepers.go +++ b/x/tokenomics/types/expected_keepers.go @@ -53,6 +53,7 @@ type ProofKeeper interface { AllClaims(ctx context.Context, req *prooftypes.QueryAllClaimsRequest) (*prooftypes.QueryAllClaimsResponse, error) EnsureValidProof(ctx context.Context, proof *prooftypes.Proof) error + ProofRequirementForClaim(ctx context.Context, claim *prooftypes.Claim) (prooftypes.ProofRequirementReason, error) // Only used for testing & simulation GetAllProofs(ctx context.Context) []prooftypes.Proof diff --git a/x/tokenomics/types/genesis_test.go b/x/tokenomics/types/genesis_test.go index 4c8d30f84..737132e3c 100644 --- a/x/tokenomics/types/genesis_test.go +++ b/x/tokenomics/types/genesis_test.go @@ -22,9 +22,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "valid genesis state", genState: &types.GenesisState{ - Params: types.Params{ - ComputeUnitsToTokensMultiplier: 1, - }, + Params: types.Params{}, RelayMiningDifficultyList: []types.RelayMiningDifficulty{ { ServiceId: "0", @@ -37,16 +35,6 @@ func TestGenesisState_Validate(t *testing.T) { }, isValid: true, }, - { - desc: "invalid genesis state - ComputeUnitsToTokensMultiplier is 0", - genState: &types.GenesisState{ - Params: types.Params{ - ComputeUnitsToTokensMultiplier: 0, - }, - // this line is used by starport scaffolding # types/genesis/validField - }, - isValid: false, - }, { desc: "duplicated relayMiningDifficulty", genState: &types.GenesisState{ diff --git a/x/tokenomics/types/message_update_param.go b/x/tokenomics/types/message_update_param.go index b69a5b826..1474f95ae 100644 --- a/x/tokenomics/types/message_update_param.go +++ b/x/tokenomics/types/message_update_param.go @@ -45,21 +45,7 @@ func (msg *MsgUpdateParam) ValidateBasic() error { // Parameter name must be supported by this module. switch msg.Name { - case ParamComputeUnitsToTokensMultiplier: - return msg.paramTypeIsInt64() default: return ErrTokenomicsParamNameInvalid.Wrapf("unsupported param %q", msg.Name) } } - -// paramTypeIsInt64 checks if the parameter type is int64, returning an error if not. -func (msg *MsgUpdateParam) paramTypeIsInt64() error { - if _, ok := msg.AsType.(*MsgUpdateParam_AsInt64); !ok { - return ErrTokenomicsParamInvalid.Wrapf( - "invalid type for param %q expected %T, got %T", - msg.Name, &MsgUpdateParam_AsInt64{}, - msg.AsType, - ) - } - return nil -} diff --git a/x/tokenomics/types/message_update_param_test.go b/x/tokenomics/types/message_update_param_test.go index 4be202bfb..ffe0f74a0 100644 --- a/x/tokenomics/types/message_update_param_test.go +++ b/x/tokenomics/types/message_update_param_test.go @@ -32,22 +32,6 @@ func TestMsgUpdateParam_ValidateBasic(t *testing.T) { AsType: &MsgUpdateParam_AsInt64{AsInt64: 1}, }, expectedErr: ErrTokenomicsParamNameInvalid, - }, { - name: "invalid: incorrect param type", - msg: MsgUpdateParam{ - Authority: sample.AccAddress(), - Name: ParamComputeUnitsToTokensMultiplier, - AsType: &MsgUpdateParam_AsString{AsString: "invalid"}, - }, - expectedErr: ErrTokenomicsParamInvalid, - }, { - name: "valid: correct authority, param name, and type", - msg: MsgUpdateParam{ - Authority: sample.AccAddress(), - Name: ParamComputeUnitsToTokensMultiplier, - AsType: &MsgUpdateParam_AsInt64{AsInt64: 1}, - }, - expectedErr: nil, }, } for _, tt := range tests { diff --git a/x/tokenomics/types/message_update_params.go b/x/tokenomics/types/message_update_params.go index de6de6bc3..fe4c0366c 100644 --- a/x/tokenomics/types/message_update_params.go +++ b/x/tokenomics/types/message_update_params.go @@ -4,15 +4,10 @@ import sdk "github.com/cosmos/cosmos-sdk/types" var _ sdk.Msg = (*MsgUpdateParams)(nil) -func NewMsgUpdateParams( - authority string, - computeUnitsToTokensMultiplier uint64, -) *MsgUpdateParams { +func NewMsgUpdateParams(authority string) *MsgUpdateParams { return &MsgUpdateParams{ Authority: authority, - Params: Params{ - ComputeUnitsToTokensMultiplier: computeUnitsToTokensMultiplier, - }, + Params: Params{}, } } diff --git a/x/tokenomics/types/message_update_params_test.go b/x/tokenomics/types/message_update_params_test.go index bc85ec072..914051b92 100644 --- a/x/tokenomics/types/message_update_params_test.go +++ b/x/tokenomics/types/message_update_params_test.go @@ -18,9 +18,7 @@ func TestMsgUpdateParams_ValidateBasic(t *testing.T) { desc: "invalid authority address", msg: MsgUpdateParams{ Authority: "invalid_address", - Params: Params{ - ComputeUnitsToTokensMultiplier: 1, - }, + Params: Params{}, }, expectedErr: ErrTokenomicsAddressInvalid, }, @@ -28,21 +26,9 @@ func TestMsgUpdateParams_ValidateBasic(t *testing.T) { desc: "valid address", msg: MsgUpdateParams{ Authority: sample.AccAddress(), - Params: Params{ - ComputeUnitsToTokensMultiplier: 1, - }, + Params: Params{}, }, }, - { - desc: "invalid ComputeUnitsToTokensMultiplier", - msg: MsgUpdateParams{ - Authority: sample.AccAddress(), - Params: Params{ - ComputeUnitsToTokensMultiplier: 0, - }, - }, - expectedErr: ErrTokenomicsParamsInvalid, - }, } for _, test := range tests { diff --git a/x/tokenomics/types/params.go b/x/tokenomics/types/params.go index 0757607b6..b2044336f 100644 --- a/x/tokenomics/types/params.go +++ b/x/tokenomics/types/params.go @@ -6,10 +6,6 @@ import ( var ( _ paramtypes.ParamSet = (*Params)(nil) - - KeyComputeUnitsToTokensMultiplier = []byte("ComputeUnitsToTokensMultiplier") - ParamComputeUnitsToTokensMultiplier = "compute_units_to_tokens_multiplier" - DefaultComputeUnitsToTokensMultiplier uint64 = 42 // TODO_MAINNET: Determine the default value. ) // ParamKeyTable the param key table for launch module @@ -18,51 +14,21 @@ func ParamKeyTable() paramtypes.KeyTable { } // NewParams creates a new Params instance -func NewParams(computeUnitsToTokensMultiplier uint64) Params { - return Params{ - ComputeUnitsToTokensMultiplier: computeUnitsToTokensMultiplier, - } +func NewParams() Params { + return Params{} } // DefaultParams returns a default set of parameters func DefaultParams() Params { - return NewParams( - DefaultComputeUnitsToTokensMultiplier, - ) + return NewParams() } // ParamSetPairs get the params.ParamSet func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { - return paramtypes.ParamSetPairs{ - paramtypes.NewParamSetPair( - KeyComputeUnitsToTokensMultiplier, - &p.ComputeUnitsToTokensMultiplier, - ValidateComputeUnitsToTokensMultiplier, - ), - } + return paramtypes.ParamSetPairs{} } // ValidateBasic does a sanity check on the provided params. func (params *Params) ValidateBasic() error { - // Validate the ComputeUnitsToTokensMultiplier - if err := ValidateComputeUnitsToTokensMultiplier(params.ComputeUnitsToTokensMultiplier); err != nil { - return err - } - - return nil -} - -// ValidateComputeUnitsToTokensMultiplier validates the ComputeUnitsToTokensMultiplier governance parameter. -// NB: The argument is an interface type to satisfy the ParamSetPair function signature. -func ValidateComputeUnitsToTokensMultiplier(v interface{}) error { - computeUnitsToTokensMultiplier, ok := v.(uint64) - if !ok { - return ErrTokenomicsParamsInvalid.Wrapf("invalid parameter type: %T", v) - } - - if computeUnitsToTokensMultiplier <= 0 { - return ErrTokenomicsParamsInvalid.Wrapf("invalid ComputeUnitsToTokensMultiplier: (%v)", computeUnitsToTokensMultiplier) - } - return nil } diff --git a/x/tokenomics/types/params.pb.go b/x/tokenomics/types/params.pb.go index 9e4729fe9..909476b25 100644 --- a/x/tokenomics/types/params.pb.go +++ b/x/tokenomics/types/params.pb.go @@ -26,8 +26,6 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // Params defines the parameters for the tokenomics module. type Params struct { - // The amount of upokt that a compute unit should translate to when settling a session. - ComputeUnitsToTokensMultiplier uint64 `protobuf:"varint,1,opt,name=compute_units_to_tokens_multiplier,json=computeUnitsToTokensMultiplier,proto3" json:"compute_units_to_tokens_multiplier" yaml:"compute_units_to_tokens_multiplier"` } func (m *Params) Reset() { *m = Params{} } @@ -59,13 +57,6 @@ func (m *Params) XXX_DiscardUnknown() { var xxx_messageInfo_Params proto.InternalMessageInfo -func (m *Params) GetComputeUnitsToTokensMultiplier() uint64 { - if m != nil { - return m.ComputeUnitsToTokensMultiplier - } - return 0 -} - func init() { proto.RegisterType((*Params)(nil), "poktroll.tokenomics.Params") } @@ -73,24 +64,19 @@ func init() { func init() { proto.RegisterFile("poktroll/tokenomics/params.proto", fileDescriptor_df10a06914fc6eee) } var fileDescriptor_df10a06914fc6eee = []byte{ - // 263 bytes of a gzipped FileDescriptorProto + // 184 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x28, 0xc8, 0xcf, 0x2e, 0x29, 0xca, 0xcf, 0xc9, 0xd1, 0x2f, 0xc9, 0xcf, 0x4e, 0xcd, 0xcb, 0xcf, 0xcd, 0x4c, 0x2e, 0xd6, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x86, 0xa9, 0xd0, 0x43, 0xa8, 0x90, 0x12, 0x4c, 0xcc, 0xcd, 0xcc, 0xcb, 0xd7, 0x07, 0x93, 0x10, 0x75, 0x52, - 0x22, 0xe9, 0xf9, 0xe9, 0xf9, 0x60, 0xa6, 0x3e, 0x88, 0x05, 0x11, 0x55, 0xba, 0xc8, 0xc8, 0xc5, - 0x16, 0x00, 0x36, 0x4e, 0x68, 0x3e, 0x23, 0x97, 0x52, 0x72, 0x7e, 0x6e, 0x41, 0x69, 0x49, 0x6a, - 0x7c, 0x69, 0x5e, 0x66, 0x49, 0x71, 0x7c, 0x49, 0x7e, 0x3c, 0xd8, 0xcc, 0xe2, 0xf8, 0xdc, 0xd2, - 0x9c, 0x92, 0xcc, 0x82, 0x9c, 0xcc, 0xd4, 0x22, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x16, 0xa7, 0xe0, - 0x57, 0xf7, 0xe4, 0x89, 0x50, 0xfd, 0xe9, 0x9e, 0xbc, 0x66, 0x65, 0x62, 0x6e, 0x8e, 0x15, 0x11, - 0x6a, 0x95, 0x82, 0xe4, 0xa0, 0x8a, 0x42, 0x41, 0x6a, 0x42, 0xf2, 0x43, 0xc0, 0x2a, 0x7c, 0xe1, - 0x0a, 0xac, 0x54, 0x5f, 0x2c, 0x90, 0x67, 0xec, 0x7a, 0xbe, 0x41, 0x4b, 0x06, 0x1e, 0x2a, 0x15, - 0xc8, 0xe1, 0x02, 0xf1, 0x88, 0x53, 0xe0, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0xde, - 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, - 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0x65, 0x9c, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, - 0xab, 0x0f, 0x32, 0x46, 0x37, 0x2f, 0xb5, 0xa4, 0x3c, 0xbf, 0x28, 0x5b, 0x1f, 0xbb, 0x99, 0x25, - 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0xe0, 0xd0, 0x32, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xe1, - 0x48, 0x1b, 0x16, 0x8f, 0x01, 0x00, 0x00, + 0x22, 0xe9, 0xf9, 0xe9, 0xf9, 0x60, 0xa6, 0x3e, 0x88, 0x05, 0x11, 0x55, 0xd2, 0xe7, 0x62, 0x0b, + 0x00, 0x9b, 0x66, 0xa5, 0xfa, 0x62, 0x81, 0x3c, 0x63, 0xd7, 0xf3, 0x0d, 0x5a, 0x32, 0x70, 0x2b, + 0x2b, 0x90, 0x2d, 0x85, 0x28, 0x73, 0x0a, 0x3c, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, + 0x1b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, + 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0x8c, 0xd3, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, + 0x73, 0xf5, 0x41, 0xc6, 0xe8, 0xe6, 0xa5, 0x96, 0x94, 0xe7, 0x17, 0x65, 0xeb, 0x63, 0x37, 0xb3, + 0xa4, 0xb2, 0x20, 0xb5, 0x38, 0x89, 0x0d, 0xec, 0x14, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x45, 0xfa, 0x9e, 0x90, 0xec, 0x00, 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { @@ -112,9 +98,6 @@ func (this *Params) Equal(that interface{}) bool { } else if this == nil { return false } - if this.ComputeUnitsToTokensMultiplier != that1.ComputeUnitsToTokensMultiplier { - return false - } return true } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -137,11 +120,6 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.ComputeUnitsToTokensMultiplier != 0 { - i = encodeVarintParams(dAtA, i, uint64(m.ComputeUnitsToTokensMultiplier)) - i-- - dAtA[i] = 0x8 - } return len(dAtA) - i, nil } @@ -162,9 +140,6 @@ func (m *Params) Size() (n int) { } var l int _ = l - if m.ComputeUnitsToTokensMultiplier != 0 { - n += 1 + sovParams(uint64(m.ComputeUnitsToTokensMultiplier)) - } return n } @@ -203,25 +178,6 @@ func (m *Params) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ComputeUnitsToTokensMultiplier", wireType) - } - m.ComputeUnitsToTokensMultiplier = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowParams - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ComputeUnitsToTokensMultiplier |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } default: iNdEx = preIndex skippy, err := skipParams(dAtA[iNdEx:])