Skip to content

Commit

Permalink
update: voteBundleProposal return type. (#77)
Browse files Browse the repository at this point in the history
* update: voteBundleProposal return type.

* update: invalid vote test.

* update: improve validateDataItem.
  • Loading branch information
christopherbrumm authored Oct 5, 2023
1 parent b11a925 commit a1633a2
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 26 deletions.
17 changes: 16 additions & 1 deletion common/protocol/src/methods/validate/validateBundleProposal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,27 @@ export async function validateBundleProposal(
this.logger.debug(
`this.runtime.validateDataItem($THIS, $PROPOSED_DATA_ITEM, $VALIDATION_DATA_ITEM)`
);
valid = await this.runtime.validateDataItem(
const vote = await this.runtime.validateDataItem(
this,
proposedBundle[i],
validationBundle[i]
);

// vote abstain if data item validation returned abstain
if (vote === VOTE.ABSTAIN) {
const success = await this.voteBundleProposal(
this.pool.bundle_proposal!.storage_id,
VOTE.ABSTAIN
);
return success;
}

if (vote === VOTE.VALID) {
valid = true;
} else if (vote === VOTE.INVALID) {
valid = false;
}

// only log if data item validation returned invalid
if (!valid) {
this.logger.info(
Expand Down
4 changes: 2 additions & 2 deletions common/protocol/src/types/interfaces/runtime.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,13 @@ export interface IRuntime {
* @param {Validator} v the class of @kyvejs/protocol
* @param {DataItem} proposedDataItem the data item proposed by the uploader
* @param {DataItem} validationDataItem the data item which the validator created himself for validation again the proposed data item
* @return {Promise<boolean>} returns whether the proposed data item is valid compared to the validation data item
* @return {Promise<number>} returns whether the vote is valid, invalid or abstain compared against the proposed data item
*/
validateDataItem(
v: Validator,
proposedDataItem: DataItem,
validationDataItem: DataItem
): Promise<boolean>;
): Promise<number>;

/**
* Gets a formatted value string from a bundle. This produces a "summary" of
Expand Down
15 changes: 8 additions & 7 deletions common/protocol/test/vote_invalid.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Validator,
sha256,
standardizeJSON,
VOTE,
} from "../src/index";
import { runNode } from "../src/methods/main/runNode";
import { genesis_pool } from "./mocks/constants";
Expand Down Expand Up @@ -115,7 +116,7 @@ describe("invalid votes tests", () => {

test("vote invalid because runtime validate function returns false", async () => {
// ARRANGE
const validateBundleMock = jest.fn().mockResolvedValue(false);
const validateBundleMock = jest.fn().mockResolvedValue(VOTE.INVALID);
v["runtime"].validateDataItem = validateBundleMock;

const bundle = [
Expand Down Expand Up @@ -949,7 +950,7 @@ describe("invalid votes tests", () => {

test("try to vote invalid after validator has voted abstain bebore", async () => {
// ARRANGE
const validateBundleMock = jest.fn().mockResolvedValue(false);
const validateBundleMock = jest.fn().mockResolvedValue(VOTE.INVALID);

v["runtime"].validateDataItem = validateBundleMock;

Expand Down Expand Up @@ -1096,7 +1097,7 @@ describe("invalid votes tests", () => {

test("try to vote invalid after validator has voted invalid before", async () => {
// ARRANGE
const validateBundleMock = jest.fn().mockResolvedValue(false);
const validateBundleMock = jest.fn().mockResolvedValue(VOTE.INVALID);

v["runtime"].validateDataItem = validateBundleMock;

Expand Down Expand Up @@ -1226,7 +1227,7 @@ describe("invalid votes tests", () => {

test("try to vote invalid after validator has voted valid before", async () => {
// ARRANGE
const validateBundleMock = jest.fn().mockResolvedValue(false);
const validateBundleMock = jest.fn().mockResolvedValue(VOTE.INVALID);

v["runtime"].validateDataItem = validateBundleMock;

Expand Down Expand Up @@ -1354,7 +1355,7 @@ describe("invalid votes tests", () => {

test("vote invalid but local bundle could not be loaded in the first try", async () => {
// ARRANGE
v["runtime"].validateDataItem = jest.fn().mockResolvedValue(false);
v["runtime"].validateDataItem = jest.fn().mockResolvedValue(VOTE.INVALID);

const bundle = [
{ key: "test_key_1", value: "test_value_1" },
Expand Down Expand Up @@ -1513,7 +1514,7 @@ describe("invalid votes tests", () => {

test("vote invalid but bundle from storage provider could not be loaded in the first try", async () => {
// ARRANGE
v["runtime"].validateDataItem = jest.fn().mockResolvedValue(false);
v["runtime"].validateDataItem = jest.fn().mockResolvedValue(VOTE.INVALID);

const bundle = [
{ key: "test_key_1", value: "test_value_1" },
Expand Down Expand Up @@ -1690,7 +1691,7 @@ describe("invalid votes tests", () => {
.mockReturnValueOnce(true)
.mockReturnValue(false);

v["runtime"].validateDataItem = jest.fn().mockResolvedValue(false);
v["runtime"].validateDataItem = jest.fn().mockResolvedValue(VOTE.INVALID);

v["client"][0].kyve.bundles.v1beta1.voteBundleProposal = jest
.fn()
Expand Down
11 changes: 6 additions & 5 deletions integrations/tendermint-bsync/src/runtime.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DataItem, IRuntime, Validator } from '@kyvejs/protocol';
import { DataItem, IRuntime, Validator, VOTE } from "@kyvejs/protocol";
import { name, version } from '../package.json';
import axios from 'axios';

Expand Down Expand Up @@ -62,11 +62,12 @@ export default class TendermintBSync implements IRuntime {
_: Validator,
proposedDataItem: DataItem,
validationDataItem: DataItem
): Promise<boolean> {
): Promise<number> {
// apply equal comparison
return (
JSON.stringify(proposedDataItem) === JSON.stringify(validationDataItem)
);
if (JSON.stringify(proposedDataItem) === JSON.stringify(validationDataItem)) {
return VOTE.VALID
}
return VOTE.INVALID
}

async summarizeDataBundle(_: Validator, bundle: DataItem[]): Promise<string> {
Expand Down
11 changes: 6 additions & 5 deletions integrations/tendermint-ssync/src/runtime.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DataItem, IRuntime, Validator } from '@kyvejs/protocol';
import { DataItem, IRuntime, Validator, VOTE } from "@kyvejs/protocol";
import { name, version } from '../package.json';
import axios from 'axios';

Expand Down Expand Up @@ -126,11 +126,12 @@ export default class TendermintSSync implements IRuntime {
_: Validator,
proposedDataItem: DataItem,
validationDataItem: DataItem
): Promise<boolean> {
): Promise<number> {
// apply equal comparison
return (
JSON.stringify(proposedDataItem) === JSON.stringify(validationDataItem)
);
if (JSON.stringify(proposedDataItem) === JSON.stringify(validationDataItem)) {
return VOTE.VALID
}
return VOTE.INVALID
}

async summarizeDataBundle(_: Validator, bundle: DataItem[]): Promise<string> {
Expand Down
26 changes: 20 additions & 6 deletions integrations/tendermint/src/runtime.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DataItem, IRuntime, Validator } from '@kyvejs/protocol';
import { DataItem, IRuntime, Validator, VOTE } from '@kyvejs/protocol';
import { name, version } from '../package.json';
import axios from 'axios';
import Ajv from 'ajv';
Expand Down Expand Up @@ -182,11 +182,25 @@ export default class Tendermint implements IRuntime {
_: Validator,
proposedDataItem: DataItem,
validationDataItem: DataItem
): Promise<boolean> {
// apply equal comparison
return (
JSON.stringify(proposedDataItem) === JSON.stringify(validationDataItem)
);
): Promise<number> {
if (JSON.stringify(proposedDataItem) === JSON.stringify(validationDataItem)) {
return VOTE.VALID
}
// prevent nondeterministic misbehaviour due to osmosis-1 specific problems
if (validationDataItem.value.block.block.header.chain_id === "osmosis-1") {
_.logger.info("Removing begin_block_events: osmosis-1 identified")
// remove nondeterministic begin_block_events to prevent incorrect invalid vote
delete validationDataItem.value.block_results.begin_block_events;
delete proposedDataItem.value.block_results.begin_block_events;

if (JSON.stringify(proposedDataItem) === JSON.stringify(validationDataItem)) {
_.logger.warn("Voting abstain: value.block_results.begin_block_events don't match")
// vote abstain if begin_block_events are not equal
return VOTE.ABSTAIN
}
}
// vote invalid if data does not match
return VOTE.INVALID
}

async summarizeDataBundle(_: Validator, bundle: DataItem[]): Promise<string> {
Expand Down

0 comments on commit a1633a2

Please sign in to comment.