Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

Invalid seed reveal is selected at the end of the hash onion section #6781

Closed
shuse2 opened this issue Sep 15, 2021 · 0 comments · Fixed by #6783
Closed

Invalid seed reveal is selected at the end of the hash onion section #6781

shuse2 opened this issue Sep 15, 2021 · 0 comments · Fixed by #6783

Comments

@shuse2
Copy link
Collaborator

shuse2 commented Sep 15, 2021

Expected behavior

Without changing the forger.db and the hash onion in the config.json, it should always return consecutive seed reveal.

Actual behavior

at the end of the distance of hash onion, it returns invalid seed reveal. it seems like it returns the previous value. For example,

"hashOnion": {
	"count": 10000,
	"distance": 1000,
	"hashes": [
		"aaf012545a584890a169cf57d8f7e688",
		"f7a3fb976e50d882c709edb63bde4d9c",
		"1bd121882cb1dee1107699001c2676fb",
		"c4ad7d98da02c94ef8bda2f80d35290a",
		"096f0e77f963face5e99b9db460ce45f",
		"de3d0c34bdcbdcfa2b7b1871c99d4948",
		"5deb5e369a98510932835d74768cf86c",
		"c0cd6ce3f75256149c8fe5d0bffdc99a",
		"1a32706893f1523db0c7bb81be5e55ac",
		"7e8f1ea4aa317993152e1a6b55b16f25",
		"5e5100bbd2c2d5e00197d4ec19102dd6"
	]
},

with above case, at distance 1000, it returns aaf012545a584890a169cf57d8f7e688.

Steps to reproduce

// framework/test/integration/node/forger/seed_reveal.js
/* eslint-disable */

const config = require('../../../fixtures/config/devnet/config.json');
const { KVStore } = require('@liskhq/lisk-db');
const { hash } = require('@liskhq/lisk-cryptography');
const { Forger } = require('../../../../dist-node/node/forger/forger');

(async () => {
	const dbName = 'seed_reveal';
	const forgerDB = new KVStore(`./${dbName}`);
	const forger = new Forger({
		db: forgerDB,
		chainModule: { constants: {} },
		bftModule: {
			finalizedHeight: 1,
		},
		forgingDelegates: config.forging.delegates.map(d => ({
			address: Buffer.from(d.address, 'hex'),
			encryptedPassphrase: d.encryptedPassphrase,
			hashOnion: {
				count: d.hashOnion.count,
				distance: d.hashOnion.distance,
				hashes: d.hashOnion.hashes.map(h => Buffer.from(h, 'hex')),
			},
		})),
	});

	const address = '9cabee3d27426676b852ce6b804cb2fdff7cd0b5';
	let lastHash;
	let height = 1;
	try {
		for (let i = 0; i < 1005; i += 1) {
			const next = await forger.loopHashOnion(Buffer.from(address, 'hex'), height);
			height += 1;
			const prev = hash(next).slice(0, 16);
			console.log({ lastHash, next });
			if (lastHash !== undefined && !prev.equals(lastHash)) {
				console.error(`Fail i=${i} with ${next.toString('hex')}`)
			}
			lastHash = next
		}
	} catch (error) {
		console.error(error);

	} finally {
		await forgerDB.clear();
		await forgerDB.close();
	}
})();

// forger.ts (temporal test code)
public async loopHashOnion(delegateAddress: Buffer, nextHeight: number): Promise<Buffer> {
		const usedHashOnions = await getUsedHashOnions(this._db);
		const nextHashOnion = this._getNextHashOnion(usedHashOnions, delegateAddress, nextHeight);
		const index = usedHashOnions.findIndex(
			ho => ho.address.equals(delegateAddress) && ho.count === nextHashOnion.count,
		);
		const nextUsedHashOnion = {
			count: nextHashOnion.count,
			address: delegateAddress,
			height: nextHeight,
		} as UsedHashOnion;
		if (index > -1) {
			// Overwrite the hash onion if it exists
			usedHashOnions[index] = nextUsedHashOnion;
		} else {
			usedHashOnions.push(nextUsedHashOnion);
		}

		const updatedUsedHashOnion = this._filterUsedHashOnions(
			usedHashOnions,
			this._bftModule.finalizedHeight,
		);

		await setUsedHashOnions(this._db, updatedUsedHashOnion);
		return nextHashOnion.hash;
	}

Which version(s) does this affect? (Environment, OS, etc...)

v5.1.4

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants