From 6d1b293d7eb93a6b61468656ef571e3633a6e7f3 Mon Sep 17 00:00:00 2001 From: decanus Date: Sun, 24 Mar 2019 15:43:02 +0100 Subject: [PATCH] started experimenting --- Sources/BeaconChain/BeaconChain.swift | 14 ++++----- .../DataStructures/State/BeaconState.swift | 4 +-- .../Extensions/Dictionary+UInt64.swift | 8 +++++ ...dator.swift => Dictionary+Validator.swift} | 6 ++-- Sources/BeaconChain/StateTransition.swift | 30 +++++++++---------- ....swift => Dictionary+ValidatorTests.swift} | 8 ++--- 6 files changed, 39 insertions(+), 31 deletions(-) create mode 100644 Sources/BeaconChain/Extensions/Dictionary+UInt64.swift rename Sources/BeaconChain/Extensions/{Array+Validator.swift => Dictionary+Validator.swift} (61%) rename Tests/BeaconChainTests/Extensions/{Array+ValidatorTests.swift => Dictionary+ValidatorTests.swift} (74%) diff --git a/Sources/BeaconChain/BeaconChain.swift b/Sources/BeaconChain/BeaconChain.swift index 305452a..945b7d7 100644 --- a/Sources/BeaconChain/BeaconChain.swift +++ b/Sources/BeaconChain/BeaconChain.swift @@ -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 { @@ -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 } } diff --git a/Sources/BeaconChain/DataStructures/State/BeaconState.swift b/Sources/BeaconChain/DataStructures/State/BeaconState.swift index 1a36ae7..19fd5f0 100644 --- a/Sources/BeaconChain/DataStructures/State/BeaconState.swift +++ b/Sources/BeaconChain/DataStructures/State/BeaconState.swift @@ -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] diff --git a/Sources/BeaconChain/Extensions/Dictionary+UInt64.swift b/Sources/BeaconChain/Extensions/Dictionary+UInt64.swift new file mode 100644 index 0000000..ce9bed8 --- /dev/null +++ b/Sources/BeaconChain/Extensions/Dictionary+UInt64.swift @@ -0,0 +1,8 @@ +import Foundation + +extension Dictionary where Key == UInt64 { + + mutating func append(_ element: Value) { + self[UInt64(count + 1)] = element + } +} \ No newline at end of file diff --git a/Sources/BeaconChain/Extensions/Array+Validator.swift b/Sources/BeaconChain/Extensions/Dictionary+Validator.swift similarity index 61% rename from Sources/BeaconChain/Extensions/Array+Validator.swift rename to Sources/BeaconChain/Extensions/Dictionary+Validator.swift index c27c903..4cb70a2 100644 --- a/Sources/BeaconChain/Extensions/Array+Validator.swift +++ b/Sources/BeaconChain/Extensions/Dictionary+Validator.swift @@ -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 diff --git a/Sources/BeaconChain/StateTransition.swift b/Sources/BeaconChain/StateTransition.swift index 16587eb..4191059 100644 --- a/Sources/BeaconChain/StateTransition.swift +++ b/Sources/BeaconChain/StateTransition.swift @@ -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, @@ -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( @@ -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) @@ -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) @@ -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: [ @@ -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()) @@ -261,7 +261,7 @@ extension StateTransition { ) ) - state.validatorRegistry[Int(exit.validatorIndex)].initiatedExit = true + state.validatorRegistry[exit.validatorIndex].initiatedExit = true } } @@ -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( @@ -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) } }) @@ -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) } } } diff --git a/Tests/BeaconChainTests/Extensions/Array+ValidatorTests.swift b/Tests/BeaconChainTests/Extensions/Dictionary+ValidatorTests.swift similarity index 74% rename from Tests/BeaconChainTests/Extensions/Array+ValidatorTests.swift rename to Tests/BeaconChainTests/Extensions/Dictionary+ValidatorTests.swift index 07f8168..3dba3fd 100644 --- a/Tests/BeaconChainTests/Extensions/Array+ValidatorTests.swift +++ b/Tests/BeaconChainTests/Extensions/Dictionary+ValidatorTests.swift @@ -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])