Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.5.0 updates #228

Merged
merged 5 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Blockchain/Sources/Blockchain/Config/ProtocolConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public struct ProtocolConfig: Sendable, Codable, Equatable {
// P = 6: The slot period, in seconds.
public var slotPeriodSeconds: Int

// Q = 80: The maximum number of items in the authorizations queue.
// Q = 80: The number of items in the authorizations queue.
public var maxAuthorizationsQueueItems: Int

// R = 10: The rotation period of validator-core assignments, in timeslots.
Expand Down Expand Up @@ -107,7 +107,7 @@ public struct ProtocolConfig: Sendable, Codable, Equatable {
// ZI = 2^24: The standard pvm program initialization input data size.
public var pvmProgramInitInputDataSize: Int

// ZP = 2^14: The standard pvm program initialization page size.
// ZG = 2^14: The standard pvm program initialization page size.
public var pvmProgramInitPageSize: Int

// ZQ = 2^16: The standard pvm program initialization segment size.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ extension Accumulation {
}

switch service {
case privilegedServices.empower:
case privilegedServices.blessed:
newPrivilegedServices = singleOutput.state.privilegedServices
case privilegedServices.assign:
newAuthorizationQueue = singleOutput.state.authorizationQueue
Expand Down
25 changes: 17 additions & 8 deletions Blockchain/Sources/Blockchain/RuntimeProtocols/Runtime.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,7 @@ public final class Runtime {
throw Error.invalidHeaderStateRoot
}

let expectedExtrinsicHash = try Result { try JamEncoder.encode(block.extrinsic).blake2b256hash() }
.mapError(Error.encodeError).get()

guard block.header.extrinsicsHash == expectedExtrinsicHash else {
guard block.header.extrinsicsHash == block.extrinsic.hash() else {
throw Error.invalidExtrinsicHash
}

Expand Down Expand Up @@ -297,7 +294,7 @@ public final class Runtime {
}

public func updateDisputes(block: BlockRef, state newState: inout State) throws {
let (posState, offenders) = try newState.update(config: config, disputes: block.extrinsic.judgements)
let (posState, offenders) = try newState.update(config: config, disputes: block.extrinsic.disputes)
newState.mergeWith(postState: posState)

guard offenders == block.header.offendersMarkers else {
Expand Down Expand Up @@ -379,7 +376,7 @@ public final class Runtime {
return availableReports
}

public func updatePreimages(block: BlockRef, state newState: inout State) async throws {
public func updatePreimages(block: BlockRef, state newState: inout State, prevState: StateRef) async throws {
let preimages = block.extrinsic.preimages.preimages

guard preimages.isSortedAndUnique() else {
Expand All @@ -388,14 +385,26 @@ public final class Runtime {

for preimage in preimages {
let hash = preimage.data.blake2b256hash()

// check prior state
let prevPreimageData: Data? = try await prevState.value.get(serviceAccount: preimage.serviceIndex, preimageHash: hash)
let prevInfo = try await prevState.value.get(
serviceAccount: preimage.serviceIndex, preimageHash: hash, length: UInt32(preimage.data.count)
)
guard prevPreimageData == nil, prevInfo == nil else {
throw Error.duplicatedPreimage
}

// disregard no longer useful ones in new state
let preimageData: Data? = try await newState.get(serviceAccount: preimage.serviceIndex, preimageHash: hash)
let info = try await newState.get(
serviceAccount: preimage.serviceIndex, preimageHash: hash, length: UInt32(preimage.data.count)
)
guard preimageData == nil, info == nil else {
throw Error.duplicatedPreimage
if preimageData != nil || info != nil {
continue
}

// update state
newState[serviceAccount: preimage.serviceIndex, preimageHash: hash] = preimage.data
newState[
serviceAccount: preimage.serviceIndex, preimageHash: hash, length: UInt32(preimage.data.count)
Expand Down
2 changes: 1 addition & 1 deletion Blockchain/Sources/Blockchain/State/State.swift
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ extension State: Dummy {
let authorizationQueue: StateKeys.AuthorizationQueueKey.Value =
try! ConfigFixedSizeArray(config: config, defaultValue: ConfigFixedSizeArray(config: config, defaultValue: Data32()))
let privilegedServices: StateKeys.PrivilegedServicesKey.Value = PrivilegedServices(
empower: ServiceIndex(),
blessed: ServiceIndex(),
assign: ServiceIndex(),
designate: ServiceIndex(),
basicGas: [:]
Expand Down
26 changes: 13 additions & 13 deletions Blockchain/Sources/Blockchain/State/StateKeys.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,23 @@ private func constructKey(_ idx: UInt8, _ service: ServiceIndex) -> Data32 {
return Data32(data)!
}

private func constructKey(_ service: ServiceIndex, _ val: UInt32, _: Data) -> Data32 {
var data = Data(capacity: 32)
private func constructKey(_ service: ServiceIndex, _ val: UInt32, _ data: Data) -> Data32 {
var stateKey = Data(capacity: 32)

withUnsafeBytes(of: service) { servicePtr in
withUnsafeBytes(of: val) { valPtr in
data.append(servicePtr.load(as: UInt8.self))
data.append(valPtr.load(as: UInt8.self))
data.append(servicePtr.load(fromByteOffset: 1, as: UInt8.self))
data.append(valPtr.load(fromByteOffset: 1, as: UInt8.self))
data.append(servicePtr.load(fromByteOffset: 2, as: UInt8.self))
data.append(valPtr.load(fromByteOffset: 2, as: UInt8.self))
data.append(servicePtr.load(fromByteOffset: 3, as: UInt8.self))
data.append(valPtr.load(fromByteOffset: 3, as: UInt8.self))
stateKey.append(servicePtr.load(as: UInt8.self))
stateKey.append(valPtr.load(as: UInt8.self))
stateKey.append(servicePtr.load(fromByteOffset: 1, as: UInt8.self))
stateKey.append(valPtr.load(fromByteOffset: 1, as: UInt8.self))
stateKey.append(servicePtr.load(fromByteOffset: 2, as: UInt8.self))
stateKey.append(valPtr.load(fromByteOffset: 2, as: UInt8.self))
stateKey.append(servicePtr.load(fromByteOffset: 3, as: UInt8.self))
stateKey.append(valPtr.load(fromByteOffset: 3, as: UInt8.self))
}
}
data.append(contentsOf: data[relative: 0 ..< 24])
return Data32(data)!
stateKey.append(contentsOf: data[relative: 0 ..< 24])
return Data32(stateKey)!
}

public enum StateKeys {
Expand Down Expand Up @@ -316,7 +316,7 @@ public enum StateKeys {
}

public func encode() -> Data32 {
constructKey(index, length, hash.blake2b256hash().data)
constructKey(index, length, hash.blake2b256hash().data[2...])
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,21 @@ public struct AvailabilitySpecifications: Sendable, Equatable, Codable {
// e
public var segmentRoot: Data32

// n
public var segmentCount: UInt16

public init(
workPackageHash: Data32,
length: DataLength,
erasureRoot: Data32,
segmentRoot: Data32
segmentRoot: Data32,
segmentCount: UInt16
) {
self.workPackageHash = workPackageHash
self.length = length
self.erasureRoot = erasureRoot
self.segmentRoot = segmentRoot
self.segmentCount = segmentCount
}
}

Expand All @@ -34,14 +39,15 @@ extension AvailabilitySpecifications: Dummy {
workPackageHash: Data32(),
length: 0,
erasureRoot: Data32(),
segmentRoot: Data32()
segmentRoot: Data32(),
segmentCount: 0
)
}
}

extension AvailabilitySpecifications: EncodedSize {
public var encodedSize: Int {
workPackageHash.encodedSize + length.encodedSize + erasureRoot.encodedSize + segmentRoot.encodedSize
workPackageHash.encodedSize + length.encodedSize + erasureRoot.encodedSize + segmentRoot.encodedSize + segmentCount.encodedSize
}

public static var encodeedSizeHint: Int? {
Expand Down
26 changes: 17 additions & 9 deletions Blockchain/Sources/Blockchain/Types/Extrinsic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,28 @@ public struct Extrinsic: Sendable, Equatable, Codable {
// permissioning of block authoring
public var tickets: ExtrinsicTickets

// ED: Votes, by validators, on dispute(s) arising between them presently taking place
public var judgements: ExtrinsicDisputes

// EP: Static data which is presently being requested to be available for workloads to be able to fetch on demand
public var preimages: ExtrinsicPreimages

// EG: Reports of newly completed workloads whose accuracy is guaranteed by specific validators
public var reports: ExtrinsicGuarantees

// EA: Assurances by each validator concerning which of the input data of workloads they have
// correctly received and are storing locally
public var availability: ExtrinsicAvailability

// EG: Reports of newly completed workloads whose accuracy is guaranteed by specific validators
public var reports: ExtrinsicGuarantees
// ED: Votes, by validators, on dispute(s) arising between them presently taking place
public var disputes: ExtrinsicDisputes

public init(
tickets: ExtrinsicTickets,
judgements: ExtrinsicDisputes,
disputes: ExtrinsicDisputes,
preimages: ExtrinsicPreimages,
availability: ExtrinsicAvailability,
reports: ExtrinsicGuarantees
) {
self.tickets = tickets
self.judgements = judgements
self.disputes = disputes
self.preimages = preimages
self.availability = availability
self.reports = reports
Expand All @@ -42,7 +42,7 @@ extension Extrinsic: Dummy {
public static func dummy(config: Config) -> Extrinsic {
Extrinsic(
tickets: ExtrinsicTickets.dummy(config: config),
judgements: ExtrinsicDisputes.dummy(config: config),
disputes: ExtrinsicDisputes.dummy(config: config),
preimages: ExtrinsicPreimages.dummy(config: config),
availability: ExtrinsicAvailability.dummy(config: config),
reports: ExtrinsicGuarantees.dummy(config: config)
Expand All @@ -55,7 +55,15 @@ extension Extrinsic: Validate {}
extension Extrinsic {
public func hash() -> Data32 {
do {
return try JamEncoder.encode(self).blake2b256hash()
return try JamEncoder.encode([
JamEncoder.encode(tickets).blake2b256hash(),
JamEncoder.encode(preimages).blake2b256hash(),
JamEncoder.encode(reports.guarantees.array.map { item in
try JamEncoder.encode(item.workReport.hash()) + JamEncoder.encode(item.timeslot) + JamEncoder.encode(item.credential)
}).blake2b256hash(),
JamEncoder.encode(availability).blake2b256hash(),
JamEncoder.encode(disputes).blake2b256hash(),
]).blake2b256hash()
} catch {
logger.error("Failed to encode extrinsic, returning empty hash", metadata: ["error": "\(error)"])
return Data32()
Expand Down
6 changes: 3 additions & 3 deletions Blockchain/Sources/Blockchain/Types/PrivilegedServices.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ import Utils

public struct PrivilegedServices: Sendable, Equatable, Codable {
// m
public var empower: ServiceIndex
public var blessed: ServiceIndex
// a
public var assign: ServiceIndex
// v
public var designate: ServiceIndex
// g
@CodingAs<SortedKeyValues<ServiceIndex, Gas>> public var basicGas: [ServiceIndex: Gas]

public init(empower: ServiceIndex, assign: ServiceIndex, designate: ServiceIndex, basicGas: [ServiceIndex: Gas]) {
self.empower = empower
public init(blessed: ServiceIndex, assign: ServiceIndex, designate: ServiceIndex, basicGas: [ServiceIndex: Gas]) {
self.blessed = blessed
self.assign = assign
self.designate = designate
self.basicGas = basicGas
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ public class Empower: HostCall {

if basicGas.count != 0 {
state.writeRegister(Registers.Index(raw: 7), HostCallResultCode.OK.rawValue)
x.accumulateState.privilegedServices.empower = regs[0]
x.accumulateState.privilegedServices.blessed = regs[0]
x.accumulateState.privilegedServices.assign = regs[1]
x.accumulateState.privilegedServices.designate = regs[2]
x.accumulateState.privilegedServices.basicGas = basicGas
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ extension AccumulateFunction {
let (exitReason, gas, output) = await invokePVM(
config: config,
blob: accumulatingAccountDetails.codeHash.data,
pc: 10,
pc: 5,
gas: gas,
argumentData: argument,
ctx: ctx
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ extension OnTransferFunction {
_ = await invokePVM(
config: config,
blob: account.codeHash.data,
pc: 15,
pc: 10,
gas: gasLimitSum,
argumentData: argument,
ctx: ctx
Expand Down
2 changes: 1 addition & 1 deletion Blockchain/Sources/Blockchain/Validator/BlockAuthor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public final class BlockAuthor: ServiceBase2, @unchecked Sendable {

let extrinsic = try Extrinsic(
tickets: ExtrinsicTickets(tickets: ConfigLimitedSizeArray(config: config, array: Array(tickets))),
judgements: ExtrinsicDisputes.dummy(config: config), // TODO:
disputes: ExtrinsicDisputes.dummy(config: config), // TODO:
preimages: ExtrinsicPreimages.dummy(config: config), // TODO:
availability: ExtrinsicAvailability.dummy(config: config), // TODO:
reports: ExtrinsicGuarantees.dummy(config: config) // TODO:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ struct ExtrinsicPoolServiceTests {
let blockTickets = Array(tickets[0 ..< 2])
let extrinsic = try Extrinsic(
tickets: ExtrinsicTickets(tickets: ConfigLimitedSizeArray(config: config, array: blockTickets.map(\.ticket))),
judgements: ExtrinsicDisputes.dummy(config: config),
disputes: ExtrinsicDisputes.dummy(config: config),
preimages: ExtrinsicPreimages.dummy(config: config),
availability: ExtrinsicAvailability.dummy(config: config),
reports: ExtrinsicGuarantees.dummy(config: config)
Expand Down
Loading