Skip to content

Commit

Permalink
add time provider (#59)
Browse files Browse the repository at this point in the history
  • Loading branch information
xlc authored Aug 13, 2024
1 parent 77b3dd3 commit 186f1d0
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 4 deletions.
7 changes: 5 additions & 2 deletions Blockchain/Sources/Blockchain/Blockchain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ public final class Blockchain: Sendable {
public let config: ProtocolConfigRef

private let dataProvider: BlockchainDataProvider
private let timeProvider: TimeProvider

public init(config: ProtocolConfigRef, dataProvider: BlockchainDataProvider) async {
public init(config: ProtocolConfigRef, dataProvider: BlockchainDataProvider, timeProvider: TimeProvider) async {
self.config = config
self.dataProvider = dataProvider
self.timeProvider = timeProvider
}

public func importBlock(_ block: BlockRef) async throws {
Expand All @@ -21,7 +23,8 @@ public final class Blockchain: Sendable {

let runtime = Runtime(config: config)
let parent = try await dataProvider.getState(hash: block.header.parentHash)
let state = try runtime.apply(block: block, state: parent)
let timeslot = timeProvider.getTime() / UInt32(config.value.slotPeriodSeconds)
let state = try runtime.apply(block: block, state: parent, context: .init(timeslot: timeslot))
try await dataProvider.add(state: state)
}
}
Expand Down
22 changes: 21 additions & 1 deletion Blockchain/Sources/Blockchain/Runtime.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ public final class Runtime {
public enum Error: Swift.Error {
case safroleError(SafroleError)
case invalidValidatorEd25519Key
case invalidTimeslot
}

public struct ApplyContext {
public let timeslot: TimeslotIndex

public init(timeslot: TimeslotIndex) {
self.timeslot = timeslot
}
}

public let config: ProtocolConfigRef
Expand All @@ -13,7 +22,18 @@ public final class Runtime {
self.config = config
}

public func apply(block: BlockRef, state prevState: StateRef) throws(Error) -> StateRef {
public func validate(block: BlockRef, state _: StateRef, context: ApplyContext) throws(Error) {
guard context.timeslot >= block.header.timeslotIndex else {
throw Error.invalidTimeslot
}

// TODO: validate block.header.seal
// TODO: abstract input validation logic from Safrole state update function and call it here
}

public func apply(block: BlockRef, state prevState: StateRef, context: ApplyContext) throws(Error) -> StateRef {
try validate(block: block, state: prevState, context: context)

var newState = prevState.value
newState.lastBlock = block

Expand Down
35 changes: 35 additions & 0 deletions Blockchain/Sources/Blockchain/TimeProvider.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import Foundation

public protocol TimeProvider: Sendable {
func getTime() -> UInt32
}

public struct SystemTimeProvider: TimeProvider {
public init() {}

public func getTime() -> UInt32 {
Date().timeIntervalSinceJamCommonEra
}
}

public struct FixedTimeProvider: TimeProvider {
private let time: UInt32

public init(time: UInt32) {
self.time = time
}

public func getTime() -> UInt32 {
time
}
}

extension Date {
public var timeIntervalSinceJamCommonEra: UInt32 {
// the Jam Common Era: 1200 UTC on January 1, 2024
// number of seconds since the Unix epoch
let beginning = 1_704_110_400.0
let now = timeIntervalSince1970
return UInt32(now - beginning)
}
}
3 changes: 2 additions & 1 deletion Node/Sources/Node/Node.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ public class Node {

let genesisState = try genesis.toState(config: config.protcol)
let dataProvider = await InMemoryDataProvider(genesis: genesisState)
blockchain = await Blockchain(config: config.protcol, dataProvider: dataProvider)
let timeProvider = SystemTimeProvider()
blockchain = await Blockchain(config: config.protcol, dataProvider: dataProvider, timeProvider: timeProvider)

rpcServer = try Server(config: config.rpc, source: blockchain)
}
Expand Down

0 comments on commit 186f1d0

Please sign in to comment.