diff --git a/Sources/BeaconChain/BeaconChain.swift b/Sources/BeaconChain/BeaconChain.swift index 735de51..8aaa04f 100644 --- a/Sources/BeaconChain/BeaconChain.swift +++ b/Sources/BeaconChain/BeaconChain.swift @@ -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 @@ -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) } @@ -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) @@ -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)] } @@ -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 { @@ -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) { @@ -452,11 +441,11 @@ 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 } @@ -464,7 +453,7 @@ extension BeaconChain { 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 @@ -472,12 +461,12 @@ extension BeaconChain { 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 } } diff --git a/Sources/BeaconChain/DataStructures/State/BeaconState.swift b/Sources/BeaconChain/DataStructures/State/BeaconState.swift index 1a36ae7..c67ca83 100644 --- a/Sources/BeaconChain/DataStructures/State/BeaconState.swift +++ b/Sources/BeaconChain/DataStructures/State/BeaconState.swift @@ -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 diff --git a/Sources/BeaconChain/StateTransition.swift b/Sources/BeaconChain/StateTransition.swift index a08ecef..6a6db83 100644 --- a/Sources/BeaconChain/StateTransition.swift +++ b/Sources/BeaconChain/StateTransition.swift @@ -43,7 +43,7 @@ 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) ) ) } @@ -51,17 +51,17 @@ extension StateTransition { 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) { @@ -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())) @@ -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) @@ -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)) @@ -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) @@ -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) @@ -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.. BeaconState { + return BeaconChain.getInitialBeaconState( + genesisValidatorDeposits: [Deposit](), + genesisTime: 0, + latestEth1Data: Eth1Data(depositRoot: ZERO_HASH, blockHash: ZERO_HASH) + ) + } +} diff --git a/Tests/BeaconChainTests/XCTestManifests.swift b/Tests/BeaconChainTests/XCTestManifests.swift index 19d8fa7..f44d725 100644 --- a/Tests/BeaconChainTests/XCTestManifests.swift +++ b/Tests/BeaconChainTests/XCTestManifests.swift @@ -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) ]