Skip to content

Commit

Permalink
ActivityStatistics test (#262)
Browse files Browse the repository at this point in the history
  • Loading branch information
xlc authored Jan 6, 2025
1 parent 7c063ea commit 74aa897
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import Foundation
import Utils

enum ActivityStatisticsError: Error {
case invalidAuthorKey
}

public protocol ActivityStatistics {
var activityStatistics: ValidatorActivityStatistics { get }
var timeslot: TimeslotIndex { get }
var currentValidators: ConfigFixedSizeArray<ValidatorKey, ProtocolConfig.TotalNumberOfValidators> { get }
}

extension ActivityStatistics {
public func update(
config: ProtocolConfigRef,
newTimeslot: TimeslotIndex,
extrinsic: Extrinsic,
authorIndex: ValidatorIndex
) throws -> ValidatorActivityStatistics {
let epochLength = UInt32(config.value.epochLength)
let currentEpoch = timeslot / epochLength
let newEpoch = newTimeslot / epochLength
let isEpochChange = currentEpoch != newEpoch

var acc = try isEpochChange
? ConfigFixedSizeArray<_, ProtocolConfig.TotalNumberOfValidators>(
config: config,
defaultValue: ValidatorActivityStatistics.StatisticsItem.dummy(config: config)
) : activityStatistics.accumulator

let prev = isEpochChange ? activityStatistics.accumulator : activityStatistics.previous

var item = acc[authorIndex]
item.blocks += 1
item.tickets += UInt32(extrinsic.tickets.tickets.count)
item.preimages += UInt32(extrinsic.preimages.preimages.count)
item.preimagesBytes += UInt32(extrinsic.preimages.preimages.reduce(into: 0) { $0 += $1.data.count })
acc[authorIndex] = item

for report in extrinsic.reports.guarantees {
for cred in report.credential {
acc[cred.index].guarantees += 1
}
}

for assurance in extrinsic.availability.assurances {
acc[assurance.validatorIndex].assurances += 1
}

return ValidatorActivityStatistics(
accumulator: acc,
previous: prev
)
}
}
45 changes: 5 additions & 40 deletions Blockchain/Sources/Blockchain/RuntimeProtocols/Runtime.swift
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,11 @@ public final class Runtime {
throw Error.authorizationError(error)
}

newState.activityStatistics = try updateValidatorActivityStatistics(
block: block, state: prevState
newState.activityStatistics = try prevState.value.update(
config: config,
newTimeslot: block.header.timeslot,
extrinsic: block.extrinsic,
authorIndex: block.header.authorIndex
)

// after reports as it need old recent history
Expand Down Expand Up @@ -367,42 +370,4 @@ public final class Runtime {
] = .init([newState.timeslot])
}
}

// TODO: add tests
public func updateValidatorActivityStatistics(block: BlockRef, state: StateRef) throws -> ValidatorActivityStatistics {
let epochLength = UInt32(config.value.epochLength)
let currentEpoch = state.value.timeslot / epochLength
let newEpoch = block.header.timeslot / epochLength
let isEpochChange = currentEpoch != newEpoch

var acc = try isEpochChange
? ConfigFixedSizeArray<_, ProtocolConfig.TotalNumberOfValidators>(
config: config,
defaultValue: ValidatorActivityStatistics.StatisticsItem.dummy(config: config)
) : state.value.activityStatistics.accumulator

let prev = isEpochChange ? state.value.activityStatistics.accumulator : state.value.activityStatistics.previous

var item = acc[block.header.authorIndex]
item.blocks += 1
item.tickets += UInt32(block.extrinsic.tickets.tickets.count)
item.preimages += UInt32(block.extrinsic.preimages.preimages.count)
item.preimagesBytes += UInt32(block.extrinsic.preimages.preimages.reduce(into: 0) { $0 += $1.data.count })
acc[block.header.authorIndex] = item

for report in block.extrinsic.reports.guarantees {
for cred in report.credential {
acc[cred.index].guarantees += 1
}
}

for assurance in block.extrinsic.availability.assurances {
acc[assurance.validatorIndex].assurances += 1
}

return ValidatorActivityStatistics(
accumulator: acc,
previous: prev
)
}
}
2 changes: 2 additions & 0 deletions Blockchain/Sources/Blockchain/State/State.swift
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,8 @@ extension State: Authorization {
}
}

extension State: ActivityStatistics {}

struct DummyFunction: AccumulateFunction, OnTransferFunction {
func invoke(
config _: ProtocolConfigRef,
Expand Down
58 changes: 58 additions & 0 deletions JAMTests/Tests/JAMTests/StatisticsTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import Blockchain
import Codec
import Foundation
import Testing
import Utils

@testable import JAMTests

struct StatisticsState: Equatable, Codable, ActivityStatistics {
var activityStatistics: ValidatorActivityStatistics
var timeslot: TimeslotIndex
var currentValidators: ConfigFixedSizeArray<ValidatorKey, ProtocolConfig.TotalNumberOfValidators>
}

struct StatisticsInput: Codable {
var timeslot: TimeslotIndex
var author: ValidatorIndex
var extrinsic: Extrinsic
}

struct StatisticsTestcase: Codable {
var input: StatisticsInput
var preState: StatisticsState
var postState: StatisticsState
}

struct StatisticsTests {
static func loadTests(variant: TestVariants) throws -> [Testcase] {
try TestLoader.getTestcases(path: "statistics/\(variant)", extension: "bin")
}

func statisticsTests(_ testcase: Testcase, variant: TestVariants) throws {
let config = variant.config
let decoder = JamDecoder(data: testcase.data, config: config)
let testcase = try decoder.decode(StatisticsTestcase.self)

var state = testcase.preState
let result = try state.update(
config: config,
newTimeslot: testcase.input.timeslot,
extrinsic: testcase.input.extrinsic,
authorIndex: testcase.input.author
)
state.activityStatistics = result

#expect(state == testcase.postState)
}

@Test(arguments: try StatisticsTests.loadTests(variant: .tiny))
func tinyTests(_ testcase: Testcase) throws {
try statisticsTests(testcase, variant: .tiny)
}

@Test(arguments: try StatisticsTests.loadTests(variant: .full))
func fullTests(_ testcase: Testcase) throws {
try statisticsTests(testcase, variant: .full)
}
}

0 comments on commit 74aa897

Please sign in to comment.