From 41274f7de9444d440f765e7c3bdce3a80a201f4f Mon Sep 17 00:00:00 2001 From: decanus Date: Sun, 24 Feb 2019 22:09:35 +0100 Subject: [PATCH 01/16] renamed constants --- Sources/BeaconChain/BeaconChain.swift | 24 +++++++-------- Sources/BeaconChain/Constants.swift | 26 ++++++++-------- Sources/BeaconChain/Enums/Domain.swift | 1 + .../BeaconChain/Extensions/EpochNumber.swift | 4 +-- .../BeaconChain/Extensions/SlotNumber.swift | 2 +- Sources/BeaconChain/StateTransition.swift | 30 +++++++++---------- 6 files changed, 45 insertions(+), 42 deletions(-) diff --git a/Sources/BeaconChain/BeaconChain.swift b/Sources/BeaconChain/BeaconChain.swift index f788d85..e05afa7 100644 --- a/Sources/BeaconChain/BeaconChain.swift +++ b/Sources/BeaconChain/BeaconChain.swift @@ -78,10 +78,10 @@ extension BeaconChain { max( 1, min( - SHARD_COUNT / EPOCH_LENGTH, - UInt64(activeValidatorCount) / EPOCH_LENGTH / TARGET_COMMITTEE_SIZE + SHARD_COUNT / SLOTS_PER_EPOCH, + UInt64(activeValidatorCount) / SLOTS_PER_EPOCH / TARGET_COMMITTEE_SIZE ) - ) * EPOCH_LENGTH + ) * SLOTS_PER_EPOCH ) } @@ -146,8 +146,8 @@ extension BeaconChain { let shuffling = getShuffling(seed: seed, validators: state.validatorRegistry, epoch: shufflingEpoch) - let offset = slot % EPOCH_LENGTH - let committeesPerSlot = UInt64(committeesPerEpoch) / EPOCH_LENGTH + let offset = slot % SLOTS_PER_EPOCH + let committeesPerSlot = UInt64(committeesPerEpoch) / SLOTS_PER_EPOCH let slotStartShard = (shufflingStartShard + committeesPerSlot * offset) % SHARD_COUNT return (0.. Bytes32 { let currentEpoch = getCurrentEpoch(state: state) - assert(currentEpoch - LATEST_INDEX_ROOTS_LENGTH + ENTRY_EXIT_DELAY < epoch && epoch <= currentEpoch + ENTRY_EXIT_DELAY) - return state.latestIndexRoots[Int(epoch % LATEST_INDEX_ROOTS_LENGTH)] + assert(currentEpoch - LATEST_ACTIVE_INDEX_ROOTS_LENGTH + ACTIVATION_EXIT_DELAY < epoch && epoch <= currentEpoch + ACTIVATION_EXIT_DELAY) + return state.latestIndexRoots[Int(epoch % LATEST_ACTIVE_INDEX_ROOTS_LENGTH)] } } @@ -185,7 +185,7 @@ extension BeaconChain { static func generateSeed(state: BeaconState, epoch: EpochNumber) -> Data { return hash( - getRandaoMix(state: state, epoch: epoch - SEED_LOOKAHEAD) + + getRandaoMix(state: state, epoch: epoch - MIN_SEED_LOOKAHEAD) + getActiveIndexRoot(state: state, epoch: epoch) + epoch.bytes32 ) @@ -363,7 +363,7 @@ extension BeaconChain { } } - state.latestIndexRoots[Int(GENESIS_EPOCH % LATEST_INDEX_ROOTS_LENGTH)] = hashTreeRoot( + state.latestIndexRoots[Int(GENESIS_EPOCH % LATEST_ACTIVE_INDEX_ROOTS_LENGTH)] = hashTreeRoot( state.validatorRegistry.activeIndices(epoch: GENESIS_EPOCH) ) state.currentEpochSeed = generateSeed(state: state, epoch: GENESIS_EPOCH) @@ -396,8 +396,8 @@ extension BeaconChain { finalizedEpoch: GENESIS_EPOCH, latestCrosslinks: [Crosslink](repeating: Crosslink(epoch: GENESIS_EPOCH, shardBlockRoot: ZERO_HASH), count: Int(SHARD_COUNT)), latestBlockRoots: [Data](repeating: ZERO_HASH, count: Int(LATEST_BLOCK_ROOTS_LENGTH)), - latestIndexRoots: [Data](repeating: ZERO_HASH, count: Int(LATEST_INDEX_ROOTS_LENGTH)), - latestPenalizedBalances: [UInt64](repeating: 0, count: Int(LATEST_PENALIZED_EXIT_LENGTH)), + latestIndexRoots: [Data](repeating: ZERO_HASH, count: Int(LATEST_ACTIVE_INDEX_ROOTS_LENGTH)), + latestPenalizedBalances: [UInt64](repeating: 0, count: Int(LATEST_SLASHED_EXIT_LENGTH)), latestAttestations: [PendingAttestation](), batchedBlockRoots: [Data](), latestEth1Data: latestEth1Data, @@ -487,7 +487,7 @@ extension BeaconChain { static func penalizeValidator(state: inout BeaconState, index: ValidatorIndex) { exitValidator(state: &state, index: index) - state.latestPenalizedBalances[Int(getCurrentEpoch(state: state) % LATEST_PENALIZED_EXIT_LENGTH)] += getEffectiveBalance(state: state, index: index) + state.latestPenalizedBalances[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 diff --git a/Sources/BeaconChain/Constants.swift b/Sources/BeaconChain/Constants.swift index e042a32..ee4226f 100644 --- a/Sources/BeaconChain/Constants.swift +++ b/Sources/BeaconChain/Constants.swift @@ -6,7 +6,7 @@ let TARGET_COMMITTEE_SIZE = UInt64(2**7) let MAX_BALANCE_CHURN_QUOTIENT = UInt64(2**5) let BEACON_CHAIN_SHARD_NUMBER = UInt64.max let MAX_INDICES_PER_SLASHABLE_VOTE = UInt64(2**12) -let MAX_WITHDRAWALS_PER_EPOCH = UInt64(2**2) +let MAX_EXIT_DEQUEUES_PER_EPOCH = UInt64(2**2) let SHUFFLE_ROUND_COUNT = 90 // Deposit Contract @@ -30,29 +30,31 @@ let EMPTY_SIGNATURE = Data(repeating: 0, count: 96) let BLS_WITHDRAWAL_PREFIX_BYTE = Data(repeating: 0, count: 1) // Time parameters -let SLOT_DURATION = UInt64(6) +let SECONDS_PER_SLOT = UInt64(6) let MIN_ATTESTATION_INCLUSION_DELAY = UInt64(2**2) -let EPOCH_LENGTH = UInt64(2**6) -let SEED_LOOKAHEAD = UInt64(2**0) -let ENTRY_EXIT_DELAY = UInt64(2**2) -let ETH1_DATA_VOTING_PERIOD = UInt64(2**4) -let MIN_VALIDATOR_WITHDRAWAL_EPOCHS = UInt64(2**8) +let SLOTS_PER_EPOCH = UInt64(2**6) +let MIN_SEED_LOOKAHEAD = UInt64(2**0) +let ACTIVATION_EXIT_DELAY = UInt64(2**2) +let EPOCHS_PER_ETH1_VOTING_PERIOD = UInt64(2**4) +let MIN_VALIDATOR_WITHDRAWAL_DELAY = UInt64(2**8) // State list lengths let LATEST_BLOCK_ROOTS_LENGTH = UInt64(2**13) let LATEST_RANDAO_MIXES_LENGTH = UInt64(2**13) -let LATEST_INDEX_ROOTS_LENGTH = UInt64(2**13) -let LATEST_PENALIZED_EXIT_LENGTH = UInt64(2**13) +let LATEST_ACTIVE_INDEX_ROOTS_LENGTH = UInt64(2**13) +let LATEST_SLASHED_EXIT_LENGTH = UInt64(2**13) // Reward and penalty quotients let BASE_REWARD_QUOTIENT = UInt64(2**5) let WHISTLEBLOWER_REWARD_QUOTIENT = UInt64(2**9) -let INCLUDER_REWARD_QUOTIENT = UInt64(2**3) +let ATTESTATION_INCLUSION_REWARD_QUOTIENT = UInt64(2**3) let INACTIVITY_PENALTY_QUOTIENT = UInt64(2**24) +let MIN_PENALTY_QUOTIENT = UInt64(2**5) -// Max operations per block +// Max transactions per block let MAX_PROPOSER_SLASHINGS = UInt64(2**4) let MAX_ATTESTER_SLASHINGS = UInt64(2**0) let MAX_ATTESTATIONS = UInt64(2**7) let MAX_DEPOSITS = UInt64(2**4) -let MAX_EXITS = UInt64(2**4) +let MAX_VOLUNTARY_EXITS = UInt64(2**4) +let MAX_TRANSFERS = UInt64(2**4) diff --git a/Sources/BeaconChain/Enums/Domain.swift b/Sources/BeaconChain/Enums/Domain.swift index 49c658d..5d4b692 100644 --- a/Sources/BeaconChain/Enums/Domain.swift +++ b/Sources/BeaconChain/Enums/Domain.swift @@ -6,4 +6,5 @@ enum Domain: UInt64 { case PROPOSAL case EXIT case RANDAO + case TRANSFER } diff --git a/Sources/BeaconChain/Extensions/EpochNumber.swift b/Sources/BeaconChain/Extensions/EpochNumber.swift index 1cde22e..02cc6a2 100644 --- a/Sources/BeaconChain/Extensions/EpochNumber.swift +++ b/Sources/BeaconChain/Extensions/EpochNumber.swift @@ -3,10 +3,10 @@ import Foundation extension EpochNumber { func startSlot() -> SlotNumber { - return self * EPOCH_LENGTH + return self * SLOTS_PER_EPOCH } func entryExitEpoch() -> EpochNumber { - return self + 1 + ENTRY_EXIT_DELAY + return self + 1 + ACTIVATION_EXIT_DELAY } } diff --git a/Sources/BeaconChain/Extensions/SlotNumber.swift b/Sources/BeaconChain/Extensions/SlotNumber.swift index ea4a403..3fb73ba 100644 --- a/Sources/BeaconChain/Extensions/SlotNumber.swift +++ b/Sources/BeaconChain/Extensions/SlotNumber.swift @@ -3,6 +3,6 @@ import Foundation extension SlotNumber { func toEpoch() -> EpochNumber { - return self / EPOCH_LENGTH + return self / SLOTS_PER_EPOCH } } diff --git a/Sources/BeaconChain/StateTransition.swift b/Sources/BeaconChain/StateTransition.swift index 701a913..7152011 100644 --- a/Sources/BeaconChain/StateTransition.swift +++ b/Sources/BeaconChain/StateTransition.swift @@ -149,7 +149,7 @@ extension StateTransition { for attestation in block.body.attestations { assert(attestation.data.slot <= state.slot - MIN_ATTESTATION_INCLUSION_DELAY) - assert(state.slot - MIN_ATTESTATION_INCLUSION_DELAY < attestation.data.slot + EPOCH_LENGTH) + assert(state.slot - MIN_ATTESTATION_INCLUSION_DELAY < attestation.data.slot + SLOTS_PER_EPOCH) let e = attestation.data.justifiedEpoch >= BeaconChain.getCurrentEpoch(state: state) ? state.justifiedEpoch : state.previousJustifiedEpoch assert(attestation.data.justifiedEpoch == e) @@ -254,7 +254,7 @@ extension StateTransition { } static func exits(state: inout BeaconState, block: BeaconBlock) { - assert(block.body.exits.count <= MAX_EXITS) + assert(block.body.exits.count <= MAX_VOLUNTARY_EXITS) for exit in block.body.exits { let validator = state.validatorRegistry[Int(exit.validatorIndex)] @@ -297,7 +297,7 @@ extension StateTransition { extension StateTransition { static func processEpoch(state: inout BeaconState) { - assert(state.slot + 1 % EPOCH_LENGTH == 0) // @todo not sure if this should be here + 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) @@ -419,11 +419,11 @@ extension StateTransition { processPenaltiesAndExit(state: &state) - state.latestIndexRoots[Int((nextEpoch % ENTRY_EXIT_DELAY) % LATEST_INDEX_ROOTS_LENGTH)] = BeaconChain.hashTreeRoot( - state.validatorRegistry.activeIndices(epoch: nextEpoch + ENTRY_EXIT_DELAY) + state.latestIndexRoots[Int((nextEpoch % ACTIVATION_EXIT_DELAY) % LATEST_ACTIVE_INDEX_ROOTS_LENGTH)] = BeaconChain.hashTreeRoot( + state.validatorRegistry.activeIndices(epoch: nextEpoch + ACTIVATION_EXIT_DELAY) ) - state.latestPenalizedBalances[Int(nextEpoch % LATEST_PENALIZED_EXIT_LENGTH)] = state.latestPenalizedBalances[Int(currentEpoch % LATEST_PENALIZED_EXIT_LENGTH)] + state.latestPenalizedBalances[Int(nextEpoch % LATEST_SLASHED_EXIT_LENGTH)] = state.latestPenalizedBalances[Int(currentEpoch % LATEST_SLASHED_EXIT_LENGTH)] state.latestRandaoMixes[Int(nextEpoch % LATEST_RANDAO_MIXES_LENGTH)] = BeaconChain.getRandaoMix( state: state, epoch: currentEpoch @@ -437,12 +437,12 @@ extension StateTransition { } private static func eth1data(state: inout BeaconState, nextEpoch: EpochNumber) { - if nextEpoch % ETH1_DATA_VOTING_PERIOD != 0 { + if nextEpoch % EPOCHS_PER_ETH1_VOTING_PERIOD != 0 { return } for vote in state.eth1DataVotes { - if vote.voteCount * 2 > ETH1_DATA_VOTING_PERIOD * EPOCH_LENGTH { + if vote.voteCount * 2 > EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH { state.latestEth1Data = vote.eth1Data } } @@ -619,7 +619,7 @@ extension StateTransition { state: state, slot: inclusionSlot(state: state, index: Int(index)) ) - state.validatorBalances[Int(proposer)] += baseReward(state: state, index: index, baseRewardQuotient: baseRewardQuotient) / INCLUDER_REWARD_QUOTIENT + state.validatorBalances[Int(proposer)] += baseReward(state: state, index: index, baseRewardQuotient: baseRewardQuotient) / ATTESTATION_INCLUSION_REWARD_QUOTIENT } for slot in previousEpoch.startSlot()..= validator.penalizedEpoch + penalizedWithdrawalEpochs } else { - return currentEpoch >= validator.penalizedEpoch + MIN_VALIDATOR_WITHDRAWAL_EPOCHS + return currentEpoch >= validator.penalizedEpoch + MIN_VALIDATOR_WITHDRAWAL_DELAY } } @@ -686,7 +686,7 @@ extension StateTransition { for i in eligibleIndices { BeaconChain.prepareValidatorForWithdrawal(state: &state, index: ValidatorIndex(i)) withdrawan += 1 - if withdrawan >= MAX_WITHDRAWALS_PER_EPOCH { + if withdrawan >= MAX_EXIT_DEQUEUES_PER_EPOCH { break } } From 6fc795f5237684090ace37cc7bdaeb6f35fb2fd7 Mon Sep 17 00:00:00 2001 From: decanus Date: Sun, 24 Feb 2019 22:17:51 +0100 Subject: [PATCH 02/16] data structure updates --- Sources/BeaconChain/BeaconChain.swift | 54 +++++++++---------- .../Blocks/BeaconBlockBody.swift | 3 +- .../DataStructures/State/BeaconState.swift | 17 +++--- .../DataStructures/State/Validator.swift | 4 +- .../Attestations/Attestation.swift | 0 .../Attestations/AttestationData.swift | 0 .../AttestationDataAndCustodyBit.swift | 0 .../AttesterSlashings/AttesterSlashing.swift | 0 .../SlashableAttestation.swift | 0 .../Deposits/Deposit.swift | 0 .../Deposits/DepositData.swift | 0 .../Deposits/DepositInput.swift | 0 .../ProposerSlashing.swift | 0 .../Transactions/Transfer.swift | 11 ++++ .../VoluntaryExit.swift} | 2 +- Sources/BeaconChain/StateTransition.swift | 40 +++++++------- Tests/BeaconChainTests/BeaconChainTests.swift | 8 +-- .../DataStructures/State/ValidatorTests.swift | 4 +- .../Extensions/Array+ValidatorTests.swift | 4 +- 19 files changed, 80 insertions(+), 67 deletions(-) rename Sources/BeaconChain/DataStructures/{Operations => Transactions}/Attestations/Attestation.swift (100%) rename Sources/BeaconChain/DataStructures/{Operations => Transactions}/Attestations/AttestationData.swift (100%) rename Sources/BeaconChain/DataStructures/{Operations => Transactions}/Attestations/AttestationDataAndCustodyBit.swift (100%) rename Sources/BeaconChain/DataStructures/{Operations => Transactions}/AttesterSlashings/AttesterSlashing.swift (100%) rename Sources/BeaconChain/DataStructures/{Operations => Transactions}/AttesterSlashings/SlashableAttestation.swift (100%) rename Sources/BeaconChain/DataStructures/{Operations => Transactions}/Deposits/Deposit.swift (100%) rename Sources/BeaconChain/DataStructures/{Operations => Transactions}/Deposits/DepositData.swift (100%) rename Sources/BeaconChain/DataStructures/{Operations => Transactions}/Deposits/DepositInput.swift (100%) rename Sources/BeaconChain/DataStructures/{Operations => Transactions}/ProposerSlashing.swift (100%) create mode 100644 Sources/BeaconChain/DataStructures/Transactions/Transfer.swift rename Sources/BeaconChain/DataStructures/{Operations/Exit.swift => Transactions/VoluntaryExit.swift} (80%) diff --git a/Sources/BeaconChain/BeaconChain.swift b/Sources/BeaconChain/BeaconChain.swift index e05afa7..f905944 100644 --- a/Sources/BeaconChain/BeaconChain.swift +++ b/Sources/BeaconChain/BeaconChain.swift @@ -86,12 +86,12 @@ extension BeaconChain { } static func getPreviousEpochCommitteeCount(state: BeaconState) -> Int { - let previousActiveValidators = state.validatorRegistry.activeIndices(epoch: state.previousCalculationEpoch) + let previousActiveValidators = state.validatorRegistry.activeIndices(epoch: state.previousShufflingEpoch) return getEpochCommitteeCount(activeValidatorCount: previousActiveValidators.count) } static func getCurrentEpochCommitteeCount(state: BeaconState) -> Int { - let currentActiveValidators = state.validatorRegistry.activeIndices(epoch: state.currentCalculationEpoch) + let currentActiveValidators = state.validatorRegistry.activeIndices(epoch: state.currentShufflingEpoch) return getEpochCommitteeCount(activeValidatorCount: currentActiveValidators.count) } @@ -119,14 +119,14 @@ extension BeaconChain { if epoch == previousEpoch { committeesPerEpoch = getPreviousEpochCommitteeCount(state: state) - seed = state.previousEpochSeed - shufflingEpoch = state.previousCalculationEpoch - shufflingStartShard = state.previousEpochStartShard + seed = state.previousShufflingSeed + shufflingEpoch = state.previousShufflingEpoch + shufflingStartShard = state.previousShufflingStartShard } else if epoch == currentEpoch { committeesPerEpoch = getCurrentEpochCommitteeCount(state: state) - seed = state.currentEpochSeed - shufflingEpoch = state.currentCalculationEpoch - shufflingStartShard = state.currentEpochStartShard + seed = state.currentShufflingSeed + shufflingEpoch = state.currentShufflingEpoch + shufflingStartShard = state.currentShufflingStartShard } else if epoch == nextEpoch { let currentCommitteesPerEpoch = getCurrentEpochCommitteeCount(state: state) committeesPerEpoch = getNextEpochCommitteeCount(state: state) @@ -134,13 +134,13 @@ extension BeaconChain { let epochsSinceLastRegistryUpdate = currentEpoch - state.validatorRegistryUpdateEpoch if registryChange { seed = generateSeed(state: state, epoch: nextEpoch) - shufflingStartShard = (state.currentEpochStartShard + UInt64(currentCommitteesPerEpoch)) % SHARD_COUNT + shufflingStartShard = (state.currentShufflingStartShard + UInt64(currentCommitteesPerEpoch)) % SHARD_COUNT } else if epochsSinceLastRegistryUpdate > 1 && Int(epochsSinceLastRegistryUpdate).isPowerOfTwo() { seed = generateSeed(state: state, epoch: nextEpoch) - shufflingStartShard = state.currentEpochStartShard + shufflingStartShard = state.currentShufflingStartShard } else { - seed = state.currentEpochSeed - shufflingStartShard = state.currentEpochStartShard + seed = state.currentShufflingSeed + shufflingStartShard = state.currentShufflingStartShard } } @@ -177,7 +177,7 @@ extension BeaconChain { static func getActiveIndexRoot(state: BeaconState, epoch: EpochNumber) -> Bytes32 { let currentEpoch = getCurrentEpoch(state: state) assert(currentEpoch - LATEST_ACTIVE_INDEX_ROOTS_LENGTH + ACTIVATION_EXIT_DELAY < epoch && epoch <= currentEpoch + ACTIVATION_EXIT_DELAY) - return state.latestIndexRoots[Int(epoch % LATEST_ACTIVE_INDEX_ROOTS_LENGTH)] + return state.latestActiveIndexRoots[Int(epoch % LATEST_ACTIVE_INDEX_ROOTS_LENGTH)] } } @@ -363,10 +363,10 @@ extension BeaconChain { } } - state.latestIndexRoots[Int(GENESIS_EPOCH % LATEST_ACTIVE_INDEX_ROOTS_LENGTH)] = hashTreeRoot( + state.latestActiveIndexRoots[Int(GENESIS_EPOCH % LATEST_ACTIVE_INDEX_ROOTS_LENGTH)] = hashTreeRoot( state.validatorRegistry.activeIndices(epoch: GENESIS_EPOCH) ) - state.currentEpochSeed = generateSeed(state: state, epoch: GENESIS_EPOCH) + state.currentShufflingSeed = generateSeed(state: state, epoch: GENESIS_EPOCH) return state } @@ -384,20 +384,20 @@ extension BeaconChain { validatorBalances: [UInt64](), validatorRegistryUpdateEpoch: GENESIS_EPOCH, latestRandaoMixes: [Data](repeating: ZERO_HASH, count: Int(LATEST_RANDAO_MIXES_LENGTH)), - previousEpochStartShard: GENESIS_START_SHARD, - currentEpochStartShard: GENESIS_START_SHARD, - previousCalculationEpoch: GENESIS_EPOCH, - currentCalculationEpoch: GENESIS_EPOCH, - previousEpochSeed: ZERO_HASH, - currentEpochSeed: ZERO_HASH, + previousShufflingStartShard: GENESIS_START_SHARD, + currentShufflingStartShard: GENESIS_START_SHARD, + previousShufflingEpoch: GENESIS_EPOCH, + currentShufflingEpoch: GENESIS_EPOCH, + previousShufflingSeed: ZERO_HASH, + currentShufflingSeed: ZERO_HASH, previousJustifiedEpoch: GENESIS_EPOCH, justifiedEpoch: GENESIS_EPOCH, justificationBitfield: 0, finalizedEpoch: GENESIS_EPOCH, latestCrosslinks: [Crosslink](repeating: Crosslink(epoch: GENESIS_EPOCH, shardBlockRoot: ZERO_HASH), count: Int(SHARD_COUNT)), latestBlockRoots: [Data](repeating: ZERO_HASH, count: Int(LATEST_BLOCK_ROOTS_LENGTH)), - latestIndexRoots: [Data](repeating: ZERO_HASH, count: Int(LATEST_ACTIVE_INDEX_ROOTS_LENGTH)), - latestPenalizedBalances: [UInt64](repeating: 0, count: Int(LATEST_SLASHED_EXIT_LENGTH)), + latestActiveIndexRoots: [Data](repeating: ZERO_HASH, count: Int(LATEST_ACTIVE_INDEX_ROOTS_LENGTH)), + latestSlashedBalances: [UInt64](repeating: 0, count: Int(LATEST_SLASHED_EXIT_LENGTH)), latestAttestations: [PendingAttestation](), batchedBlockRoots: [Data](), latestEth1Data: latestEth1Data, @@ -453,8 +453,8 @@ extension BeaconChain { withdrawalCredentials: withdrawalCredentials, activationEpoch: FAR_FUTURE_EPOCH, exitEpoch: FAR_FUTURE_EPOCH, - withdrawalEpoch: FAR_FUTURE_EPOCH, - penalizedEpoch: FAR_FUTURE_EPOCH, + withdrawableEpoch: FAR_FUTURE_EPOCH, + slashedEpoch: FAR_FUTURE_EPOCH, statusFlags: 0 ) @@ -487,14 +487,14 @@ extension BeaconChain { static func penalizeValidator(state: inout BeaconState, index: ValidatorIndex) { exitValidator(state: &state, index: index) - state.latestPenalizedBalances[Int(getCurrentEpoch(state: state) % LATEST_SLASHED_EXIT_LENGTH)] += getEffectiveBalance(state: state, index: index) + 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.validatorRegistry[Int(index)].penalizedEpoch = getCurrentEpoch(state: state) + state.validatorRegistry[Int(index)].slashedEpoch = getCurrentEpoch(state: state) } static func prepareValidatorForWithdrawal(state: inout BeaconState, index: ValidatorIndex) { diff --git a/Sources/BeaconChain/DataStructures/Blocks/BeaconBlockBody.swift b/Sources/BeaconChain/DataStructures/Blocks/BeaconBlockBody.swift index 9c0fc7d..5d9ca4c 100644 --- a/Sources/BeaconChain/DataStructures/Blocks/BeaconBlockBody.swift +++ b/Sources/BeaconChain/DataStructures/Blocks/BeaconBlockBody.swift @@ -5,5 +5,6 @@ struct BeaconBlockBody { let attesterSlashings: [AttesterSlashing] let attestations: [Attestation] let deposits: [Deposit] - let exits: [Exit] + let voluntaryExits: [VoluntaryExit] + let transfers: [Transfer] } diff --git a/Sources/BeaconChain/DataStructures/State/BeaconState.swift b/Sources/BeaconChain/DataStructures/State/BeaconState.swift index 1c83ca9..e2406a7 100644 --- a/Sources/BeaconChain/DataStructures/State/BeaconState.swift +++ b/Sources/BeaconChain/DataStructures/State/BeaconState.swift @@ -10,12 +10,12 @@ struct BeaconState { var validatorRegistryUpdateEpoch: UInt64 var latestRandaoMixes: [Data] - var previousEpochStartShard: UInt64 - let currentEpochStartShard: UInt64 - var previousCalculationEpoch: UInt64 - var currentCalculationEpoch: UInt64 - var previousEpochSeed: Data - var currentEpochSeed: Data + var previousShufflingStartShard: UInt64 + let currentShufflingStartShard: UInt64 + var previousShufflingEpoch: UInt64 + var currentShufflingEpoch: UInt64 + var previousShufflingSeed: Data + var currentShufflingSeed: Data var previousJustifiedEpoch: UInt64 var justifiedEpoch: UInt64 @@ -24,11 +24,12 @@ struct BeaconState { var latestCrosslinks: [Crosslink] var latestBlockRoots: [Data] - var latestIndexRoots: [Data] - var latestPenalizedBalances: [UInt64] + var latestActiveIndexRoots: [Data] + var latestSlashedBalances: [UInt64] var latestAttestations: [PendingAttestation] var batchedBlockRoots: [Data] var latestEth1Data: Eth1Data var eth1DataVotes: [Eth1DataVote] + let depositIndex: UInt64 } diff --git a/Sources/BeaconChain/DataStructures/State/Validator.swift b/Sources/BeaconChain/DataStructures/State/Validator.swift index 93aa899..192a63b 100644 --- a/Sources/BeaconChain/DataStructures/State/Validator.swift +++ b/Sources/BeaconChain/DataStructures/State/Validator.swift @@ -5,8 +5,8 @@ struct Validator { let withdrawalCredentials: Data var activationEpoch: UInt64 var exitEpoch: UInt64 - let withdrawalEpoch: UInt64 - var penalizedEpoch: UInt64 + let withdrawableEpoch: UInt64 + var slashedEpoch: UInt64 var statusFlags: UInt64 func isActive(epoch: EpochNumber) -> Bool { diff --git a/Sources/BeaconChain/DataStructures/Operations/Attestations/Attestation.swift b/Sources/BeaconChain/DataStructures/Transactions/Attestations/Attestation.swift similarity index 100% rename from Sources/BeaconChain/DataStructures/Operations/Attestations/Attestation.swift rename to Sources/BeaconChain/DataStructures/Transactions/Attestations/Attestation.swift diff --git a/Sources/BeaconChain/DataStructures/Operations/Attestations/AttestationData.swift b/Sources/BeaconChain/DataStructures/Transactions/Attestations/AttestationData.swift similarity index 100% rename from Sources/BeaconChain/DataStructures/Operations/Attestations/AttestationData.swift rename to Sources/BeaconChain/DataStructures/Transactions/Attestations/AttestationData.swift diff --git a/Sources/BeaconChain/DataStructures/Operations/Attestations/AttestationDataAndCustodyBit.swift b/Sources/BeaconChain/DataStructures/Transactions/Attestations/AttestationDataAndCustodyBit.swift similarity index 100% rename from Sources/BeaconChain/DataStructures/Operations/Attestations/AttestationDataAndCustodyBit.swift rename to Sources/BeaconChain/DataStructures/Transactions/Attestations/AttestationDataAndCustodyBit.swift diff --git a/Sources/BeaconChain/DataStructures/Operations/AttesterSlashings/AttesterSlashing.swift b/Sources/BeaconChain/DataStructures/Transactions/AttesterSlashings/AttesterSlashing.swift similarity index 100% rename from Sources/BeaconChain/DataStructures/Operations/AttesterSlashings/AttesterSlashing.swift rename to Sources/BeaconChain/DataStructures/Transactions/AttesterSlashings/AttesterSlashing.swift diff --git a/Sources/BeaconChain/DataStructures/Operations/AttesterSlashings/SlashableAttestation.swift b/Sources/BeaconChain/DataStructures/Transactions/AttesterSlashings/SlashableAttestation.swift similarity index 100% rename from Sources/BeaconChain/DataStructures/Operations/AttesterSlashings/SlashableAttestation.swift rename to Sources/BeaconChain/DataStructures/Transactions/AttesterSlashings/SlashableAttestation.swift diff --git a/Sources/BeaconChain/DataStructures/Operations/Deposits/Deposit.swift b/Sources/BeaconChain/DataStructures/Transactions/Deposits/Deposit.swift similarity index 100% rename from Sources/BeaconChain/DataStructures/Operations/Deposits/Deposit.swift rename to Sources/BeaconChain/DataStructures/Transactions/Deposits/Deposit.swift diff --git a/Sources/BeaconChain/DataStructures/Operations/Deposits/DepositData.swift b/Sources/BeaconChain/DataStructures/Transactions/Deposits/DepositData.swift similarity index 100% rename from Sources/BeaconChain/DataStructures/Operations/Deposits/DepositData.swift rename to Sources/BeaconChain/DataStructures/Transactions/Deposits/DepositData.swift diff --git a/Sources/BeaconChain/DataStructures/Operations/Deposits/DepositInput.swift b/Sources/BeaconChain/DataStructures/Transactions/Deposits/DepositInput.swift similarity index 100% rename from Sources/BeaconChain/DataStructures/Operations/Deposits/DepositInput.swift rename to Sources/BeaconChain/DataStructures/Transactions/Deposits/DepositInput.swift diff --git a/Sources/BeaconChain/DataStructures/Operations/ProposerSlashing.swift b/Sources/BeaconChain/DataStructures/Transactions/ProposerSlashing.swift similarity index 100% rename from Sources/BeaconChain/DataStructures/Operations/ProposerSlashing.swift rename to Sources/BeaconChain/DataStructures/Transactions/ProposerSlashing.swift diff --git a/Sources/BeaconChain/DataStructures/Transactions/Transfer.swift b/Sources/BeaconChain/DataStructures/Transactions/Transfer.swift new file mode 100644 index 0000000..bd1678e --- /dev/null +++ b/Sources/BeaconChain/DataStructures/Transactions/Transfer.swift @@ -0,0 +1,11 @@ +import Foundation + +struct Transfer { + let from: UInt64 + let to: UInt64 + let amount: UInt64 + let fee: UInt64 + let slot: UInt64 + let pubkey: Data + let signature: Data +} diff --git a/Sources/BeaconChain/DataStructures/Operations/Exit.swift b/Sources/BeaconChain/DataStructures/Transactions/VoluntaryExit.swift similarity index 80% rename from Sources/BeaconChain/DataStructures/Operations/Exit.swift rename to Sources/BeaconChain/DataStructures/Transactions/VoluntaryExit.swift index 6bc546e..da533ab 100644 --- a/Sources/BeaconChain/DataStructures/Operations/Exit.swift +++ b/Sources/BeaconChain/DataStructures/Transactions/VoluntaryExit.swift @@ -1,6 +1,6 @@ import Foundation -struct Exit { +struct VoluntaryExit { let epoch: UInt64 let validatorIndex: UInt64 let signature: Data diff --git a/Sources/BeaconChain/StateTransition.swift b/Sources/BeaconChain/StateTransition.swift index 7152011..0936e2f 100644 --- a/Sources/BeaconChain/StateTransition.swift +++ b/Sources/BeaconChain/StateTransition.swift @@ -91,7 +91,7 @@ extension StateTransition { assert(proposerSlashing.proposalData1.slot == proposerSlashing.proposalData2.slot) assert(proposerSlashing.proposalData1.shard == proposerSlashing.proposalData2.shard) assert(proposerSlashing.proposalData1.blockRoot != proposerSlashing.proposalData2.blockRoot) - assert(proposer.penalizedEpoch > epoch) + assert(proposer.slashedEpoch > epoch) assert( BLS.verify( @@ -133,7 +133,7 @@ extension StateTransition { let slashableIndices = slashableAttestation1.validatorIndices.filter { slashableAttestation2.validatorIndices.contains($0) - && state.validatorRegistry[Int($0)].penalizedEpoch > BeaconChain.getCurrentEpoch(state: state) + && state.validatorRegistry[Int($0)].slashedEpoch > BeaconChain.getCurrentEpoch(state: state) } assert(slashableIndices.count >= 1) @@ -254,9 +254,9 @@ extension StateTransition { } static func exits(state: inout BeaconState, block: BeaconBlock) { - assert(block.body.exits.count <= MAX_VOLUNTARY_EXITS) + assert(block.body.voluntaryExits.count <= MAX_VOLUNTARY_EXITS) - for exit in block.body.exits { + for exit in block.body.voluntaryExits { let validator = state.validatorRegistry[Int(exit.validatorIndex)] let epoch = BeaconChain.getCurrentEpoch(state: state) @@ -264,7 +264,7 @@ extension StateTransition { assert(epoch >= exit.epoch) let exitMessage = BeaconChain.hashTreeRoot( - Exit(epoch: exit.epoch, validatorIndex: exit.validatorIndex, signature: EMPTY_SIGNATURE) + VoluntaryExit(epoch: exit.epoch, validatorIndex: exit.validatorIndex, signature: EMPTY_SIGNATURE) ) assert( @@ -404,7 +404,7 @@ extension StateTransition { shufflingSeedData(state: &state, nextEpoch: nextEpoch) let shards = (0.. state.validatorRegistryUpdateEpoch && shards.count == 0 { @@ -412,18 +412,18 @@ extension StateTransition { } else { let epochsSinceLastRegistryUpdate = currentEpoch - state.validatorRegistryUpdateEpoch if epochsSinceLastRegistryUpdate > 1 && Int(epochsSinceLastRegistryUpdate).isPowerOfTwo() { - state.currentCalculationEpoch = nextEpoch - state.currentEpochSeed = BeaconChain.generateSeed(state: state, epoch: state.currentCalculationEpoch) + state.currentShufflingEpoch = nextEpoch + state.currentShufflingSeed = BeaconChain.generateSeed(state: state, epoch: state.currentShufflingEpoch) } } processPenaltiesAndExit(state: &state) - state.latestIndexRoots[Int((nextEpoch % ACTIVATION_EXIT_DELAY) % LATEST_ACTIVE_INDEX_ROOTS_LENGTH)] = BeaconChain.hashTreeRoot( + state.latestActiveIndexRoots[Int((nextEpoch % ACTIVATION_EXIT_DELAY) % LATEST_ACTIVE_INDEX_ROOTS_LENGTH)] = BeaconChain.hashTreeRoot( state.validatorRegistry.activeIndices(epoch: nextEpoch + ACTIVATION_EXIT_DELAY) ) - state.latestPenalizedBalances[Int(nextEpoch % LATEST_SLASHED_EXIT_LENGTH)] = state.latestPenalizedBalances[Int(currentEpoch % LATEST_SLASHED_EXIT_LENGTH)] + state.latestSlashedBalances[Int(nextEpoch % LATEST_SLASHED_EXIT_LENGTH)] = state.latestSlashedBalances[Int(currentEpoch % LATEST_SLASHED_EXIT_LENGTH)] state.latestRandaoMixes[Int(nextEpoch % LATEST_RANDAO_MIXES_LENGTH)] = BeaconChain.getRandaoMix( state: state, epoch: currentEpoch @@ -603,7 +603,7 @@ extension StateTransition { activeValidators.forEach({ index in - if state.validatorRegistry[Int(index)].penalizedEpoch <= currentEpoch { + if state.validatorRegistry[Int(index)].slashedEpoch <= currentEpoch { state.validatorBalances[Int(index)] -= 2 * inactivityPenalty(state: state, index: index, epochsSinceFinality: epochsSinceFinality, baseRewardQuotient: baseRewardQuotient) + baseReward(state: state, index: index, baseRewardQuotient: baseRewardQuotient) } }) @@ -656,13 +656,13 @@ extension StateTransition { let totalBalance = activeValidatorIndices.totalBalance(state: state) for (i, v) in state.validatorRegistry.enumerated() { - if currentEpoch != v.penalizedEpoch + LATEST_SLASHED_EXIT_LENGTH / 2 { + if currentEpoch != v.slashedEpoch + LATEST_SLASHED_EXIT_LENGTH / 2 { continue } let epochIndex = currentEpoch % LATEST_SLASHED_EXIT_LENGTH - let totalAtStart = state.latestPenalizedBalances[Int((epochIndex + 1) % LATEST_SLASHED_EXIT_LENGTH)] - let totalAtEnd = state.latestPenalizedBalances[Int(epochIndex)] + let totalAtStart = state.latestSlashedBalances[Int((epochIndex + 1) % LATEST_SLASHED_EXIT_LENGTH)] + let totalAtEnd = state.latestSlashedBalances[Int(epochIndex)] let totalPenalties = totalAtEnd - totalAtStart let penalty = BeaconChain.getEffectiveBalance(state: state, index: ValidatorIndex(i)) * min(totalPenalties * 3, totalBalance) / totalBalance state.validatorBalances[i] -= penalty @@ -670,11 +670,11 @@ extension StateTransition { var eligibleIndices = (0..= validator.penalizedEpoch + penalizedWithdrawalEpochs + return currentEpoch >= validator.slashedEpoch + penalizedWithdrawalEpochs } else { - return currentEpoch >= validator.penalizedEpoch + MIN_VALIDATOR_WITHDRAWAL_DELAY + return currentEpoch >= validator.slashedEpoch + MIN_VALIDATOR_WITHDRAWAL_DELAY } } @@ -727,9 +727,9 @@ extension StateTransition { } static func shufflingSeedData(state: inout BeaconState, nextEpoch: EpochNumber) { - state.previousCalculationEpoch = state.currentCalculationEpoch - state.previousEpochSeed = state.currentEpochSeed - state.previousEpochStartShard = state.currentEpochStartShard + state.previousShufflingEpoch = state.currentShufflingEpoch + state.previousShufflingSeed = state.currentShufflingSeed + state.previousShufflingStartShard = state.currentShufflingStartShard } static func processEjections(state: inout BeaconState) { diff --git a/Tests/BeaconChainTests/BeaconChainTests.swift b/Tests/BeaconChainTests/BeaconChainTests.swift index 7ee8d1a..4bf714f 100644 --- a/Tests/BeaconChainTests/BeaconChainTests.swift +++ b/Tests/BeaconChainTests/BeaconChainTests.swift @@ -91,8 +91,8 @@ final class BeaconChainTests: XCTestCase { withdrawalCredentials: Data(count: 32), activationEpoch: 0, exitEpoch: 0, - withdrawalEpoch: 0, - penalizedEpoch: 0, + withdrawableEpoch: 0, + slashedEpoch: 0, statusFlags: 0 ) ) @@ -117,8 +117,8 @@ final class BeaconChainTests: XCTestCase { withdrawalCredentials: Data(count: 32), activationEpoch: 0, exitEpoch: 0, - withdrawalEpoch: 0, - penalizedEpoch: 0, + withdrawableEpoch: 0, + slashedEpoch: 0, statusFlags: 0 ) ) diff --git a/Tests/BeaconChainTests/DataStructures/State/ValidatorTests.swift b/Tests/BeaconChainTests/DataStructures/State/ValidatorTests.swift index 5477051..ef5550c 100644 --- a/Tests/BeaconChainTests/DataStructures/State/ValidatorTests.swift +++ b/Tests/BeaconChainTests/DataStructures/State/ValidatorTests.swift @@ -17,8 +17,8 @@ final class ValidatorTests: XCTestCase { withdrawalCredentials: ZERO_HASH, activationEpoch: epoch - 1, exitEpoch: epoch + 1, - withdrawalEpoch: epoch, - penalizedEpoch: epoch, + withdrawableEpoch: epoch, + slashedEpoch: epoch, statusFlags: 0 ) } diff --git a/Tests/BeaconChainTests/Extensions/Array+ValidatorTests.swift b/Tests/BeaconChainTests/Extensions/Array+ValidatorTests.swift index 5e30457..8c32ecd 100644 --- a/Tests/BeaconChainTests/Extensions/Array+ValidatorTests.swift +++ b/Tests/BeaconChainTests/Extensions/Array+ValidatorTests.swift @@ -22,8 +22,8 @@ final class ArrayValidatorTests: XCTestCase { withdrawalCredentials: ZERO_HASH, activationEpoch: epoch - 1, exitEpoch: epoch + 1, - withdrawalEpoch: 1, - penalizedEpoch: 0, + withdrawableEpoch: 1, + slashedEpoch: 0, statusFlags: 0 ) } From 24eba376c2a1bf9f9896fa822750b259ac145ed8 Mon Sep 17 00:00:00 2001 From: decanus Date: Sun, 24 Feb 2019 22:19:18 +0100 Subject: [PATCH 03/16] typealias updates --- Sources/BeaconChain/BeaconChain.swift | 24 +++++++++---------- .../DataStructures/State/Validator.swift | 2 +- .../Attestations/AttestationData.swift | 4 ++-- .../Extensions/Array+Validator.swift | 2 +- .../{EpochNumber.swift => Epoch.swift} | 6 ++--- .../{SlotNumber.swift => Slot.swift} | 4 ++-- Sources/BeaconChain/StateTransition.swift | 20 ++++++++-------- Sources/BeaconChain/Types.swift | 6 ++--- .../DataStructures/State/ValidatorTests.swift | 2 +- .../Extensions/Array+ValidatorTests.swift | 2 +- 10 files changed, 36 insertions(+), 36 deletions(-) rename Sources/BeaconChain/Extensions/{EpochNumber.swift => Epoch.swift} (53%) rename Sources/BeaconChain/Extensions/{SlotNumber.swift => Slot.swift} (52%) diff --git a/Sources/BeaconChain/BeaconChain.swift b/Sources/BeaconChain/BeaconChain.swift index f905944..4079f9d 100644 --- a/Sources/BeaconChain/BeaconChain.swift +++ b/Sources/BeaconChain/BeaconChain.swift @@ -19,7 +19,7 @@ class BeaconChain { extension BeaconChain { - static func getPreviousEpoch(state: BeaconState) -> EpochNumber { + static func getPreviousEpoch(state: BeaconState) -> Epoch { let currentEpoch = getCurrentEpoch(state: state) if currentEpoch == GENESIS_EPOCH { return GENESIS_EPOCH @@ -28,7 +28,7 @@ extension BeaconChain { return currentEpoch - 1 } - static func getCurrentEpoch(state: BeaconState) -> EpochNumber { + static func getCurrentEpoch(state: BeaconState) -> Epoch { return state.slot.toEpoch() } } @@ -59,7 +59,7 @@ extension BeaconChain { return index } - static func getShuffling(seed: Bytes32, validators: [Validator], epoch: EpochNumber) -> [[ValidatorIndex]] { + static func getShuffling(seed: Bytes32, validators: [Validator], epoch: Epoch) -> [[ValidatorIndex]] { let activeValidatorIndices = validators.activeIndices(epoch: epoch) let committeesPerEpoch = getEpochCommitteeCount(activeValidatorCount: validators.count) @@ -102,9 +102,9 @@ extension BeaconChain { static func getCrosslinkCommitteesAtSlot( state: BeaconState, - slot: SlotNumber, + slot: Slot, registryChange: Bool = false - ) -> [([ValidatorIndex], ShardNumber)] { + ) -> [([ValidatorIndex], Shard)] { let epoch = slot.toEpoch() let currentEpoch = getCurrentEpoch(state: state) let previousEpoch = getPreviousEpoch(state: state) @@ -162,19 +162,19 @@ extension BeaconChain { extension BeaconChain { - static func getBlockRoot(state: BeaconState, slot: SlotNumber) -> Bytes32 { + static func getBlockRoot(state: BeaconState, slot: Slot) -> Bytes32 { assert(state.slot <= slot + LATEST_BLOCK_ROOTS_LENGTH) assert(slot < state.slot) return state.latestBlockRoots[Int(slot % LATEST_BLOCK_ROOTS_LENGTH)] } - static func getRandaoMix(state: BeaconState, epoch: EpochNumber) -> Bytes32 { + static func getRandaoMix(state: BeaconState, epoch: Epoch) -> Bytes32 { let currentEpoch = getCurrentEpoch(state: state) assert(currentEpoch - LATEST_RANDAO_MIXES_LENGTH < epoch && epoch <= currentEpoch) return state.latestRandaoMixes[Int(epoch % LATEST_RANDAO_MIXES_LENGTH)] } - static func getActiveIndexRoot(state: BeaconState, epoch: EpochNumber) -> Bytes32 { + static func getActiveIndexRoot(state: BeaconState, epoch: Epoch) -> Bytes32 { let currentEpoch = getCurrentEpoch(state: state) 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)] @@ -183,7 +183,7 @@ extension BeaconChain { extension BeaconChain { - static func generateSeed(state: BeaconState, epoch: EpochNumber) -> Data { + static func generateSeed(state: BeaconState, epoch: Epoch) -> Data { return hash( getRandaoMix(state: state, epoch: epoch - MIN_SEED_LOOKAHEAD) + getActiveIndexRoot(state: state, epoch: epoch) + @@ -191,7 +191,7 @@ extension BeaconChain { ) } - static func getBeaconProposerIndex(state: BeaconState, slot: SlotNumber) -> ValidatorIndex { + static func getBeaconProposerIndex(state: BeaconState, slot: Slot) -> ValidatorIndex { let (firstCommittee, _) = getCrosslinkCommitteesAtSlot(state: state, slot: slot)[0] return firstCommittee[Int(slot) % firstCommittee.count] } @@ -238,7 +238,7 @@ extension BeaconChain { return min(state.validatorBalances[Int(index)], MAX_DEPOSIT_AMOUNT) } - static func getForkVersion(fork: Fork, epoch: EpochNumber) -> UInt64 { + static func getForkVersion(fork: Fork, epoch: Epoch) -> UInt64 { if epoch < fork.epoch { return fork.previousVersion } @@ -246,7 +246,7 @@ extension BeaconChain { return fork.currentVersion } - static func getDomain(fork: Fork, epoch: EpochNumber, domainType: Domain) -> UInt64 { + static func getDomain(fork: Fork, epoch: Epoch, domainType: Domain) -> UInt64 { return getForkVersion(fork: fork, epoch: epoch) * 2 ** 32 + domainType.rawValue } diff --git a/Sources/BeaconChain/DataStructures/State/Validator.swift b/Sources/BeaconChain/DataStructures/State/Validator.swift index 192a63b..5a19867 100644 --- a/Sources/BeaconChain/DataStructures/State/Validator.swift +++ b/Sources/BeaconChain/DataStructures/State/Validator.swift @@ -9,7 +9,7 @@ struct Validator { var slashedEpoch: UInt64 var statusFlags: UInt64 - func isActive(epoch: EpochNumber) -> Bool { + func isActive(epoch: Epoch) -> Bool { return self.activationEpoch <= epoch && epoch < self.exitEpoch } } diff --git a/Sources/BeaconChain/DataStructures/Transactions/Attestations/AttestationData.swift b/Sources/BeaconChain/DataStructures/Transactions/Attestations/AttestationData.swift index c631632..20bcf5e 100644 --- a/Sources/BeaconChain/DataStructures/Transactions/Attestations/AttestationData.swift +++ b/Sources/BeaconChain/DataStructures/Transactions/Attestations/AttestationData.swift @@ -1,12 +1,12 @@ import Foundation struct AttestationData: Equatable { - let slot: SlotNumber + let slot: Slot let shard: UInt64 let beaconBlockRoot: Data let epochBoundaryRoot: Data let shardBlockRoot: Data let latestCrosslink: Crosslink - let justifiedEpoch: EpochNumber + let justifiedEpoch: Epoch let justifiedBlockRoot: Data } diff --git a/Sources/BeaconChain/Extensions/Array+Validator.swift b/Sources/BeaconChain/Extensions/Array+Validator.swift index be13d54..c27c903 100644 --- a/Sources/BeaconChain/Extensions/Array+Validator.swift +++ b/Sources/BeaconChain/Extensions/Array+Validator.swift @@ -2,7 +2,7 @@ import Foundation extension Array where Element == Validator { - func activeIndices(epoch: EpochNumber) -> [ValidatorIndex] { + func activeIndices(epoch: Epoch) -> [ValidatorIndex] { return enumerated().compactMap { (k, v) in if v.isActive(epoch: epoch) { diff --git a/Sources/BeaconChain/Extensions/EpochNumber.swift b/Sources/BeaconChain/Extensions/Epoch.swift similarity index 53% rename from Sources/BeaconChain/Extensions/EpochNumber.swift rename to Sources/BeaconChain/Extensions/Epoch.swift index 02cc6a2..90ffda2 100644 --- a/Sources/BeaconChain/Extensions/EpochNumber.swift +++ b/Sources/BeaconChain/Extensions/Epoch.swift @@ -1,12 +1,12 @@ import Foundation -extension EpochNumber { +extension Epoch { - func startSlot() -> SlotNumber { + func startSlot() -> Slot { return self * SLOTS_PER_EPOCH } - func entryExitEpoch() -> EpochNumber { + func entryExitEpoch() -> Epoch { return self + 1 + ACTIVATION_EXIT_DELAY } } diff --git a/Sources/BeaconChain/Extensions/SlotNumber.swift b/Sources/BeaconChain/Extensions/Slot.swift similarity index 52% rename from Sources/BeaconChain/Extensions/SlotNumber.swift rename to Sources/BeaconChain/Extensions/Slot.swift index 3fb73ba..77179c6 100644 --- a/Sources/BeaconChain/Extensions/SlotNumber.swift +++ b/Sources/BeaconChain/Extensions/Slot.swift @@ -1,8 +1,8 @@ import Foundation -extension SlotNumber { +extension Slot { - func toEpoch() -> EpochNumber { + func toEpoch() -> Epoch { return self / SLOTS_PER_EPOCH } } diff --git a/Sources/BeaconChain/StateTransition.swift b/Sources/BeaconChain/StateTransition.swift index 0936e2f..2cc1f0a 100644 --- a/Sources/BeaconChain/StateTransition.swift +++ b/Sources/BeaconChain/StateTransition.swift @@ -436,7 +436,7 @@ extension StateTransition { } } - private static func eth1data(state: inout BeaconState, nextEpoch: EpochNumber) { + private static func eth1data(state: inout BeaconState, nextEpoch: Epoch) { if nextEpoch % EPOCHS_PER_ETH1_VOTING_PERIOD != 0 { return } @@ -452,8 +452,8 @@ extension StateTransition { private static func justification( state: inout BeaconState, - previousEpoch: EpochNumber, - currentEpoch: EpochNumber, + previousEpoch: Epoch, + currentEpoch: Epoch, previousTotalBalance: Gwei, previousEpochBoundaryAttestingBalance: Gwei, currentTotalBalance: Gwei, @@ -494,9 +494,9 @@ extension StateTransition { private static func crosslink( state: inout BeaconState, - previousEpoch: EpochNumber, - currentEpoch: EpochNumber, - nextEpoch: EpochNumber, + previousEpoch: Epoch, + currentEpoch: Epoch, + nextEpoch: Epoch, currentEpochAttestations: [PendingAttestation], previousEpochAttestations: [PendingAttestation] ) { @@ -525,9 +525,9 @@ extension StateTransition { private static func rewardsAndPenalties( state: inout BeaconState, - previousEpoch: EpochNumber, - currentEpoch: EpochNumber, - nextEpoch: EpochNumber, + previousEpoch: Epoch, + currentEpoch: Epoch, + nextEpoch: Epoch, previousTotalBalance: Gwei, totalBalance: UInt64, previousEpochJustifiedAttesterIndices: [ValidatorIndex], @@ -726,7 +726,7 @@ extension StateTransition { state.validatorRegistryUpdateEpoch = currentEpoch } - static func shufflingSeedData(state: inout BeaconState, nextEpoch: EpochNumber) { + static func shufflingSeedData(state: inout BeaconState, nextEpoch: Epoch) { state.previousShufflingEpoch = state.currentShufflingEpoch state.previousShufflingSeed = state.currentShufflingSeed state.previousShufflingStartShard = state.currentShufflingStartShard diff --git a/Sources/BeaconChain/Types.swift b/Sources/BeaconChain/Types.swift index ca18745..7e02de6 100644 --- a/Sources/BeaconChain/Types.swift +++ b/Sources/BeaconChain/Types.swift @@ -1,8 +1,8 @@ import Foundation -typealias SlotNumber = UInt64 -typealias EpochNumber = UInt64 -typealias ShardNumber = UInt64 +typealias Slot = UInt64 +typealias Epoch = UInt64 +typealias Shard = UInt64 typealias ValidatorIndex = UInt64 typealias Gwei = UInt64 typealias Bytes32 = Data // @todo needs to be 32 fixed length data diff --git a/Tests/BeaconChainTests/DataStructures/State/ValidatorTests.swift b/Tests/BeaconChainTests/DataStructures/State/ValidatorTests.swift index ef5550c..c6e6b04 100644 --- a/Tests/BeaconChainTests/DataStructures/State/ValidatorTests.swift +++ b/Tests/BeaconChainTests/DataStructures/State/ValidatorTests.swift @@ -11,7 +11,7 @@ final class ValidatorTests: XCTestCase { } - private func createValidator(epoch: EpochNumber) -> Validator { + private func createValidator(epoch: Epoch) -> Validator { return Validator( pubkey: ZERO_HASH, withdrawalCredentials: ZERO_HASH, diff --git a/Tests/BeaconChainTests/Extensions/Array+ValidatorTests.swift b/Tests/BeaconChainTests/Extensions/Array+ValidatorTests.swift index 8c32ecd..a9b4e27 100644 --- a/Tests/BeaconChainTests/Extensions/Array+ValidatorTests.swift +++ b/Tests/BeaconChainTests/Extensions/Array+ValidatorTests.swift @@ -16,7 +16,7 @@ final class ArrayValidatorTests: XCTestCase { XCTAssertEqual(validators.activeIndices(epoch: epoch), [ValidatorIndex(0), 1]) } - private func createValidator(epoch: EpochNumber) -> Validator { + private func createValidator(epoch: Epoch) -> Validator { return Validator( pubkey: ZERO_HASH, withdrawalCredentials: ZERO_HASH, From b6b9804a7c278965944ece9314d6a589ba22c773 Mon Sep 17 00:00:00 2001 From: decanus Date: Sun, 24 Feb 2019 22:21:23 +0100 Subject: [PATCH 04/16] unnecessary self --- Sources/BeaconChain/DataStructures/State/Validator.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/BeaconChain/DataStructures/State/Validator.swift b/Sources/BeaconChain/DataStructures/State/Validator.swift index 5a19867..2139e83 100644 --- a/Sources/BeaconChain/DataStructures/State/Validator.swift +++ b/Sources/BeaconChain/DataStructures/State/Validator.swift @@ -10,6 +10,6 @@ struct Validator { var statusFlags: UInt64 func isActive(epoch: Epoch) -> Bool { - return self.activationEpoch <= epoch && epoch < self.exitEpoch + return activationEpoch <= epoch && epoch < exitEpoch } } From 5010e7fe076bdc9fc3a2bd4756c6acabcba23f58 Mon Sep 17 00:00:00 2001 From: decanus Date: Sun, 24 Feb 2019 22:37:12 +0100 Subject: [PATCH 05/16] updated on genesis --- Sources/BeaconChain/BeaconChain.swift | 55 ++++++++++++------- .../DataStructures/State/Validator.swift | 2 +- Sources/BeaconChain/StateTransition.swift | 4 +- 3 files changed, 39 insertions(+), 22 deletions(-) diff --git a/Sources/BeaconChain/BeaconChain.swift b/Sources/BeaconChain/BeaconChain.swift index 4079f9d..8fb5499 100644 --- a/Sources/BeaconChain/BeaconChain.swift +++ b/Sources/BeaconChain/BeaconChain.swift @@ -38,6 +38,9 @@ extension BeaconChain { // @todo check this shit static func getPermutedIndex(index i: Int, listSize: Int, seed: Bytes32) -> Int { var index = i + + assert(index < listSize) + for round in 0.. Int { - return Int((bitfield[i / 8] >> (7 - (i % 8))) % 2) + return Int((bitfield[i / 8] >> (i % 8))) % 2 } static func verifyBitfield(bitfield: Data, committeeSize: Int) -> Bool { @@ -340,14 +343,18 @@ extension BeaconChain { extension BeaconChain { static func getInitialBeaconState( - initialValidatorDeposits: [Deposit], + genesisValidatorDeposits: [Deposit], genesisTime: UInt64, latestEth1Data: Eth1Data ) -> BeaconState { - var state = genesisState(genesisTime: genesisTime, latestEth1Data: latestEth1Data) + var state = genesisState( + genesisTime: genesisTime, + latestEth1Data: latestEth1Data, + depositLength: genesisValidatorDeposits.count + ) - for deposit in initialValidatorDeposits { + for deposit in genesisValidatorDeposits { processDeposit( state: &state, pubkey: deposit.depositData.depositInput.pubkey, @@ -363,15 +370,18 @@ extension BeaconChain { } } - state.latestActiveIndexRoots[Int(GENESIS_EPOCH % LATEST_ACTIVE_INDEX_ROOTS_LENGTH)] = hashTreeRoot( - state.validatorRegistry.activeIndices(epoch: GENESIS_EPOCH) - ) + let genesisActiveIndexRoot = hashTreeRoot(state.validatorRegistry.activeIndices(epoch: GENESIS_EPOCH)) + + for i in 0.. BeaconState { + static func genesisState(genesisTime: UInt64, latestEth1Data: Eth1Data, depositLength: Int) -> BeaconState { return BeaconState( slot: GENESIS_SLOT, genesisTime: genesisTime, @@ -401,7 +411,8 @@ extension BeaconChain { latestAttestations: [PendingAttestation](), batchedBlockRoots: [Data](), latestEth1Data: latestEth1Data, - eth1DataVotes: [Eth1DataVote]() + eth1DataVotes: [Eth1DataVote](), + depositIndex: UInt64(depositLength) ) } } @@ -435,15 +446,17 @@ extension BeaconChain { proofOfPossession: BLSSignature, withdrawalCredentials: Bytes32 ) { - assert( - validateProofOfPossesion( - state: state, - pubkey: pubkey, - proofOfPossession: proofOfPossession, - withdrawalCredentials: withdrawalCredentials - ) + let proofIsValid = validateProofOfPossesion( + state: state, + pubkey: pubkey, + proofOfPossession: proofOfPossession, + withdrawalCredentials: withdrawalCredentials ) + if !proofIsValid { + return + } + if let index = state.validatorRegistry.firstIndex(where: { $0.pubkey == pubkey }) { assert(state.validatorRegistry[index].withdrawalCredentials == withdrawalCredentials) state.validatorBalances[index] += amount @@ -484,7 +497,8 @@ extension BeaconChain { state.validatorRegistry[Int(index)] = validator } - static func penalizeValidator(state: inout BeaconState, index: ValidatorIndex) { + 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) @@ -494,10 +508,13 @@ extension BeaconChain { state.validatorBalances[Int(whistleblowerIndex)] += whistleblowerReward state.validatorBalances[Int(index)] -= whistleblowerReward - state.validatorRegistry[Int(index)].slashedEpoch = getCurrentEpoch(state: state) + + let currentEpoch = getCurrentEpoch(state: state) + state.validatorRegistry[Int(index)].slashedEpoch = currentEpoch + state.validatorRegistry[Int(index)].withdrawableEpoch = currentEpoch + LATEST_SLASHED_EXIT_LENGTH } static func prepareValidatorForWithdrawal(state: inout BeaconState, index: ValidatorIndex) { - state.validatorRegistry[Int(index)].statusFlags |= StatusFlag.WITHDRAWABLE.rawValue + state.validatorRegistry[Int(index)].withdrawableEpoch = getCurrentEpoch(state: state) + MIN_VALIDATOR_WITHDRAWABILITY_DELAY } } diff --git a/Sources/BeaconChain/DataStructures/State/Validator.swift b/Sources/BeaconChain/DataStructures/State/Validator.swift index 2139e83..d07c4da 100644 --- a/Sources/BeaconChain/DataStructures/State/Validator.swift +++ b/Sources/BeaconChain/DataStructures/State/Validator.swift @@ -5,7 +5,7 @@ struct Validator { let withdrawalCredentials: Data var activationEpoch: UInt64 var exitEpoch: UInt64 - let withdrawableEpoch: UInt64 + var withdrawableEpoch: UInt64 var slashedEpoch: UInt64 var statusFlags: UInt64 diff --git a/Sources/BeaconChain/StateTransition.swift b/Sources/BeaconChain/StateTransition.swift index 2cc1f0a..1216f72 100644 --- a/Sources/BeaconChain/StateTransition.swift +++ b/Sources/BeaconChain/StateTransition.swift @@ -111,7 +111,7 @@ extension StateTransition { ) ) - BeaconChain.penalizeValidator(state: &state, index: proposerSlashing.proposerIndex) + BeaconChain.slashValidator(state: &state, index: proposerSlashing.proposerIndex) } } @@ -139,7 +139,7 @@ extension StateTransition { assert(slashableIndices.count >= 1) for i in slashableIndices { - BeaconChain.penalizeValidator(state: &state, index: i) + BeaconChain.slashValidator(state: &state, index: i) } } } From d72cf56eb17497a841d482b43b3623de2df276c7 Mon Sep 17 00:00:00 2001 From: decanus Date: Sun, 24 Feb 2019 22:44:14 +0100 Subject: [PATCH 06/16] fixed if --- Sources/BeaconChain/StateTransition.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/BeaconChain/StateTransition.swift b/Sources/BeaconChain/StateTransition.swift index 1216f72..188f33f 100644 --- a/Sources/BeaconChain/StateTransition.swift +++ b/Sources/BeaconChain/StateTransition.swift @@ -151,7 +151,7 @@ extension StateTransition { assert(attestation.data.slot <= state.slot - MIN_ATTESTATION_INCLUSION_DELAY) assert(state.slot - MIN_ATTESTATION_INCLUSION_DELAY < attestation.data.slot + SLOTS_PER_EPOCH) - let e = attestation.data.justifiedEpoch >= BeaconChain.getCurrentEpoch(state: state) ? state.justifiedEpoch : state.previousJustifiedEpoch + let e = (attestation.data.slot + 1).toEpoch() >= BeaconChain.getCurrentEpoch(state: state) ? state.justifiedEpoch : state.previousJustifiedEpoch assert(attestation.data.justifiedEpoch == e) assert(attestation.data.justifiedBlockRoot == BeaconChain.getBlockRoot(state: state, slot: attestation.data.justifiedEpoch.startSlot())) From b64c47a1d39cf6fa4eacbad37fb9cda788189840 Mon Sep 17 00:00:00 2001 From: decanus Date: Sun, 24 Feb 2019 22:53:49 +0100 Subject: [PATCH 07/16] fixed tests --- Sources/BeaconChain/BeaconChain.swift | 2 +- Sources/BeaconChain/Constants.swift | 4 ++-- Sources/BeaconChain/StateTransition.swift | 6 +++++- Tests/BeaconChainTests/BeaconChainTests.swift | 10 ++++++---- .../DataStructures/State/ValidatorTests.swift | 2 +- .../Extensions/Array+ValidatorIndexTests.swift | 3 ++- .../Extensions/Array+ValidatorTests.swift | 4 ++-- .../Extensions/EpochNumberTests.swift | 13 ------------- Tests/BeaconChainTests/Extensions/EpochTests.swift | 13 +++++++++++++ .../Extensions/SlotNumberTests.swift | 9 --------- Tests/BeaconChainTests/Extensions/SlotTests.swift | 9 +++++++++ Tests/BeaconChainTests/XCTestManifests.swift | 4 ++-- 12 files changed, 43 insertions(+), 36 deletions(-) delete mode 100644 Tests/BeaconChainTests/Extensions/EpochNumberTests.swift create mode 100644 Tests/BeaconChainTests/Extensions/EpochTests.swift delete mode 100644 Tests/BeaconChainTests/Extensions/SlotNumberTests.swift create mode 100644 Tests/BeaconChainTests/Extensions/SlotTests.swift diff --git a/Sources/BeaconChain/BeaconChain.swift b/Sources/BeaconChain/BeaconChain.swift index 8fb5499..49223e7 100644 --- a/Sources/BeaconChain/BeaconChain.swift +++ b/Sources/BeaconChain/BeaconChain.swift @@ -373,7 +373,7 @@ extension BeaconChain { let genesisActiveIndexRoot = hashTreeRoot(state.validatorRegistry.activeIndices(epoch: GENESIS_EPOCH)) for i in 0.. Bool { var value = leaf for i in 0..= validator.slashedEpoch + penalizedWithdrawalEpochs } else { - return currentEpoch >= validator.slashedEpoch + MIN_VALIDATOR_WITHDRAWAL_DELAY + return currentEpoch >= validator.slashedEpoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY } } diff --git a/Tests/BeaconChainTests/BeaconChainTests.swift b/Tests/BeaconChainTests/BeaconChainTests.swift index 4bf714f..d8e78c0 100644 --- a/Tests/BeaconChainTests/BeaconChainTests.swift +++ b/Tests/BeaconChainTests/BeaconChainTests.swift @@ -69,19 +69,20 @@ final class BeaconChainTests: XCTestCase { XCTAssertEqual( BeaconChain.getDomain(fork: data, epoch: 9, domainType: Domain.PROPOSAL), - EpochNumber((2*constant)+2) + Epoch((2*constant)+2) ) XCTAssertEqual( BeaconChain.getDomain(fork: data, epoch: 11, domainType: Domain.EXIT), - EpochNumber((3*constant)+3) + Epoch((3*constant)+3) ) } func testInitiateValidatorExit() { var state = BeaconChain.genesisState( genesisTime: 0, - latestEth1Data: Eth1Data(depositRoot: Data(count: 32), blockHash: Data(count: 32)) + latestEth1Data: Eth1Data(depositRoot: Data(count: 32), blockHash: Data(count: 32)), + depositLength: 0 ) for _ in 0..<3 { @@ -107,7 +108,8 @@ final class BeaconChainTests: XCTestCase { func testActivateValidator() { var state = BeaconChain.genesisState( genesisTime: 0, - latestEth1Data: Eth1Data(depositRoot: Data(count: 32), blockHash: Data(count: 32)) + latestEth1Data: Eth1Data(depositRoot: Data(count: 32), blockHash: Data(count: 32)), + depositLength: 0 ) state.slot = 10 diff --git a/Tests/BeaconChainTests/DataStructures/State/ValidatorTests.swift b/Tests/BeaconChainTests/DataStructures/State/ValidatorTests.swift index c6e6b04..2d9fafc 100644 --- a/Tests/BeaconChainTests/DataStructures/State/ValidatorTests.swift +++ b/Tests/BeaconChainTests/DataStructures/State/ValidatorTests.swift @@ -4,7 +4,7 @@ import XCTest final class ValidatorTests: XCTestCase { func testIsActive() { - let epoch = EpochNumber(10) + let epoch = Epoch(10) XCTAssertFalse(createValidator(epoch: epoch).isActive(epoch: epoch + 2)) XCTAssertTrue(createValidator(epoch: epoch).isActive(epoch: epoch)) diff --git a/Tests/BeaconChainTests/Extensions/Array+ValidatorIndexTests.swift b/Tests/BeaconChainTests/Extensions/Array+ValidatorIndexTests.swift index 09d3f7a..5babb23 100644 --- a/Tests/BeaconChainTests/Extensions/Array+ValidatorIndexTests.swift +++ b/Tests/BeaconChainTests/Extensions/Array+ValidatorIndexTests.swift @@ -6,7 +6,8 @@ final class ArrayValidatorIndexTests: XCTestCase { func testTotalBalance() { var state = BeaconChain.genesisState( genesisTime: 10, - latestEth1Data: Eth1Data(depositRoot: Data(count: 32), blockHash: Data(count: 32)) + latestEth1Data: Eth1Data(depositRoot: Data(count: 32), blockHash: Data(count: 32)), + depositLength: 0 ) // @todo make dynamic diff --git a/Tests/BeaconChainTests/Extensions/Array+ValidatorTests.swift b/Tests/BeaconChainTests/Extensions/Array+ValidatorTests.swift index a9b4e27..dcccf37 100644 --- a/Tests/BeaconChainTests/Extensions/Array+ValidatorTests.swift +++ b/Tests/BeaconChainTests/Extensions/Array+ValidatorTests.swift @@ -5,12 +5,12 @@ final class ArrayValidatorTests: XCTestCase { func testActiveIndices() { - let epoch = EpochNumber(10) + let epoch = Epoch(10) let validators = [ createValidator(epoch: epoch), createValidator(epoch: epoch), - createValidator(epoch: EpochNumber(12)) + createValidator(epoch: Epoch(12)) ] XCTAssertEqual(validators.activeIndices(epoch: epoch), [ValidatorIndex(0), 1]) diff --git a/Tests/BeaconChainTests/Extensions/EpochNumberTests.swift b/Tests/BeaconChainTests/Extensions/EpochNumberTests.swift deleted file mode 100644 index e2a2230..0000000 --- a/Tests/BeaconChainTests/Extensions/EpochNumberTests.swift +++ /dev/null @@ -1,13 +0,0 @@ -import XCTest -@testable import BeaconChain - -final class EpochNumberTests: XCTestCase { - - func testStartSlot() { - XCTAssertEqual(EpochNumber(1).startSlot(), 64) - } - - func testEntryExitEpoch() { - XCTAssertEqual(EpochNumber(1).entryExitEpoch(), 6) - } -} diff --git a/Tests/BeaconChainTests/Extensions/EpochTests.swift b/Tests/BeaconChainTests/Extensions/EpochTests.swift new file mode 100644 index 0000000..ad74ba0 --- /dev/null +++ b/Tests/BeaconChainTests/Extensions/EpochTests.swift @@ -0,0 +1,13 @@ +import XCTest +@testable import BeaconChain + +final class EpochTests: XCTestCase { + + func testStartSlot() { + XCTAssertEqual(Epoch(1).startSlot(), 64) + } + + func testEntryExitEpoch() { + XCTAssertEqual(Epoch(1).entryExitEpoch(), 6) + } +} diff --git a/Tests/BeaconChainTests/Extensions/SlotNumberTests.swift b/Tests/BeaconChainTests/Extensions/SlotNumberTests.swift deleted file mode 100644 index c5d7e0c..0000000 --- a/Tests/BeaconChainTests/Extensions/SlotNumberTests.swift +++ /dev/null @@ -1,9 +0,0 @@ -import XCTest -@testable import BeaconChain - -final class SlotNumberTests: XCTestCase { - - func testToEpoch() { - XCTAssertEqual(SlotNumber(128).toEpoch(), 2) - } -} \ No newline at end of file diff --git a/Tests/BeaconChainTests/Extensions/SlotTests.swift b/Tests/BeaconChainTests/Extensions/SlotTests.swift new file mode 100644 index 0000000..b5af5d2 --- /dev/null +++ b/Tests/BeaconChainTests/Extensions/SlotTests.swift @@ -0,0 +1,9 @@ +import XCTest +@testable import BeaconChain + +final class SlotTests: XCTestCase { + + func testToEpoch() { + XCTAssertEqual(Slot(128).toEpoch(), 2) + } +} \ No newline at end of file diff --git a/Tests/BeaconChainTests/XCTestManifests.swift b/Tests/BeaconChainTests/XCTestManifests.swift index 6794d65..525da97 100644 --- a/Tests/BeaconChainTests/XCTestManifests.swift +++ b/Tests/BeaconChainTests/XCTestManifests.swift @@ -7,8 +7,8 @@ public func allTests() -> [XCTestCaseEntry] { testCase(ArrayTests.allTests), testCase(ArrayValidatorIndexTests.allTests), testCase(ArrayValidatorTests.allTests), - testCase(SlotNumberTests.allTests), - testCase(EpochNumberTests.allTests), + testCase(SlotTests.allTests), + testCase(EpochTests.allTests), testCase(ValidatorTests.allTests), // testCase(StateTransitionTests.allTests) ] From 86003c375c6304d124ba8ab792ad4d1fdf5fa701 Mon Sep 17 00:00:00 2001 From: decanus Date: Sun, 24 Feb 2019 23:01:55 +0100 Subject: [PATCH 08/16] started working on transfer --- Sources/BeaconChain/StateTransition.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Sources/BeaconChain/StateTransition.swift b/Sources/BeaconChain/StateTransition.swift index a13b6f2..f72147a 100644 --- a/Sources/BeaconChain/StateTransition.swift +++ b/Sources/BeaconChain/StateTransition.swift @@ -281,7 +281,19 @@ extension StateTransition { } static func transfers(state: inout BeaconState, block: BeaconBlock) { + assert(block.body.transfers.count <= MAX_TRANSFERS) + for transfer in block.body.transfers { + assert( + state.validatorBalances[Int(transfer.from)] == transfer.amount + transfer.fee + || state.validatorBalances[Int(transfer.from)] >= transfer.amount + transfer.fee + MIN_DEPOSIT_AMOUNT + ) + + assert(state.slot == transfer.slot) + assert(BeaconChain.getCurrentEpoch(state: state) >= state.validatorRegistry[Int(transfer.from)].withdrawableEpoch) + + // @todo * Verify that `state.validator_registry[transfer.from].withdrawal_credentials == BLS_WITHDRAWAL_PREFIX_BYTE + hash(transfer.pubkey)[1:]`. + } } static func verifyMerkleBranch(leaf: Bytes32, branch: [Bytes32], depth: Int, index: Int, root: Bytes32) -> Bool { From 216e6acc8f56f40c96bf62ee79faf00f1934701d Mon Sep 17 00:00:00 2001 From: decanus Date: Mon, 25 Feb 2019 17:32:26 +0100 Subject: [PATCH 09/16] finished transfer implementation --- Sources/BeaconChain/StateTransition.swift | 30 +++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/Sources/BeaconChain/StateTransition.swift b/Sources/BeaconChain/StateTransition.swift index f72147a..7ca3bba 100644 --- a/Sources/BeaconChain/StateTransition.swift +++ b/Sources/BeaconChain/StateTransition.swift @@ -284,6 +284,8 @@ extension StateTransition { assert(block.body.transfers.count <= MAX_TRANSFERS) for transfer in block.body.transfers { + assert(state.validatorBalances[Int(transfer.from)] >= transfer.amount) + assert(state.validatorBalances[Int(transfer.from)] >= transfer.fee) assert( state.validatorBalances[Int(transfer.from)] == transfer.amount + transfer.fee || state.validatorBalances[Int(transfer.from)] >= transfer.amount + transfer.fee + MIN_DEPOSIT_AMOUNT @@ -291,8 +293,33 @@ extension StateTransition { assert(state.slot == transfer.slot) assert(BeaconChain.getCurrentEpoch(state: state) >= state.validatorRegistry[Int(transfer.from)].withdrawableEpoch) + // @todo does this work (-1)? + assert(state.validatorRegistry[Int(transfer.from)].withdrawalCredentials == BLS_WITHDRAWAL_PREFIX_BYTE + BeaconChain.hash(transfer.pubkey)[1 ..< -1]) + + let message = BeaconChain.hashTreeRoot( + Transfer( + from: transfer.from, + to: transfer.to, + amount: transfer.amount, + fee: transfer.fee, + slot: transfer.slot, + pubkey: transfer.pubkey, + signature: EMPTY_SIGNATURE + ) + ) + + assert( + BLS.verify( + pubkey: transfer.pubkey, + message: message, + signature: transfer.signature, + domain: BeaconChain.getDomain(fork: state.fork, epoch: transfer.slot.toEpoch(), domainType: Domain.TRANSFER) + ) + ) - // @todo * Verify that `state.validator_registry[transfer.from].withdrawal_credentials == BLS_WITHDRAWAL_PREFIX_BYTE + hash(transfer.pubkey)[1:]`. + state.validatorBalances[Int(transfer.from)] -= transfer.amount + transfer.fee + state.validatorBalances[Int(transfer.to)] += transfer.amount + state.validatorBalances[BeaconChain.getBeaconProposerIndex(state: state, slot: state.slot)] += transfer.fee } } @@ -327,7 +354,6 @@ extension StateTransition { let currentEpochBoundryAttestations = currentEpochAttestations.filter { $0.data.epochBoundaryRoot == BeaconChain.getBlockRoot(state: state, slot: currentEpoch.startSlot()) - && $0.data.justifiedEpoch == state.justifiedEpoch } let currentEpochBoundaryAttesterIndices = currentEpochBoundryAttestations.flatMap { From 0c3948d77c567d870b2550785565390db0ce2ce4 Mon Sep 17 00:00:00 2001 From: decanus Date: Mon, 25 Feb 2019 17:32:59 +0100 Subject: [PATCH 10/16] spellcheck --- Sources/BeaconChain/StateTransition.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/BeaconChain/StateTransition.swift b/Sources/BeaconChain/StateTransition.swift index 7ca3bba..d785c73 100644 --- a/Sources/BeaconChain/StateTransition.swift +++ b/Sources/BeaconChain/StateTransition.swift @@ -352,11 +352,11 @@ extension StateTransition { currentEpoch == $0.data.slot.toEpoch() } - let currentEpochBoundryAttestations = currentEpochAttestations.filter { + let currentEpochBoundaryAttestations = currentEpochAttestations.filter { $0.data.epochBoundaryRoot == BeaconChain.getBlockRoot(state: state, slot: currentEpoch.startSlot()) } - let currentEpochBoundaryAttesterIndices = currentEpochBoundryAttestations.flatMap { + let currentEpochBoundaryAttesterIndices = currentEpochBoundaryAttestations.flatMap { return BeaconChain.getAttestationParticipants(state: state, attestationData: $0.data, bitfield: $0.aggregationBitfield) } From 91ee53219be3b9a14ef8fbc81680d5a6efd2934e Mon Sep 17 00:00:00 2001 From: decanus Date: Mon, 25 Feb 2019 17:56:34 +0100 Subject: [PATCH 11/16] beacon chain up to date --- Sources/BeaconChain/StateTransition.swift | 61 ++++++++++------------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/Sources/BeaconChain/StateTransition.swift b/Sources/BeaconChain/StateTransition.swift index d785c73..518325a 100644 --- a/Sources/BeaconChain/StateTransition.swift +++ b/Sources/BeaconChain/StateTransition.swift @@ -319,7 +319,7 @@ extension StateTransition { state.validatorBalances[Int(transfer.from)] -= transfer.amount + transfer.fee state.validatorBalances[Int(transfer.to)] += transfer.amount - state.validatorBalances[BeaconChain.getBeaconProposerIndex(state: state, slot: state.slot)] += transfer.fee + state.validatorBalances[Int(BeaconChain.getBeaconProposerIndex(state: state, slot: state.slot))] += transfer.fee } } @@ -372,17 +372,9 @@ extension StateTransition { return BeaconChain.getAttestationParticipants(state: state, attestationData: $0.data, bitfield: $0.aggregationBitfield) } - let previousEpochJustifiedAttestations = (currentEpochAttestations + previousEpochAttestations).filter { - $0.data.justifiedEpoch == state.previousJustifiedEpoch - } - - let previousEpochJustifiedAttesterIndices = previousEpochJustifiedAttestations.flatMap { - return BeaconChain.getAttestationParticipants(state: state, attestationData: $0.data, bitfield: $0.aggregationBitfield) - } + let previousEpochAttestingBalance = previousEpochAttesterIndices.totalBalance(state: state) - let previousEpochJustifiedAttestingBalance = (previousEpochJustifiedAttesterIndices as [ValidatorIndex]).totalBalance(state: state) - - let previousEpochBoundaryAttestations = previousEpochJustifiedAttestations.filter { + let previousEpochBoundaryAttestations = previousEpochAttestations.filter { $0.data.epochBoundaryRoot == BeaconChain.getBlockRoot(state: state, slot: previousEpoch.startSlot()) } @@ -430,8 +422,7 @@ extension StateTransition { nextEpoch: nextEpoch, previousTotalBalance: previousTotalBalance, totalBalance: currentTotalBalance, - previousEpochJustifiedAttesterIndices: previousEpochJustifiedAttesterIndices, - previousEpochJustifiedAttestingBalance: previousEpochJustifiedAttestingBalance, + previousEpochAttestingBalance: previousEpochAttestingBalance, previousEpochBoundaryAttesterIndices: previousEpochBoundaryAttesterIndices, previousEpochBoundaryAttestingBalance: previousEpochBoundaryAttestingBalance, previousEpochHeadAttesterIndices: previousEpochHeadAttesterIndices, @@ -459,7 +450,8 @@ extension StateTransition { } } - processPenaltiesAndExit(state: &state) + processSlashing(state: &state) + processExitQueue(state: &state) state.latestActiveIndexRoots[Int((nextEpoch % ACTIVATION_EXIT_DELAY) % LATEST_ACTIVE_INDEX_ROOTS_LENGTH)] = BeaconChain.hashTreeRoot( state.validatorRegistry.activeIndices(epoch: nextEpoch + ACTIVATION_EXIT_DELAY) @@ -572,8 +564,7 @@ extension StateTransition { nextEpoch: Epoch, previousTotalBalance: Gwei, totalBalance: UInt64, - previousEpochJustifiedAttesterIndices: [ValidatorIndex], - previousEpochJustifiedAttestingBalance: UInt64, + previousEpochAttestingBalance: UInt64, previousEpochBoundaryAttesterIndices: [ValidatorIndex], previousEpochBoundaryAttestingBalance: UInt64, previousEpochHeadAttesterIndices: [ValidatorIndex], @@ -592,9 +583,9 @@ extension StateTransition { expectedFFGSource( state: &state, - previousEpochJustifiedAttesterIndices: previousEpochJustifiedAttesterIndices, + previousEpochAttesterIndices: previousEpochAttesterIndices, activeValidators: activeValidators, - previousEpochJustifiedAttestingBalance: previousEpochJustifiedAttestingBalance, + previousEpochAttestingBalance: previousEpochAttestingBalance, baseRewardQuotient: baseRewardQuotient, totalBalance: previousTotalBalance ) @@ -625,7 +616,7 @@ extension StateTransition { deductInactivityBalance( state: &state, activeValidators: activeValidators, - excluding: previousEpochJustifiedAttesterIndices, + excluding: previousEpochAttesterIndices, epochsSinceFinality: epochsSinceFinality, baseRewardQuotient: baseRewardQuotient ) @@ -691,7 +682,7 @@ extension StateTransition { } } - static func processPenaltiesAndExit(state: inout BeaconState) { + static func processSlashing(state: inout BeaconState) { let currentEpoch = BeaconChain.getCurrentEpoch(state: state) let activeValidatorIndices = state.validatorRegistry.activeIndices(epoch: currentEpoch) @@ -709,14 +700,17 @@ extension StateTransition { let penalty = BeaconChain.getEffectiveBalance(state: state, index: ValidatorIndex(i)) * min(totalPenalties * 3, totalBalance) / totalBalance state.validatorBalances[i] -= penalty } + } + + static func processExitQueue(state: inout BeaconState) { + let currentEpoch = BeaconChain.getCurrentEpoch(state: state) var eligibleIndices = (0..= validator.slashedEpoch + penalizedWithdrawalEpochs + if validator.withdrawableEpoch <= FAR_FUTURE_EPOCH { + return false } else { - return currentEpoch >= validator.slashedEpoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY + return currentEpoch >= validator.exitEpoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY } } @@ -724,13 +718,12 @@ extension StateTransition { state.validatorRegistry[$0].exitEpoch > state.validatorRegistry[$1].exitEpoch } - var withdrawan = 0 - for i in eligibleIndices { - BeaconChain.prepareValidatorForWithdrawal(state: &state, index: ValidatorIndex(i)) - withdrawan += 1 - if withdrawan >= MAX_EXIT_DEQUEUES_PER_EPOCH { + for (dequeues, i) in eligibleIndices.enumerated() { + if dequeues >= MAX_EXIT_DEQUEUES_PER_EPOCH { break } + + BeaconChain.prepareValidatorForWithdrawal(state: &state, index: ValidatorIndex(i)) } } @@ -796,17 +789,17 @@ extension StateTransition { static func expectedFFGSource( state: inout BeaconState, - previousEpochJustifiedAttesterIndices: [ValidatorIndex], + previousEpochAttesterIndices: [ValidatorIndex], activeValidators: Set, - previousEpochJustifiedAttestingBalance: UInt64, + previousEpochAttestingBalance: UInt64, baseRewardQuotient: UInt64, totalBalance: UInt64 ) { - for index in previousEpochJustifiedAttesterIndices { - state.validatorBalances[Int(index)] += baseReward(state: state, index: index, baseRewardQuotient: baseRewardQuotient) * previousEpochJustifiedAttestingBalance / totalBalance + for index in previousEpochAttesterIndices { + state.validatorBalances[Int(index)] += baseReward(state: state, index: index, baseRewardQuotient: baseRewardQuotient) * previousEpochAttestingBalance / totalBalance } - activeValidators.subtracting(Set(previousEpochJustifiedAttesterIndices)).forEach({ + activeValidators.subtracting(Set(previousEpochAttesterIndices)).forEach({ (index) in state.validatorBalances[Int(index)] -= baseReward(state: state, index: index, baseRewardQuotient: baseRewardQuotient) }) From 988501b4e9fbbb553a45336cc903d54080c4aab0 Mon Sep 17 00:00:00 2001 From: Dean Eigenmann Date: Mon, 25 Feb 2019 18:11:30 +0100 Subject: [PATCH 12/16] Update SlotTests.swift --- Tests/BeaconChainTests/Extensions/SlotTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/BeaconChainTests/Extensions/SlotTests.swift b/Tests/BeaconChainTests/Extensions/SlotTests.swift index b5af5d2..57c35a4 100644 --- a/Tests/BeaconChainTests/Extensions/SlotTests.swift +++ b/Tests/BeaconChainTests/Extensions/SlotTests.swift @@ -6,4 +6,4 @@ final class SlotTests: XCTestCase { func testToEpoch() { XCTAssertEqual(Slot(128).toEpoch(), 2) } -} \ No newline at end of file +} From 0ed8772b7080b08cf62408e6372f9b6e10269ce2 Mon Sep 17 00:00:00 2001 From: decanus Date: Mon, 25 Feb 2019 18:34:54 +0100 Subject: [PATCH 13/16] changes --- Sources/BeaconChain/StateTransition.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/BeaconChain/StateTransition.swift b/Sources/BeaconChain/StateTransition.swift index 518325a..ad5b7c0 100644 --- a/Sources/BeaconChain/StateTransition.swift +++ b/Sources/BeaconChain/StateTransition.swift @@ -26,7 +26,7 @@ extension StateTransition { attesterSlashings(state: &state, block: block) attestations(state: &state, block: block) deposits(state: &state, block: block) - exits(state: &state, block: block) + voluntaryExits(state: &state, block: block) } static func proposerSignature(state: inout BeaconState, block: BeaconBlock) { @@ -253,7 +253,7 @@ extension StateTransition { } } - static func exits(state: inout BeaconState, block: BeaconBlock) { + static func voluntaryExits(state: inout BeaconState, block: BeaconBlock) { assert(block.body.voluntaryExits.count <= MAX_VOLUNTARY_EXITS) for exit in block.body.voluntaryExits { @@ -294,7 +294,7 @@ extension StateTransition { assert(state.slot == transfer.slot) assert(BeaconChain.getCurrentEpoch(state: state) >= state.validatorRegistry[Int(transfer.from)].withdrawableEpoch) // @todo does this work (-1)? - assert(state.validatorRegistry[Int(transfer.from)].withdrawalCredentials == BLS_WITHDRAWAL_PREFIX_BYTE + BeaconChain.hash(transfer.pubkey)[1 ..< -1]) + assert(state.validatorRegistry[Int(transfer.from)].withdrawalCredentials == BLS_WITHDRAWAL_PREFIX_BYTE + BeaconChain.hash(transfer.pubkey).suffix(from: 1)) let message = BeaconChain.hashTreeRoot( Transfer( From 42e087c1321a05ff34d9923570db05e7cc86cb46 Mon Sep 17 00:00:00 2001 From: decanus Date: Mon, 25 Feb 2019 18:36:43 +0100 Subject: [PATCH 14/16] remove todo --- Sources/BeaconChain/StateTransition.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Sources/BeaconChain/StateTransition.swift b/Sources/BeaconChain/StateTransition.swift index ad5b7c0..51c0634 100644 --- a/Sources/BeaconChain/StateTransition.swift +++ b/Sources/BeaconChain/StateTransition.swift @@ -293,7 +293,6 @@ extension StateTransition { assert(state.slot == transfer.slot) assert(BeaconChain.getCurrentEpoch(state: state) >= state.validatorRegistry[Int(transfer.from)].withdrawableEpoch) - // @todo does this work (-1)? assert(state.validatorRegistry[Int(transfer.from)].withdrawalCredentials == BLS_WITHDRAWAL_PREFIX_BYTE + BeaconChain.hash(transfer.pubkey).suffix(from: 1)) let message = BeaconChain.hashTreeRoot( From 34f72faf6737e020bdb50c4355500c48bc5986c6 Mon Sep 17 00:00:00 2001 From: decanus Date: Mon, 25 Feb 2019 18:37:33 +0100 Subject: [PATCH 15/16] using append --- Sources/BeaconChain/StateTransition.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/BeaconChain/StateTransition.swift b/Sources/BeaconChain/StateTransition.swift index 51c0634..ce0e1d0 100644 --- a/Sources/BeaconChain/StateTransition.swift +++ b/Sources/BeaconChain/StateTransition.swift @@ -293,7 +293,7 @@ extension StateTransition { assert(state.slot == transfer.slot) assert(BeaconChain.getCurrentEpoch(state: state) >= state.validatorRegistry[Int(transfer.from)].withdrawableEpoch) - assert(state.validatorRegistry[Int(transfer.from)].withdrawalCredentials == BLS_WITHDRAWAL_PREFIX_BYTE + BeaconChain.hash(transfer.pubkey).suffix(from: 1)) + assert(state.validatorRegistry[Int(transfer.from)].withdrawalCredentials == BLS_WITHDRAWAL_PREFIX_BYTE.append(BeaconChain.hash(transfer.pubkey).suffix(from: 1))) let message = BeaconChain.hashTreeRoot( Transfer( From 8892c46d332d2f17cacb147ce3018f97bb36ba09 Mon Sep 17 00:00:00 2001 From: decanus Date: Mon, 25 Feb 2019 18:38:14 +0100 Subject: [PATCH 16/16] plus --- Sources/BeaconChain/StateTransition.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/BeaconChain/StateTransition.swift b/Sources/BeaconChain/StateTransition.swift index ce0e1d0..51c0634 100644 --- a/Sources/BeaconChain/StateTransition.swift +++ b/Sources/BeaconChain/StateTransition.swift @@ -293,7 +293,7 @@ extension StateTransition { assert(state.slot == transfer.slot) assert(BeaconChain.getCurrentEpoch(state: state) >= state.validatorRegistry[Int(transfer.from)].withdrawableEpoch) - assert(state.validatorRegistry[Int(transfer.from)].withdrawalCredentials == BLS_WITHDRAWAL_PREFIX_BYTE.append(BeaconChain.hash(transfer.pubkey).suffix(from: 1))) + assert(state.validatorRegistry[Int(transfer.from)].withdrawalCredentials == BLS_WITHDRAWAL_PREFIX_BYTE + BeaconChain.hash(transfer.pubkey).suffix(from: 1)) let message = BeaconChain.hashTreeRoot( Transfer(