Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: BEEFY compact signed commitment in versioned finality proofs #5781

Merged
merged 1 commit into from
Jan 26, 2024
Merged

fix: BEEFY compact signed commitment in versioned finality proofs #5781

merged 1 commit into from
Jan 26, 2024

Conversation

mfornos
Copy link
Contributor

@mfornos mfornos commented Jan 15, 2024

The present version of BEEFY sends the versioned finality proof as a CompactSignedCommitment over the wire.
In PolkadotJS the definition of VersionedFinalityProof is expecting an uncompressed signed commitment, therefore the decoded data is wrong (although it does not generate any decoding error).

You can verify the new definition using the following script:

import assert from 'node:assert/strict';

import { ApiPromise, WsProvider } from '@polkadot/api';
import { keccak256AsU8a, secp256k1Recover } from '@polkadot/util-crypto';

async function start() {
  const wsProvider = new WsProvider(
    'wss://rococo-rpc.polkadot.io'
    //'wss://kusama-rpc.polkadot.io'
  );
  const api = await ApiPromise.create({
    provider: wsProvider,
  });
  const authorities = (await api.query.beefy.authorities()).toHuman() as Array<string>;

  console.log('Waiting for BEEFY justifications...');

  api.rpc.beefy.subscribeJustifications(j => {
    const {
      commitment,
      signaturesFrom,
      signaturesCompact
    } = j.asV1;
    const commitmentHash = keccak256AsU8a(commitment.toU8a());
    const bitField = signaturesFrom.toU8a().slice(1);

    console.log({ justification: j.asV1.toHuman() });

    const sigs = signaturesCompact.values();

    for (let n = 0; n < bitField.length; n++) {
      const byte = bitField[n];
      for (let p = 0; p < 8; p++) {
        const bit = (byte >> (8 - p - 1)) & 1;
        if (bit === 1) {
          const i = (n * 8) + p;
          const sig = sigs.next().value.toU8a();
          const recoveryId = sig[64] > 26 ? sig[64] - 27 : sig[64];
          const pubKey =  secp256k1Recover(commitmentHash, sig.slice(0, 64), recoveryId);
          const hexPubKey = '0x' + Buffer.from(pubKey).toString('hex');

          assert.strictEqual(hexPubKey, authorities[i]);

          console.log(`Bit[${i}]: ${hexPubKey}`);
        }
      }
    }
  });
}

start();

@mfornos mfornos changed the title BEEFY compact signed commitment in versioned finality proofs fix: BEEFY compact signed commitment in versioned finality proofs Jan 15, 2024
@jacogr jacogr merged commit a64228c into polkadot-js:master Jan 26, 2024
4 checks passed
@mfornos mfornos deleted the mf-beefy_compact_signed_commitment branch January 26, 2024 10:58
@polkadot-js-bot
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@polkadot-js polkadot-js locked as resolved and limited conversation to collaborators Jan 28, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants