diff --git a/Blockchain/Sources/Blockchain/Config/ProtocolConfig.swift b/Blockchain/Sources/Blockchain/Config/ProtocolConfig.swift index 7884d01c..988cbe63 100644 --- a/Blockchain/Sources/Blockchain/Config/ProtocolConfig.swift +++ b/Blockchain/Sources/Blockchain/Config/ProtocolConfig.swift @@ -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. diff --git a/Blockchain/Sources/Blockchain/RuntimeProtocols/Accumulation.swift b/Blockchain/Sources/Blockchain/RuntimeProtocols/Accumulation.swift index d5190e81..6cf55f9b 100644 --- a/Blockchain/Sources/Blockchain/RuntimeProtocols/Accumulation.swift +++ b/Blockchain/Sources/Blockchain/RuntimeProtocols/Accumulation.swift @@ -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 diff --git a/Blockchain/Sources/Blockchain/RuntimeProtocols/Runtime.swift b/Blockchain/Sources/Blockchain/RuntimeProtocols/Runtime.swift index eb50be6f..d3b1dc13 100644 --- a/Blockchain/Sources/Blockchain/RuntimeProtocols/Runtime.swift +++ b/Blockchain/Sources/Blockchain/RuntimeProtocols/Runtime.swift @@ -60,7 +60,15 @@ public final class Runtime { throw Error.invalidHeaderStateRoot } - let expectedExtrinsicHash = try Result { try JamEncoder.encode(block.extrinsic).blake2b256hash() } + let expectedExtrinsicHash = try Result { try JamEncoder.encode([ + JamEncoder.encode(block.extrinsic.tickets).blake2b256hash(), + JamEncoder.encode(block.extrinsic.preimages).blake2b256hash(), + JamEncoder.encode(block.extrinsic.reports.guarantees.array.map { item in + try JamEncoder.encode(item.workReport.hash()) + JamEncoder.encode(item.timeslot) + JamEncoder.encode(item.credential) + }).blake2b256hash(), + JamEncoder.encode(block.extrinsic.availability).blake2b256hash(), + JamEncoder.encode(block.extrinsic.disputes).blake2b256hash(), + ]).blake2b256hash() } .mapError(Error.encodeError).get() guard block.header.extrinsicsHash == expectedExtrinsicHash else { @@ -297,7 +305,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 { @@ -379,7 +387,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 { @@ -388,14 +396,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) diff --git a/Blockchain/Sources/Blockchain/State/State.swift b/Blockchain/Sources/Blockchain/State/State.swift index 6295ae5e..e1284322 100644 --- a/Blockchain/Sources/Blockchain/State/State.swift +++ b/Blockchain/Sources/Blockchain/State/State.swift @@ -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: [:] diff --git a/Blockchain/Sources/Blockchain/Types/AvailabilitySpecifications.swift b/Blockchain/Sources/Blockchain/Types/AvailabilitySpecifications.swift index 0013f9c8..4a8f0346 100644 --- a/Blockchain/Sources/Blockchain/Types/AvailabilitySpecifications.swift +++ b/Blockchain/Sources/Blockchain/Types/AvailabilitySpecifications.swift @@ -14,16 +14,21 @@ public struct AvailabilitySpecifications: Sendable, Equatable, Codable { // e public var segmentRoot: Data32 + // n + public var segmentCount: Int + public init( workPackageHash: Data32, length: DataLength, erasureRoot: Data32, - segmentRoot: Data32 + segmentRoot: Data32, + segmentCount: Int ) { self.workPackageHash = workPackageHash self.length = length self.erasureRoot = erasureRoot self.segmentRoot = segmentRoot + self.segmentCount = segmentCount } } @@ -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? { diff --git a/Blockchain/Sources/Blockchain/Types/Extrinsic.swift b/Blockchain/Sources/Blockchain/Types/Extrinsic.swift index 62dbabef..4c96d1f9 100644 --- a/Blockchain/Sources/Blockchain/Types/Extrinsic.swift +++ b/Blockchain/Sources/Blockchain/Types/Extrinsic.swift @@ -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 @@ -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) diff --git a/Blockchain/Sources/Blockchain/Types/PrivilegedServices.swift b/Blockchain/Sources/Blockchain/Types/PrivilegedServices.swift index 30061f48..a0850284 100644 --- a/Blockchain/Sources/Blockchain/Types/PrivilegedServices.swift +++ b/Blockchain/Sources/Blockchain/Types/PrivilegedServices.swift @@ -3,7 +3,7 @@ import Utils public struct PrivilegedServices: Sendable, Equatable, Codable { // m - public var empower: ServiceIndex + public var blessed: ServiceIndex // a public var assign: ServiceIndex // v @@ -11,8 +11,8 @@ public struct PrivilegedServices: Sendable, Equatable, Codable { // g @CodingAs> 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 diff --git a/Blockchain/Sources/Blockchain/VMInvocations/HostCall/HostCalls.swift b/Blockchain/Sources/Blockchain/VMInvocations/HostCall/HostCalls.swift index ea414bdd..5ba7e920 100644 --- a/Blockchain/Sources/Blockchain/VMInvocations/HostCall/HostCalls.swift +++ b/Blockchain/Sources/Blockchain/VMInvocations/HostCall/HostCalls.swift @@ -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 diff --git a/Blockchain/Sources/Blockchain/Validator/BlockAuthor.swift b/Blockchain/Sources/Blockchain/Validator/BlockAuthor.swift index 785a027f..a55f72e8 100644 --- a/Blockchain/Sources/Blockchain/Validator/BlockAuthor.swift +++ b/Blockchain/Sources/Blockchain/Validator/BlockAuthor.swift @@ -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: diff --git a/Blockchain/Tests/BlockchainTests/ExtrinsicPoolServiceTests.swift b/Blockchain/Tests/BlockchainTests/ExtrinsicPoolServiceTests.swift index 9c993ea0..e9a17aa4 100644 --- a/Blockchain/Tests/BlockchainTests/ExtrinsicPoolServiceTests.swift +++ b/Blockchain/Tests/BlockchainTests/ExtrinsicPoolServiceTests.swift @@ -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) diff --git a/JAMTests/Tests/JAMTests/CodecTests.swift b/JAMTests/Tests/JAMTests/CodecTests.swift index adf9b875..f5787dc1 100644 --- a/JAMTests/Tests/JAMTests/CodecTests.swift +++ b/JAMTests/Tests/JAMTests/CodecTests.swift @@ -197,7 +197,7 @@ struct CodecTests { if let value = value as? Extrinsic { return [ "tickets": transform(json["tickets"]!, value: value.tickets), - "disputes": transform(json["judgements"]!, value: value.judgements), + "disputes": transform(json["disputes"]!, value: value.disputes), "preimages": transform(json["preimages"]!, value: value.preimages), "assurances": transform(json["availability"]!, value: value.availability), "guarantees": transform(json["reports"]!, value: value.reports),