Skip to content
This repository was archived by the owner on Oct 25, 2023. It is now read-only.

enhancement/previous-current-epoch-computed-variables #69

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 12 additions & 23 deletions Sources/BeaconChain/BeaconChain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,6 @@ class BeaconChain {

}

extension BeaconChain {

static func getPreviousEpoch(state: BeaconState) -> Epoch {
return max(getCurrentEpoch(state: state) - 1, GENESIS_EPOCH)
}

static func getCurrentEpoch(state: BeaconState) -> Epoch {
return state.slot.toEpoch()
}
}

extension BeaconChain {

// @todo check this shit
Expand Down Expand Up @@ -98,7 +87,7 @@ extension BeaconChain {
}

static func getNextEpochCommitteeCount(state: BeaconState) -> Int {
let nextActiveValidators = state.validatorRegistry.activeIndices(epoch: getCurrentEpoch(state: state) + 1)
let nextActiveValidators = state.validatorRegistry.activeIndices(epoch: state.currentEpoch + 1)
return getEpochCommitteeCount(activeValidatorCount: nextActiveValidators.count)
}

Expand All @@ -108,8 +97,8 @@ extension BeaconChain {
registryChange: Bool = false
) -> [([ValidatorIndex], Shard)] {
let epoch = slot.toEpoch()
let currentEpoch = getCurrentEpoch(state: state)
let previousEpoch = getPreviousEpoch(state: state)
let currentEpoch = state.currentEpoch
let previousEpoch = state.previousEpoch
let nextEpoch = currentEpoch + 1

assert(previousEpoch <= epoch && epoch <= nextEpoch)
Expand Down Expand Up @@ -173,13 +162,13 @@ extension BeaconChain {
}

static func getRandaoMix(state: BeaconState, epoch: Epoch) -> Bytes32 {
let currentEpoch = getCurrentEpoch(state: state)
let currentEpoch = state.currentEpoch
assert(currentEpoch - LATEST_RANDAO_MIXES_LENGTH < epoch && epoch <= currentEpoch)
return state.latestRandaoMixes[Int(epoch % LATEST_RANDAO_MIXES_LENGTH)]
}

static func getActiveIndexRoot(state: BeaconState, epoch: Epoch) -> Bytes32 {
let currentEpoch = getCurrentEpoch(state: state)
let currentEpoch = state.currentEpoch
assert(currentEpoch - LATEST_ACTIVE_INDEX_ROOTS_LENGTH + ACTIVATION_EXIT_DELAY < epoch && epoch <= currentEpoch + ACTIVATION_EXIT_DELAY)
return state.latestActiveIndexRoots[Int(epoch % LATEST_ACTIVE_INDEX_ROOTS_LENGTH)]
}
Expand Down Expand Up @@ -409,7 +398,7 @@ extension BeaconChain {
pubkey: depositInput.pubkey,
message: BeaconChain.signedRoot(depositInput, field: "proofOfPossession"),
signature: depositInput.proofOfPossession,
domain: state.fork.domain(epoch: BeaconChain.getCurrentEpoch(state: state), type: .DEPOSIT)
domain: state.fork.domain(epoch: state.currentEpoch, type: .DEPOSIT)
)

if !proofIsValid {
Expand Down Expand Up @@ -443,7 +432,7 @@ extension BeaconChain {
extension BeaconChain {

static func activateValidator(state: inout BeaconState, index: ValidatorIndex, genesis: Bool) {
state.validatorRegistry[Int(index)].activationEpoch = genesis ? GENESIS_EPOCH : getCurrentEpoch(state: state).delayedActivationExitEpoch()
state.validatorRegistry[Int(index)].activationEpoch = genesis ? GENESIS_EPOCH : state.currentEpoch.delayedActivationExitEpoch()
}

static func initiateValidatorExit(state: inout BeaconState, index: ValidatorIndex) {
Expand All @@ -452,32 +441,32 @@ extension BeaconChain {

static func exitValidator(state: inout BeaconState, index: ValidatorIndex) {
var validator = state.validatorRegistry[Int(index)]
if validator.exitEpoch <= getCurrentEpoch(state: state).delayedActivationExitEpoch() {
if validator.exitEpoch <= state.currentEpoch.delayedActivationExitEpoch() {
return
}

validator.exitEpoch = getCurrentEpoch(state: state).delayedActivationExitEpoch()
validator.exitEpoch = state.currentEpoch.delayedActivationExitEpoch()
state.validatorRegistry[Int(index)] = validator
}

static func slashValidator(state: inout BeaconState, index: ValidatorIndex) {
assert(state.slot < state.validatorRegistry[Int(index)].withdrawableEpoch.startSlot())
exitValidator(state: &state, index: index)

state.latestSlashedBalances[Int(getCurrentEpoch(state: state) % LATEST_SLASHED_EXIT_LENGTH)] += getEffectiveBalance(state: state, index: index)
state.latestSlashedBalances[Int(state.currentEpoch % LATEST_SLASHED_EXIT_LENGTH)] += getEffectiveBalance(state: state, index: index)

let whistleblowerIndex = getBeaconProposerIndex(state: state, slot: state.slot)
let whistleblowerReward = getEffectiveBalance(state: state, index: index) / WHISTLEBLOWER_REWARD_QUOTIENT

state.validatorBalances[Int(whistleblowerIndex)] += whistleblowerReward
state.validatorBalances[Int(index)] -= whistleblowerReward

let currentEpoch = getCurrentEpoch(state: state)
let currentEpoch = state.currentEpoch
state.validatorRegistry[Int(index)].slashed = true
state.validatorRegistry[Int(index)].withdrawableEpoch = currentEpoch + LATEST_SLASHED_EXIT_LENGTH
}

static func prepareValidatorForWithdrawal(state: inout BeaconState, index: ValidatorIndex) {
state.validatorRegistry[Int(index)].withdrawableEpoch = getCurrentEpoch(state: state) + MIN_VALIDATOR_WITHDRAWABILITY_DELAY
state.validatorRegistry[Int(index)].withdrawableEpoch = state.currentEpoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY
}
}
9 changes: 9 additions & 0 deletions Sources/BeaconChain/DataStructures/State/BeaconState.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import Foundation

struct BeaconState {

var previousEpoch: UInt64 {
return max(currentEpoch - 1, GENESIS_EPOCH)
}

var currentEpoch: UInt64 {
return slot.toEpoch()
}

var slot: UInt64
let genesisTime: UInt64
let fork: Fork
Expand Down
26 changes: 13 additions & 13 deletions Sources/BeaconChain/StateTransition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,25 +43,25 @@ extension StateTransition {
pubkey: proposer.pubkey,
message: BeaconChain.signedRoot(proposal, field: "signature"),
signature: proposal.signature,
domain: state.fork.domain(epoch: BeaconChain.getCurrentEpoch(state: state), type: .PROPOSAL)
domain: state.fork.domain(epoch: state.currentEpoch, type: .PROPOSAL)
)
)
}

static func randao(state: inout BeaconState, block: BeaconBlock) {
let proposer = state.validatorRegistry[Int(BeaconChain.getBeaconProposerIndex(state: state, slot: state.slot))]

var epoch = BeaconChain.getCurrentEpoch(state: state)
var epoch = state.currentEpoch
assert(
BLS.verify(
pubkey: proposer.pubkey,
message: Data(bytes: &epoch, count: 32),
signature: block.randaoReveal,
domain: state.fork.domain(epoch: BeaconChain.getCurrentEpoch(state: state), type: .RANDAO)
domain: state.fork.domain(epoch: state.currentEpoch, type: .RANDAO)
)
)

state.latestRandaoMixes[Int(BeaconChain.getCurrentEpoch(state: state) % LATEST_RANDAO_MIXES_LENGTH)] = BeaconChain.getRandaoMix(state: state, epoch: BeaconChain.getCurrentEpoch(state: state)) ^ BeaconChain.hash(block.randaoReveal)
state.latestRandaoMixes[Int(state.currentEpoch % LATEST_RANDAO_MIXES_LENGTH)] = BeaconChain.getRandaoMix(state: state, epoch: state.currentEpoch) ^ BeaconChain.hash(block.randaoReveal)
}

static func eth1data(state: inout BeaconState, block: BeaconBlock) {
Expand Down Expand Up @@ -145,7 +145,7 @@ extension StateTransition {
assert(attestation.data.slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot)
assert(state.slot < attestation.data.slot + SLOTS_PER_EPOCH)

let e = (attestation.data.slot + 1).toEpoch() >= BeaconChain.getCurrentEpoch(state: state) ? state.justifiedEpoch : state.previousJustifiedEpoch
let e = (attestation.data.slot + 1).toEpoch() >= state.currentEpoch ? state.justifiedEpoch : state.previousJustifiedEpoch
assert(attestation.data.justifiedEpoch == e)
assert(attestation.data.justifiedBlockRoot == BeaconChain.getBlockRoot(state: state, slot: attestation.data.justifiedEpoch.startSlot()))

Expand Down Expand Up @@ -248,7 +248,7 @@ extension StateTransition {
for exit in block.body.voluntaryExits {
let validator = state.validatorRegistry[Int(exit.validatorIndex)]

let epoch = BeaconChain.getCurrentEpoch(state: state)
let epoch = state.currentEpoch
assert(validator.exitEpoch > epoch.delayedActivationExitEpoch())
assert(epoch >= exit.epoch)

Expand Down Expand Up @@ -278,7 +278,7 @@ extension StateTransition {

assert(state.slot == transfer.slot)
assert(
BeaconChain.getCurrentEpoch(state: state) >= state.validatorRegistry[Int(transfer.from)].withdrawableEpoch
state.currentEpoch >= state.validatorRegistry[Int(transfer.from)].withdrawableEpoch
|| state.validatorRegistry[Int(transfer.from)].activationEpoch == FAR_FUTURE_EPOCH
)
assert(state.validatorRegistry[Int(transfer.from)].withdrawalCredentials == BLS_WITHDRAWAL_PREFIX_BYTE + BeaconChain.hash(transfer.pubkey).suffix(from: 1))
Expand Down Expand Up @@ -317,8 +317,8 @@ extension StateTransition {
static func processEpoch(state: inout BeaconState) {
assert(state.slot + 1 % SLOTS_PER_EPOCH == 0) // @todo not sure if this should be here

let currentEpoch = BeaconChain.getCurrentEpoch(state: state)
let previousEpoch = BeaconChain.getPreviousEpoch(state: state)
let currentEpoch = state.currentEpoch
let previousEpoch = state.previousEpoch
let nextEpoch = currentEpoch + 1

let currentTotalBalance = state.validatorRegistry.activeIndices(epoch: currentEpoch).totalBalance(state: state)
Expand Down Expand Up @@ -658,7 +658,7 @@ extension StateTransition {
}

static func processSlashing(state: inout BeaconState) {
let currentEpoch = BeaconChain.getCurrentEpoch(state: state)
let currentEpoch = state.currentEpoch
let activeValidatorIndices = state.validatorRegistry.activeIndices(epoch: currentEpoch)

let totalBalance = activeValidatorIndices.totalBalance(state: state)
Expand All @@ -678,7 +678,7 @@ extension StateTransition {
}

static func processExitQueue(state: inout BeaconState) {
let currentEpoch = BeaconChain.getCurrentEpoch(state: state)
let currentEpoch = state.currentEpoch

var eligibleIndices = (0..<state.validatorRegistry.count).filter {
let validator = state.validatorRegistry[$0]
Expand All @@ -703,7 +703,7 @@ extension StateTransition {
}

static func updateValidatorRegistry(state: inout BeaconState) {
let currentEpoch = BeaconChain.getCurrentEpoch(state: state)
let currentEpoch = state.currentEpoch
let activeValidatorIndices = state.validatorRegistry.activeIndices(epoch: currentEpoch)

let totalBalance = activeValidatorIndices.totalBalance(state: state)
Expand Down Expand Up @@ -743,7 +743,7 @@ extension StateTransition {
}

static func processEjections(state: inout BeaconState) {
for i in state.validatorRegistry.activeIndices(epoch: BeaconChain.getCurrentEpoch(state: state)) {
for i in state.validatorRegistry.activeIndices(epoch: state.currentEpoch) {
if state.validatorBalances[Int(i)] < EJECTION_BALANCE {
BeaconChain.exitValidator(state: &state, index: i)
}
Expand Down
27 changes: 27 additions & 0 deletions Tests/BeaconChainTests/DataStructures/State/BeaconStateTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import XCTest
@testable import BeaconChain

final class BeaconStateTests: XCTestCase {

func testPreviousEpoch() {
var state = getState()
XCTAssertEqual(GENESIS_EPOCH, state.previousEpoch)

state.slot = GENESIS_SLOT * 2
XCTAssertEqual((GENESIS_EPOCH * 2) - 1, state.previousEpoch)
}

func testCurrentEpoch() {
var state = getState()
state.slot = GENESIS_SLOT
XCTAssertEqual(GENESIS_EPOCH, state.currentEpoch)
}

private func getState() -> BeaconState {
return BeaconChain.getInitialBeaconState(
genesisValidatorDeposits: [Deposit](),
genesisTime: 0,
latestEth1Data: Eth1Data(depositRoot: ZERO_HASH, blockHash: ZERO_HASH)
)
}
}
1 change: 1 addition & 0 deletions Tests/BeaconChainTests/XCTestManifests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public func allTests() -> [XCTestCaseEntry] {
testCase(SlotTests.allTests),
testCase(EpochTests.allTests),
testCase(ValidatorTests.allTests),
testCase(BeaconStateTests.allTests),
testCase(ForkTests.allTests),
// testCase(StateTransitionTests.allTests)
]
Expand Down