Eth2.0 BeaconChainのRANDAOについて
用語の整理
Beacon Chainでは新しい用語がいくつか出てくるのでここで簡単に整理する。
slot
- blockを生成する枠のこと。=ブロックと思ってもそんなに差し支えはない。
- 32 slotで1 epoch1となる。
- 各 epoch ごとに32 slotの枠が作成され、各slotにはblock properserが割り当てられる。
- block proposerは自分の番が来たらslotにブロックを提案する。
- 最初からブロックがあるわけじゃなくて、あらかじめブロックの入る枠を作るので、slotという。
- slotは12秒間隔で埋められていく。
- ブロックが提案されない空っぽのslotももちろんある。
epoch
- 32 slot = 1 epoch
- 提案されたブロックが有効かどうかの判定や、Non-ActiveなValidatorへの罰則、ブロックのjustifyやfinalizeなどはこのepoch単位で行われる。
- BeaconChainにおける最小単位の時間とも言っても差し支えないかも。
- 委員会のシャッフルは数epoch毎に行われる。
- exitの処理は数epoch毎に行われる。
- justifyの判定は毎epoch行われる。
- block proposerのslotへの割り当ては毎epoch行われる。
- comitteeを各slotのattestorへの割り当ては毎epoch行われる。
- みたいな感じ。
validator - ブロック生成者と検証者
- 32ETHデポジットした人
- validatorはcommitteeに割り当てられる。committeeはブロックの投票者の集まった委員会
- validatorはblock proposerに割り当てられる時もある。
- ブロックの投票も提案も行わないvalidatorは徐々に資金が没収される。
- 2重投票や2重提案を行ったvalidatorも資金が没収される(こっちの没収される額の方が大きい)。
委員会 - committee
- ブロックに投票する投票者が集まったもの。
- 1 committeeは最低128のattestor(= validator)で構成される。
- committeeは最低32は必要。それ以上はvalidatorの総数次第で増えていく。
- committeeはepoch毎にランダムに各slotに割り当てられる。
- committeeの参加者のお仕事は、割り当てられたslotに正当なブロックが提案されたときに、証明(=投票)を与える人。
- committeeのメンバーは数epochの間は同じ人同士(確か128epochぐらい)。
- committeeのメンバーは数epoch毎にシャッフルされる。
block proposer ブロック生成者
- 1epoch毎にvalidatorの中からランダムに選出される。
- block proposerはslotに割り当てられる。
- 自分の担当するslotの時間がきたら正当なblockを提案する。
- 不正なblockや2重にblockを提案した場合は資金が没収される。
証明書?投票 - Attestation]
- ブロックが正当であるという証明書のこと。
- committeeの参加者が自分の担当しているslotのブロックに対してつける。
- ブロックが正しいという証明書であり、投票である。
- 2/3のAttestationが集まったブロックはjustifyされる。
- Attestationを送らないvalidatorは資金が没収される。
RANDAO
前述した委員会メンバーのシャッフルや、block proposerのランダム選出などに使うランダム値のseed的なもの。
RANDAOの値はすべてのblock proposerが共同して生成する。
BeaconBlockBodyのrandao_revealの値のハッシュ値をxorしていく。
process_randaoを参照。
randao_revealはBeaconChainのGenesisのmerklized_root値+epoch数に対して、block proposerのBLSSigunatureしたもの。
process_randaoを参照。
merlized_rootはSSZによって算出される値。詳細はSSZを参照
RANDAO値はepochが切り替わるときに参照される。
RANDAOは65,536epoch分キャッシュされる。
currentのRANDAOはblockが提案されるたびに更新される。
Randao Spec
Defined parameters
table:params
Name Value Unit Duration
EPOCHS_PER_HISTORICAL_VECTOR uint64(2**16) (= 65,536) epochs ~0.8 years
Genesis
code:python
def initialize_beacon_state_from_eth1(eth1_block_hash: Hash32,
eth1_timestamp: uint64,
deposits: SequenceDeposit) -> BeaconState: fork = Fork(
previous_version=GENESIS_FORK_VERSION,
current_version=GENESIS_FORK_VERSION,
epoch=GENESIS_EPOCH,
)
state = BeaconState(
genesis_time=eth1_timestamp + GENESIS_DELAY,
fork=fork,
eth1_data=Eth1Data(block_hash=eth1_block_hash, deposit_count=uint64(len(deposits))),
latest_block_header=BeaconBlockHeader(body_root=hash_tree_root(BeaconBlockBody())),
randao_mixes=eth1_block_hash * EPOCHS_PER_HISTORICAL_VECTOR, # Seed RANDAO with Eth1 entropy )
BeaconBlockBody
code:python
class BeaconBlockBody(Container):
randao_reveal: BLSSignature
eth1_data: Eth1Data # Eth1 data vote
graffiti: Bytes32 # Arbitrary data
# Operations
BeaconState
code:python
class BeaconState(Container):
# Versioning
genesis_time: uint64
genesis_validators_root: Root
slot: Slot
fork: Fork
# History
latest_block_header: BeaconBlockHeader
# Eth1
eth1_data: Eth1Data
eth1_deposit_index: uint64
# Registry
# Randomness
# Slashings
# Attestations
# Finality
previous_justified_checkpoint: Checkpoint # Previous epoch snapshot
current_justified_checkpoint: Checkpoint
finalized_checkpoint: Checkpoint
get_randao_mix
code:python
def get_randao_mix(state: BeaconState, epoch: Epoch) -> Bytes32:
"""
Return the randao mix at a recent epoch.
"""
Epoch processing
code:python
def process_epoch(state: BeaconState) -> None:
process_justification_and_finalization(state)
process_rewards_and_penalties(state)
process_registry_updates(state)
process_slashings(state)
process_eth1_data_reset(state)
process_effective_balance_updates(state)
process_slashings_reset(state)
process_randao_mixes_reset(state)
process_historical_roots_update(state)
process_participation_record_updates(state)
Randao mixes updates
code:python
def process_randao_mixes_reset(state: BeaconState) -> None:
current_epoch = get_current_epoch(state)
next_epoch = Epoch(current_epoch + 1)
# Set randao mix
Block processing
code:python
def process_block(state: BeaconState, block: BeaconBlock) -> None:
process_block_header(state, block)
process_randao(state, block.body)
process_eth1_data(state, block.body)
process_operations(state, block.body)
Randao
code:python
def process_randao(state: BeaconState, body: BeaconBlockBody) -> None:
epoch = get_current_epoch(state)
# Verify RANDAO reveal
signing_root = compute_signing_root(epoch, get_domain(state, DOMAIN_RANDAO))
assert bls.Verify(proposer.pubkey, signing_root, body.randao_reveal)
# Mix in RANDAO reveal
mix = xor(get_randao_mix(state, epoch), hash(body.randao_reveal))
参考