@@ -401,6 +401,82 @@ contract BeefyClient {
401
401
emit NewMMRRoot (newMMRRoot, commitment.blockNumber);
402
402
}
403
403
404
+ /**
405
+ * @dev Verify that the supplied MMR leaf is included in the latest verified MMR root.
406
+ * @param leafHash contains the merkle leaf to be verified
407
+ * @param proof contains simplified mmr proof
408
+ * @param proofOrder a bitfield describing the order of each item (left vs right)
409
+ */
410
+ function verifyMMRLeafProof (bytes32 leafHash , bytes32 [] calldata proof , uint256 proofOrder )
411
+ external
412
+ view
413
+ returns (bool )
414
+ {
415
+ return MMRProof.verifyLeafProof (latestMMRRoot, leafHash, proof, proofOrder);
416
+ }
417
+
418
+ /**
419
+ * @dev Helper to create an initial validator bitfield.
420
+ * @param bitsToSet contains indexes of all signed validators, should be deduplicated
421
+ * @param length of validator set
422
+ */
423
+ function createInitialBitfield (uint256 [] calldata bitsToSet , uint256 length )
424
+ external
425
+ pure
426
+ returns (uint256 [] memory )
427
+ {
428
+ if (length < bitsToSet.length ) {
429
+ revert InvalidBitfieldLength ();
430
+ }
431
+ return Bitfield.createBitfield (bitsToSet, length);
432
+ }
433
+
434
+ /**
435
+ * @dev Helper to create a final bitfield, with subsampled validator selections
436
+ * @param commitmentHash contains the commitmentHash signed by the validators
437
+ * @param bitfield claiming which validators have signed the commitment
438
+ */
439
+ function createFinalBitfield (bytes32 commitmentHash , uint256 [] calldata bitfield )
440
+ external
441
+ view
442
+ returns (uint256 [] memory )
443
+ {
444
+ Ticket storage ticket = tickets[createTicketID (msg .sender , commitmentHash)];
445
+ if (ticket.bitfieldHash != keccak256 (abi.encodePacked (bitfield))) {
446
+ revert InvalidBitfield ();
447
+ }
448
+ return Bitfield.subsample (
449
+ ticket.prevRandao, bitfield, ticket.numRequiredSignatures, ticket.validatorSetLen
450
+ );
451
+ }
452
+
453
+ /**
454
+ * @dev Helper to create a final bitfield with subsampled validator selections using the Fiat-Shamir approach
455
+ * @param commitment contains the full commitment that was used for the commitmentHash
456
+ * @param bitfield claiming which validators have signed the commitment
457
+ */
458
+ function createFiatShamirFinalBitfield (
459
+ Commitment calldata commitment ,
460
+ uint256 [] calldata bitfield
461
+ ) external view returns (uint256 [] memory ) {
462
+ ValidatorSetState storage vset;
463
+ if (commitment.validatorSetID == nextValidatorSet.id) {
464
+ vset = nextValidatorSet;
465
+ } else if (commitment.validatorSetID == currentValidatorSet.id) {
466
+ vset = currentValidatorSet;
467
+ } else {
468
+ revert InvalidCommitment ();
469
+ }
470
+
471
+ bytes32 bitFieldHash = keccak256 (abi.encodePacked (bitfield));
472
+ bytes32 commitmentHash = keccak256 (encodeCommitment (commitment));
473
+ bytes32 fiatShamirHash = keccak256 (bytes .concat (commitmentHash, bitFieldHash, vset.root));
474
+
475
+ return Bitfield.subsample (
476
+ uint256 (fiatShamirHash), bitfield, fiatShamirRequiredSignatures, vset.length
477
+ );
478
+ }
479
+
404
480
/**
405
481
* @dev Submit a commitment and leaf using the Fiat-Shamir approach
406
482
* @param commitment contains the full commitment that was used for the commitmentHash
@@ -466,55 +542,6 @@ contract BeefyClient {
466
542
emit NewMMRRoot (newMMRRoot, commitment.blockNumber);
467
543
}
468
544
469
- /**
470
- * @dev Verify that the supplied MMR leaf is included in the latest verified MMR root.
471
- * @param leafHash contains the merkle leaf to be verified
472
- * @param proof contains simplified mmr proof
473
- * @param proofOrder a bitfield describing the order of each item (left vs right)
474
- */
475
- function verifyMMRLeafProof (bytes32 leafHash , bytes32 [] calldata proof , uint256 proofOrder )
476
- external
477
- view
478
- returns (bool )
479
- {
480
- return MMRProof.verifyLeafProof (latestMMRRoot, leafHash, proof, proofOrder);
481
- }
482
-
483
- /**
484
- * @dev Helper to create an initial validator bitfield.
485
- * @param bitsToSet contains indexes of all signed validators, should be deduplicated
486
- * @param length of validator set
487
- */
488
- function createInitialBitfield (uint256 [] calldata bitsToSet , uint256 length )
489
- external
490
- pure
491
- returns (uint256 [] memory )
492
- {
493
- if (length < bitsToSet.length ) {
494
- revert InvalidBitfieldLength ();
495
- }
496
- return Bitfield.createBitfield (bitsToSet, length);
497
- }
498
-
499
- /**
500
- * @dev Helper to create a final bitfield, with subsampled validator selections
501
- * @param commitmentHash contains the commitmentHash signed by the validators
502
- * @param bitfield claiming which validators have signed the commitment
503
- */
504
- function createFinalBitfield (bytes32 commitmentHash , uint256 [] calldata bitfield )
505
- external
506
- view
507
- returns (uint256 [] memory )
508
- {
509
- Ticket storage ticket = tickets[createTicketID (msg .sender , commitmentHash)];
510
- if (ticket.bitfieldHash != keccak256 (abi.encodePacked (bitfield))) {
511
- revert InvalidBitfield ();
512
- }
513
- return Bitfield.subsample (
514
- ticket.prevRandao, bitfield, ticket.numRequiredSignatures, ticket.validatorSetLen
515
- );
516
- }
517
-
518
545
/* Internal Functions */
519
546
520
547
// Creates a unique ticket ID for a new interactive prover-verifier session
0 commit comments