Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

more clear randomness API for BABE #8180

Merged
16 commits merged into from
Mar 10, 2021
Merged

more clear randomness API for BABE #8180

16 commits merged into from
Mar 10, 2021

Conversation

rphmeier
Copy link
Contributor

@rphmeier rphmeier commented Feb 23, 2021

type Randomness = Babe lacked a lot of clarity.

There are actually 3 types of randomness we'd want to get from BABE with different security and timing considerations. I changed the API of BABE to reflect those so you'd do one of

type Randomness = pallet_babe::RandomnessFromOneEpochAgo<Runtime>;
type Randomness = pallet_babe::RandomnessFromTwoEpochsAgo<Runtime>;
type Randomness = pallet_babe::CurrentBlockRandomness<Runtime>;

instead.

TODO in this PR:

  • improve doc comments around usage (@burdges please provide color)
  • handle fallout in node and Polkadot

polkadot companion: paritytech/polkadot#2504

@rphmeier rphmeier added A3-in_progress Pull request is in progress. No review needed at this stage. B3-apinoteworthy C1-low PR touches the given topic and has a low impact on builders. labels Feb 23, 2021
@burdges
Copy link

burdges commented Feb 23, 2021

/// Randomness usable by on-chain code that does not depend upon finality and take action
/// based upon on-chain commitments two epochs ago.
///
/// All randomness is relative to commitments to any other inputs to the computation:  
/// If Alice samples randomness near perfectly using radioactive decay, but then afterwards
/// Eve selects an arbitrary value with which to xor Alice's randomness, then Eve always wins
/// whatever game they play.
///
/// All input commitments used with `RandomnessFromPreviousEpoch` should come from 
/// at least two epochs ago, although the previous epoch might work in special cases
/// under additional assumption.
///
/// All users learn `RandomnessFromPreviousEpoch` at the end of the previous epoch,
/// although some block producers learn it several block earlier.
///
/// Adversaries with enough block producers could bias this randomness by choosing upon
/// what their block producers build at either the end of the previous epoch or the beginning
/// of the current epoch, or electing to skipping some of their own block production slots
/// towards the end of the previous epoch. 
/// 
/// Adversaries should not possess many block production slots towards the beginning or
/// end of every epoch, but they possess some influence over when they possess more slots.
///
/// As an example usage, we determine parachain auctions ending times in Polkadot using 
/// `RandomnessFromPreviousEpoch` because it reduces bias from `CurrentBlockRandomness`
/// and does not require the extra finality delay of `RandomnessFromTwoEpochsAgo`.
pub struct RandomnessFromPreviousEpoch<Runtime> { }
// or RandomnessFromOneEpochAgo<Runtime>; whatever name. 

/// Randomness usable by consensus protocols that depend upon finality and take action
/// based upon on-chain commitments three epochs ago.
///
/// An off-chain consensus protocols requires randomness be finalized before usage, but
/// one extra epoch delay beyond `RandomnessFromPreviousEpoch` suffices, under the
/// assumption that finality never stalls for longer than one epoch.
///
/// All randomness is relative to commitments to any other inputs to the computation:  
/// If Alice samples randomness near perfectly using radioactive decay, but then afterwards
/// Eve selects an arbitrary value with which to xor Alice's randomness, then Eve always wins
/// whatever game they play. 
///
/// All input commitments used with `RandomnessFromTwoEpochsAgo` should come from 
/// at least three epochs ago.  We require BABE session keys be registered at least three
/// epochs before being used to derive `CurrentBlockRandomness` for example.
///
/// All users learn `RandomnessFromTwoEpochsAgo` when epoch `current_epoch - 1` starts,
/// although some learn it a few block earlier inside epoch `current_epoch - 2`.
///
/// Adversaries with enough block producers could bias this randomness by choosing upon
/// what their block producers build at the end of epoch `current_epoch - 2` or the beginning
/// epoch `current_epoch - 1`, or skipping slots at the end of epoch `current_epoch - 2`.  
///
/// Adversaries should not possess many block production slots towards the beginning or
/// end of every epoch, but they possess some influence over when they possess more slots.
pub struct RandomnessFromTwoEpochsAgo<Runtime> { }

/// Randomness produced semi-freshly with each relay chain block, but inherits limitations
/// of `RandomnessFromTwoEpochsAgo` from which it derives. 
///
/// All randomness is relative to commitments to any other inputs to the computation:  
/// If Alice samples randomness near perfectly using radioactive decay, but then afterwards
/// Eve selects an arbitrary value with which to xor Alice's randomness, then Eve always wins
/// whatever game they play. 
///
/// As with  `RandomnessFromTwoEpochsAgo`, all input commitments combined with 
/// `CurrentBlockRandomness` should come from at least two epoch ago, except preferably
/// not near epoch ending, and thus ideally three epochs ago.  
/// 
/// Almost all users learn this randomness for a block when the block producer announces
/// the block, which makes this randomness appear quite fresh.  Yet, the block producer
/// themselves learned this randomness at the beginning of epoch `current_epoch - 2`,
/// at the same time as they learn `RandomnessFromTwoEpochsAgo`.
///
/// Aside from just biasing `RandomnessFromTwoEpochsAgo`, adversaries could also bias
/// `CurrentBlockRandomness` by never announcing their block if doing so yields an
/// unfavorable randomness.  As such, `CurrentBlockRandomness` should be considered
/// weaker than both other randomness randomness sources provided by BABE, but
/// `CurrentBlockRandomness` remains constrained by declared staking, while a 
/// randomness source like block hash is only constrained by adversaries' unknowable
/// computational power.  
///
/// As an example use,  parachains could asign block production slots based upon the
/// `CurrentBlockRandomness` of their relay parent or relay parent's parent, provided
/// the parachain registers collators but avoids censorship sensitive functionality like slashing.
/// Any parachain with slashing could operate BABE itself or perhaps better yet a BABE-like
/// approach that derives its `CurrentBlockRandomness`, and authorizes block production,
/// based upon the relay parent's `CurrentBlockRandomness` or more likely the relay parent's
/// `RandomnessFromTwoEpochsAgo`.
pub struct CurrentBlockRandomness<Runtime> { }

@burdges
Copy link

burdges commented Feb 23, 2021

At some point we might improve how the randomness gets collected too ala https://github.com/w3f/research-internal/issues/691 but this requires a protocol upgrade, and thus should be delayed until Sassafras.

@andresilva andresilva marked this pull request as ready for review February 23, 2021 11:51
@andresilva andresilva self-requested a review as a code owner February 23, 2021 11:51
@github-actions github-actions bot added A0-please_review Pull request needs code review. and removed A3-in_progress Pull request is in progress. No review needed at this stage. labels Feb 23, 2021
@andresilva andresilva removed their request for review February 23, 2021 12:06
@rphmeier rphmeier requested a review from athei as a code owner March 5, 2021 17:52

(
seed,
block_number.saturating_sub(RANDOM_MATERIAL_LEN.into()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit tricky but I think it's the safest thing we can ensure here.

@andresilva
Copy link
Contributor

@rphmeier I can't add you as a reviewer but I'd appreciate if you could have a look at this.

Copy link
Member

@gavofyork gavofyork left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside from the changes to the docs.

@andresilva
Copy link
Contributor

bot merge

@ghost
Copy link

ghost commented Mar 10, 2021

Trying merge.

This pull request was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A0-please_review Pull request needs code review. C1-low PR touches the given topic and has a low impact on builders.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants