Skip to content
This repository was archived by the owner on Oct 25, 2023. It is now read-only.
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
14 changes: 7 additions & 7 deletions Sources/BeaconChain/BeaconChain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ extension BeaconChain {
}

static func getEffectiveBalance(state: BeaconState, index: ValidatorIndex) -> Gwei {
return min(state.validatorBalances[Int(index)], MAX_DEPOSIT_AMOUNT)
return min(state.validatorBalances[index], MAX_DEPOSIT_AMOUNT)
}

static func getBitfieldBit(bitfield: Data, i: Int) -> Int {
Expand Down Expand Up @@ -443,19 +443,19 @@ extension BeaconChain {
extension BeaconChain {

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

state.latestSlashedBalances[Int(getCurrentEpoch(state: state) % 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
state.validatorBalances[whistleblowerIndex] += whistleblowerReward
state.validatorBalances[index] -= whistleblowerReward

let currentEpoch = getCurrentEpoch(state: state)
state.validatorRegistry[Int(index)].slashed = true
state.validatorRegistry[Int(index)].withdrawableEpoch = currentEpoch + LATEST_SLASHED_EXIT_LENGTH
state.validatorRegistry[index].slashed = true
state.validatorRegistry[index].withdrawableEpoch = currentEpoch + LATEST_SLASHED_EXIT_LENGTH
}
}
4 changes: 2 additions & 2 deletions Sources/BeaconChain/DataStructures/State/BeaconState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ struct BeaconState {
let genesisTime: UInt64
let fork: Fork

var validatorRegistry: [Validator]
var validatorBalances: [UInt64]
var validatorRegistry: [UInt64: Validator]
var validatorBalances: [UInt64: UInt64]
var validatorRegistryUpdateEpoch: UInt64

var latestRandaoMixes: [Data]
Expand Down
8 changes: 8 additions & 0 deletions Sources/BeaconChain/Extensions/Dictionary+UInt64.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Foundation

extension Dictionary where Key == UInt64 {

mutating func append(_ element: Value) {
self[UInt64(count + 1)] = element
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import Foundation

extension Array where Element == Validator {
extension Dictionary where Key == UInt64, Value == Validator {

func activeIndices(epoch: Epoch) -> [ValidatorIndex] {
return enumerated().compactMap {
return compactMap {
(k, v) in
if v.isActive(epoch: epoch) {
return ValidatorIndex(k)
return k
}

return nil
Expand Down
30 changes: 15 additions & 15 deletions Sources/BeaconChain/StateTransition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ extension StateTransition {
}

static func blockSignature(state: inout BeaconState, block: BeaconBlock) {
let proposer = state.validatorRegistry[Int(BeaconChain.getBeaconProposerIndex(state: state, slot: state.slot))]
let proposer = state.validatorRegistry[BeaconChain.getBeaconProposerIndex(state: state, slot: state.slot)]
let proposal = Proposal(
slot: block.slot,
shard: BEACON_CHAIN_SHARD_NUMBER,
Expand All @@ -49,7 +49,7 @@ extension StateTransition {
}

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

var epoch = BeaconChain.getCurrentEpoch(state: state)
assert(
Expand Down Expand Up @@ -79,7 +79,7 @@ extension StateTransition {
assert(block.body.proposerSlashings.count <= MAX_PROPOSER_SLASHINGS)

for proposerSlashing in block.body.proposerSlashings {
let proposer = state.validatorRegistry[Int(proposerSlashing.proposerIndex)]
let proposer = state.validatorRegistry[proposerSlashing.proposerIndex]
// @todo none of these should be asserts
assert(proposerSlashing.proposal1.slot == proposerSlashing.proposal2.slot)
assert(proposerSlashing.proposal1.shard == proposerSlashing.proposal2.shard)
Expand Down Expand Up @@ -126,7 +126,7 @@ extension StateTransition {

let slashableIndices = slashableAttestation1.validatorIndices.filter {
slashableAttestation2.validatorIndices.contains($0)
&& state.validatorRegistry[Int($0)].slashed == false
&& state.validatorRegistry[$0].slashed == false
}

assert(slashableIndices.count >= 1)
Expand Down Expand Up @@ -190,10 +190,10 @@ extension StateTransition {
BLS.verify(
pubkeys: [
BLS.aggregate(pubkeys: custodyBit0Participants.map {
return state.validatorRegistry[Int($0)].pubkey
return state.validatorRegistry[$0].pubkey
}),
BLS.aggregate(pubkeys: custodyBit1Participants.map {
return state.validatorRegistry[Int($0)].pubkey
return state.validatorRegistry[$0].pubkey
})
],
messages: [
Expand Down Expand Up @@ -246,7 +246,7 @@ extension StateTransition {
assert(block.body.voluntaryExits.count <= MAX_VOLUNTARY_EXITS)

for exit in block.body.voluntaryExits {
let validator = state.validatorRegistry[Int(exit.validatorIndex)]
let validator = state.validatorRegistry[exit.validatorIndex]

let epoch = BeaconChain.getCurrentEpoch(state: state)
assert(validator.exitEpoch > epoch.delayedActivationExitEpoch())
Expand All @@ -261,7 +261,7 @@ extension StateTransition {
)
)

state.validatorRegistry[Int(exit.validatorIndex)].initiatedExit = true
state.validatorRegistry[exit.validatorIndex].initiatedExit = true
}
}

Expand All @@ -278,10 +278,10 @@ extension StateTransition {

assert(state.slot == transfer.slot)
assert(
BeaconChain.getCurrentEpoch(state: state) >= state.validatorRegistry[Int(transfer.from)].withdrawableEpoch
|| state.validatorRegistry[Int(transfer.from)].activationEpoch == FAR_FUTURE_EPOCH
BeaconChain.getCurrentEpoch(state: state) >= state.validatorRegistry[transfer.from].withdrawableEpoch
|| state.validatorRegistry[transfer.from].activationEpoch == FAR_FUTURE_EPOCH
)
assert(state.validatorRegistry[Int(transfer.from)].withdrawalCredentials == BLS_WITHDRAWAL_PREFIX_BYTE + BeaconChain.hash(transfer.pubkey).suffix(from: 1))
assert(state.validatorRegistry[transfer.from].withdrawalCredentials == BLS_WITHDRAWAL_PREFIX_BYTE + BeaconChain.hash(transfer.pubkey).suffix(from: 1))

assert(
BLS.verify(
Expand Down Expand Up @@ -611,8 +611,8 @@ extension StateTransition {

activeValidators.forEach({
index in
if state.validatorRegistry[Int(index)].slashed {
state.validatorBalances[Int(index)] -= 2 * inactivityPenalty(state: state, index: index, epochsSinceFinality: epochsSinceFinality, baseRewardQuotient: baseRewardQuotient) + baseReward(state: state, index: index, baseRewardQuotient: baseRewardQuotient)
if state.validatorRegistry[index].slashed {
state.validatorBalances[index] -= 2 * inactivityPenalty(state: state, index: index, epochsSinceFinality: epochsSinceFinality, baseRewardQuotient: baseRewardQuotient) + baseReward(state: state, index: index, baseRewardQuotient: baseRewardQuotient)
}
})

Expand Down Expand Up @@ -744,8 +744,8 @@ extension StateTransition {

static func processEjections(state: inout BeaconState) {
for i in state.validatorRegistry.activeIndices(epoch: BeaconChain.getCurrentEpoch(state: state)) {
if state.validatorBalances[Int(i)] < EJECTION_BALANCE {
state.validatorRegistry[Int(i)].exit(state: state)
if state.validatorBalances[i] < EJECTION_BALANCE {
state.validatorRegistry[i].exit(state: state)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import XCTest
@testable import BeaconChain

final class ArrayValidatorTests: XCTestCase {
final class DictionaryValidatorTests: XCTestCase {

func testActiveIndices() {

let epoch = Epoch(10)

let validators = [
createValidator(epoch: epoch),
createValidator(epoch: epoch),
createValidator(epoch: Epoch(12))
UInt64(0): createValidator(epoch: epoch),
1: createValidator(epoch: epoch),
2: createValidator(epoch: Epoch(12))
]

XCTAssertEqual(validators.activeIndices(epoch: epoch), [ValidatorIndex(0), 1])
Expand Down